在has_many关系中的权威授权

时间:2014-06-07 05:53:15

标签: ruby-on-rails ruby-on-rails-4 authorization has-many-through pundit

我在我的专家授权中执行最后一步时遇到了一些麻烦......我有一个项目模型以及一个project_policy,它授权应用程序中的哪些用户可以查看项目并与之交互。但是,我的项目有几个组件 - 其中一个是在项目中访问的项目版本的索引(项目has_many版本)...所以我需要能够限制用户访问这个版本列表。 ..以及默认项目配置文件(如果用户不是所有者/管理员或协作者,则限制)。我目前拥有这些版本'但是,在他们自己的模型中设置。

详细信息:目前,如果我不是管理员/所有者或协作者,当我尝试访问url projects / 20时,限制会起作用(它会重定向我并说“#34;您未经授权&#34” ;),但如果我导航到' projects / 20 /版本'或' 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

的routes.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

非常感谢...让我知道,如果我错过任何其他内容将有助于看到。

0 个答案:

没有答案