设置 CanCanability.rs 模型

发布于 2024-10-19 14:14:49 字数 982 浏览 2 评论 0 原文

我用Devise和CanCan成功制作了登录系统,我有3种类型的用户。管理员、内部和全局用户。我创建了控制器和索引操作:Admin、Cpanel、Report 和 State,并且我想限制某些用户对此控制器的访问。

管理员用户应具有访问权限:报告(全部)、状态(读取)、管理员(全部)

全局用户应具有访问权限:报告(仅读取)、状态(读取)、Cpanel(全部)

内部用户应该具有访问权限:报告(全部)、状态(读取)

我尝试使用下列代码来执行此操作:ability.rs< /strong>:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)

    if user.role? :admin
      can :manage, [Report, Admin]
      can :read, State
    elsif user.role? :global_user
      can :read, [Report, State]
      can :manage, Cpanel
    elsif user.role? :internal_user
      can :manage, Report
      can :read, State     
    end
   end
end

此时我在此控制器中只有索引操作,当我使用内部用户登录应用程序时,我可以访问 /admin,但这不是我想要的行为。我想限制对所有控制器的访问,而不是能力.rb 类中列出的控制器。

源代码在这里

I successfully made login system with Devise and CanCan, and I have 3 types of users. Admin, internal and global users. I created Controllers and index actions: Admin, Cpanel, Report and State, and I want to restrict access to this controllers for some users.

Admin user should have privilegies to access: Reports(all), State (read), Admin (all)

Global user should have privilegies to access: Reports(only read), State(read), Cpanel(all)

Internal user should have privilegies to access: Reports(all), State (read)

And I tried to do this with following code in ability.rs:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)

    if user.role? :admin
      can :manage, [Report, Admin]
      can :read, State
    elsif user.role? :global_user
      can :read, [Report, State]
      can :manage, Cpanel
    elsif user.role? :internal_user
      can :manage, Report
      can :read, State     
    end
   end
end

At this time I have only index actions in this controllers, and when I login to app with internal user I CAN access to /admin for example, and that is not behavior that I want. I want to restrict access to all controllers instead of controllers listed in ability.rb class.

Source code is here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

演多会厌 2024-10-26 14:14:49

如果我要阻止对整个控制器的访问,我会创建一个 before 过滤器,如果用户没有管理员角色,则将用户重定向到访问被拒绝的页面。可能看起来像这样:

def check_permissions
 raise CanCan::AccessDenied unless @current_user.role?(:admin)
end

例如,如果我只是想阻止对更新和创建的访问,我会这样做:

def update
  raise CanCan::AccessDenied unless can?(:update,Thing)
  ...
end

def create
  raise CanCan::AccessDenied unless can?(:create,Thing)
  ...
end

您可以在应用程序控制器中处理 CanCan::AccessDenied 异常:

rescue_from CanCan::AccessDenied do |exception|
    flash[:error] = exception.message
    redirect_to no_access_path
  end

我有一些非常好的关于 CanCan 和 Devise 的帖子 此处此处

更新
我在应用程序控制器中使用此方法来设置当前的用户变量:

# Make the current user object available to views
  #----------------------------------------------------------------------------
  def get_user
    @current_user = session[:current_user]
  end

If I were going to prevent access to an entire controller, I would make a before filter that redirects the user to an access denied page if he does not have the admin role. Might look something like:

def check_permissions
 raise CanCan::AccessDenied unless @current_user.role?(:admin)
end

If I just wanted to prevent access to update and create, for example, I would do:

def update
  raise CanCan::AccessDenied unless can?(:update,Thing)
  ...
end

def create
  raise CanCan::AccessDenied unless can?(:create,Thing)
  ...
end

You can handle the CanCan::AccessDenied exception in your application controller:

rescue_from CanCan::AccessDenied do |exception|
    flash[:error] = exception.message
    redirect_to no_access_path
  end

I have some pretty good posts about CanCan and Devise here and here

UPDATE
I use this method in my application controller to set my current user variable:

# Make the current user object available to views
  #----------------------------------------------------------------------------
  def get_user
    @current_user = session[:current_user]
  end
长途伴 2024-10-26 14:14:49

您需要向控制器添加对 cancan 授权的检查。

这可能只是

authorize! :read, @state

向状态控制器索引操作添加一行,对于所有其他索引操作也类似。

编辑:
抱歉,在状态控制器索引操作中,您可能没有 @state,因此上述内容不适用。可能类似

authorize! :read, State

还有一个 load_and_authorize 方法,您可以使用它来组合控制器中多个操作的授权并减少代码。 类似

load_and_authorize 版本可能与load_and_authorize_resource :state

,它应该位于您的操作之前。

您可能需要查看railscast on cancan 授权以获得完整的基本设置(在 Rails2) 中。

我怀疑要解决其他问题,我们可能需要查看更多代码。尝试发布一些控制器代码。

我没有在rails3中使用过这个,但我认为它的大部分或多或少都是相似的。

You need to add checks for the cancan authorization to your controllers.

This might be just adding a line like

authorize! :read, @state

to your state controller index action, and similarly for all the other index actions.

EDIT:
Sorry, in a state controller index action, you likely don't have @state, so the above wouldn't apply. Possibly something like

authorize! :read, State

There is also a load_and_authorize method that you can use to combine authorization for multiple actions in a controller and reduce your code. The load_and_authorize version is likely to look similar to

load_and_authorize_resource :state

and it should be before your actions.

You might want to look at this railscast on cancan authorization for a complete basic setup (in rails2).

I suspect to clear up other problems, we might need to see some more code. Try posting some of your controller code.

I haven't used this in rails3, but I assume most of it remains more or less similar.

不语却知心 2024-10-26 14:14:49

我解决了这个问题

def check_permissions
 raise CanCan::AccessDenied unless current_user.role?(:admin)
end

,但是,请注意,我必须将 @current_user 更改为 current_user (不带@)

谢谢托尼

I solved this problem with

def check_permissions
 raise CanCan::AccessDenied unless current_user.role?(:admin)
end

but, note that I must to change @current_user to current_user (without @)

Thanks Tony

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文