Add customizable user roles (#18641)
* Add customizable user roles * Various fixes and improvements * Add migration for old settings and fix tootctl role management
This commit is contained in:
		@@ -5,7 +5,7 @@ require 'pundit/rspec'
 | 
			
		||||
 | 
			
		||||
RSpec.describe AccountModerationNotePolicy do
 | 
			
		||||
  let(:subject) { described_class }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, admin: true).account }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
 | 
			
		||||
  let(:john)    { Fabricate(:account) }
 | 
			
		||||
 | 
			
		||||
  permissions :create? do
 | 
			
		||||
@@ -31,7 +31,7 @@ RSpec.describe AccountModerationNotePolicy do
 | 
			
		||||
 | 
			
		||||
    context 'admin' do
 | 
			
		||||
      it 'grants to destroy' do
 | 
			
		||||
        expect(subject).to permit(admin, AccountModerationNotePolicy)
 | 
			
		||||
        expect(subject).to permit(admin, account_moderation_note)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ require 'pundit/rspec'
 | 
			
		||||
 | 
			
		||||
RSpec.describe AccountPolicy do
 | 
			
		||||
  let(:subject) { described_class }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, admin: true).account }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
 | 
			
		||||
  let(:john)    { Fabricate(:account) }
 | 
			
		||||
  let(:alice)   { Fabricate(:account) }
 | 
			
		||||
 | 
			
		||||
@@ -55,7 +55,7 @@ RSpec.describe AccountPolicy do
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  permissions :redownload?, :subscribe?, :unsubscribe? do
 | 
			
		||||
  permissions :redownload? do
 | 
			
		||||
    context 'admin' do
 | 
			
		||||
      it 'permits' do
 | 
			
		||||
        expect(subject).to permit(admin)
 | 
			
		||||
@@ -70,7 +70,7 @@ RSpec.describe AccountPolicy do
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  permissions :suspend?, :silence? do
 | 
			
		||||
    let(:staff) { Fabricate(:user, admin: true).account }
 | 
			
		||||
    let(:staff) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
 | 
			
		||||
 | 
			
		||||
    context 'staff' do
 | 
			
		||||
      context 'record is staff' do
 | 
			
		||||
@@ -94,7 +94,7 @@ RSpec.describe AccountPolicy do
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  permissions :memorialize? do
 | 
			
		||||
    let(:other_admin) { Fabricate(:user, admin: true).account }
 | 
			
		||||
    let(:other_admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
 | 
			
		||||
 | 
			
		||||
    context 'admin' do
 | 
			
		||||
      context 'record is admin' do
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ require 'pundit/rspec'
 | 
			
		||||
 | 
			
		||||
RSpec.describe CustomEmojiPolicy do
 | 
			
		||||
  let(:subject) { described_class }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, admin: true).account }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
 | 
			
		||||
  let(:john)    { Fabricate(:account) }
 | 
			
		||||
 | 
			
		||||
  permissions :index?, :enable?, :disable? do
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ require 'pundit/rspec'
 | 
			
		||||
 | 
			
		||||
RSpec.describe DomainBlockPolicy do
 | 
			
		||||
  let(:subject) { described_class }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, admin: true).account }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
 | 
			
		||||
  let(:john)    { Fabricate(:account) }
 | 
			
		||||
 | 
			
		||||
  permissions :index?, :show?, :create?, :destroy? do
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ require 'pundit/rspec'
 | 
			
		||||
 | 
			
		||||
RSpec.describe EmailDomainBlockPolicy do
 | 
			
		||||
  let(:subject) { described_class }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, admin: true).account }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
 | 
			
		||||
  let(:john)    { Fabricate(:account) }
 | 
			
		||||
 | 
			
		||||
  permissions :index?, :create?, :destroy? do
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ require 'pundit/rspec'
 | 
			
		||||
 | 
			
		||||
RSpec.describe InstancePolicy do
 | 
			
		||||
  let(:subject) { described_class }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, admin: true).account }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
 | 
			
		||||
  let(:john)    { Fabricate(:account) }
 | 
			
		||||
 | 
			
		||||
  permissions :index?, :show?, :destroy? do
 | 
			
		||||
 
 | 
			
		||||
@@ -5,8 +5,8 @@ require 'pundit/rspec'
 | 
			
		||||
 | 
			
		||||
RSpec.describe InvitePolicy do
 | 
			
		||||
  let(:subject) { described_class }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, admin: true).account }
 | 
			
		||||
  let(:john)    { Fabricate(:account) }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
 | 
			
		||||
  let(:john)    { Fabricate(:user).account }
 | 
			
		||||
 | 
			
		||||
  permissions :index? do
 | 
			
		||||
    context 'staff?' do
 | 
			
		||||
@@ -17,16 +17,22 @@ RSpec.describe InvitePolicy do
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  permissions :create? do
 | 
			
		||||
    context 'min_required_role?' do
 | 
			
		||||
    context 'has privilege' do
 | 
			
		||||
      before do
 | 
			
		||||
        UserRole.everyone.update(permissions: UserRole::FLAGS[:invite_users])
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'permits' do
 | 
			
		||||
        allow_any_instance_of(described_class).to receive(:min_required_role?) { true }
 | 
			
		||||
        expect(subject).to permit(john, Invite)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context 'not min_required_role?' do
 | 
			
		||||
    context 'does not have privilege' do
 | 
			
		||||
      before do
 | 
			
		||||
        UserRole.everyone.update(permissions: UserRole::Flags::NONE)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'denies' do
 | 
			
		||||
        allow_any_instance_of(described_class).to receive(:min_required_role?) { false }
 | 
			
		||||
        expect(subject).to_not permit(john, Invite)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
@@ -54,39 +60,15 @@ RSpec.describe InvitePolicy do
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context 'not owner?' do
 | 
			
		||||
      context 'Setting.min_invite_role == "admin"' do
 | 
			
		||||
        before do
 | 
			
		||||
          Setting.min_invite_role = 'admin'
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        context 'admin?' do
 | 
			
		||||
          it 'permits' do
 | 
			
		||||
            expect(subject).to permit(admin, Fabricate(:invite))
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        context 'not admin?' do
 | 
			
		||||
          it 'denies' do
 | 
			
		||||
            expect(subject).to_not permit(john, Fabricate(:invite))
 | 
			
		||||
          end
 | 
			
		||||
      context 'admin?' do
 | 
			
		||||
        it 'permits' do
 | 
			
		||||
          expect(subject).to permit(admin, Fabricate(:invite))
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      context 'Setting.min_invite_role != "admin"' do
 | 
			
		||||
        before do
 | 
			
		||||
          Setting.min_invite_role = 'else'
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        context 'staff?' do
 | 
			
		||||
          it 'permits' do
 | 
			
		||||
            expect(subject).to permit(admin, Fabricate(:invite))
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        context 'not staff?' do
 | 
			
		||||
          it 'denies' do
 | 
			
		||||
            expect(subject).to_not permit(john, Fabricate(:invite))
 | 
			
		||||
          end
 | 
			
		||||
      context 'not admin?' do
 | 
			
		||||
        it 'denies' do
 | 
			
		||||
          expect(subject).to_not permit(john, Fabricate(:invite))
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ require 'pundit/rspec'
 | 
			
		||||
 | 
			
		||||
RSpec.describe RelayPolicy do
 | 
			
		||||
  let(:subject) { described_class }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, admin: true).account }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
 | 
			
		||||
  let(:john)    { Fabricate(:account) }
 | 
			
		||||
 | 
			
		||||
  permissions :update? do
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ require 'pundit/rspec'
 | 
			
		||||
 | 
			
		||||
RSpec.describe ReportNotePolicy do
 | 
			
		||||
  let(:subject) { described_class }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, admin: true).account }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
 | 
			
		||||
  let(:john)    { Fabricate(:account) }
 | 
			
		||||
 | 
			
		||||
  permissions :create? do
 | 
			
		||||
@@ -25,7 +25,8 @@ RSpec.describe ReportNotePolicy do
 | 
			
		||||
  permissions :destroy? do
 | 
			
		||||
    context 'admin?' do
 | 
			
		||||
      it 'permit' do
 | 
			
		||||
        expect(subject).to permit(admin, ReportNote)
 | 
			
		||||
        report_note = Fabricate(:report_note, account: john)
 | 
			
		||||
        expect(subject).to permit(admin, report_note)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ require 'pundit/rspec'
 | 
			
		||||
 | 
			
		||||
RSpec.describe ReportPolicy do
 | 
			
		||||
  let(:subject) { described_class }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, admin: true).account }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
 | 
			
		||||
  let(:john)    { Fabricate(:account) }
 | 
			
		||||
 | 
			
		||||
  permissions :update?, :index?, :show? do
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ require 'pundit/rspec'
 | 
			
		||||
 | 
			
		||||
RSpec.describe SettingsPolicy do
 | 
			
		||||
  let(:subject) { described_class }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, admin: true).account }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
 | 
			
		||||
  let(:john)    { Fabricate(:account) }
 | 
			
		||||
 | 
			
		||||
  permissions :update?, :show? do
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ require 'pundit/rspec'
 | 
			
		||||
RSpec.describe StatusPolicy, type: :model do
 | 
			
		||||
  subject { described_class }
 | 
			
		||||
 | 
			
		||||
  let(:admin) { Fabricate(:user, admin: true) }
 | 
			
		||||
  let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
 | 
			
		||||
  let(:alice) { Fabricate(:account, username: 'alice') }
 | 
			
		||||
  let(:bob) { Fabricate(:account, username: 'bob') }
 | 
			
		||||
  let(:status) { Fabricate(:status, account: alice) }
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ require 'pundit/rspec'
 | 
			
		||||
 | 
			
		||||
RSpec.describe TagPolicy do
 | 
			
		||||
  let(:subject) { described_class }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, admin: true).account }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
 | 
			
		||||
  let(:john)    { Fabricate(:account) }
 | 
			
		||||
 | 
			
		||||
  permissions :index?, :show?, :update? do
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ require 'pundit/rspec'
 | 
			
		||||
 | 
			
		||||
RSpec.describe UserPolicy do
 | 
			
		||||
  let(:subject) { described_class }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, admin: true).account }
 | 
			
		||||
  let(:admin)   { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
 | 
			
		||||
  let(:john)    { Fabricate(:account) }
 | 
			
		||||
 | 
			
		||||
  permissions :reset_password?, :change_email? do
 | 
			
		||||
@@ -111,57 +111,4 @@ RSpec.describe UserPolicy do
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  permissions :promote? do
 | 
			
		||||
    context 'admin?' do
 | 
			
		||||
      context 'promotable?' do
 | 
			
		||||
        it 'permits' do
 | 
			
		||||
          expect(subject).to permit(admin, john.user)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      context '!promotable?' do
 | 
			
		||||
        it 'denies' do
 | 
			
		||||
          expect(subject).to_not permit(admin, admin.user)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context '!admin?' do
 | 
			
		||||
      it 'denies' do
 | 
			
		||||
        expect(subject).to_not permit(john, User)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  permissions :demote? do
 | 
			
		||||
    context 'admin?' do
 | 
			
		||||
      context '!record.admin?' do
 | 
			
		||||
        context 'demoteable?' do
 | 
			
		||||
          it 'permits' do
 | 
			
		||||
            john.user.update(moderator: true)
 | 
			
		||||
            expect(subject).to permit(admin, john.user)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        context '!demoteable?' do
 | 
			
		||||
          it 'denies' do
 | 
			
		||||
            expect(subject).to_not permit(admin, john.user)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      context 'record.admin?' do
 | 
			
		||||
        it 'denies' do
 | 
			
		||||
          expect(subject).to_not permit(admin, admin.user)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context '!admin?' do
 | 
			
		||||
      it 'denies' do
 | 
			
		||||
        expect(subject).to_not permit(john, User)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user