require "rails_helper" RSpec.describe "Api::V1::UserRoles" do let(:api_secret) { create(:api_secret) } let(:headers) { { "Accept" => "application/vnd.forem.api-v1+json" } } let(:auth_headers) { headers.merge({ "api-key" => api_secret.secret }) } let(:listener) { :admin_api } describe "PUT /api/users/:id/suspend", :aggregate_failures do let(:target_user) { create(:user) } let(:payload) { { note: "Violated CoC despite multiple warnings" } } before { Audit::Subscribe.listen listener } after { Audit::Subscribe.forget listener } context "when unauthenticated" do it "returns unauthorized" do put api_user_add_role_path(id: target_user.id, role: "suspended"), params: payload, headers: headers expect(response).to have_http_status(:unauthorized) end end context "when unauthorized" do it "returns unauthorized if api key is invalid" do put api_user_add_role_path(id: target_user.id, role: "suspended"), params: payload, headers: headers.merge({ "api-key" => "invalid api key" }) expect(response).to have_http_status(:unauthorized) end it "returns unauthorized if api key belongs to non-admin user" do put api_user_add_role_path(id: target_user.id, role: "suspended"), params: payload, headers: headers expect(response).to have_http_status(:unauthorized) end end context "when request is authenticated" do before { api_secret.user.add_role(:super_admin) } it "is successful in suspending a user", :aggregate_failures do expect do put api_user_add_role_path(id: target_user.id, role: "suspended"), params: payload, headers: auth_headers expect(response).to have_http_status(:no_content) expect(target_user.reload.suspended?).to be true expect(Note.last.content).to eq(payload[:note]) end.to change(Note, :count).by(1) end it "creates an audit log of the action taken" do put api_user_add_role_path(id: target_user.id, role: "suspended"), params: payload, headers: auth_headers log = AuditLog.last expect(log.category).to eq(AuditLog::ADMIN_API_AUDIT_LOG_CATEGORY) expect(log.data["action"]).to eq("api_user_suspend") expect(log.data["target_user_id"]).to eq(target_user.id) expect(log.user_id).to eq(api_secret.user.id) end end end describe "PUT /api/users/:id/limited", :aggregate_failures do let(:target_user) { create(:user) } before { Audit::Subscribe.listen listener } after { Audit::Subscribe.forget listener } context "when unauthenticated" do it "returns unauthorized" do put api_user_add_role_path(target_user, "limited"), headers: headers expect(response).to have_http_status(:unauthorized) end end context "when unauthorized" do it "returns unauthorized if api key is invalid" do put api_user_add_role_path(target_user, "limited"), headers: headers.merge({ "api-key" => "invalid api key" }) expect(response).to have_http_status(:unauthorized) end # Setup via let(:api_secret) creates a user with no admin privileges it "returns unauthorized if api key belongs to non-admin user" do put api_user_add_role_path(target_user, "limited"), headers: auth_headers expect(response).to have_http_status(:unauthorized) end end context "when request is authenticated" do before { api_secret.user.add_role(:super_admin) } it "is successful in limiting a user", :aggregate_failures do expect do put api_user_add_role_path(target_user, "limited"), headers: auth_headers expect(response).to have_http_status(:no_content) expect(target_user.reload.limited?).to be true expect(Note.last.content).to match(/username\d+ updated username\d+/) end.to change(Note, :count).by(1) end it "creates an audit log of the action taken" do put api_user_add_role_path(target_user, "limited"), headers: auth_headers log = AuditLog.last expect(log.category).to eq(AuditLog::ADMIN_API_AUDIT_LOG_CATEGORY) expect(log.data["action"]).to eq("api_user_limited") expect(log.data["target_user_id"]).to eq(target_user.id) expect(log.user_id).to eq(api_secret.user.id) end end end describe "DELETE /api/users/:id/limited", :aggregate_failures do let(:target_user) { create(:user, :limited) } before { Audit::Subscribe.listen listener } after { Audit::Subscribe.forget listener } context "when unauthenticated" do it "returns unauthorized" do delete api_user_remove_role_path(target_user, "limited"), headers: headers expect(response).to have_http_status(:unauthorized) end end context "when unauthorized" do it "returns unauthorized if api key is invalid" do delete api_user_remove_role_path(target_user, "limited"), headers: headers.merge({ "api-key" => "invalid api key" }) expect(response).to have_http_status(:unauthorized) end # Setup via let(:api_secret) creates a user with no admin privileges it "returns unauthorized if api key belongs to non-admin user" do delete api_user_remove_role_path(target_user, "limited"), headers: auth_headers expect(response).to have_http_status(:unauthorized) end end context "when request is authenticated" do before { api_secret.user.add_role(:super_admin) } it "is successful in limiting a user", :aggregate_failures do expect do delete api_user_remove_role_path(target_user, "limited"), headers: auth_headers expect(response).to have_http_status(:no_content) expect(target_user.reload.limited?).to be false expect(target_user.roles).to eq([]) expect(Note.last.content).to match(/username\d+ updated username\d+/) end.to change(Note, :count).by(1) end it "creates an audit log of the action taken" do delete api_user_remove_role_path(target_user, "limited"), headers: auth_headers log = AuditLog.last expect(log.category).to eq(AuditLog::ADMIN_API_AUDIT_LOG_CATEGORY) expect(log.data["action"]).to eq("api_user_remove_limited") expect(log.data["target_user_id"]).to eq(target_user.id) expect(log.user_id).to eq(api_secret.user.id) end end end describe "PUT /api/users/:id/spam", :aggregate_failures do let(:target_user) { create(:user) } before { Audit::Subscribe.listen listener } after { Audit::Subscribe.forget listener } context "when unauthenticated" do it "returns unauthorized" do put api_user_add_role_path(target_user, "spam"), headers: headers expect(response).to have_http_status(:unauthorized) end end context "when unauthorized" do it "returns unauthorized if api key is invalid" do put api_user_add_role_path(target_user, "spam"), headers: headers.merge({ "api-key" => "invalid api key" }) expect(response).to have_http_status(:unauthorized) end # Setup via let(:api_secret) creates a user with no admin privileges it "returns unauthorized if api key belongs to non-admin user" do put api_user_add_role_path(target_user, "spam"), headers: auth_headers expect(response).to have_http_status(:unauthorized) end end context "when request is authenticated" do before { api_secret.user.add_role(:super_admin) } it "is successful in limiting a user", :aggregate_failures do expect do put api_user_add_role_path(target_user, "spam"), headers: auth_headers expect(response).to have_http_status(:no_content) expect(target_user.reload.spam?).to be true expect(Note.last.content).to match(/username\d+ updated username\d+/) end.to change(Note, :count).by(1) end it "creates an audit log of the action taken" do put api_user_add_role_path(target_user, "spam"), headers: auth_headers log = AuditLog.last expect(log.category).to eq(AuditLog::ADMIN_API_AUDIT_LOG_CATEGORY) expect(log.data["action"]).to eq("api_user_spam") expect(log.data["target_user_id"]).to eq(target_user.id) expect(log.user_id).to eq(api_secret.user.id) end end end describe "DELETE /api/users/:id/spam", :aggregate_failures do let(:target_user) { create(:user, :spam) } before { Audit::Subscribe.listen listener } after { Audit::Subscribe.forget listener } context "when unauthenticated" do it "returns unauthorized" do delete api_user_remove_role_path(target_user, "spam"), headers: headers expect(response).to have_http_status(:unauthorized) end end context "when unauthorized" do it "returns unauthorized if api key is invalid" do delete api_user_remove_role_path(target_user, "spam"), headers: headers.merge({ "api-key" => "invalid api key" }) expect(response).to have_http_status(:unauthorized) end # Setup via let(:api_secret) creates a user with no admin privileges it "returns unauthorized if api key belongs to non-admin user" do delete api_user_remove_role_path(target_user, "spam"), headers: auth_headers expect(response).to have_http_status(:unauthorized) end end context "when request is authenticated" do before { api_secret.user.add_role(:super_admin) } it "is successful in adding the spam role to a user", :aggregate_failures do expect do delete api_user_remove_role_path(target_user, "spam"), headers: auth_headers expect(response).to have_http_status(:no_content) expect(target_user.reload.spam?).to be false expect(target_user.roles).to eq([]) expect(Note.last.content).to match(/username\d+ updated username\d+/) end.to change(Note, :count).by(1) end it "creates an audit log of the action taken" do delete api_user_remove_role_path(target_user, "spam"), headers: auth_headers log = AuditLog.last expect(log.category).to eq(AuditLog::ADMIN_API_AUDIT_LOG_CATEGORY) expect(log.data["action"]).to eq("api_user_remove_spam") expect(log.data["target_user_id"]).to eq(target_user.id) expect(log.user_id).to eq(api_secret.user.id) end end end describe "PUT /api/users/:id/trusted", :aggregate_failures do let(:target_user) { create(:user) } before { Audit::Subscribe.listen listener } after { Audit::Subscribe.forget listener } context "when unauthenticated" do it "returns unauthorized" do put api_user_add_role_path(target_user, "trusted"), headers: headers expect(response).to have_http_status(:unauthorized) end end context "when unauthorized" do it "returns unauthorized if api key is invalid" do put api_user_add_role_path(target_user, "trusted"), headers: headers.merge({ "api-key" => "invalid api key" }) expect(response).to have_http_status(:unauthorized) end it "returns unauthorized if api key belongs to non-admin user" do put api_user_add_role_path(target_user, "trusted"), headers: auth_headers expect(response).to have_http_status(:unauthorized) end end context "when request is authenticated" do before { api_secret.user.add_role(:super_admin) } it "is successful in assigning the trusted role to a user", :aggregate_failures do expect do put api_user_add_role_path(target_user, "trusted"), headers: auth_headers expect(response).to have_http_status(:no_content) expect(target_user.reload.has_trusted_role?).to be true expect(Note.last.content).to match(/username\d+ updated username\d+/) end.to change(Note, :count).by(1) end it "creates an audit log of the action taken" do put api_user_add_role_path(target_user, "trusted"), headers: auth_headers log = AuditLog.last expect(log.category).to eq(AuditLog::ADMIN_API_AUDIT_LOG_CATEGORY) expect(log.data["action"]).to eq("api_user_trusted") expect(log.data["target_user_id"]).to eq(target_user.id) expect(log.user_id).to eq(api_secret.user.id) end end end describe "DELETE /api/users/:id/trusted", :aggregate_failures do let(:target_user) { create(:user, :trusted) } before { Audit::Subscribe.listen listener } after { Audit::Subscribe.forget listener } context "when unauthenticated" do it "returns unauthorized" do delete api_user_remove_role_path(target_user, "trusted"), headers: headers expect(response).to have_http_status(:unauthorized) end end context "when unauthorized" do it "returns unauthorized if api key is invalid" do delete api_user_remove_role_path(target_user, "trusted"), headers: headers.merge({ "api-key" => "invalid api key" }) expect(response).to have_http_status(:unauthorized) end it "returns unauthorized if api key belongs to non-admin user" do delete api_user_remove_role_path(target_user, "trusted"), headers: auth_headers expect(response).to have_http_status(:unauthorized) end end context "when request is authenticated" do before { api_secret.user.add_role(:super_admin) } it "is successful in removing the trusted role from a user", :aggregate_failures do expect do delete api_user_remove_role_path(target_user, "trusted"), headers: auth_headers expect(response).to have_http_status(:no_content) expect(target_user.reload.has_trusted_role?).to be false expect(target_user.roles).to eq([]) expect(Note.last.content).to match(/username\d+ updated username\d+/) end.to change(Note, :count).by(1) end it "creates an audit log of the action taken" do delete api_user_remove_role_path(target_user, "trusted"), headers: auth_headers log = AuditLog.last expect(log.category).to eq(AuditLog::ADMIN_API_AUDIT_LOG_CATEGORY) expect(log.data["action"]).to eq("api_user_remove_trusted") expect(log.data["target_user_id"]).to eq(target_user.id) expect(log.user_id).to eq(api_secret.user.id) end end end end