3

我在我的 Rails 应用程序中运行 Pundit 以获得授权。我似乎已经掌握了这一切,但想知道如何将编辑或更新操作限制在某个字段。

例如,用户可以编辑他们的 user.first_name、user.mobile 或 user.birthday 等,但不能编辑他们的 user.role。本质上,我的逻辑是,让用户编辑任何装饰性的东西,但如果它是功能性的,则不要编辑。

这些字段应该只能由具有“super_admin”角色的用户编辑(我在 user.rb 上使用如下方法进行了设置)。

  def super_admin?
    role == "super admin"
  end

  def account?
    role == "account"
  end

  def segment?
    role == "segment"
  end

  def sales?
    role == "sale"
  end

  def regional?
    role == "regional"
  end

  def national?
    role == "national"
  end

  def global?
    role == "global"
  end 

我几乎有一个干净的 slateuser_policy.rb文件,其中更新和编辑操作是默认的

  def update?
    false
  end

  def edit?
    update?
  end

也许我对此的想法完全错误,应该包装一个user.super_admin?if 语句围绕用户显示页面上的角色字段,但如果我只是为了安全而使用该策略,这感觉不对。

4

2 回答 2

6

使用 gem 的 README 页面上描述的 Pundit 的 allowed_attributes 助手:https ://github.com/elabs/pundit

# app/policies/post_policy.rb
class PostPolicy < ApplicationPolicy
  def permitted_attributes
    if user.admin? || user.owner_of?(post)
      [:title, :body, :tag_list]
    else
      [:tag_list]
    end
  end
end

# app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def update
    @post = Post.find(params[:id])
    if @post.update_attributes(post_params)
      redirect_to @post
    else
      render :edit
    end
  end

  private

  def post_params
    params.require(:post).permit(policy(@post).permitted_attributes)
  end
end
于 2017-02-03T03:47:24.143 回答
2

在您的视图中,您可以根据用户的角色限制用户可以看到的内容。

用户视图

- if current_user.super_admin? 
  = f.select(:role, User.roles.keys.map {|role| [role.titleize.role]})
- else
  = user.role

在策略中,您可以调用用户的角色以确保他们能够进行编辑。

class UserPolicy
  attr_reader :current_user, :model

  def initialize(current_user, model)
    @current_user = current_user
    @user = model
  end

  def edit?
    @current_user.super_admin || @current_user == @user
  end
end
于 2015-03-19T14:33:34.657 回答