views:

359

answers:

2

I want to hide the urls for editing users and their profiles behind safer and meaningful urls. For instance, I want /user/13/edit to be /settings/account and /user/13/profile/edit to be /settings/profile.

I managed to achieve that, but for that I had to load the user information from the current_user bit from the session. Like so:

# users_controller
def edit
  @user = current_user
end

# profiles_controller
def edit
  @user = current_user
  @profile = @user.profile
end

But now, since I can't compare @user.id from the params with the current_user in the session, how can I stop the old urls (/user/13/edit and /user/13/profile/edit) from being exploitable? They always load the forms for the current user, so there's no harm done, but I'd be more comfortable if they just produced a 404 error or something.

Thanks in advance.

+1  A: 

First of all, your authentication mechanism needs to set the current user.

routes.rb

map.account '/settings/account', :controller => 'user', :action => 'edit' 
map.profile '/settings/profile', :controller => 'user', :action => 'edit_profile'

map.resources :users, :only => [:edit, :update, :show],
              :member => { :edit_profile => :get, :update_profile, :put }

this produces the following routes:

/settings/account         (get)
/settings/profile         (get)
/users/:id                (get, put)
/users/:id/edit           (get)
/users/:id/edit_profile   (get)
/users/:id/update_profile (put)

users_controller.rb

before_filter :redirect_if_unauthorized

def edit
  @user = current_user
end

# profiles_controller
def edit
  @user = current_user
  @profile = @user.profile
end

protected

def redirect_if_unauthorized
  redirect_to some_path if params[:id] or current_user.nil?
end

Obviously some_path does not exist, you will have to create a page/path, etc. to display an error.

With this solution, you never display/manipulate a user based on params[:id], only the current_user saved by your authentication scheme.


I might also suggest looking at the declarative_authorization gem/plugin (Github, Railscast)

Patrick Klingemann
My problem is precisely that the new urls don't provide params that I can use for comparison anymore.
Baby Diego
I made some edits, is that closer to what you're looking for?
Patrick Klingemann
I tried adapting your solution to my code but couldn't get it to work. I'm going to look into the plugin now. Thanks for helping.
Baby Diego
My pleasure, let me know how it goes. By the way, what was the specific problem you were having with this solution?
Patrick Klingemann
A: 

the /edit urls still exist because i'm betting you have a map.resources in your routes.rb file for the user model. you can put a line higher than that in your routes.rb file that matches explicitly the edit lines you are looking to re-route and point them wherever you'd like.

imightbeinatree at Cloudspace