2019-04-29 20:27:42 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2022-07-27 22:27:38 -04:00
|
|
|
RSpec.describe Admin::ApiController do
|
2023-11-09 17:47:59 -05:00
|
|
|
fab!(:admin)
|
|
|
|
fab!(:moderator)
|
|
|
|
fab!(:user)
|
2018-06-11 00:35:45 -04:00
|
|
|
|
2019-12-12 06:45:00 -05:00
|
|
|
fab!(:key1, refind: false) { Fabricate(:api_key, description: "my key") }
|
|
|
|
fab!(:key2, refind: false) { Fabricate(:api_key, user: admin) }
|
2021-11-09 05:18:23 -05:00
|
|
|
fab!(:key3, refind: false) { Fabricate(:api_key, user: admin) }
|
2019-11-05 09:10:23 -05:00
|
|
|
|
2022-11-02 23:42:44 -04:00
|
|
|
describe "#index" do
|
|
|
|
context "when logged in as an admin" do
|
|
|
|
before { sign_in(admin) }
|
2018-06-11 00:35:45 -04:00
|
|
|
|
2022-11-02 23:42:44 -04:00
|
|
|
it "returns keys successfully" do
|
2018-09-11 12:02:06 -04:00
|
|
|
get "/admin/api/keys.json"
|
2022-11-02 23:42:44 -04:00
|
|
|
|
2018-09-11 12:02:06 -04:00
|
|
|
expect(response.status).to eq(200)
|
2021-11-09 05:18:23 -05:00
|
|
|
expect(response.parsed_body["keys"].length).to eq(3)
|
|
|
|
end
|
|
|
|
|
2023-07-28 07:53:46 -04:00
|
|
|
describe "when limit params is invalid" do
|
|
|
|
include_examples "invalid limit params",
|
|
|
|
"/admin/api/keys.json",
|
|
|
|
described_class::INDEX_LIMIT
|
|
|
|
end
|
|
|
|
|
2021-11-09 05:18:23 -05:00
|
|
|
it "can paginate results" do
|
|
|
|
get "/admin/api/keys.json?offset=0&limit=2"
|
2022-11-02 23:42:44 -04:00
|
|
|
|
2021-11-09 05:18:23 -05:00
|
|
|
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"
|
2022-11-02 23:42:44 -04:00
|
|
|
|
2021-11-09 05:18:23 -05:00
|
|
|
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"
|
2022-11-02 23:42:44 -04:00
|
|
|
|
2021-11-09 05:18:23 -05:00
|
|
|
expect(response.status).to eq(200)
|
|
|
|
expect(response.parsed_body["keys"].map { |x| x["id"] }).to contain_exactly(key1.id)
|
2018-09-11 12:02:06 -04:00
|
|
|
end
|
2018-06-11 00:35:45 -04:00
|
|
|
end
|
|
|
|
|
2022-11-02 23:42:44 -04:00
|
|
|
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
|
2019-11-05 09:10:23 -05:00
|
|
|
get "/admin/api/keys/#{key1.id}.json"
|
2022-11-02 23:42:44 -04:00
|
|
|
|
2019-11-05 09:10:23 -05:00
|
|
|
expect(response.status).to eq(200)
|
2020-05-07 11:04:12 -04:00
|
|
|
data = response.parsed_body["key"]
|
2019-11-05 09:10:23 -05:00
|
|
|
expect(data["id"]).to eq(key1.id)
|
2019-12-12 06:45:00 -05:00
|
|
|
expect(data["key"]).to eq(nil)
|
|
|
|
expect(data["truncated_key"]).to eq(key1.key[0..3])
|
2019-11-05 09:10:23 -05:00
|
|
|
expect(data["description"]).to eq("my key")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-11-02 23:42:44 -04:00
|
|
|
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) }
|
|
|
|
|
2019-11-05 09:10:23 -05:00
|
|
|
it "allows updating the description" do
|
|
|
|
original_key = key1.key
|
|
|
|
|
|
|
|
put "/admin/api/keys/#{key1.id}.json",
|
|
|
|
params: {
|
|
|
|
key: {
|
|
|
|
description: "my new description",
|
|
|
|
key: "overridekey",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
|
|
|
|
key1.reload
|
|
|
|
expect(key1.description).to eq("my new description")
|
|
|
|
expect(key1.key).to eq(original_key)
|
2018-06-11 00:35:45 -04:00
|
|
|
|
2019-11-05 09:10:23 -05:00
|
|
|
expect(UserHistory.last.action).to eq(UserHistory.actions[:api_key_update])
|
|
|
|
expect(UserHistory.last.subject).to eq(key1.truncated_key)
|
2018-09-11 12:02:06 -04:00
|
|
|
end
|
2018-06-11 00:35:45 -04:00
|
|
|
|
2019-11-05 09:10:23 -05:00
|
|
|
it "returns 400 for invalid payloads" do
|
|
|
|
put "/admin/api/keys/#{key1.id}.json", params: { key: "string not a hash" }
|
|
|
|
expect(response.status).to eq(400)
|
|
|
|
|
|
|
|
put "/admin/api/keys/#{key1.id}.json", params: {}
|
|
|
|
expect(response.status).to eq(400)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-11-02 23:42:44 -04:00
|
|
|
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) }
|
|
|
|
|
2019-11-05 09:10:23 -05:00
|
|
|
it "works" do
|
|
|
|
expect(ApiKey.exists?(key1.id)).to eq(true)
|
|
|
|
|
|
|
|
delete "/admin/api/keys/#{key1.id}.json"
|
|
|
|
|
2018-09-11 12:02:06 -04:00
|
|
|
expect(response.status).to eq(200)
|
2019-11-05 09:10:23 -05:00
|
|
|
expect(ApiKey.exists?(key1.id)).to eq(false)
|
2018-06-11 00:35:45 -04:00
|
|
|
|
2019-11-05 09:10:23 -05:00
|
|
|
expect(UserHistory.last.action).to eq(UserHistory.actions[:api_key_destroy])
|
|
|
|
expect(UserHistory.last.subject).to eq(key1.truncated_key)
|
2018-09-11 12:02:06 -04:00
|
|
|
end
|
2018-06-11 00:35:45 -04:00
|
|
|
end
|
|
|
|
|
2022-11-02 23:42:44 -04:00
|
|
|
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) }
|
|
|
|
|
2019-11-05 09:10:23 -05:00
|
|
|
it "can create a master key" do
|
|
|
|
post "/admin/api/keys.json", params: { key: { description: "master key description" } }
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
|
2020-05-07 11:04:12 -04:00
|
|
|
data = response.parsed_body
|
2019-11-05 09:10:23 -05:00
|
|
|
|
|
|
|
expect(data["key"]["description"]).to eq("master key description")
|
|
|
|
expect(data["key"]["user"]).to eq(nil)
|
|
|
|
expect(data["key"]["key"]).to_not eq(nil)
|
|
|
|
expect(data["key"]["last_used_at"]).to eq(nil)
|
2018-09-11 12:02:06 -04:00
|
|
|
|
2019-11-05 09:10:23 -05:00
|
|
|
key = ApiKey.find(data["key"]["id"])
|
|
|
|
expect(key.description).to eq("master key description")
|
|
|
|
expect(key.user).to eq(nil)
|
|
|
|
|
|
|
|
expect(UserHistory.last.action).to eq(UserHistory.actions[:api_key_create])
|
|
|
|
expect(UserHistory.last.subject).to eq(key.truncated_key)
|
2018-09-11 12:02:06 -04:00
|
|
|
end
|
|
|
|
|
2019-11-05 09:10:23 -05:00
|
|
|
it "can create a user-specific key" do
|
|
|
|
user = Fabricate(:user)
|
|
|
|
post "/admin/api/keys.json",
|
|
|
|
params: {
|
|
|
|
key: {
|
|
|
|
description: "restricted key description",
|
|
|
|
username: user.username,
|
|
|
|
},
|
|
|
|
}
|
2018-09-11 12:02:06 -04:00
|
|
|
expect(response.status).to eq(200)
|
2019-11-05 09:10:23 -05:00
|
|
|
|
2020-05-07 11:04:12 -04:00
|
|
|
data = response.parsed_body
|
2019-11-05 09:10:23 -05:00
|
|
|
|
|
|
|
expect(data["key"]["description"]).to eq("restricted key description")
|
|
|
|
expect(data["key"]["user"]["username"]).to eq(user.username)
|
|
|
|
expect(data["key"]["key"]).to_not eq(nil)
|
|
|
|
expect(data["key"]["last_used_at"]).to eq(nil)
|
|
|
|
|
|
|
|
key = ApiKey.find(data["key"]["id"])
|
|
|
|
expect(key.description).to eq("restricted key description")
|
|
|
|
expect(key.user.id).to eq(user.id)
|
|
|
|
|
|
|
|
expect(UserHistory.last.action).to eq(UserHistory.actions[:api_key_create])
|
|
|
|
expect(UserHistory.last.subject).to eq(key.truncated_key)
|
2018-09-11 12:02:06 -04:00
|
|
|
end
|
2020-07-16 14:51:24 -04:00
|
|
|
|
|
|
|
describe "Scopes" do
|
|
|
|
it "creates an scope with allowed parameters" do
|
|
|
|
post "/admin/api/keys.json",
|
|
|
|
params: {
|
|
|
|
key: {
|
|
|
|
description: "master key description",
|
2021-02-17 12:42:44 -05:00
|
|
|
scopes: [{ scope_id: "topics:write", topic_id: "55" }],
|
2020-07-16 14:51:24 -04:00
|
|
|
},
|
|
|
|
}
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
|
|
|
|
data = response.parsed_body
|
|
|
|
scope = ApiKeyScope.find_by(api_key_id: data.dig("key", "id"))
|
|
|
|
|
|
|
|
expect(scope.resource).to eq("topics")
|
|
|
|
expect(scope.action).to eq("write")
|
|
|
|
expect(scope.allowed_parameters["topic_id"]).to contain_exactly("55")
|
|
|
|
end
|
|
|
|
|
2024-01-10 21:30:10 -05:00
|
|
|
it "creates an scope for /logs" do
|
|
|
|
post "/admin/api/keys.json",
|
|
|
|
params: {
|
|
|
|
key: {
|
|
|
|
description: "logs",
|
|
|
|
scopes: [{ scope_id: "logs:messages" }],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
|
|
|
|
data = response.parsed_body
|
|
|
|
scope = ApiKeyScope.find_by(api_key_id: data.dig("key", "id"))
|
|
|
|
|
|
|
|
expect(scope.resource).to eq("logs")
|
|
|
|
expect(scope.action).to eq("messages")
|
|
|
|
|
|
|
|
api_key = data.dig("key", "key")
|
|
|
|
post "/logs/messages.json", headers: { "Api-Key": api_key, "Api-Username": "system" }
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
end
|
|
|
|
|
2020-07-16 14:51:24 -04:00
|
|
|
it "allows multiple parameters separated by a comma" do
|
|
|
|
post "/admin/api/keys.json",
|
|
|
|
params: {
|
|
|
|
key: {
|
|
|
|
description: "master key description",
|
2021-02-17 12:42:44 -05:00
|
|
|
scopes: [{ scope_id: "topics:write", topic_id: "55,33" }],
|
2020-07-16 14:51:24 -04:00
|
|
|
},
|
|
|
|
}
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
|
|
|
|
data = response.parsed_body
|
|
|
|
scope = ApiKeyScope.find_by(api_key_id: data.dig("key", "id"))
|
|
|
|
|
|
|
|
expect(scope.allowed_parameters["topic_id"]).to contain_exactly("55", "33")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it "ignores invalid parameters" do
|
|
|
|
post "/admin/api/keys.json",
|
|
|
|
params: {
|
|
|
|
key: {
|
|
|
|
description: "master key description",
|
2021-02-17 12:42:44 -05:00
|
|
|
scopes: [{ scope_id: "topics:write", fake_id: "55" }],
|
2020-07-16 14:51:24 -04:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
|
|
|
|
data = response.parsed_body
|
|
|
|
scope = ApiKeyScope.find_by(api_key_id: data.dig("key", "id"))
|
|
|
|
|
|
|
|
expect(scope.allowed_parameters["fake_id"]).to be_nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it "fails when the scope is invalid" do
|
|
|
|
post "/admin/api/keys.json",
|
|
|
|
params: {
|
|
|
|
key: {
|
|
|
|
description: "master key description",
|
2021-02-17 12:42:44 -05:00
|
|
|
scopes: [{ scope_id: "something:else" }],
|
2020-07-16 14:51:24 -04:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
expect(response.status).to eq(400)
|
|
|
|
end
|
2018-06-11 00:35:45 -04:00
|
|
|
end
|
|
|
|
|
2022-11-02 23:42:44 -04:00
|
|
|
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) }
|
|
|
|
|
2019-11-05 09:10:23 -05:00
|
|
|
it "works correctly" do
|
|
|
|
post "/admin/api/keys/#{key1.id}/revoke.json"
|
|
|
|
expect(response.status).to eq 200
|
|
|
|
|
|
|
|
key1.reload
|
|
|
|
expect(key1.revoked_at).to_not eq(nil)
|
|
|
|
expect(UserHistory.last.action).to eq(UserHistory.actions[:api_key_update])
|
|
|
|
expect(UserHistory.last.subject).to eq(key1.truncated_key)
|
|
|
|
expect(UserHistory.last.details).to eq(I18n.t("staff_action_logs.api_key.revoked"))
|
|
|
|
|
|
|
|
post "/admin/api/keys/#{key1.id}/undo-revoke.json"
|
|
|
|
expect(response.status).to eq 200
|
|
|
|
|
|
|
|
key1.reload
|
|
|
|
expect(key1.revoked_at).to eq(nil)
|
|
|
|
expect(UserHistory.last.action).to eq(UserHistory.actions[:api_key_update])
|
|
|
|
expect(UserHistory.last.subject).to eq(key1.truncated_key)
|
|
|
|
expect(UserHistory.last.details).to eq(I18n.t("staff_action_logs.api_key.restored"))
|
|
|
|
end
|
2018-06-11 00:35:45 -04:00
|
|
|
end
|
2020-07-16 14:51:24 -04:00
|
|
|
|
2022-11-02 23:42:44 -04:00
|
|
|
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"
|
2020-07-16 14:51:24 -04:00
|
|
|
|
2022-11-02 23:42:44 -04:00
|
|
|
expect(response.status).to eq(404)
|
|
|
|
expect(response.parsed_body["errors"]).to include(I18n.t("not_found"))
|
|
|
|
expect(key1.revoked_at).to eq(nil)
|
2020-07-16 14:51:24 -04:00
|
|
|
|
2022-11-02 23:42:44 -04:00
|
|
|
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)
|
2020-07-16 14:51:24 -04:00
|
|
|
end
|
|
|
|
end
|
2022-11-02 23:42:44 -04:00
|
|
|
|
|
|
|
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
|
2019-11-05 09:10:23 -05:00
|
|
|
end
|
2018-09-11 12:02:06 -04:00
|
|
|
|
2022-11-02 23:42:44 -04:00
|
|
|
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",
|
2024-03-14 17:24:54 -04:00
|
|
|
"revisions",
|
2023-02-23 10:33:29 -05:00
|
|
|
"tags",
|
2023-10-03 04:20:17 -04:00
|
|
|
"tag_groups",
|
2022-11-02 23:42:44 -04:00
|
|
|
"uploads",
|
2022-11-24 10:16:28 -05:00
|
|
|
"user_status",
|
2022-11-02 23:42:44 -04:00
|
|
|
"global",
|
|
|
|
"badges",
|
2023-02-22 11:06:49 -05:00
|
|
|
"groups",
|
2022-11-02 23:42:44 -04:00
|
|
|
"categories",
|
2023-01-23 16:06:57 -05:00
|
|
|
"search",
|
2023-01-23 18:20:22 -05:00
|
|
|
"invites",
|
2022-11-02 23:42:44 -04:00
|
|
|
"wordpress",
|
2023-12-18 21:45:04 -05:00
|
|
|
"logs",
|
2022-11-02 23:42:44 -04:00
|
|
|
)
|
2023-06-02 10:28:14 -04:00
|
|
|
|
2023-07-13 12:48:22 -04:00
|
|
|
topic_routes = [
|
|
|
|
"/t/:id (GET)",
|
|
|
|
"/t/external_id/:external_id (GET)",
|
|
|
|
"/t/:slug/:topic_id/print (GET)",
|
|
|
|
"/t/:slug/:topic_id/summary (GET)",
|
|
|
|
"/t/:topic_id/summary (GET)",
|
|
|
|
"/t/:topic_id/:post_number (GET)",
|
|
|
|
"/t/:topic_id/last (GET)",
|
|
|
|
"/t/:slug/:topic_id.rss (GET)",
|
|
|
|
"/t/:slug/:topic_id (GET)",
|
|
|
|
"/t/:slug/:topic_id/:post_number (GET)",
|
|
|
|
"/t/:slug/:topic_id/last (GET)",
|
|
|
|
"/t/:topic_id/posts (GET)",
|
|
|
|
"/latest.rss (GET)",
|
2024-02-29 17:49:29 -05:00
|
|
|
"/t/:topic_id/recover (PUT)",
|
2023-07-13 12:48:22 -04:00
|
|
|
]
|
|
|
|
|
|
|
|
topic_routes.each do |route|
|
|
|
|
expect(scopes["topics"].any? { |h| h["urls"].include?(route) }).to be_truthy
|
|
|
|
end
|
|
|
|
|
2023-06-05 11:04:34 -04:00
|
|
|
expect(scopes["posts"].any? { |h| h["urls"].include?("/posts (GET)") }).to be_truthy
|
|
|
|
expect(scopes["posts"].any? { |h| h["urls"].include?("/private-posts (GET)") }).to be_truthy
|
2024-02-29 17:49:29 -05:00
|
|
|
expect(
|
|
|
|
scopes["posts"].any? { |h| h["urls"].include?("/posts/:post_id/recover (PUT)") },
|
|
|
|
).to be_truthy
|
2023-10-19 09:37:25 -04:00
|
|
|
|
2024-03-14 17:24:54 -04:00
|
|
|
expect(
|
|
|
|
scopes["revisions"].any? do |h|
|
|
|
|
h["urls"].include?("/posts/:post_id/revisions/permanently_delete (DELETE)")
|
|
|
|
end,
|
|
|
|
).to be_truthy
|
|
|
|
|
2023-10-19 09:37:25 -04:00
|
|
|
expect(scopes["users"].find { _1["key"] == "update" }["urls"]).to contain_exactly(
|
|
|
|
"/users/:username (PUT)",
|
|
|
|
"/users/:username/preferences/badge_title (PUT)",
|
|
|
|
"/users/:username/preferences/avatar/pick (PUT)",
|
|
|
|
"/users/:username/preferences/avatar/select (PUT)",
|
|
|
|
"/users/:username/feature-topic (PUT)",
|
|
|
|
"/users/:username/clear-featured-topic (PUT)",
|
|
|
|
"/u/:username (PUT)",
|
|
|
|
"/u/:username/preferences/badge_title (PUT)",
|
|
|
|
"/u/:username/preferences/avatar/pick (PUT)",
|
|
|
|
"/u/:username/preferences/avatar/select (PUT)",
|
|
|
|
"/u/:username/feature-topic (PUT)",
|
|
|
|
"/u/:username/clear-featured-topic (PUT)",
|
|
|
|
)
|
2023-12-18 21:45:04 -05:00
|
|
|
|
|
|
|
expect(
|
|
|
|
scopes["logs"].any? { |h| h["urls"].include?("/logs/messages.json (POST)") },
|
|
|
|
).to be_truthy
|
2022-11-02 23:42:44 -04:00
|
|
|
end
|
2018-09-11 12:02:06 -04:00
|
|
|
end
|
|
|
|
|
2022-11-02 23:42:44 -04:00
|
|
|
shared_examples "key scopes inaccessible" do
|
|
|
|
it "denies key scopes access with a 404 response" do
|
|
|
|
get "/admin/api/keys/scopes.json"
|
2019-11-05 09:10:23 -05:00
|
|
|
|
2022-11-02 23:42:44 -04:00
|
|
|
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
|
2019-11-05 09:10:23 -05:00
|
|
|
|
2022-11-02 23:42:44 -04:00
|
|
|
context "when logged in as a moderator" do
|
|
|
|
before { sign_in(moderator) }
|
|
|
|
|
|
|
|
include_examples "key scopes inaccessible"
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when logged in as a non-staff user" do
|
|
|
|
before { sign_in(user) }
|
2019-11-05 09:10:23 -05:00
|
|
|
|
2022-11-02 23:42:44 -04:00
|
|
|
include_examples "key scopes inaccessible"
|
2019-11-05 09:10:23 -05:00
|
|
|
end
|
2018-06-11 00:35:45 -04:00
|
|
|
end
|
|
|
|
end
|