Переглянути джерело

Add status destroy authorization to policy (#3453)

* Add status destroy authorization to policy

* Create explicit unreblog status authorization
master
Jack Jennings 7 роки тому
committed by Eugen Rochko
джерело
коміт
33f669a5f8
6 змінених файлів з 78 додано та 5 видалено
  1. +3
    -0
      app/controllers/admin/reported_statuses_controller.rb
  2. +5
    -0
      app/controllers/api/v1/statuses_controller.rb
  3. +16
    -2
      app/policies/status_policy.rb
  4. +5
    -2
      app/services/process_interaction_service.rb
  5. +20
    -0
      spec/policies/status_policy_spec.rb
  6. +29
    -1
      spec/services/process_interaction_service_spec.rb

+ 3
- 0
app/controllers/admin/reported_statuses_controller.rb Переглянути файл

@@ -2,6 +2,8 @@

module Admin
class ReportedStatusesController < BaseController
include Authorization

before_action :set_report
before_action :set_status

@@ -11,6 +13,7 @@ module Admin
end

def destroy
authorize @status, :destroy?
RemovalWorker.perform_async(@status.id)
redirect_to admin_report_path(@report)
end


+ 5
- 0
app/controllers/api/v1/statuses_controller.rb Переглянути файл

@@ -79,7 +79,10 @@ class Api::V1::StatusesController < ApiController

def destroy
@status = Status.where(account_id: current_user.account).find(params[:id])
authorize @status, :destroy?

RemovalWorker.perform_async(@status.id)

render_empty
end

@@ -93,6 +96,8 @@ class Api::V1::StatusesController < ApiController
@status = reblog.reblog
@reblogs_map = { @status.id => false }

authorize reblog, :unreblog?

RemovalWorker.perform_async(reblog.id)

render :show


+ 16
- 2
app/policies/status_policy.rb Переглянути файл

@@ -10,9 +10,9 @@ class StatusPolicy

def show?
if direct?
status.account.id == account&.id || status.mentions.where(account: account).exists?
owned? || status.mentions.where(account: account).exists?
elsif private?
status.account.id == account&.id || account&.following?(status.account) || status.mentions.where(account: account).exists?
owned? || account&.following?(status.account) || status.mentions.where(account: account).exists?
else
account.nil? || !status.account.blocking?(account)
end
@@ -22,12 +22,26 @@ class StatusPolicy
!direct? && !private? && show?
end

def destroy?
admin? || owned?
end

alias unreblog? destroy?

private

def admin?
account&.user&.admin?
end

def direct?
status.direct_visibility?
end

def owned?
status.account.id == account&.id
end

def private?
status.private_visibility?
end


+ 5
- 2
app/services/process_interaction_service.rb Переглянути файл

@@ -2,6 +2,7 @@

class ProcessInteractionService < BaseService
include AuthorExtractor
include Authorization

# Record locally the remote interaction with our user
# @param [String] envelope Salmon envelope
@@ -46,7 +47,7 @@ class ProcessInteractionService < BaseService
reflect_unblock!(account, target_account)
end
end
rescue Goldfinger::Error, HTTP::Error, OStatus2::BadSalmonError
rescue Goldfinger::Error, HTTP::Error, OStatus2::BadSalmonError, Mastodon::NotPermittedError
nil
end

@@ -103,7 +104,9 @@ class ProcessInteractionService < BaseService

return if status.nil?

RemovalWorker.perform_async(status.id) if account.id == status.account_id
authorize_with account, status, :destroy?

RemovalWorker.perform_async(status.id)
end

def favourite!(xml, from_account)


+ 20
- 0
spec/policies/status_policy_spec.rb Переглянути файл

@@ -4,7 +4,9 @@ require 'pundit/rspec'
RSpec.describe StatusPolicy, type: :model do
subject { described_class }

let(:admin) { Fabricate(:user, admin: true) }
let(:alice) { Fabricate(:account, username: 'alice') }
let(:bob) { Fabricate(:account, username: 'bob') }
let(:status) { Fabricate(:status, account: alice) }

permissions :show?, :reblog? do
@@ -86,4 +88,22 @@ RSpec.describe StatusPolicy, type: :model do
expect(subject).to_not permit(viewer, status)
end
end

permissions :destroy?, :unreblog? do
it 'grants access when account is deleter' do
expect(subject).to permit(status.account, status)
end

it 'grants access when account is admin' do
expect(subject).to permit(admin.account, status)
end

it 'denies access when account is not deleter' do
expect(subject).to_not permit(bob, status)
end

it 'denies access when no deleter' do
expect(subject).to_not permit(nil, status)
end
end
end

+ 29
- 1
spec/services/process_interaction_service_spec.rb Переглянути файл

@@ -7,6 +7,35 @@ RSpec.describe ProcessInteractionService do

subject { ProcessInteractionService.new }

describe 'status delete slap' do
let(:remote_status) { Fabricate(:status, account: remote_sender) }
let(:envelope) { OStatus2::Salmon.new.pack(payload, sender.keypair) }
let(:payload) {
<<~XML
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/">
<author>
<email>carol@localdomain.com</email>
<name>carol</name>
<uri>https://webdomain.com/users/carol</uri>
</author>

<id>#{remote_status.id}</id>
<activity:verb>http://activitystrea.ms/schema/1.0/delete</activity:verb>
</entry>
XML
}

before do
receiver.update(locked: true)
remote_sender.update(private_key: sender.private_key, public_key: remote_sender.public_key)
end

it 'deletes a record' do
expect(RemovalWorker).to receive(:perform_async).with(remote_status.id)
subject.call(envelope, receiver)
end
end

describe 'follow request slap' do
before do
receiver.update(locked: true)
@@ -60,7 +89,6 @@ XML
end
end


describe 'follow request authorization slap' do
before do
receiver.update(locked: true)


Завантаження…
Відмінити
Зберегти