Hello. In my application controller, I have a function like this: def is_owner_or_admin(user_id) if cur_user.role != "Admin" && cur_user.id != Integer(user_id) flash[:error] = "Access denied" redirect_to(:controller => :users, :action => :account) and return false end end I call it in my users controller like so: def show is_owner_or_admin(params[:id]) @user = User.find_by_id(params[:id]) unless @user flash[:error] = "User not found" redirect_to :action => :account end end If @user ends up being nil, however, then I get a DoubleRender error. My question is, what can I put in "is_owner_or_admin" that will redirect and not complete the "show" action? -- 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 -~----------~----~----~----~------~----~------~--~---
Joe, You want to call this method as a before_filter. Then returning false will stop further request processing. before_filter :is_owner_or_admin You''ll also need to pull out the param user_id and just locate this within the method as you can''t pass params to filters. -- Zack Chandler http://depixelate.com On 4/3/07, Joe Peck <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > Hello. > > In my application controller, I have a function like this: > > def is_owner_or_admin(user_id) > if cur_user.role != "Admin" && cur_user.id != Integer(user_id) > flash[:error] = "Access denied" > redirect_to(:controller => :users, :action => :account) and return > false > end > end > > I call it in my users controller like so: > def show > is_owner_or_admin(params[:id]) > @user = User.find_by_id(params[:id]) > unless @user > flash[:error] = "User not found" > redirect_to :action => :account > end > end > > If @user ends up being nil, however, then I get a DoubleRender error. > My question is, what can I put in "is_owner_or_admin" that will redirect > and not complete the "show" action? > > -- > 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 -~----------~----~----~----~------~----~------~--~---
Joe Peck wrote the following on 03.04.2007 19:37 :> Hello. > > In my application controller, I have a function like this: > > def is_owner_or_admin(user_id) > if cur_user.role != "Admin" && cur_user.id != Integer(user_id) > flash[:error] = "Access denied" > redirect_to(:controller => :users, :action => :account) and return > false > end > end > > I call it in my users controller like so: > def show > is_owner_or_admin(params[:id]) > @user = User.find_by_id(params[:id]) > unless @user > flash[:error] = "User not found" > redirect_to :action => :account > end > end > > If @user ends up being nil, however, then I get a DoubleRender error. > My question is, what can I put in "is_owner_or_admin" that will redirect > and not complete the "show" action? > >I ended with throwing a SecurityError instead of redirecting, makes it more DRY: I catch the exception and do what I want with it. In your ApplicationController : # 1/ save the original exception handling alias_method :rescue_action_without_security_error, :rescue_action # 2/ handle the SecurityError case def rescue_action(exception) return rescue_action_without_security_error(exception) unless exception.is_a?(SecurityError) log_url_hacking(exception) reset_session render :file => "#{RAILS_ROOT}/public/403.html", :status => 403 end My personal choice has demonstrated above is to: - log the hacking attempt, - destroy the session, - render a default 403 page with the corresponding HTTP Response code. Lionel --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Zack Chandler wrote:> Joe, > > You want to call this method as a before_filter. Then returning false > will stop further request processing. > > before_filter :is_owner_or_admin > > You''ll also need to pull out the param user_id and just locate this > within the method as you can''t pass params to filters. > > -- > Zack Chandler > http://depixelate.comZack, How could I check the user_id if I can''t pass in params to the filter? That''s basically what I am checking. Joe -- 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 -~----------~----~----~----~------~----~------~--~---
Joe, There is actually a lot wrong here. First of all you can never trust params with anything as important as access control. What happens when a user passes in param[:id] equal to an admins? They have admin access under your code. You need to do some sort of user authentication, store the user_id in the session and then check that in your code. Example: # application.rb ... def current_user @current_user ||= (session[:user_id] ? User.find(session[:user_id]) : nil) end helper_method :current_user ... private def authenticate redirect_to(login_url) and return false unless current_user end So now you can write the authorization check as a before_filter: def is_owner_or_admin if current_user.role != "Admin" || [ownership check here] flash[:error] = "Access denied" redirect_to(:controller => :users, :action => :account) and return false end end -- Zack Chandler http://depixelate.com On 4/3/07, Joe Peck <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > Zack Chandler wrote: > > Joe, > > > > You want to call this method as a before_filter. Then returning false > > will stop further request processing. > > > > before_filter :is_owner_or_admin > > > > You''ll also need to pull out the param user_id and just locate this > > within the method as you can''t pass params to filters. > > > > -- > > Zack Chandler > > http://depixelate.com > > Zack, > > How could I check the user_id if I can''t pass in params to the filter? > That''s basically what I am checking. > > Joe > > -- > 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 -~----------~----~----~----~------~----~------~--~---
Zack Chandler wrote:> Joe, > > There is actually a lot wrong here. First of all you can never trust > params with anything as important as access control. What happens > when a user passes in param[:id] equal to an admins? They have admin > access under your code. You need to do some sort of user > authentication, store the user_id in the session and then check that > in your code. Example: > > # application.rb > ... > def current_user > @current_user ||= (session[:user_id] ? User.find(session[:user_id]) : > nil) > end > helper_method :current_user > ... > private > > def authenticate > redirect_to(login_url) and return false unless current_user > end > > So now you can write the authorization check as a before_filter: > > def is_owner_or_admin > if current_user.role != "Admin" || [ownership check here] > flash[:error] = "Access denied" > redirect_to(:controller => :users, :action => :account) and return > false > end > end > > -- > Zack Chandler > http://depixelate.comdef is_owner_or_admin(user_id) if cur_user.role != "Admin" && cur_user.id != Integer(user_id) flash[:error] = "Access denied" redirect_to(:controller => :users, :action => :account) and return false end end Actually, "cur_user" returns the current user based on session data already, so whatever user_id they pass in, it won''t affect their access. -- 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 -~----------~----~----~----~------~----~------~--~---