I ended up with the following:
1) For admin pages: I used acts_as_authenticated plugin for users (and
by users I mean admins).
My aaplication.rb controller has:
class ApplicationController < ActionController::Base
include AuthenticatedSystem
...
My base_controller.rb for the admin area inherits from the
ApplicationController and also has a before_filter:
class Admin::BaseController < ApplicationController
before_filter :login_required
end
And all my admin pages inherit from the base controller by using:
class Admin::UserController < Admin::BaseController
...
Which means, they all require login to be viewed.
In my views/layout/application.rhtml I have:
<p id="adminlogin">
<% if logged_in? %>
Logged in as <%= current_user.login %>
(<%= link_to "Logout", :controller => "/admin", :action =>
"logout" %>)
<% else %>
<%= link_to "Admin Login", :controller => "/admin", :action =>
"login" %>
<% end %>
</p>
2) Next, I added another column in my users table called
'role' (:integer, :limit => 1) to identify 1 for manager and 0 for
staff.
Only managers can add admins. Staff can do everything else in the
admin area besides administering admins.
So, in my user_controller.rb I added another before_filter:
before_filter :check_authorization
def check_authorization
user = User.find(session[:user])
unless user.role?
flash[:notice] = "You are not authorized to view the page
requested"
redirect_to :controller => 'product', :action => 'index'
return false
end
end
3) Lastly, I created a customer model which admins can create,
edit....
Now, only logged customers can checkout. So, in my checkout controller
I added all my customer's login methods, like so:
class CheckoutController < ApplicationController
before_filter :initialize_cart
before_filter :authorize, :except => ["login"]
def authorize
return true if @c
flash[:notice] = "To place your order please login"
redirect_to :controller => "catalog"
end
def login
# examine the form data for "name" and "password"
pw,name = params[:customer].values_at(*%w{password name})
# Retrieve the customer record for the name and store it in a
variable 'c'
c = Customer.find_by_name(name)
# if such record exists, and it's password matches the password
from the form
if c && Digest::SHA1.hexdigest(pw) == c.password
# start a session with the customer id
@session['customer'] = c.id
if @cart.products.empty?
redirect_to :controller => "catalog"
else
redirect_to :controller => "checkout", :action => "index"
end
else
# otherwise report an error
flash[:notice] = "Invalid Login"
end
end
def logout
@session['customer'] = nil
redirect_to :controller => "catalog"
end
And in my application.rb controller:
# register the method get_customer as a filter
before_filter :get_customer
def get_customer
# sets an instance variable @c to the customer object
# drawn from the db record of the customer who's logged in
# else the method is not assigned to @c and @c defaults to nil
if @session['customer']
@c = Customer.find(@session['customer'])
end
end
This login method is taken from "Ruby from Rails" book, Part 4, which
I am going to use next to change my current cart.
I am going to change it that both cart and checkout are in the same
controller because I need the cart to belongs_to :customer.
The reason is that I need to apply the customer's discount level and I
also want to record the customer's id in the orders table.
(optional later, I will add the option to remember customer's shipping
address.)
This has been a huge learning curve for me. I'm happy (and tired) that
it finally works. I'm off to re-do my cart.
If you have any suggestions/improvements to my code or way of
thinking, please share your thoughts.
Just one last question, when I create a session, does the information
for session['customer'] and session[:cart_id] get stored in the same
file?
and How do I call on the customer_id from the session? Have run into
trouble with this, where the order recorded the order_id in the
customer_id column. Not sure where is my mistake yet.
Cheers,
Elle