Install Pundit and add UserPolicy
Some checks are pending
CI / scan_ruby (push) Waiting to run
CI / scan_js (push) Waiting to run
CI / lint (push) Waiting to run
CI / test (push) Waiting to run

This commit is contained in:
sto 2025-03-22 09:48:40 +01:00
parent 0b47cc4d8a
commit 5472a400d1
6 changed files with 114 additions and 1 deletions

View File

@ -67,3 +67,5 @@ group :test do
gem "capybara" gem "capybara"
gem "selenium-webdriver" gem "selenium-webdriver"
end end
gem "pundit", "~> 2.5"

View File

@ -221,6 +221,8 @@ GEM
public_suffix (6.0.1) public_suffix (6.0.1)
puma (6.6.0) puma (6.6.0)
nio4r (~> 2.0) nio4r (~> 2.0)
pundit (2.5.0)
activesupport (>= 3.0.0)
raabro (1.4.0) raabro (1.4.0)
racc (1.8.1) racc (1.8.1)
rack (3.1.12) rack (3.1.12)
@ -406,6 +408,7 @@ DEPENDENCIES
kamal kamal
propshaft propshaft
puma (>= 5.0) puma (>= 5.0)
pundit (~> 2.5)
rails (~> 8.0.2) rails (~> 8.0.2)
rubocop-rails-omakase rubocop-rails-omakase
selenium-webdriver selenium-webdriver

View File

@ -1,8 +1,14 @@
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
include Authentication include Authentication
include Pundit::Authorization
before_action :set_title, :set_current_user
# TODO: add later
# after_action :verify_authorized
# Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has. # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has.
allow_browser versions: :modern allow_browser versions: :modern
before_action :set_title, :set_current_user rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
layout "authenticated" layout "authenticated"
private private
@ -14,4 +20,11 @@ class ApplicationController < ActionController::Base
def set_current_user def set_current_user
@current_user = current_user @current_user = current_user
end end
def user_not_authorized(exception)
policy_name = exception.policy.class.to_s.underscore
flash[:error] = t "#{policy_name}.#{exception.query}", scope: "pundit", default: :default
redirect_back_or_to(root_path)
end
end end

View File

@ -2,15 +2,21 @@ class UsersController < ApplicationController
before_action :set_user, only: %i[ destroy edit show update ] before_action :set_user, only: %i[ destroy edit show update ]
def index def index
authorize :user
@title = "All users" @title = "All users"
@users = User.all @users = User.all
end end
def edit def edit
authorize @user
@title = "My settings" @title = "My settings"
end end
def update def update
authorize @user
if @user.update(user_params) if @user.update(user_params)
redirect_to contests_path redirect_to contests_path
else else
@ -19,15 +25,21 @@ class UsersController < ApplicationController
end end
def show def show
authorize @user
redirect_to edit_user_path(@user) redirect_to edit_user_path(@user)
end end
def new def new
authorize :user
@title = "New user" @title = "New user"
@user = User.new() @user = User.new()
end end
def create def create
authorize :user
@user = User.new(user_params) @user = User.new(user_params)
if @user.save if @user.save
redirect_to users_path redirect_to users_path
@ -38,6 +50,7 @@ class UsersController < ApplicationController
end end
def destroy def destroy
authorize @user
end end
private private

View File

@ -0,0 +1,53 @@
# frozen_string_literal: true
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
@user = user
@record = record
end
def index?
false
end
def show?
false
end
def create?
false
end
def new?
create?
end
def update?
false
end
def edit?
update?
end
def destroy?
false
end
class Scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
raise NoMethodError, "You must define #resolve in #{self.class}"
end
private
attr_reader :user, :scope
end
end

View File

@ -0,0 +1,29 @@
class UserPolicy < ApplicationPolicy
def index
user.admin?
end
def show?
user.admin? || user.id == record.id
end
def new?
user.admin?
end
def create?
user.admin?
end
def edit?
user.admin? || user.id == record.id
end
def update?
user.admin? || user.id == record.id
end
def destroy?
user.admin?
end
end