Rule based authorization library.
Add this line to your application's Gemfile:
gem 'authorule'
And then execute:
$ bundle
Or install it yourself as:
$ gem install authorule
Write a permission rule model. By default, Authorule
expects this to be called PermissionRule
. You may add any associations in the class, but this is not required by this gem.
class PermissionRule < ActiveRecord::Base
include Authorule::Rule
belongs_to :user
end
Use the following migration for this class (TODO: write a generator):
class CreatePermissionRules < ActiveRecord::Migration
def change
create_table :permission_rules do |t|
t.boolean :allow, :default => true
t.string :kind, :limit => 20
t.string :name, :limit => 80
t.string :action, :limit => 20
# --> Add any other columns here.
end
end
end
Write a permission holder model. This is typically a User
object. Include Authorule::PermissionHolder
into this class, and call is_permission_holder!
.
class User < ActiveRecord::Base
include Authorule::PermissionHolder
is_permission_holder!
end
This creates an association and a rule base accessor. By default, it is assumed that the rule class is called PermissionRule
.
Write a permission class. Each permission class should at a minimum:
- Register itself under a name.
- Provide a way to resolve any argument into a permission target.
- Provide a way to list all permission targets.
A permission target is the object that you wish to secure using the permission. The following example is a permission that secures access to any ActiveRecord object. The target is the class (e.g. 'Allow user X to access Active Record class Y.'), but the permission can also resolve model instances.
class ResourcePermission < Authorule::Permission
# Register under name :resource.
register :resource
# Resolution.
resolve do |arg|
if arg.is_a?(ActiveRecord::Base)
arg.class
elsif arg.is_a?(Class) && arg < ActiveRecord::Base
arg
end
end
list do
classes = []
Dir[ Rails.root + 'app/models' + '*.rb' ].each do |file|
klass = File.basename(file, '.rb').camelize.safe_constantize
classes << klass if klass
end
classes
end
end
You can now give any user a set of rules, e.g.:
- Allow access to everything
- Deny access to ActiveRecord class 'Account'
This allows the user to access all other ActiveRecord classes (and their objects).
To check a permission, you can call:
User.may_access?(Account)
or
User.may_access?(Account.new)
(because it resolves into a class), or the equivalent
permission = Authorule.resolve(Account.new)
User.has_permission?(permission)
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request