I''d like to always add a condition to any version of "find" (e.g. Thing.find(), Thing.find_by_name(), Thing.find_by_whatever) so that in addition to whatever conditions are set, an additional condition is set :conditions=>"user_id=#{current_user.id}" I''d like to make sure that a user only sees/edits/creates entries in the database that have the user_id field set to their id. I could wrap all of my controller functions (create/new/show/edit/list) with begin #note having to add to the ":conditions" field @thing = Thing.find(params[:id], :conditions=>"user_id=#{current_user.id}") rescue render :text=>"I''m sorry, you do not have access to that record." end ...but clearly that is immensely un-DRY. AND, it removes the ability to use the helpful Thing.find_by_name/etc functions. The goal is to make all versions of "find" work. Is it possible to change one function in the model and make it work? Thanks, -Greg Greg Edwards CTO, Eyetools Inc. (916) 792 4538
Check out Rick Olsen''s acts_as_paranoid [1] plugin. It adds a condition to queries like you want. Even better *might* be ModelSecurity by Bruce Perens. I''m not entirely sure, because I haven''t used it yet, but it gets mentioned in posts like these :) Pat [1] http://ar-paranoid.rubyforge.org/ [2] http://perens.com/FreeSoftware/ModelSecurity/Tutorial.html On 3/2/06, Greg Edwards <gedwards1@eyetools.com> wrote:> I''d like to always add a condition to any version of "find" (e.g. > Thing.find(), Thing.find_by_name(), Thing.find_by_whatever) so that in > addition to whatever conditions are set, an additional condition is set > :conditions=>"user_id=#{current_user.id}" > > I''d like to make sure that a user only sees/edits/creates entries in the > database that have the user_id field set to their id. I could wrap all of my > controller functions (create/new/show/edit/list) with > begin > #note having to add to the ":conditions" field > @thing = Thing.find(params[:id], > :conditions=>"user_id=#{current_user.id}") > rescue > render :text=>"I''m sorry, you do not have access to that record." > end > ...but clearly that is immensely un-DRY. AND, it removes the ability to use > the helpful Thing.find_by_name/etc functions. > > The goal is to make all versions of "find" work. > > Is it possible to change one function in the model and make it work? > > Thanks, > -Greg > > Greg Edwards > CTO, Eyetools Inc. > (916) 792 4538 > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Vincent AE Scott
2006-Mar-02 18:23 UTC
[Rails] Modifying "Find" to always add a condition?
Hi Greg, Sorry i don''t actually have a useful answer to your problem, but its something thats been bugging me recently as well. I''m after something that provides quite fine grained control over objects in the database, such that when a user requests a ''listing'' they only get to see things that they are allowed to. What they are allowed to see is dictated by the ACL''s that other users apply to objects of that list. So for a list of documents that a system might hold, each author can specify users and groups that are allowed to view/edit/augment said documents. In line with your original posting though, there was a line of investigation I looked at that might be useful to you. There''s a new feature in Edge Rails, "with_scope" (http://habtm.com/articles/2006/02/22/nested-with_scope) that looks like it might be useful in achieving what you want. in short: Article.with_scope(:find => { :conditions => "author_id = 3" }) Article.find(:all) # => SELECT * from articles WHERE author_id = 3 end So you can wrap up your "finds" as outlined in the blog entry, and carry on using it as you normally would do, but with the added benefit of having it add on extra filters. HTH somewhat, -v #if gedwards1 /* Mar 02, 02:24 */> I''d like to always add a condition to any version of "find" (e.g. > Thing.find(), Thing.find_by_name(), Thing.find_by_whatever) so that in > addition to whatever conditions are set, an additional condition is set > :conditions=>"user_id=#{current_user.id}" > > I''d like to make sure that a user only sees/edits/creates entries in the > database that have the user_id field set to their id. I could wrap all of my > controller functions (create/new/show/edit/list) with > begin > #note having to add to the ":conditions" field > @thing = Thing.find(params[:id], > :conditions=>"user_id=#{current_user.id}") > rescue > render :text=>"I''m sorry, you do not have access to that record." > end > ...but clearly that is immensely un-DRY. AND, it removes the ability to use > the helpful Thing.find_by_name/etc functions. > > The goal is to make all versions of "find" work. > > Is it possible to change one function in the model and make it work? > > Thanks, > -Greg > > Greg Edwards > CTO, Eyetools Inc. > (916) 792 4538#endif /* gedwards1@eyetools.com */ -- keys: http://codex.net/gpg.asc Neurotics build castles in the sky. Psychotics live in them. Psychiatrists collect the rent.
Mathias Stjernström
2006-Mar-02 20:16 UTC
[Rails] Modifying "Find" to always add a condition?
Hi Greg! I have been working on a plugin for a couple of days that i think do what you want. I call it Acts as restricted. Its one of those Acts_as plugins, DUH. You simply add acts_as_restricted to your model and then tree columns to the model table owner_id, group_id and restricted owner_id is the owner of the object, group_id is the group the object belongs to and restricted is a integer that handles the current permissions for the object. The permission can be: OWNER_READ, OWNER_WRITE, OWNER_DELETE GROUP_READ, GROUP_WRITE, GROUP_DELETE WORLD_READ, WORLD_WRITE, WORLD_DELETE The plugin then overrides the find/destroy/save/count methods of that object to check if the permissions is correct for the current user. I have only been using rails for a couple of weeks so a cannot guarantee that it''s fail-safe, but it works pretty good so far ;-) I am waiting for ruby-forge approval for my project and then i put it out in public. Cheers! Mathias Stjernstrom On Mar 2, 2006, at 11:24 AM, Greg Edwards wrote:> I''d like to always add a condition to any version of "find" (e.g. > Thing.find(), Thing.find_by_name(), Thing.find_by_whatever) so that in > addition to whatever conditions are set, an additional condition is > set > :conditions=>"user_id=#{current_user.id}" > > I''d like to make sure that a user only sees/edits/creates entries > in the > database that have the user_id field set to their id. I could wrap > all of my > controller functions (create/new/show/edit/list) with > begin > #note having to add to the ":conditions" field > @thing = Thing.find(params[:id], > :conditions=>"user_id=#{current_user.id}") > rescue > render :text=>"I''m sorry, you do not have access to that > record." > end > ...but clearly that is immensely un-DRY. AND, it removes the > ability to use > the helpful Thing.find_by_name/etc functions. > > The goal is to make all versions of "find" work. > > Is it possible to change one function in the model and make it work? > > Thanks, > -Greg > > Greg Edwards > CTO, Eyetools Inc. > (916) 792 4538 > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails-- Mathias Stjernstr?m mathias@globalinn.se Direktnr: 08 - 525 09 112 V?xel: 020 - 140 00 60 Fax: 020 - 140 00 61