Closed toxix closed 10 years ago
Nop, it's not a bug. You simply misunderstand things a little bit.
Protector works on 2 levels: during retrieval and after that on the level of fields. Let's carefully look at what you are doing here: User.find(3).restrict!(current_user)
– as a first step you tell AR to load your model without any restrictions. And then you restrict the result. Protector can not change past and you explicitly tell system to find a model without any protection with such call.
Even more – it's sometimes a case when you actually want to retrieve something you normally can't and then apply fields restrictions. So it works perfectly right here.
The sample from documentation you provide is out of context. Originally it shows you how to protect an instance of model comparing it to scope protection. So it's also correct.
Anyway if you have any ideas how to make documentation more explicit about this – pull requests (or just separate issues) are welcome.
Okay, think I get it.
The scope is only used when selecting from the database. After the database results are cached, the can :read, %w(name admin)
is evaluated unaffected by scope { where(id: user.id)}
). This grant excess in the following call sequence:
irb(main):002:0> u = User.find(3).restrict!(current_user)
D, [2013-12-11T01:32:01.425081 #15107] DEBUG -- : User Load (49.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 3]]
=> #<User id: 3, name: "admin user2", admin: true, created_at: "2013-10-28 13:57:47", updated_at: "2013-10-28 13:57:47">
irb(main):003:0> u.name
=> "admin user2"
I expected the scope would be evaluated in this case too and the u.name
fail because it is not in the scope. Maybe a hint in the part where scopes are invented would be nice.
Let me know if I get it the right way, so I'm able to improve the documentation.
After the database results are cached
Not cached. Just fetched. User.find(3)
doesn't cache anything. It fetches data from database. Other than that it's quite close, yes.
hopefully did my first pull request the right way… If not just give me a hint.
User.restrict!(current_user).find(3) is behalving like I'm expecting it to work. But the other way arround User.find(3).restrict!(current_user) doesn't do it's job. The not working way is also in the documentation
so I'm assuming this is a bug.
Way to reproduce
app/models/user.rb
used the current github Version of protector