【发布时间】:2015-09-09 23:04:18
【问题描述】:
在我的 Rails 4 应用中,有 5 个模型:
class User < ActiveRecord::Base
has_many :administrations
has_many :calendars, through: :administrations
end
class Calendar < ActiveRecord::Base
has_many :administrations
has_many :users, through: :administrations
has_many :posts
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
class Post < ActiveRecord::Base
belongs_to :calendar
end
class Comment < ActiveRecord::Base
belongs_to :post
belongs_to :user
end
我使用 Devise 实现了身份验证(因此我们可以访问 current_user)。
现在,我正在尝试使用 Pundit(第一个计时器)实施授权。
按照documentation,我安装了gem并运行rails g pundit:install生成器。
然后,我创建了一个CalendarPolicy,如下:
class CalendarPolicy < ApplicationPolicy
attr_reader :user, :calendar
def initialize(user, calendar)
@user = user
@calendar = calendar
end
def index?
user.owner? || user.editor? || user.viewer?
end
def show?
user.owner? || user.editor? || user.viewer?
end
def update?
user.owner? || user.editor?
end
def edit?
user.owner? || user.editor?
end
def destroy?
user.owner?
end
end
我还使用以下方法更新了我的User 模型:
def owner?
Administration.find_by(user_id: params[:user_id], calendar_id: params[:calendar_id]).role == "Owner"
end
def editor?
Administration.find_by(user_id: params[:user_id], calendar_id: params[:calendar_id]).role == "Editor"
end
def viewer?
Administration.find_by(user_id: params[:user_id], calendar_id: params[:calendar_id]).role == "Viewer"
end
我用authorize @calendar 更新了我的CalendarsController 操作,如下所示:
def index
@user = current_user
@calendars = @user.calendars.all
end
# GET /calendars/1
# GET /calendars/1.json
def show
@user = current_user
@calendar = @user.calendars.find(params[:id])
authorize @calendar
end
# GET /calendars/new
def new
@user = current_user
@calendar = @user.calendars.new
authorize @calendar
end
# GET /calendars/1/edit
def edit
@user = current_user
authorize @calendar
end
# POST /calendars
# POST /calendars.json
def create
@user = current_user
@calendar = @user.calendars.create(calendar_params)
authorize @calendar
respond_to do |format|
if @calendar.save
current_user.set_default_role(@calendar.id, 'Owner')
format.html { redirect_to calendar_path(@calendar), notice: 'Calendar was successfully created.' }
format.json { render :show, status: :created, location: @calendar }
else
format.html { render :new }
format.json { render json: @calendar.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /calendars/1
# PATCH/PUT /calendars/1.json
def update
@user = current_user
@calendar = Calendar.find(params[:id])
authorize @calendar
respond_to do |format|
if @calendar.update(calendar_params)
format.html { redirect_to calendar_path(@calendar), notice: 'Calendar was successfully updated.' }
format.json { render :show, status: :ok, location: @calendar }
else
format.html { render :edit }
format.json { render json: @calendar.errors, status: :unprocessable_entity }
end
end
end
# DELETE /calendars/1
# DELETE /calendars/1.json
def destroy
@user = current_user
@calendar.destroy
authorize @calendar
respond_to do |format|
format.html { redirect_to calendars_url, notice: 'Calendar was successfully destroyed.' }
format.json { head :no_content }
end
end
我将after_action :verify_authorized, :except => :index 包含在我的ApplicationController 中。
现在,当我登录时,我可以访问 http://localhost:3000/calendars/,但是当我尝试访问 http://localhost:3000/calendars/new 时,我收到以下错误:
Pundit::NotAuthorizedError in CalendarsController#new
not allowed to new? this #<Calendar id: nil, name: nil, created_at: nil, updated_at: nil>
@user = current_user
@calendar = @user.calendars.new
authorize @calendar
end
显然,我一定做错了什么。
问题:我不知道是什么。
有什么想法吗?
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-4 authorization pundit