0

我在执行权威人士授权的最后一步时遇到了一些麻烦......我有一个项目模型以及一个 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

非常感谢......让我知道我错过的任何其他内容是否会有所帮助。

4

0 回答 0