以允许的角色登录,但未经授权

问题描述 投票:0回答:1

我遵循了Pundit的典型授权教程,因此遇到了问题。我是Ruby on Rails的新手,所以我真的不太了解这是什么原因。我用谷歌搜索其他堆栈问题,但没有像我一样使用角色进行授权。随时发表评论并留下建议。

(错误发生在users#index;我以讲师身份登录,但不允许我进入用户的索引页面。]

application_policy.rb

class ApplicationPolicy
  attr_reader :user, :record

  def initialize(user, record)
    @user = user
    @record = record
  end

  def index?
    false
  end

  def show?
    scope.where(:id => record.id).exists?
  end

  def create?
    false
  end

  def new?
    create?
  end

  def update?
    false
  end

  def edit?
    update?
  end

  def destroy?
    false
  end

  def scope
    Pundit.policy_scope!(user, record.class)
  end

  class Scope
    attr_reader :user, :scope

    def initialize(user, scope)
      @user = user
      @scope = scope
    end

    def resolve
      scope
    end
  end
end

user_policy.rb

class UserPolicy < ApplicationPolicy
  class Scope < Scope
    def resolve
      scope.all
    end
    def create?
      can_make_changes?
    end
    def update?
      can_make_changes?
    end
    def edit?
      can_make_changes?
    end

    def can_make_changes?
      @user.role == "Instructor"
    end
  end
end

users_controller.rb

class UsersController < ApplicationController
  before_action :authenticate_user!, :find_user, only: [:edit, :update,:destroy]

  def index
    @users = User.all
    authorize User
  end

  #other methods...

  private
    def find_user
      @user = User.find(params[:id])
    end

    def user_params
      params.require(:user).permit(:first_name, :last_name, :login, :student_id, :citizen_id, :department_name, :instructor_id)
    end
end

application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :configure_permitted_parameters, if: :devise_controller?
  rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized

  include Pundit

  protected
    def configure_permitted_parameters
      devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name, :last_name, :citizen_id, :student_id, :instructor_id, :department_name, :login, :role])
    end

    def user_not_authorized
      flash[:warning] = "You are not authorized to perform this action."
      redirect_to(request.referrer || courses_path)
    end

end

user.rb

class User < ApplicationRecord
  validates :first_name, presence: true, format: { with: /\A[a-zA-Z]+\z/, message: "only allows letters" }
  validates :last_name, presence: true, format: { with: /\A[a-zA-Z]+\z/, message: "only allows letters" }
  validates :login, presence: true, format: { with: /\A[a-zA-Z0-9]+\z/, message: "no special characters allowed" }
  validates :citizen_id, presence: true, uniqueness: true, format: { with: /\A[0-9]+\z/, message: "only allows numbers" }
  validates :role, presence: true
  validates :password, presence: true, length: { minimum: 6 }
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable

  enum role: {'Student'=>'Student','Instructor'=>'Instructor','Other'=>'Other'}
  has_and_belongs_to_many :courses
  has_and_belongs_to_many :groups
  has_many :projects
end
ruby-on-rails ruby devise pundit
1个回答
0
投票

您需要向user_policy.rb添加方法以允许访问索引。

def index?
  can_make_changes?
end

否则,根据application_policy.rb,它默认为false

然后,您需要更新users_controller.rb文件中的索引方法,以仅返回范围内的记录。

def index
  @users = policy_scope(User)
end

根据您的情况,根据UserPolicy all方法,作用域将为resolve

© www.soinside.com 2019 - 2024. All rights reserved.