Okay, here's how I did it in complete detail for anyone else that wants 
to implement something similar:

First in my users controller I place the following (NEW THINGS):

==========

class UsersController < ApplicationController
  before_filter :login_required, :except => [:new, :create]
  before_filter :authorize, :except => [:user_edit, :update]
..
..
end

==========

Summary:  What this does is forces a login for any action except new and 
create because those are what users will register with.  If a user 
attempts to go to any other action they will hit the authorize method (I 
will show what this does in a minute) except if they are doing user_edit 
and update actions.

Now I created a new method called user_edit in the users controller:

==========

def user_edit
  @user = User.find(params[:id])
  if logged_in? && User.find(current_user).id == @user.id
    # continue processing
  else
    @user = User.find(current_user.id)
    redirect_to :controller => 'users', :action => 'user_edit', :id => 
@user
  end
end

==========

Summary: What this does is first matches the id up for the page the 
person tries to go to.  Let's say for instance someone is trying to hack 
your site and they use this new method to look up /users/4/user_edit 
(user #4)...

It checks if the user is logged in and if not forces them to.  It then 
matches their id with the id they are looking for and if it's not 
matched, forces a redirect to the currently logged in user's real 
profile path.  So, if the user was user #2, it would force a redirect to 
/users/user_edit/2.

Then I changed the way the update action works:

==========

def update
  @user = User.find(params[:id])
  if logged_in? && User.find(current_user).admin?
    if @user.update_attributes(params[:user])

      flash[:notice] = 'Administrative Use : User was successfully 
updated.'
      redirect_to(user_path(@user))
    else
      render :action => 'edit'
    end
  else # our user is not an admin so we'll keep him/her that way
    if @user.update_attributes(params[:user].merge({ :admin => "false" 
}))
      flash[:notice] = 'Your profile was successfully updated.'
      redirect_to(user_path(@user))
    else
      render :action => 'user_edit'
    end
  end
end

==========

Summary: Now this update action works with both the normal edit and the 
new user_edit methods.

It basically checks to see if the currently logged in user is an 
administrator.  If that person is, it processes all of the normal update 
params, including the admin checkbox.

If the user is not an admin it simply updates the params specified in 
the user_edit view template plus it merges another option forcing the 
admin value to false.  This makes it so that no one can hack your value 
and supply something different.  If the user is not an admin, then their 
value should be false.

In the user model I then place the following:

==========

attr_accessible :login, :email, :name, :password, 
:password_confirmation, :admin

==========

Summary: .. which allows me to update admin fields with my admin page.

Keep in mind that the admin page or the edit pages that house the 
checkbox fields can't be accessed without being logged in and the user 
already having admin rights enabled before hand.

In the new user_edit template I have the following:

==========

<%= error_messages_for :user %>

<% form_for @user do |f| -%>
  <p><label for="login">Login</label><br/>

  <p><label for="email">Email</label><br/>
  <%= f.text_field :email %></p>

  <p><label for="password">Password</label><br/>
  <%= f.password_field :password %></p>

  <p><label for="password_confirmation">Confirm Password</label><br/>
  <%= f.password_field :password_confirmation %></p>

  <p><%= submit_tag 'Update' %></p>
<% end %>

==========

Summary: I place my custom authorize method in application_controller.rb 
by doing the following at the very bottom of the controller:

==========

private

def authorize
  unless logged_in? && User.find(current_user).admin?
    redirect_to root_url
  end
end

==========

Summary: When you make a call to authorize, if the person is not an 
admin, it automatically redirects them back to the root_url of your 
site.

Lastly, you need to update a new route in your routes.rb file so that it 
can access the new user_edit method in the users controller:

==========

map.resources :users, :member => { :user_edit => :get }

==========

This keeps the controller RESTful but adds a new member method to it.


===================================================

I hope this helps someone in the future.
-- 
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 [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to