Rendering error page for "Unauthorized" from before_filter


#1

Hey all,

I am writing a plugin in which I want to stop the rendering of an
action with an unauthorized response if the user is not authorized to
view the resource. I am using a before filter to achieve this and
inside that before filter I do it like so:

render :text => "Unauthorized!", :status => :unauthorized, :layout

=> false

The status is properly set since I see the following in the log:

Filter chain halted as [:check_access] rendered_or_redirected.
Completed in 130ms (View: 0, DB: 10) | 401 Unauthorized

So far so good. What I would like to do is to show a user a nice
(static html) error page so he knows what went wrong. Taking my cue
from the rails documentation, I created a file named 401.html and
placed it into the public/ directory of the rails app. However,
instead of this static html file I see the “Unauthorized!” text being
rendered.

I also went into the rails source and tweaked the rescue module a bit
so that I surely get the ‘public’ view of the exception:

 def rescue_action_without_handler(exception)
    (...)

    if false && (consider_all_requests_local || local_request?) #

here
rescue_action_locally(exception)
else
rescue_action_in_public(exception)
end
(…)

That did not change anything, either. Am I not doing the proper thing?
Should I throw an exception (which one?) instead of rendering
something and setting the http status code of the response? Or is
rendering from before_filters a syntactic vinegar type of thing?
(probably not).

Thank you for your help in advance,
Balint


#2

Hi,

Maybe you should try render_optional_error_file

Jan


#3

Hey, Jan, thank you.

Yes, but in fact what you suggest is the “standard procedure” of
rescuing “an exception” for the public view (what I described in my
first post). Rails source code:

(rescue.rb)
def rescue_action_in_public(exception) #:doc:
render_optional_error_file response_code_for_rescue(exception)
end

The problem is that it seems that “rescue_action_without_handler” does
not get called if I set the response status from the before filter.

Anyway, I figured out a way, I have the following in my before filter
now which works great:

render :file => "#{Rails.public_path}/401.html", :status

=> :unauthorized and return

Balint