mirror of
https://github.com/discourse/discourse.git
synced 2025-05-25 00:32:52 +08:00
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:
@ -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
|
||||
|
Reference in New Issue
Block a user