IQ::ACL

This aim of this gem is to provide a series of classes to handle common ACL requirements. Currently provided is the IQ::ACL::Basic class which although super simple, is also extremely powerful. Read more about usage on the IQ::ACL::Basic page.

Install

gem install iq-acl

Usage

# Create an instance of the basic class, supplying rights as a hash, note
# that asterisks are used as wildcards.
auth = IQ::ACL::Basic.new({
  '*'                 => { 'terry' => 'r' },
  'projects'          => { 'jonny' => 'rw' },
  'projects/private'  => { 'billy' => 'rw', 'terry' => nil },
  'projects/public'   => { 'terry' => 'rw', '*' => 'r' }
})

# You could alternatively read rights from a YAML file
auth = IQ::ACL::Basic.new(YAML.load_file('rights.yml'))

auth.authenticate! 'guest', 'projects'         #=> raises IQ::ACL::AccessDeniedError
auth.authenticate! 'jonny', 'projects'         #=> 'rw'
auth.authenticate! 'billy', 'projects'         #=> raises IQ::ACL::AccessDeniedError
auth.authenticate! 'terry', 'projects'         #=> 'r'
auth.authenticate! 'guest', 'projects/private' #=> raises IQ::ACL::AccessDeniedError
auth.authenticate! 'jonny', 'projects/private' #=> 'rw'
auth.authenticate! 'billy', 'projects/private' #=> 'rw'
auth.authenticate! 'terry', 'projects/private' #=> raises IQ::ACL::AccessDeniedError
auth.authenticate! 'guest', 'projects/public'  #=> 'r'
auth.authenticate! 'jonny', 'projects/public'  #=> 'r'
auth.authenticate! 'billy', 'projects/public'  #=> 'r'
auth.authenticate! 'terry', 'projects/public'  #=> 'rw

A block may be given to authenticate! that should return true if the yielded rights are adequate for the user, for example the following will raise an IQ::ACL::AccessDeniedError as ‘terry’ does not have write access to the ‘projects’ path. If ‘terry’ had write access to the ‘projects’ path, the exception would not be thrown.

auth.authenticate! 'terry', 'projects' do |rights|
  rights.include?('w')
end

In the previous examples, strings are used to identify the user, however user may be any object. This becomes quite powerful as you could use the objects returned from an ORM such as ActiveRecord. Also the rights in the previous examples were strings, however these may be of any type also, again allowing powerful solutions to be built e.g.

user = User.find_by_email('[email protected]')
auth = IQ::ACL::Basic.new('projects/*' => { user => user.roles })

auth.authenticate!(user, 'projects/some-project') do |roles|
  roles.find_by_name('project_editor')
end

Documentation

Documentation is handled with YARD. You can generate the documentation by running:

rake yard

Note on Patches/Pull Requests

  • Fork the project.

  • Make your feature addition or bug fix.

  • Add tests for it. This is important so I don’t break it in a future version unintentionally.

  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)

  • Send me a pull request. Bonus points for topic branches.

Copyright © 2010 Jamie Hill, SonicIQ Ltd. See LICENSE for details.