나는 세 명의 다른 사용자 (관리자, 판매자, 뷰어)에게 권한을 부여하기 위해 pundit gem
을 사용하고 있습니다. 현재 모든 것이 작동하고 관리자는 모든 것에 액세스 할 수 있으며 판매자는 자신의 제품을 볼 수 있으며 뷰어는 제품을 볼 수 있습니다.레일스 평단의 보석, 로그인하지 않은 사용자에게보기 허용
내가 가지고있는 유일한 결함은 signed_up/signed_in 사용자가 아닌 사용자가 검색 결과를 통해 제품을 볼 수 있도록하려는 것입니다. 현재 non sign_up/signed_in 사용자는 검색 결과를 볼 수 있지만 표시보기에는 액세스 할 수 없습니다. 여기
는 내가 가지고있는 설정입니다 :class ItemPolicy < ApplicationPolicy
attr_reader :item
def initialize(user, record)
super(user, record)
@user = user
@item = record
end
def update?
@user.is_a?(Admin) ? item.all : @user.items
end
def index?
@user.is_a?(Admin) ? item.all : @user.items
end
def show?
@user.is_a?(Admin) ? item.all : @user.items
end
def create?
@user.is_a?(Admin) ? item.all : @user.items
end
def new?
@user.is_a?(Admin) ? item.all : @user.items
end
def edit?
@user.is_a?(Admin) ? item.all : @user.items
end
def destroy?
@user.is_a?(Admin) ? item.all : @user.items
end
class Scope < Struct.new(:user, :scope)
def resolve
if user.is_a?(Admin)
scope.where(:parent_id => nil)
elsif user.is_a?(Seller)
scope.where(:id => user.items)
end
end
def show?
return true if user.is_a?(Admin)
return true if user.seller_id == seller.id && user.is_a?(Seller)
false
end
end
end
컨트롤러 :
class ItemsController < ApplicationController
before_action :set_item, only: [:show, :edit, :update, :destroy]
def index
authorize Item
@items = policy_scope(Item)
end
def search
if params[:term]
@items = Item.search(params[:term]).order("created_at DESC")
else
@items = []
end
end
def show
@comments = Comment.where(item_id: @item).order("created_at DESC")
@items = policy_scope(Item).find(params[:id])
authorize @item
end
def new
@item = Item.new
authorize @item
@categories = Category.order(:name)
end
def edit
authorize @item
@categories = Category.order(:name)
end
def create
@item = Item.new(item_params)
authorize @item
respond_to do |format|
if @item.save
format.html { redirect_to @item, notice: 'Item was successfully created.' }
format.json { render :show, status: :created, location: @item }
else
format.html { render :new }
format.json { render json: @item.errors, status: :unprocessable_entity }
end
end
end
def update
authorize @item
respond_to do |format|
if @item.update(item_params)
format.html { redirect_to @item, notice: 'Item was successfully updated.' }
format.json { render :show, status: :ok, location: @item }
else
format.html { render :edit }
format.json { render json: @item.errors, status: :unprocessable_entity }
end
end
end
def destroy
authorize @item
@item.destroy
respond_to do |format|
format.html { redirect_to items_url, notice: 'Item was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_item
@item = Item.find(params[:id])
authorize @item
end
def item_params
params.require(:item).permit(:title, :description, :image, :price, :category_id)
end
end
application_contoller.rb
class ApplicationController < ActionController::Base
include Pundit
protect_from_forgery prepend: true
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
def pundit_user
current_seller || current_admin || current_viewer
end
private
def user_not_authorized(exception)
policy_name = exception.policy.class.to_s.underscore
flash[:warning] = t "#{policy_name}.#{exception.query}", scope: "pundit", default: :default
redirect_to(request.referrer || root_path)
end
end
업데이트 1
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
raise Pundit::NotAuthorizedError, "must be logged in" unless user
@user = user
@record = record
end
def index?
true # anybody can view
end
def show?
true # anybody can view
end
def search?
index?
end
def new?
create?
end
def edit?
update?
end
def destroy?
update?
end
private
# don't repeat yourself
def admin?
user.is_a?(Admin)
end
def seller?
user.is_a?(Seller)
end
end
class ItemPolicy < ApplicationPolicy
attr_reader :item
class Scope < Struct.new(:user, :scope)
def resolve
if admin?
scope.where(parent_id: nil)
elsif seller?
# avoids a query for user.items
scope.where(seller: user)
end
end
end
def initialize(user, record)
super(user, record)
@user = user
@item = record
end
def update?
admin? || is_owner?
end
def create?
# just guessing here
admin? || seller?
end
private
def is_owner?
# or whatever the association between the item and its owner is
item.seller == user
end
end
다시 한번 감사드립니다. @max !!! 귀하의 답변에 따라 코드를 업데이트했지만 여전히 '인증되지 않은 사용자'가 쇼 페이지를 볼 수 없습니다 ... 또한 사용자가 로그인하면 모든 항목을보고 편집 할 수 있습니다. 업데이트 1을 내 질문에 추가 했으므로 지금까지 내가 한 것을 확인할 수 있습니다. – Theopap
관리자는 모든 항목을보고 편집 할 수 있습니다. #update에서 논리를 변경하려는 것이 아니라면? 방법. 또한 무단 사용자가 리소스에 액세스 할 수있게하려면 Devise 'authorize_user!' (또는 무엇이든) 콜백. – max
네, 그게 바로 제가 관리자가 모든 항목에 대한 액세스 권한을 갖고 싶어한다는 것입니다. 뷰어 만 검색 결과 색인과 보여줍니다 ....하지만 현재 변경 사항은 ... 로그인 한 판매자가 할 수 있습니다. 편집 /보기/모든 항목 삭제. – Theopap