I got authlogic and acl_system2 to work together under Rails 2.3.2. authlogic provides authentication. acl_system2 provide authorization, i.e. ACLs. authlogic is very up-to-date, but acl_system2 is a bit dated. That's okay, though, because it's not the sort of thing that should need to change much.
Let me cover some of the stumbling blocks I encountered after I followed the authlogic tutorial and the acl_system2 documentation.
acl_system2 is not available as a gem. Hence, you need to install it via:
script/plugin install git://github.com/ezmobius/acl_system2.gitIf you followed the authlogic tutorial, you'll end up with the ApplicationController#current_user method being private. To work with acl_system2, it should instead be protected. Otherwise, you'll end up with this:
You have a nil object when you didn't expect it!Here's what my migration looks like:
The error occurred while evaluating nil.roles (NoMethodError)
.../vendor/plugins/acl_system2/lib/caboose/role_handler.rb:15:in `check'
.../vendor/plugins/acl_system2/lib/caboose/logic_parser.rb:43:in `process'
.../vendor/plugins/acl_system2/lib/caboose/access_control.rb:101:in `allowed?'
.../vendor/plugins/acl_system2/lib/caboose/access_control.rb:28:in `access_control'
class CreateRoles < ActiveRecord::MigrationEach of my controllers has something like:
def self.up
create_table :roles do |t|
t.string :title, :null => false
t.timestamps
end
add_index :roles, :title, :unique => true
create_table :roles_users, :id => false do |t|
t.integer :role_id, :null => false, :options => "CONSTRAINT fk_role_id_roles REFERENCES roles(id)"
t.integer :user_id, :null => false, :options => "CONSTRAINT fk_user_id_users REFERENCES users(id)"
end
Role.delete_all
Role.create :title => "admin"
end
def self.down
Role.delete_all
drop_table :roles_users
drop_table :roles
end
end
before_filter :require_userI decided to add the following to ApplicationController as protected methods:
access_control :DEFAULT => 'admin'
def permission_deniedThat way the HTTP status gets set for "Permission denied".
render :text => "Forbidden", :status => "403 Forbidden"
end
def permission_granted
end
In order to test the above using Cucumber and Webrat, I added a feature step like:
And the HTTP status should be "403 Forbidden"Then, I added a step definition:
Then /^the HTTP status should be "([^\"]*)"$/ do |status|So far, I'm pleased :)
response.status.should == status
end


2 comments:
There is also something else that caused me to spend some time debugging, and that is that acl_system2 makes the assumption that there is a method called "current_user". In access_control.rb:
@default_access_context[:user] = send(:current_user) if respond_to?(:current_user)
Now that is fine and dandy but my method was not called current_user, and because of this it was throwing the nil.roles error (and there was no obvious stack trace).
The reason I had to change the (I guess "standard") naming of current_user is very non-obvious (and I also spent a long time debugging this). I use ActiveScaffold and that is also defining its own version (and for different purposes) of "current_user".
I hope to be able to patch acl_system2 in a way that makes this naming convention more obvious.
Thanks for your post, as it helped me determine the problem.
Good luck with that.
Post a Comment