So ist es das, was die verkürzte Version meiner ability.rb
wie folgt aussieht:Wie beschränke ich den Zugriff auf die Indexaktion meiner Ressource, aber nicht auf den einzelnen Datensatz, der diesem Benutzer gehört?
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
Meine UsersController
wie folgt aussieht:
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
Also hier, was ich versuche, für User#Index
zu tun ist, ich will um dies nur auf Administratoren zu beschränken. Gleichzeitig sollte jeder Benutzer auf seine eigene Benutzerseite zugreifen können.
Wenn ich die oben versuchen, das macht Sinn für mich, kann ich die /settings
für die current_user
zugreifen, aber ich kann auch immer noch Zugriff auf die Users#Index
das ist, was ich nicht will.
Dies ist, was die Protokolle wie folgt aussehen:
Started GET "https://stackoverflow.com/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)
Aber wenn ich diese Zeile aus kommentieren: can :crud, User, id: user.id
, so habe ich nur die cannot :read, User
Linie, es sperrt mich aus allem, wie die folgenden Protokolle zeigen (die ist auch was ich nicht will).
Started GET "/users" for 127.0.0.1 at 2016-06-26 03:45:39 -0500
Processing by UsersController#index as HTML
User Load (1.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1547], ["LIMIT", 1]]
Role Load (1.3ms) 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]]
Redirected to http://localhost:3000/
Completed 302 Found in 19ms (ActiveRecord: 2.4ms)
Started GET "/users" for 127.0.0.1 at 2016-06-26 03:45:39 -0500
Processing by UsersController#index 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]]
Role Load (2.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]]
Redirected to http://localhost:3000/
Completed 302 Found in 24ms (ActiveRecord: 4.0ms)
Also wie erreiche ich, was ich versuche zu tun?
Geck. Sie treffen den Nagel auf den Kopf. Tolles Denken! Ich kann nicht glauben, dass ich das nie versucht habe. Danke viel Brosky! – marcamillion