Modifying "Find" to always add a condition?


#1

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 E.
CTO, Eyetools Inc.
(916) 792 4538


#2

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 P… I’m not entirely sure, because I
haven’t used it yet, but it gets mentioned in posts like these :slight_smile:

Pat

[1] http://ar-paranoid.rubyforge.org/
[2] http://perens.com/FreeSoftware/ModelSecurity/Tutorial.html


#3

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 */

@thing = Thing.find(params[:id],

Thanks,
-Greg

Greg E.
CTO, Eyetools Inc.
(916) 792 4538
#endif /* removed_email_address@domain.invalid */


keys: http://codex.net/gpg.asc

Neurotics build castles in the sky.
Psychotics live in them.
Psychiatrists collect the rent.


#4

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 :wink:

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 E. wrote:

controller functions (create/new/show/edit/list) with
the helpful Thing.find_by_name/etc functions.
(916) 792 4538


Rails mailing list
removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails


Mathias
Stjernströremoved_email_address@domain.invalid

Direktnr: 08 - 525 09 112
Växel: 020 - 140 00 60
Fax: 020 - 140 00 61