我在执行权威人士授权的最后一步时遇到了一些麻烦......我有一个项目模型以及一个 project_policy,它授权应用程序中的哪些用户可以查看该项目并与之交互。但是,我的项目有几个组件 - 其中一个是在项目中访问的项目版本的索引(项目 has_many 版本)......所以我还需要能够限制用户访问这个版本列表。 ..以及默认的项目配置文件(如果用户不是所有者/管理员或合作者,我会限制)。但是,我目前有这些“版本”,它们是在他们自己的模型中设置的。
详细信息:目前,如果我不是管理员/所有者或合作者,当我尝试访问 url projects/20 时,限制会起作用(它会重定向我并说“你没有被授权”),但如果我导航到“项目” /20/versions' 或 'projects/20/versions/1' 或 'projects/20/versions/new' 它不会限制我。我需要为此创建一个新的 version_policy,还是我可以在 project_policy 中限制它,因为从技术上讲,这些版本是项目的一部分?& 我需要添加的代码是什么样的?
我的代码如下 - 在此先感谢您提供的所有帮助...
PROJECT_POLICY.RB
class Scope < Struct.new(:user, :scope)
end
def update?
user.project_admin? or user.project_collaborator?
end
# method used in projects controller, (study pundit docs)
def visit?
if project.is_private?
user.project_admin?(project) || user.project_owner?(project) || user.project_collaborator?(project)
else
true
end
end
def main_profile?
true
end
def projectversions?
user.project_admin?(project) || user.project_owner?(project)
end
def settings?
user.project_admin?(project) || user.project_owner?(project)
end
def collaboration?
user.project_admin?(project) || user.project_owner?(project)
end
def invite_admin?
user.project_admin?(project) || user.project_owner?(project)
end
def invite_collaborator?
user.project_admin?(project) || user.project_owner?(project)
end
end
PROJECT.RB(项目模型)
class Project < ActiveRecord::Base
...
...
has_many :versions, dependent: :destroy
validates :title, presence: true, length: { maximum: 100 }
validates :background, presence: true
validates :user_id, presence: true
default_scope -> { order('created_at DESC') }
def user_name
owner.try(:name)
end
def user_name=(name)
self.user = User.find_by_name(name) if name.present?
end
def private?
self.is_private == true
end
def public?
self.is_private == false
end
end
PROJECTS_CONTROLLER.RB
class ProjectsController < ApplicationController
before_filter :signed_in_user, only: [:create, :new, :edit, :update]
# Creates redirect and alert when pundit sees someone is not authorized (via :not_authorized_in_project below)
rescue_from Pundit::NotAuthorizedError, :with=>:not_authorized_in_project
def new
@project = Project.new
end
def show
@project = Project.find(params[:id])
authorize @project, :visit?
@user = User.where(:id => @project.user_id).first
rescue Pundit::NotAuthorizedError
flash[:danger] = "You are not authorized to access this page."
redirect_to projects_path || root_path
end
def create
@project = current_user.own_projects.build(project_params)
if @project.save
flash[:success] = "Welcome to your new project."
redirect_to @project
else
render 'new'
end
end
def update
@project = Project.find(params[:id])
if @project.update_attributes(project_params)
flash[:success] = "Project Created"
redirect_to @project
else
render 'edit'
end
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "Project destroyed"
redirect_to users_path
end
def projectadmins
@title = "Project Admins"
@project = Project.find(params[:id])
authorize @project, :visit?
@projects = @project.projectadmins.paginate(page: params[:page])
render 'show_projectadmin_project'
rescue Pundit::NotAuthorizedError
flash[:danger] = "You are not authorized to access this page."
redirect_to projects_path || root_path
end
def projectversions
*# If I should place the authorizations in this controller...What code should go here? And how would I also restrict the new/show actions for projects/versions i.e, 'projects/20/versions/new', etc?*
end
def settings
@project = Project.find(params[:project_id])
authorize @project
render 'settings'
end
private
def project_params
params.require(:project).permit(:title, :background, :is_private)
end
# USED FOR PUNDIT REDIRECT & ALERT FLASH WHEN SOMEONE IS NOT AUTHORIZED TO ACCESS SOMETHING
def not_authorized_in_project
flash[:danger] = "You are not authorized to access this page."
redirect_to project_path(@project) || root_path
end
end
路线.RB
ProductionApp::Application.routes.draw do
resources :users
resources :sessions, only: [:new, :create, :destroy]
resources :projects do
resources :versions
match '/settings'=>'projects#settings', :via=>:get, :as=>:settings
match '/collaboration'=>'projects#collaboration', :via=>:get, :as=>:collaboration
match '/invite_admin'=>'projects#invite_admin', :via=>:patch, :as=>:invite_admin
match '/invite_collaborator'=>'projects#invite_collaborator', :via=>:patch, :as=>:invite_collaborator
get :autocomplete_user_name, :on=>:collection
end
resources :versions do
resources :users
end
resources :projects do
member do
get :projectadmins
end
end
resources :admin_relationships, only: [:create, :destroy]
resources :collaborator_relationships, only: [:create, :destroy]
# get "static_pages/home"
# get "static_pages/help"
# get "static_pages/about"
end
非常感谢......让我知道我错过的任何其他内容是否会有所帮助。