parent
33144e132d
commit
7696f77245
@ -0,0 +1,32 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
class Api::V1::Admin::AccountActionsController < Api::BaseController |
||||
before_action -> { doorkeeper_authorize! :'admin:write', :'admin:write:accounts' } |
||||
before_action :require_staff! |
||||
before_action :set_account |
||||
|
||||
def create |
||||
account_action = Admin::AccountAction.new(resource_params) |
||||
account_action.target_account = @account |
||||
account_action.current_account = current_account |
||||
account_action.save! |
||||
|
||||
render_empty |
||||
end |
||||
|
||||
private |
||||
|
||||
def set_account |
||||
@account = Account.find(params[:account_id]) |
||||
end |
||||
|
||||
def resource_params |
||||
params.permit( |
||||
:type, |
||||
:report_id, |
||||
:warning_preset_id, |
||||
:text, |
||||
:send_email_notification |
||||
) |
||||
end |
||||
end |
@ -0,0 +1,128 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
class Api::V1::Admin::AccountsController < Api::BaseController |
||||
include Authorization |
||||
include AccountableConcern |
||||
|
||||
LIMIT = 100 |
||||
|
||||
before_action -> { doorkeeper_authorize! :'admin:read', :'admin:read:accounts' }, only: [:index, :show] |
||||
before_action -> { doorkeeper_authorize! :'admin:write', :'admin:write:accounts' }, except: [:index, :show] |
||||
before_action :require_staff! |
||||
before_action :set_accounts, only: :index |
||||
before_action :set_account, except: :index |
||||
before_action :require_local_account!, only: [:enable, :approve, :reject] |
||||
|
||||
after_action :insert_pagination_headers, only: :index |
||||
|
||||
FILTER_PARAMS = %i( |
||||
local |
||||
remote |
||||
by_domain |
||||
active |
||||
pending |
||||
disabled |
||||
silenced |
||||
suspended |
||||
username |
||||
display_name |
||||
email |
||||
ip |
||||
staff |
||||
).freeze |
||||
|
||||
PAGINATION_PARAMS = (%i(limit) + FILTER_PARAMS).freeze |
||||
|
||||
def index |
||||
authorize :account, :index? |
||||
render json: @accounts, each_serializer: REST::Admin::AccountSerializer |
||||
end |
||||
|
||||
def show |
||||
authorize @account, :show? |
||||
render json: @account, serializer: REST::Admin::AccountSerializer |
||||
end |
||||
|
||||
def enable |
||||
authorize @account.user, :enable? |
||||
@account.user.enable! |
||||
log_action :enable, @account.user |
||||
render json: @account, serializer: REST::Admin::AccountSerializer |
||||
end |
||||
|
||||
def approve |
||||
authorize @account.user, :approve? |
||||
@account.user.approve! |
||||
render json: @account, serializer: REST::Admin::AccountSerializer |
||||
end |
||||
|
||||
def reject |
||||
authorize @account.user, :reject? |
||||
SuspendAccountService.new.call(@account, including_user: true, destroy: true, skip_distribution: true) |
||||
render json: @account, serializer: REST::Admin::AccountSerializer |
||||
end |
||||
|
||||
def unsilence |
||||
authorize @account, :unsilence? |
||||
@account.unsilence! |
||||
log_action :unsilence, @account |
||||
render json: @account, serializer: REST::Admin::AccountSerializer |
||||
end |
||||
|
||||
def unsuspend |
||||
authorize @account, :unsuspend? |
||||
@account.unsuspend! |
||||
log_action :unsuspend, @account |
||||
render json: @account, serializer: REST::Admin::AccountSerializer |
||||
end |
||||
|
||||
private |
||||
|
||||
def set_accounts |
||||
@accounts = filtered_accounts.order(id: :desc).includes(user: [:invite_request, :invite]).paginate_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id)) |
||||
end |
||||
|
||||
def set_account |
||||
@account = Account.find(params[:id]) |
||||
end |
||||
|
||||
def filtered_accounts |
||||
AccountFilter.new(filter_params).results |
||||
end |
||||
|
||||
def filter_params |
||||
params.permit(*FILTER_PARAMS) |
||||
end |
||||
|
||||
def insert_pagination_headers |
||||
set_pagination_headers(next_path, prev_path) |
||||
end |
||||
|
||||
def next_path |
||||
api_v1_admin_accounts_url(pagination_params(max_id: pagination_max_id)) if records_continue? |
||||
end |
||||
|
||||
def prev_path |
||||
api_v1_admin_accounts_url(pagination_params(min_id: pagination_since_id)) unless @accounts.empty? |
||||
end |
||||
|
||||
def pagination_max_id |
||||
@accounts.last.id |
||||
end |
||||
|
||||
def pagination_since_id |
||||
@accounts.first.id |
||||
end |
||||
|
||||
def records_continue? |
||||
@accounts.size == limit_param(LIMIT) |
||||
end |
||||
|
||||
def pagination_params(core_params) |
||||
params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params) |
||||
end |
||||
|
||||
def require_local_account! |
||||
forbidden unless @account.local? && @account.user.present? |
||||
end |
||||
end |
@ -0,0 +1,108 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
class Api::V1::Admin::ReportsController < Api::BaseController |
||||
include Authorization |
||||
include AccountableConcern |
||||
|
||||
LIMIT = 100 |
||||
|
||||
before_action -> { doorkeeper_authorize! :'admin:read', :'admin:read:reports' }, only: [:index, :show] |
||||
before_action -> { doorkeeper_authorize! :'admin:write', :'admin:write:reports' }, except: [:index, :show] |
||||
before_action :require_staff! |
||||
before_action :set_reports, only: :index |
||||
before_action :set_report, except: :index |
||||
|
||||
after_action :insert_pagination_headers, only: :index |
||||
|
||||
FILTER_PARAMS = %i( |
||||
resolved |
||||
account_id |
||||
target_account_id |
||||
).freeze |
||||
|
||||
PAGINATION_PARAMS = (%i(limit) + FILTER_PARAMS).freeze |
||||
|
||||
def index |
||||
authorize :report, :index? |
||||
render json: @reports, each_serializer: REST::Admin::ReportSerializer |
||||
end |
||||
|
||||
def show |
||||
authorize @report, :show? |
||||
render json: @report, serializer: REST::Admin::ReportSerializer |
||||
end |
||||
|
||||
def assign_to_self |
||||
authorize @report, :update? |
||||
@report.update!(assigned_account_id: current_account.id) |
||||
log_action :assigned_to_self, @report |
||||
render json: @report, serializer: REST::Admin::ReportSerializer |
||||
end |
||||
|
||||
def unassign |
||||
authorize @report, :update? |
||||
@report.update!(assigned_account_id: nil) |
||||
log_action :unassigned, @report |
||||
render json: @report, serializer: REST::Admin::ReportSerializer |
||||
end |
||||
|
||||
def reopen |
||||
authorize @report, :update? |
||||
@report.unresolve! |
||||
log_action :reopen, @report |
||||
render json: @report, serializer: REST::Admin::ReportSerializer |
||||
end |
||||
|
||||
def resolve |
||||
authorize @report, :update? |
||||
@report.resolve!(current_account) |
||||
log_action :resolve, @report |
||||
render json: @report, serializer: REST::Admin::ReportSerializer |
||||
end |
||||
|
||||
private |
||||
|
||||
def set_reports |
||||
@reports = filtered_reports.order(id: :desc).with_accounts.paginate_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id)) |
||||
end |
||||
|
||||
def set_report |
||||
@report = Report.find(params[:id]) |
||||
end |
||||
|
||||
def filtered_reports |
||||
ReportFilter.new(filter_params).results |
||||
end |
||||
|
||||
def filter_params |
||||
params.permit(*FILTER_PARAMS) |
||||
end |
||||
|
||||
def insert_pagination_headers |
||||
set_pagination_headers(next_path, prev_path) |
||||
end |
||||
|
||||
def next_path |
||||
api_v1_admin_reports_url(pagination_params(max_id: pagination_max_id)) if records_continue? |
||||
end |
||||
|
||||
def prev_path |
||||
api_v1_admin_reports_url(pagination_params(min_id: pagination_since_id)) unless @reports.empty? |
||||
end |
||||
|
||||
def pagination_max_id |
||||
@reports.last.id |
||||
end |
||||
|
||||
def pagination_since_id |
||||
@reports.first.id |
||||
end |
||||
|
||||
def records_continue? |
||||
@reports.size == limit_param(LIMIT) |
||||
end |
||||
|
||||
def pagination_params(core_params) |
||||
params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params) |
||||
end |
||||
end |
@ -0,0 +1,77 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
class REST::Admin::AccountSerializer < ActiveModel::Serializer |
||||
attributes :id, :username, :domain, :created_at, |
||||
:email, :ip, :role, :confirmed, :suspended, |
||||
:silenced, :disabled, :approved, :locale, |
||||
:invite_request |
||||
|
||||
attribute :created_by_application_id, if: :created_by_application? |
||||
attribute :invited_by_account_id, if: :invited? |
||||
|
||||
has_one :account, serializer: REST::AccountSerializer |
||||
|
||||
def id |
||||
object.id.to_s |
||||
end |
||||
|
||||
def email |
||||
object.user_email |
||||
end |
||||
|
||||
def ip |
||||
object.user_current_sign_in_ip.to_s.presence |
||||
end |
||||
|
||||
def role |
||||
object.user_role |
||||
end |
||||
|
||||
def suspended |
||||
object.suspended? |
||||
end |
||||
|
||||
def silenced |
||||
object.silenced? |
||||
end |
||||
|
||||
def confirmed |
||||
object.user_confirmed? |
||||
end |
||||
|
||||
def disabled |
||||
object.user_disabled? |
||||
end |
||||
|
||||
def approved |
||||
object.user_approved? |
||||
end |
||||
|
||||
def account |
||||
object |
||||
end |
||||
|
||||
def locale |
||||
object.user_locale |
||||
end |
||||
|
||||
def created_by_application_id |
||||
object.user&.created_by_application_id&.to_s&.presence |
||||
end |
||||
|
||||
def invite_request |
||||
object.user&.invite_request&.text |
||||
end |
||||
|
||||
def invited_by_account_id |
||||
object.user&.invite&.user&.account_id&.to_s&.presence |
||||
end |
||||
|
||||
def invited? |
||||
object.user&.invited? |
||||
end |
||||
|
||||
def created_by_application? |
||||
object.user&.created_by_application_id&.present? |
||||
end |
||||
end |
@ -0,0 +1,16 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
class REST::Admin::ReportSerializer < ActiveModel::Serializer |
||||
attributes :id, :action_taken, :comment, :created_at, :updated_at |
||||
|
||||
has_one :account, serializer: REST::Admin::AccountSerializer |
||||
has_one :target_account, serializer: REST::Admin::AccountSerializer |
||||
has_one :assigned_account, serializer: REST::Admin::AccountSerializer |
||||
has_one :action_taken_by_account, serializer: REST::Admin::AccountSerializer |
||||
|
||||
has_many :statuses, serializer: REST::StatusSerializer |
||||
|
||||
def id |
||||
object.id.to_s |
||||
end |
||||
end |
@ -0,0 +1,57 @@ |
||||
require 'rails_helper' |
||||
|
||||
RSpec.describe Api::V1::Admin::AccountActionsController, type: :controller do |
||||
render_views |
||||
|
||||
let(:role) { 'moderator' } |
||||
let(:user) { Fabricate(:user, role: role, account: Fabricate(:account, username: 'alice')) } |
||||
let(:scopes) { 'admin:read admin:write' } |
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } |
||||
let(:account) { Fabricate(:user).account } |
||||
|
||||
before do |
||||
allow(controller).to receive(:doorkeeper_token) { token } |
||||
end |
||||
|
||||
shared_examples 'forbidden for wrong scope' do |wrong_scope| |
||||
let(:scopes) { wrong_scope } |
||||
|
||||
it 'returns http forbidden' do |
||||
expect(response).to have_http_status(403) |
||||
end |
||||
end |
||||
|
||||
shared_examples 'forbidden for wrong role' do |wrong_role| |
||||
let(:role) { wrong_role } |
||||
|
||||
it 'returns http forbidden' do |
||||
expect(response).to have_http_status(403) |
||||
end |
||||
end |
||||
|
||||
describe 'POST #create' do |
||||
before do |
||||
post :create, params: { account_id: account.id, type: 'disable' } |
||||
end |
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses' |
||||
it_behaves_like 'forbidden for wrong role', 'user' |
||||
|
||||
it 'returns http success' do |
||||
expect(response).to have_http_status(200) |
||||
end |
||||
|
||||
it 'performs action against account' do |
||||
expect(account.reload.user_disabled?).to be true |
||||
end |
||||
|
||||
it 'logs action' do |
||||
log_item = Admin::ActionLog.last |
||||
|
||||
expect(log_item).to_not be_nil |
||||
expect(log_item.action).to eq :disable |
||||
expect(log_item.account_id).to eq user.account_id |
||||
expect(log_item.target_id).to eq account.user.id |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,147 @@ |
||||
require 'rails_helper' |
||||
|
||||
RSpec.describe Api::V1::Admin::AccountsController, type: :controller do |
||||
render_views |
||||
|
||||
let(:role) { 'moderator' } |
||||
let(:user) { Fabricate(:user, role: role, account: Fabricate(:account, username: 'alice')) } |
||||
let(:scopes) { 'admin:read admin:write' } |
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } |
||||
let(:account) { Fabricate(:user).account } |
||||
|
||||
before do |
||||
allow(controller).to receive(:doorkeeper_token) { token } |
||||
end |
||||
|
||||
shared_examples 'forbidden for wrong scope' do |wrong_scope| |
||||
let(:scopes) { wrong_scope } |
||||
|
||||
it 'returns http forbidden' do |
||||
expect(response).to have_http_status(403) |
||||
end |
||||
end |
||||
|
||||
shared_examples 'forbidden for wrong role' do |wrong_role| |
||||
let(:role) { wrong_role } |
||||
|
||||
it 'returns http forbidden' do |
||||
expect(response).to have_http_status(403) |
||||
end |
||||
end |
||||
|
||||
describe 'GET #index' do |
||||
before do |
||||
get :index |
||||
end |
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses' |
||||
it_behaves_like 'forbidden for wrong role', 'user' |
||||
|
||||
it 'returns http success' do |
||||
expect(response).to have_http_status(200) |
||||
end |
||||
end |
||||
|
||||
describe 'GET #show' do |
||||
before do |
||||
get :show, params: { id: account.id } |
||||
end |
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses' |
||||
it_behaves_like 'forbidden for wrong role', 'user' |
||||
|
||||
it 'returns http success' do |
||||
expect(response).to have_http_status(200) |
||||
end |
||||
end |
||||
|
||||
describe 'POST #approve' do |
||||
before do |
||||
account.user.update(approved: false) |
||||
post :approve, params: { id: account.id } |
||||
end |
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses' |
||||
it_behaves_like 'forbidden for wrong role', 'user' |
||||
|
||||
it 'returns http success' do |
||||
expect(response).to have_http_status(200) |
||||
end |
||||
|
||||
it 'approves user' do |
||||
expect(account.reload.user_approved?).to be true |
||||
end |
||||
end |
||||
|
||||
describe 'POST #reject' do |
||||
before do |
||||
account.user.update(approved: false) |
||||
post :reject, params: { id: account.id } |
||||
end |
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses' |
||||
it_behaves_like 'forbidden for wrong role', 'user' |
||||
|
||||
it 'returns http success' do |
||||
expect(response).to have_http_status(200) |
||||
end |
||||
|
||||
it 'removes user' do |
||||
expect(User.where(id: account.user.id).count).to eq 0 |
||||
end |
||||
end |
||||
|
||||
describe 'POST #enable' do |
||||
before do |
||||
account.user.update(disabled: true) |
||||
post :enable, params: { id: account.id } |
||||
end |
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses' |
||||
it_behaves_like 'forbidden for wrong role', 'user' |
||||
|
||||
it 'returns http success' do |
||||
expect(response).to have_http_status(200) |
||||
end |
||||
|
||||
it 'enables user' do |
||||
expect(account.reload.user_disabled?).to be false |
||||
end |
||||
end |
||||
|
||||
describe 'POST #unsuspend' do |
||||
before do |
||||
account.touch(:suspended_at) |
||||
post :unsuspend, params: { id: account.id } |
||||
end |
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses' |
||||
it_behaves_like 'forbidden for wrong role', 'user' |
||||
|
||||
it 'returns http success' do |
||||
expect(response).to have_http_status(200) |
||||
end |
||||
|
||||
it 'unsuspends account' do |
||||
expect(account.reload.suspended?).to be false |
||||
end |
||||
end |
||||
|
||||
describe 'POST #unsilence' do |
||||
before do |
||||
account.touch(:silenced_at) |
||||
post :unsilence, params: { id: account.id } |
||||
end |
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses' |
||||
it_behaves_like 'forbidden for wrong role', 'user' |
||||
|
||||
it 'returns http success' do |
||||
expect(response).to have_http_status(200) |
||||
end |
||||
|
||||
it 'unsilences account' do |
||||
expect(account.reload.silenced?).to be false |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,109 @@ |
||||
require 'rails_helper' |
||||
|
||||
RSpec.describe Api::V1::Admin::ReportsController, type: :controller do |
||||
render_views |
||||
|
||||
let(:role) { 'moderator' } |
||||
let(:user) { Fabricate(:user, role: role, account: Fabricate(:account, username: 'alice')) } |
||||
let(:scopes) { 'admin:read admin:write' } |
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } |
||||
let(:report) { Fabricate(:report) } |
||||
|
||||
before do |
||||
allow(controller).to receive(:doorkeeper_token) { token } |
||||
end |
||||
|
||||
shared_examples 'forbidden for wrong scope' do |wrong_scope| |
||||
let(:scopes) { wrong_scope } |
||||
|
||||
it 'returns http forbidden' do |
||||
expect(response).to have_http_status(403) |
||||
end |
||||
end |
||||
|
||||
shared_examples 'forbidden for wrong role' do |wrong_role| |
||||
let(:role) { wrong_role } |
||||
|
||||
it 'returns http forbidden' do |
||||
expect(response).to have_http_status(403) |
||||
end |
||||
end |
||||
|
||||
describe 'GET #index' do |
||||
before do |
||||
get :index |
||||
end |
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses' |
||||
it_behaves_like 'forbidden for wrong role', 'user' |
||||
|
||||
it 'returns http success' do |
||||
expect(response).to have_http_status(200) |
||||
end |
||||
end |
||||
|
||||
describe 'GET #show' do |
||||
before do |
||||
get :show, params: { id: report.id } |
||||
end |
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses' |
||||
it_behaves_like 'forbidden for wrong role', 'user' |
||||
|
||||
it 'returns http success' do |
||||
expect(response).to have_http_status(200) |
||||
end |
||||
end |
||||
|
||||
describe 'POST #resolve' do |
||||
before do |
||||
post :resolve, params: { id: report.id } |
||||
end |
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses' |
||||
it_behaves_like 'forbidden for wrong role', 'user' |
||||
|
||||
it 'returns http success' do |
||||
expect(response).to have_http_status(200) |
||||
end |
||||
end |
||||
|
||||
describe 'POST #reopen' do |
||||
before do |
||||
post :reopen, params: { id: report.id } |
||||
end |
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses' |
||||
it_behaves_like 'forbidden for wrong role', 'user' |
||||
|
||||
it 'returns http success' do |
||||
expect(response).to have_http_status(200) |
||||
end |
||||
end |
||||
|
||||
describe 'POST #assign_to_self' do |
||||
before do |
||||
post :assign_to_self, params: { id: report.id } |
||||
end |
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses' |
||||
it_behaves_like 'forbidden for wrong role', 'user' |
||||
|
||||
it 'returns http success' do |
||||
expect(response).to have_http_status(200) |
||||
end |
||||
end |
||||
|
||||
describe 'POST #unassign' do |
||||
before do |
||||
post :unassign, params: { id: report.id } |
||||
end |
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses' |
||||
it_behaves_like 'forbidden for wrong role', 'user' |
||||
|
||||
it 'returns http success' do |
||||
expect(response).to have_http_status(200) |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue