Build a bulletin board API with authentication authorization in Rails # 17 Add administrator privileges

Building a bulletin board API with authentication authorization in Rails 6 # 16 policy settings

Prepare administrator privileges

With the previous implementation, only the poster can edit or delete the post. However, I will extend it so that anyone can edit / delete posts when logged in as an administrator.

To do this, add an admin column to your user model.

$ rails g migration AddAdminToUsers admin:boolean

db/migrate/xxxxxxxxxxxxxx_add_admin_to_users.rb


# frozen_string_literal: true

class AddAdminToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :admin, :boolean, default: false, null: false
  end
end

By the way, until now, I wrote the test after implementing the function, but I think that I understand the basic behavior of pundit, so I will write it from the test first.

Since the test that can not be edited and deleted when logged in as another user without administrator authority has already been written,

Let's implement. Strictly speaking, it is perfect to implement both policy test and request test, but here I will implement only policy.

If you like, don't look at the sample written here, but first try implementing it yourself and compare it, as it will be a practice to write code, so please try it.

Editing post_policy_spec.rb

spec/policies/post_policy_spec.rb


...
 RSpec.describe PostPolicy, type: :policy do
   let(:user) { create(:user) }
+  let(:admin_user) { create(:user, admin: true) }
   let(:post) { create(:post) }

...
     it "Not allowed when logged in but another user" do
       expect(subject).not_to permit(user, post)
     end
+    it "Allowed when logged in as admin user" do
+      expect(subject).to permit(admin_user, post)
+    end
...

spec/factories/posts.rb


...
     remember_created_at { nil }
     name { "MyString" }
     tokens { nil }
+    admin { false }
   end
...

After implementing so far, move rubocop and rspec and check. I haven't implemented the policy file yet, so the test is moss.

implementation of policy

First, let's create a private method in application_policy.rb that determines that you are an administrator.

app/policies/application_policy.rb


...
   private

   def mine?
     @record.user == @user
   end
+
+  def admin?
+    @user.present? && @user.admin?
+  end
+

All that is left is to change the two judgments of update? Destroy? In post_policy.rb.

app/policies/post_policy.rb


   def update?
-    mine?
+    mine? || admin?
   end
 
   def destroy?
-    mine?
+    mine? || admin?
   end

That's it!

Easily create admin with trait

This is a bit thin article, so let's touch factoryBot to make it easier to create admin users.

spec/factories/users.rb


     name { "MyString" }
     tokens { nil }
     admin { false }
+
+    trait :admin do
+      admin { true }
+    end
   end

spec/policies/post_policy_spec.rb


 RSpec.describe PostPolicy, type: :policy do
   let(:user) { create(:user) }
-  let(:admin_user) { create(:user, admin: true) }
+  let(:admin_user) { create(:user, :admin) }
   let(:post) { create(:post) }

How about running rspec with this? If you can write without mistakes, you should pass the test.

As you can see, the trait can be used by passing it as an alias to the second argument such as create in factoryBot. If you just set the admin flag, there is little benefit and it doesn't make much sense, but if there is a column that you want to have an initial value as a set for admin users, for example, multiple columns will be added each time create. You don't have to set the initial value.

Please use all means.

Continued

Building a bulletin board API with authentication authorization with Rails 6 # 18 ・ Implementation of final user controller [To the serial table of contents]

Recommended Posts

Build a bulletin board API with authentication authorization in Rails # 17 Add administrator privileges
Build a bulletin board API with authentication authorization in Rails # 13 Add authentication header
Introducing # 15 pundit to build a bulletin board API with authentication authorization in Rails 6
Build a bulletin board API with authentication authorization in Rails 6 # 14 seed Execution time display
# 16 policy setting to build bulletin board API with authentication authorization in Rails 6
# 8 seed implementation to build bulletin board API with authentication authorization in Rails 6
Build a bulletin board API with authentication and authorization with Rails 6 # 1 Environment construction
Introduced # 9 serializer to build bulletin board API with authentication authorization in Rails 6
Build a bulletin board API with authentication authorization in Rails # 12 Association of user and post
# 6 show, create implementation to build bulletin board API with authentication authorization in Rails 6
Build a bulletin board API with authentication authorization with Rails 6 # 2 Introducing git and rubocop
# 7 update, destroy implementation to build bulletin board API with authentication authorization in Rails 6
Build a bulletin board API with authentication authorization in Rails 6 # 11 User model test and validation added
I tried to make a group function (bulletin board) with Rails
Create a SPA with authentication function with Rails API mode + devise_token_auth + Vue.js 3 (Rails edition)
Create a simple bulletin board with Java + MySQL
Try to create a bulletin board in Java
Add a project in any folder with Gradle
How to build API with GraphQL and Rails
[Note] Build a Python3 environment with Docker in EC2
[How to insert a video in haml with Rails]
Build Rails (API) x MySQL x Nuxt.js environment with Docker
[Ruby on Rails] Add a column with a foreign key constraint
I came across a guy with two dots in Rails
How to set up a proxy with authentication in Feign