-
Notifications
You must be signed in to change notification settings - Fork 111
Tutorial: securing a controller
Agenda: we’ve got a standard REST controller (ProductsController) and want to discover how access restrictions can be applied to it (using acl9 of course!)
Here’s the controller (with omitted action bodies for brevity):
class ProductsController < ApplicationController
def index
# ...
end
def show
# ...
end
def new
# ...
end
def edit
# ...
end
def create
# ...
end
def update
# ...
end
def destroy
# ...
end
end
Add a line to the config/environment.rb file and install the gem.
When everyone is allowed to do everything, it’s also access control. So we’ll start from this.
All access rules in controllers are put into access_control block. The all-permissive variant will be:
class ProductsController < ApplicationController
access_control do
allow all
end def index
- …
end
- …other actions…
end
allow all makes sense here, doesn’t it?
This controller should work, if it doesn’t, you might have some problems with acl9 installation.
So, you actually don’t want your competitor to come and delete all your products, replacing them with theirs! A simple scheme could work: you’re the only registered user, you do the stuff, and others are just anonymous users with no rights.
How about this?
access_control do
allow logged_in
end
Seems cool. Only logged in users can… but wait! Now nobody can’t even see your products (except you)! Something must be done:
access_control do
allow logged_in
allow anonymous, :to => [:index, :show]
end
The second rule to the rescue. In this case anonymous users can see, but not create, edit, or destroy products.
Short answer: not controller.send(:current_user).nil?.
This means you should use some authentication solution (authlogic, restful_authentication, clearance, or roll out your own current_user implementation).
Note_: if the method is named differently (current_account, or even @current_jedi_that_shouldbe@), acl9 can be configured to handle that (see the docs).
Answer: Acl9::AccessDenied exception is raised.
You’ll probably handle this in the ApplicationController, in the following manner:
class ApplicationController < ActionController::Base
rescue_from 'Acl9::AccessDenied', :with => :access_denied
# ...other stuff...
private
def access_denied
if current_user
render :template => 'home/access_denied'
else
flash[:notice] = 'Access denied. Try to log in first.'
redirect_to login_path
end
end
end
- Home
- Role Subsystem
- Access Control Subsystem
- Legacy Docs (some faults/errors may exist)