# DoubleRender Question: who can answer?

**URL:** <https://www.ruby-forum.com/t/doublerender-question-who-can-answer/91006>\
**Category:** Rails\
**Created:** [April 3, 2007, 7:37pm UTC](https://www.ruby-forum.com/t/doublerender-question-who-can-answer/91006 "2007-04-03T19:37:19Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![joep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/87869e/32.png) [@joep](https://www.ruby-forum.com/u/joep)\
**Post date:** [April 3, 2007, 7:37pm UTC](https://www.ruby-forum.com/t/doublerender-question-who-can-answer/91006/1 "2007-04-03T19:37:19Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![joep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/87869e/32.png) [@joep](https://www.ruby-forum.com/u/joep)\
**Post date:** [April 3, 2007, 7:46pm UTC](https://www.ruby-forum.com/t/doublerender-question-who-can-answer/91006/2 "2007-04-03T19:46:48Z")

</div>

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 C.  
[http://depixelate.com](http://depixelate.com)

---

<div class="post-metadata">

**Author:** ![joep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/87869e/32.png) [@joep](https://www.ruby-forum.com/u/joep)\
**Post date:** [April 3, 2007, 7:51pm UTC](https://www.ruby-forum.com/t/doublerender-question-who-can-answer/91006/3 "2007-04-03T19:51:48Z")

</div>

Joe P. wrote the following on 03.04.2007 19:37 :

> 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

---

<div class="post-metadata">

**Author:** ![joep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/87869e/32.png) [@joep](https://www.ruby-forum.com/u/joep)\
**Post date:** [April 3, 2007, 8:39pm UTC](https://www.ruby-forum.com/t/doublerender-question-who-can-answer/91006/4 "2007-04-03T20:39:50Z")

</div>

Zack C. 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 C.  
> [http://depixelate.com](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

---

<div class="post-metadata">

**Author:** ![joep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/87869e/32.png) [@joep](https://www.ruby-forum.com/u/joep)\
**Post date:** [April 3, 2007, 10:09pm UTC](https://www.ruby-forum.com/t/doublerender-question-who-can-answer/91006/5 "2007-04-03T22:09:09Z")

</div>

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 C.  
[http://depixelate.com](http://depixelate.com)

---

<div class="post-metadata">

**Author:** ![joep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/87869e/32.png) [@joep](https://www.ruby-forum.com/u/joep)\
**Post date:** [April 3, 2007, 10:30pm UTC](https://www.ruby-forum.com/t/doublerender-question-who-can-answer/91006/6 "2007-04-03T22:30:13Z")

</div>

Zack C. 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 C.  
> [http://depixelate.com](http://depixelate.com)  
> 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

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.
