Chris:
"I think that 'hacking" actions.rb is SOP (standard operating
procedure). The default actions are not really suitable for
anything
but the most basic applications so I would suggest you not hesitate
to
override them. Once you've taken that step, you can easily write
your
own before/around filters to manage the resource(s) finding and
then
your auth code. Ian put work into RC to get the resource
identification filter to be flexible -you can move it around at
will
to ensure it comes before your own filters."
Thats exactly what I did, for the time being I just commented out the
find_resource, find_resources and new_resource code and moved it into
the before_filter in the resources_controller_for method. My
before_filter chain after the changes:
before_filter(:load_enclosing_resources, when_options) unless
load_enclosing_resources_filter_exists?
before_filter :load_resources, :only => [:index]
before_filter :load_resource, :only =>
[:show, :edit, :update, :destroy]
before_filter :build_resource, :only => [:new, :create]
The other option I was thinking is to create my own actions module and
pass it to the resources_controller_for and so that my module will be
used instead of built-in actions.rb file. Either way works fine.
"Incidentally, Satynos, I'm in exactly the same situation as you -
my
custom authorization plugin (wicked good -ask me about it if you're
interested) usually needs the resource to evaluate the
authorization
expression. But depending on the action, it may need the enclosing
resource or associated resources instead of, or in addition to, the
basic resource. So drying up the auth code into a before filter
isn't
very realistic for me except in the simplest cases. Once I gave up
on
moving the authorization code into a before filter, moving the
finder
code into a before filter lost much of its appeal as well. And the
finder code has at least three variants in the canonical Rails
controller:
1. Index (find existing resource collection from class or
enclosing
resource association)
2. new/create (create a new single resource)
3. edit/update/delete (find an existing single resource)"
I am not quite sure what you mean by several variants of finders, I
think (unless I am missing something) finding the resource should be
either from its own Model or through the enclosed resources if the
resouce is nested. For instance if I have the URL like users/1/
articles/1/comments, comments will be loaded through the following:
@user = User.find
@article = @user.articles.find
@comments = @article.comments
In other instance if the URL is users/1 then there is not enclosed
resource and the user will be loaded @user = User.find
For either situations, resources_controller is handling by itself. At
this moment all I wanted is to run the load_enclosed_resources and
load_resource taken care in the before filter so that I can either use
around filter for authorization (after these two filters are taken
place) or just use before_filter to either redirect the user to login
if he has no logged in yet or thow access_denied if denied or just
return true for the rails to proceed normally.
"Incidentally, Satynos, I'm in exactly the same situation as you -
my
custom authorization plugin (wicked good -ask me about it if you're
interested) usually needs the resource to evaluate the
authorization
expression. "
I would like to take a peek at your code which might save me some time
if it is similar to what I have in my mind.
Following is what I have in mind:
User has_many :roles
User has_many :permission :through => :roles
(This setup gives me permission management through web interface)
Then use either one of the following variants in the before or after
filters or may be just inline in the method of my actions module:
Checking permission Proxy through User:
current_user.can_view?(resource)
current_user.can_create?(resource)
current_user.can_edit?(resource)
current_user.can_delete?(resource)
Checking permission Directly on Resource: (the above indirectly calls
these)
resource.viewable_by?(current_user)
resource.creatable_by?(current_user),
resource.editable_by?(current_user) and
resource.deletable_by?(current_user)
And in the Resource
def viewable_by?(current_user)
if current_user.has_perm?('View Content') || self.user_id ==
current_user.id
return true
else
return false
end
But I would certainly love to take a peek at your code, if that is ok
with you.
Thanks in advance.
-Satynos
Also I would like to utililze permission based system that can be
altered through web UI so that I can give whatever permission I want
to a particular role.
>
c...@hapgoods.com