DEV: Extend specs coverage for non-admin access to admin endpoints (#18833)

Replace base controller class inheritance specs with explicit specs
for non-staff and moderator access to admin resources
This commit is contained in:
Selase Krakani
2022-11-03 03:42:44 +00:00
committed by GitHub
parent 612ab8710a
commit 52be5b3782
31 changed files with 7047 additions and 3433 deletions

View File

@ -1,47 +1,73 @@
# frozen_string_literal: true
RSpec.describe Admin::ApiController do
it "is a subclass of AdminController" do
expect(Admin::ApiController < Admin::AdminController).to eq(true)
end
fab!(:admin) { Fabricate(:admin) }
fab!(:moderator) { Fabricate(:moderator) }
fab!(:user) { Fabricate(:user) }
fab!(:key1, refind: false) { Fabricate(:api_key, description: "my key") }
fab!(:key2, refind: false) { Fabricate(:api_key, user: admin) }
fab!(:key3, refind: false) { Fabricate(:api_key, user: admin) }
context "as an admin" do
before do
sign_in(admin)
end
describe '#index' do
context "when logged in as an admin" do
before { sign_in(admin) }
describe '#index' do
it "succeeds" do
it "returns keys successfully" do
get "/admin/api/keys.json"
expect(response.status).to eq(200)
expect(response.parsed_body["keys"].length).to eq(3)
end
it "can paginate results" do
get "/admin/api/keys.json?offset=0&limit=2"
expect(response.status).to eq(200)
expect(response.parsed_body["keys"].map { |x| x["id"] }).to contain_exactly(key3.id, key2.id)
get "/admin/api/keys.json?offset=1&limit=2"
expect(response.status).to eq(200)
expect(response.parsed_body["keys"].map { |x| x["id"] }).to contain_exactly(key2.id, key1.id)
get "/admin/api/keys.json?offset=2&limit=2"
expect(response.status).to eq(200)
expect(response.parsed_body["keys"].map { |x| x["id"] }).to contain_exactly(key1.id)
end
end
describe '#show' do
it "succeeds" do
shared_examples "keys inaccessible" do
it "denies keys access with a 404 response" do
get "/admin/api/keys.json"
expect(response.status).to eq(404)
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
expect(response.parsed_body["keys"]).to be_nil
end
end
context "when logged in as a moderator" do
before { sign_in(moderator) }
include_examples "keys inaccessible"
end
context "when logged in as a non-staff user" do
before { sign_in(user) }
include_examples "keys inaccessible"
end
end
describe '#show' do
context "when logged in as an admin" do
before { sign_in(admin) }
it "returns key successfully" do
get "/admin/api/keys/#{key1.id}.json"
expect(response.status).to eq(200)
data = response.parsed_body["key"]
expect(data["id"]).to eq(key1.id)
@ -51,7 +77,33 @@ RSpec.describe Admin::ApiController do
end
end
describe '#update' do
shared_examples "key inaccessible" do
it "denies key access with a 404 response" do
get "/admin/api/keys/#{key1.id}.json"
expect(response.status).to eq(404)
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
expect(response.parsed_body["key"]).to be_nil
end
end
context "when logged in as a moderator" do
before { sign_in(moderator) }
include_examples "key inaccessible"
end
context "when logged in as a non-staff user" do
before { sign_in(user) }
include_examples "key inaccessible"
end
end
describe '#update' do
context "when logged in as an admin" do
before { sign_in(admin) }
it "allows updating the description" do
original_key = key1.key
@ -82,7 +134,44 @@ RSpec.describe Admin::ApiController do
end
end
describe "#destroy" do
shared_examples "key update not allowed" do
it "prevents key updates with a 404 response" do
key1.reload
original_key = key1.key
original_description = key1.description
put "/admin/api/keys/#{key1.id}.json", params: {
key: {
description: "my new description",
key: "overridekey"
}
}
key1.reload
expect(response.status).to eq(404)
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
expect(key1.description).to eq(original_description)
expect(key1.key).to eq(original_key)
end
end
context "when logged in as a moderator" do
before { sign_in(moderator) }
include_examples "key update not allowed"
end
context "when logged in as a non-staff user" do
before { sign_in(user) }
include_examples "key update not allowed"
end
end
describe "#destroy" do
context "when logged in as an admin" do
before { sign_in(admin) }
it "works" do
expect(ApiKey.exists?(key1.id)).to eq(true)
@ -96,7 +185,35 @@ RSpec.describe Admin::ApiController do
end
end
describe "#create" do
shared_examples "key deletion not allowed" do
it "prevents key deletion with a 404 response" do
expect(ApiKey.exists?(key1.id)).to eq(true)
delete "/admin/api/keys/#{key1.id}.json"
expect(response.status).to eq(404)
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
expect(ApiKey.exists?(key1.id)).to eq(true)
end
end
context "when logged in as a moderator" do
before { sign_in(moderator) }
include_examples "key deletion not allowed"
end
context "when logged in as a non-staff user" do
before { sign_in(user) }
include_examples "key deletion not allowed"
end
end
describe "#create" do
context "when logged in as an admin" do
before { sign_in(admin) }
it "can create a master key" do
post "/admin/api/keys.json", params: {
key: {
@ -207,7 +324,37 @@ RSpec.describe Admin::ApiController do
end
end
describe "#revoke and #undo_revoke" do
shared_examples "key creation not allowed" do
it "prevents key creation with a 404 response" do
post "/admin/api/keys.json", params: {
key: {
description: "master key description"
}
}
expect(response.status).to eq(404)
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
expect(response.parsed_body["key"]).to be_nil
end
end
context "when logged in as a moderator" do
before { sign_in(moderator) }
include_examples "key creation not allowed"
end
context "when logged in as a non-staff user" do
before { sign_in(user) }
include_examples "key creation not allowed"
end
end
describe "#revoke and #undo_revoke" do
context "when logged in as an admin" do
before { sign_in(admin) }
it "works correctly" do
post "/admin/api/keys/#{key1.id}/revoke.json"
expect(response.status).to eq 200
@ -229,37 +376,79 @@ RSpec.describe Admin::ApiController do
end
end
describe '#scopes' do
it 'includes scopes' do
get '/admin/api/keys/scopes.json'
shared_examples "key revocation/revocation undoing not allowed" do
it "prevents revoking/un-revoking key with a 404 response" do
key1.reload
post "/admin/api/keys/#{key1.id}/revoke.json"
scopes = response.parsed_body['scopes']
expect(response.status).to eq(404)
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
expect(key1.revoked_at).to eq(nil)
expect(scopes.keys).to contain_exactly('topics', 'users', 'email', 'posts', 'uploads', 'global', 'badges', 'categories', 'wordpress')
post "/admin/api/keys/#{key1.id}/undo-revoke.json"
expect(response.status).to eq(404)
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
expect(key1.revoked_at).to eq(nil)
end
end
context "when logged in as a moderator" do
before { sign_in(moderator) }
include_examples "key revocation/revocation undoing not allowed"
end
context "when logged in as a non-staff user" do
before { sign_in(user) }
include_examples "key revocation/revocation undoing not allowed"
end
end
context "as a moderator" do
before do
sign_in(Fabricate(:moderator))
describe "#scopes" do
context "when logged in as an admin" do
before { sign_in(admin) }
it "includes scopes" do
get "/admin/api/keys/scopes.json"
scopes = response.parsed_body["scopes"]
expect(scopes.keys).to contain_exactly(
"topics",
"users",
"email",
"posts",
"uploads",
"global",
"badges",
"categories",
"wordpress"
)
end
end
it "doesn't allow access" do
get "/admin/api/keys.json"
expect(response.status).to eq(404)
shared_examples "key scopes inaccessible" do
it "denies key scopes access with a 404 response" do
get "/admin/api/keys/scopes.json"
get "/admin/api/key/#{key1.id}.json"
expect(response.status).to eq(404)
expect(response.status).to eq(404)
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
expect(response.parsed_body["scopes"]).to be_nil
end
end
post "/admin/api/keys.json", params: {
key: {
description: "master key description"
}
}
expect(response.status).to eq(404)
context "when logged in as a moderator" do
before { sign_in(moderator) }
expect(ApiKey.count).to eq(3)
include_examples "key scopes inaccessible"
end
context "when logged in as a non-staff user" do
before { sign_in(user) }
include_examples "key scopes inaccessible"
end
end
end