Rails 1.2.6
The setup for this question takes a bit... and I suspect there may be
a better solution than what my direct question is.
I have an intranet app that''s stuffed with all kinds of special
permission rights for what users can see and do. For the most part
the UI itself prevents users from seeing controls they can''t use,
however, I still wrap entire controller methods with access rights
conditionals to prevent direct attacks via URL that by pass the UI.
Inside any given controller action a number of instance vars might
get declared for use in the view. However, if an access right denies
that user the ability to run that action, those vars don''t get
declared (they''re inside the conditional). I know what you''re
thinking... just hold on a sec...
Because of Rails'' "backwards" (from everything I have ever
worked
with) way of processing a view template before the layout, I cannot
use conditional logic in the layout to preclude the processing of the
view file.
In order to show the user a message that what they tried to do is not
allowed and not showing the otherwise default view, I am currently
adding a flag to the flash to alter the layout.
So, the controller code is written along these lines:
def my_action
if @user.is_not_allowed?(:delete_comment)
flash.now[:action_not_allowed] = true
else
..... the normal code .....
@some_var = ....whatever....
end
end
Then my layout is written like so:
<% if flash[:action_not_allowed] -%>
<%= render(:partial => (@app_site_paths.panels +
''not_allowed'')) %>
<% else -%>
<%= yield %>
<% end -%>
OK, so none of that prevents the view file from being processed, and
it will complain that @some_var doesn''t exist. To solve that, I ended
up doing a couple extra things in the controller. First, I aded a
line to my not_allowed conditional:
if @user.is_not_allowed?(:delete_comment)
flash.now[:action_not_allowed] = true
render :action => ''empty''
else
And then, you guessed it, I have an empty.rhtml file which has
nothing in it.
It works, but of course it''s kind of kludgy.
I was hoping render :nothing would have done the trick, but that (and
other options I have tried) prevents the entire layout from being
rendered. Hrmm. Not so good.
So, a) is there a better way to "skip" processing a specific view
file, or b) does anyone see a more elegant replacement for my
approach with using flash in the layout?
Of course, I could repeat the whole not_allowed conditional in the
view, but it would certainly be nicer to leave all that centralized
in the controller which my kludge achieves.
For now I''m content to use my "empty" approach in order to
keep
moving, but it seems worth collecting ideas as this pattern is
foundation-level stuff for bajillions of tasks in many of my
applications.
-- gw
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
Hi Greg, Please forgive me if I''m trying to oversimplify your problem, but why won''t a before_filter that does your "is_not_allowed?" test work? Somewhere along the way you have to set @user, and I''m presuming that''s in a before_filter. You can have another one after that reads the controller and action from the params and determines if the user has rights to do that. If not, redirect them to the appropriate location. I do something similar with request methods and for the same reason (potential hits not via the UI). Unless I''m missing something, it should work for you and you''d have all the logic in one place. Peace, Phillip -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On May 13, 2008, at 6:39 PM, Phillip Koebbe wrote:> Please forgive me if I''m trying to oversimplify your problem, but why > won''t a before_filter that does your "is_not_allowed?" test work? > Somewhere along the way you have to set @user, and I''m presuming > that''s > in a before_filter. You can have another one after that reads the > controller and action from the params and determines if the user has > rights to do that. If not, redirect them to the appropriate location. > I do something similar with request methods and for the same reason > (potential hits not via the UI). Unless I''m missing something, it > should work for you and you''d have all the logic in one place.Various layout work differently, so in some cases, yes, access to the whole page might be refused in which case a redirect would be used. I also have cases though where I don''t want to redirect. The way a layout for that scenario is, there is surrounding navigation and information (which the layout incorprates through partials) that the user may have legit access to, but the core view panel of the page needs to be refused. Other layouts might refuse only sub-portions of a view in which case I either use partials if the rules are consistent, or I wrap snippets. There are dozens of authorization filters, and they get used at a variety of levels. It''s a complex application with a very complex user set. In the case of refusing the view (but not necessarily the whole layout), I could use conditional wrappers around the whole the view (it''d be consistent with refusing portions of views), but I was hoping for something as I described simply to prevent doing the unnecessary processing in the first place. As for centralizing with before_filter, I prefer to see authorization logic closely linked to the code itself so I know exactly what''s going on when I read the method code. Easier to review, debug, etc. Another reason to go ahead with wrappers in the view, but I was leaning towards preventing the processing as more important to the overall security strength. -- gw --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On May 14, 2008, at 12:21 AM, Greg Willits wrote:> On May 13, 2008, at 6:39 PM, Phillip Koebbe wrote: > >> Please forgive me if I''m trying to oversimplify your problem, but why >> won''t a before_filter that does your "is_not_allowed?" test work? >> Somewhere along the way you have to set @user, and I''m presuming >> that''s >> in a before_filter. You can have another one after that reads the >> controller and action from the params and determines if the user has >> rights to do that. If not, redirect them to the appropriate >> location. >> I do something similar with request methods and for the same reason >> (potential hits not via the UI). Unless I''m missing something, it >> should work for you and you''d have all the logic in one place. > > Various layout work differently, so in some cases, yes, access to the > whole page might be refused in which case a redirect would be used. I > also have cases though where I don''t want to redirect. The way a > layout for that scenario is, there is surrounding navigation and > information (which the layout incorprates through partials) that the > user may have legit access to, but the core view panel of the page > needs to be refused. Other layouts might refuse only sub-portions of > a view in which case I either use partials if the rules are > consistent, or I wrap snippets. There are dozens of authorization > filters, and they get used at a variety of levels. It''s a complex > application with a very complex user set. > > In the case of refusing the view (but not necessarily the whole > layout), I could use conditional wrappers around the whole the view > (it''d be consistent with refusing portions of views), but I was > hoping for something as I described simply to prevent doing the > unnecessary processing in the first place. > > As for centralizing with before_filter, I prefer to see authorization > logic closely linked to the code itself so I know exactly what''s > going on when I read the method code. Easier to review, debug, etc. > Another reason to go ahead with wrappers in the view, but I was > leaning towards preventing the processing as more important to the > overall security strength. > > -- gwI started skimming so I may have missed something from your original post, but have you tried to use either: render :text => '''', :layout => ''something'' or used in your view: <% content_for :heading do -%> <% if allowed? -%> <%= render :partial => ''group_links'' %> <% end -%> <% end -%> and then the layout: <div id=''heading''> <%= yield(:heading) || content_tag(:h1, title) %> </div> -Rob Rob Biedenharn http://agileconsultingllc.com Rob-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.org --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On May 14, 2008, at 4:09 AM, Rob Biedenharn wrote:> > I started skimming so I may have missed something from your original > post, but have you tried to use either: > > render :text => '''', :layout => ''something''Yep. Even reiterating the layout directly like this somehow causes some of the partials normally loaded by the layout to not work.> or used in your view: > > <% content_for :heading do -%> > <% if allowed? -%> > <%= render :partial => ''group_links'' %> > <% end -%> > <% end -%>Yeah, I was hoping to avoid additional conditionals in the view (that''s a part you probably skimmed over), but I''m starting to think it may be worth doing. I can get what I want with the "empty" kludge, or by using conditionals in the views, so I''ll just have to decide which looks & feels better. -- gw --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I would abstract it a bit. Rather than just sticking a bunch of "if
allowed?" all over the view, why not abstract it into a block helper
method as such:
application_helper.rb
def only_authorized(param_or_whatnot, &block)
content = capture(&block)
if some_authorization_technique
content
end
end
aircoded but the idea is you pass in a block to this method from the
view and its only outputted if the guy is authorized.
view:
<% only_authorized do %>
<p><%= super_secret_info %></p>
<% end %>
--
Posted via http://www.ruby-forum.com/.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---