如何限制对资源的索引操作的访问,而不是对属于该用户的单个记录的访问?

时间:2016-06-26 08:47:59

标签: ruby-on-rails ruby-on-rails-5 cancancan rolify

所以这就是我的ability.rb的截断版本:

class Ability
  include CanCan::Ability

  def initialize(user)
    alias_action :create, :read, :update, :destroy, to: :crud

    user ||= User.new # guest user (not logged in)
    if user.has_role?(:admin)
      can :manage, :all
    else
      cannot :read, User
      can :crud, User, id: user.id

      # cannot :read, :users unless user.has_role? :admin
    end
  end
end

我的UsersController看起来像这样:

class UsersController < ApplicationController
  load_and_authorize_resource
  before_action :set_user, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, except: [:show]
  # truncated for brevity
end

所以在这里,我要做的是User#Index,我想将其仅限于管理员用户。但与此同时,每个用户都应该能够访问自己的用户页面。

当我尝试上述操作时,对我来说很有意义,我可以访问/settings的{​​{1}},但我仍然可以访问current_user这就是我所不知道的我想要。

这就是日志的样子:

Users#Index

但是当我注释掉这一行:Started GET "/users/1547" for 127.0.0.1 at 2016-06-26 03:39:57 -0500 DEPRECATION WARNING: before_filter is deprecated and will be removed in Rails 5.1. Use before_action instead. (called from <class:UsersController> at myapp/controllers/users_controller.rb:2) Processing by UsersController#show as HTML Parameters: {"id"=>"1547"} User Load (2.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1547], ["LIMIT", 1]] User Load (1.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1547], ["LIMIT", 1]] Role Load (1.8ms) SELECT "roles".* FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL))) [["user_id", 1547]] CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1547], ["LIMIT", 1]] Rendering users/show.html.erb within layouts/application Rendered shared/_navbar.html.erb (2.4ms) Rendered shared/_footer.html.erb (1.3ms) Completed 200 OK in 244ms (Views: 196.4ms | ActiveRecord: 16.7ms) Started GET "/settings" for 127.0.0.1 at 2016-06-26 03:39:59 -0500 Processing by Devise::RegistrationsController#edit as HTML User Load (1.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1547], ["LIMIT", 1]] Rendering devise/registrations/edit.html.erb within layouts/application Rendered devise/registrations/edit.html.erb within layouts/application (16.7ms) Rendered shared/_navbar.html.erb (2.8ms) Rendered shared/_footer.html.erb (1.0ms) Completed 200 OK in 184ms (Views: 180.4ms | ActiveRecord: 1.2ms) Started GET "/users" for 127.0.0.1 at 2016-06-26 03:40:01 -0500 Processing by UsersController#index as HTML User Load (2.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1547], ["LIMIT", 1]] Role Load (2.2ms) SELECT "roles".* FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL))) [["user_id", 1547]] Rendering users/index.html.erb within layouts/application User Load (1.3ms) SELECT "users".* FROM "users" Rendered users/index.html.erb within layouts/application (7.2ms) Started GET "/users" for 127.0.0.1 at 2016-06-26 03:40:02 -0500 Processing by UsersController#index as HTML User Load (2.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1547], ["LIMIT", 1]] Role Load (3.8ms) SELECT "roles".* FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL))) [["user_id", 1547]] Rendering users/index.html.erb within layouts/application User Load (51.5ms) SELECT "users".* FROM "users" Rendered users/index.html.erb within layouts/application (55.1ms) Rendered shared/_navbar.html.erb (3.4ms) Rendered shared/_footer.html.erb (1.3ms) Completed 200 OK in 533ms (Views: 488.8ms | ActiveRecord: 5.8ms) 时,我只有can :crud, User, id: user.id行,它会将我锁定在所有内容之外,如下面的日志所示(这也是我不想要的) )。

cannot :read, User

那么我如何实现我的目标呢?

1 个答案:

答案 0 :(得分:1)

不确定,但是如何:

def initialize(user)
  alias_action :create, :read, :update, :destroy, to: :crud

  user ||= User.new # guest user (not logged in)
  if user.has_role?(:admin)
    can :manage, :all
  else
    cannot :read, User
    can :crud, User, id: user.id
    cannot :index, User
  # cannot :read, :users unless user.has_role? :admin
  end
end