Rails 应用程序的用户管理访问

Posted

技术标签:

【中文标题】Rails 应用程序的用户管理访问【英文标题】:User-Managed Access for Rails Application 【发布时间】:2017-09-21 15:39:26 【问题描述】:

我正在尝试找到一个可以处理 的 gem。有许多基于角色的宝石,但它们并不能完全满足需求。我认为的最佳场景示例是这样的:

我有一个模型,其中包含可用于不同方法(即 RECORD_CREATE 和 RECORD_UPDATE)的操作列表。我想允许用户执行这些操作或阻止用户执行这些操作。此外,我想以相同的方式创建组权限,但仍然能够为用户添加其他权限,而无需创建不同的特定组。所有这一切,我希望能够从应用程序内部而不是从 lib 中的 ruby​​ 文件进行控制。有这样的动物吗?我一直在寻找,但无济于事。如果没有,有人想帮我做一个吗?

【问题讨论】:

我认为Cancancan 符合您的要求。我们有能力根据我们的需要定制它。详情请参阅Wiki。 @HarrySuren。它看起来是一个非常好的解决方案,但我在执行过程中无法将其概念化。我可能会构建一个测试应用程序并安装 gem 来测试它。我有一个自制的解决方案,效果很好。我有一个操作列表框,可以从应用程序内部为每个用户或组打开/关闭这些操作。然后我在每个动作的开头放置一个辅助方法来测试该动作的权限。每次授权测试只使用大约 10 行代码加上 1 行代码。 找到这篇文章。非常有趣,想听听更多关于它的意见。 www-old.amg.tv/blog/… 您能否以 gist 文件的形式分享您的帮助和解决方案? 我用我自己的解决方案添加了一个答案。检查一下,让我知道它是否有帮助。 ***.com/a/51415669/8503822 【参考方案1】:

我发现了一个非常有趣的 gem,名为 Strongbolt,它基于用于基于记录的授权的 Grant gem。仍在弄清楚其中的复杂性,但似乎是一个非常强大的选择。

【讨论】:

【参考方案2】:

如果有人感兴趣,这里有一个自制的解决方案....

lib/permissions.rb

module Permissions
  def all_permissions
    @all_permissions ||= self.activities + Activity.joins(:permissions).where(permissions: group: self.groups)
  end

  def update_permissions(permissions)
    return if permissions.nil?
    self.permissions.destroy_all
    permissions.collect do |key, permission|
      self.permissions.create!(activity_id: permission)
    end
  end

  def authorized?(activity_code)
    self.all_permissions.include?(Activity.find_by(code: activity_code))
  end
end

lib/groups.rb

module Groups
  def update_groups(groups)
    return if groups.nil?
    self.group_memberships.destroy_all
    groups.each do |key, value|
      group = Group.find_by(id: value)
      self.groups << group if group
    end
  end
end

app/models/user.rb

include Permissions
include Groups

在代码中...

rails g scaffold group name description
rails g model group_membership group:belongs_to user:belongs_to
rails g model activity name code description
rails g model permission group:belongs_to user:belongs_to activity:belongs_to

app/models/activity.rb

default_scope ->  order(:name) 
has_many :permissions
has_many :users, through: :permissions
validates :name, presence: true
validates :code, presence: true, uniqueness: true

app/models/group.rb

include Permissions
has_many :permissions
has_many :activities, through: :permissions
has_many :group_memberships
has_many :users, through: :group_memberships
validates :name, uniqueness: true

app/controllers/users_controller.rb(创建和更新)

@user.update_permissions(params[:user][:permissions]) if params[:user][:permissions].present?
@user.update_groups(params[:user][:groups]) if params[:user][:groups].present?

app/helpers/sessions_helper.rb

def current_user
  @current_user ||= User.find_by(id: session[:user_id])
end

def authorized?(activity)
  current_user.authorized?(activity)
end

def authorize(activity)
  if !current_user.authorized?(activity)
    redirect_to root_path, flash:  warning: 'You do not have permission to access this area.' 
  end
end

那么检查用户权限的语法是

if authorized?('PERMISSION_SHORT_CODE')

或者...

authorize('PERMISSION_SHORT_CODE')

或任何变体。 “PERMISSION_SHORT_CODE”是用于查找相关活动的任何唯一标识符。当我向站点添加功能时,我个人通过 rails 控制台添加活动,然后我可以根据需要限制该功能。 'USER_ADD'、'USER_DESTROY'、'USER_EDIT' 等。这是我用来在 users#edit 下显示和编辑权限的代码片段。

app/helpers/users_helper.rb

def permissions_list(object, method, instance, options = )
  capture do
    options.collect.with_index do |c, index|
      if instance.groups.any?  |g| g.activities.include?(Activity.find(c[1])) 
        concat check_box_tag("#object[#method]#index", c[1], true, disabled: true)
      else
        concat check_box_tag("#object[#method]#index", c[1], instance.activities.include?(Activity.find(c[1])))
      end
      concat content_tag(:label, "#c[0]".titleize) + tag(:br)
    end
  end
end

app/views/users/_form.html.erb

<div class="listbox">
  <%= permissions_list(:user, :permissions, @user, Activity.all.order(:name).collect |c| [c.name, c.id]) %>
</div>

app/assets/stylesheets/application.css(.scss)

.listbox
  overflow: hidden
  overflow-y: scroll
  margin: 10px
  height: 250px
  width: 300px
  border: 1px solid
  padding: 0 10px 0 10px

我希望这可以帮助某人和/或某人可以查看它并找到更好的方法。谢谢大家的帮助!!

【讨论】:

以上是关于Rails 应用程序的用户管理访问的主要内容,如果未能解决你的问题,请参考以下文章

获取由用户管理的公司的详细信息 - Ruby on Rails

Rails - 使用特定属性值缓存所有用户

Ruby on Rails 用户管理引擎/框架? (带网页)

单表继承 活动管理模型映射问题 rails 4

在每个用户的Rails中使用片段缓存

Rails - 如何查找单个记录(用户名)在主页中向任何访问者显示它