CanTango is an advanced Access Control (permissions) system for Rails 3. It:
- extends CanCan and offers a more role oriented design
- integrates with role and authentication systems in a non-intrusive manner
- can cache ability rules between requests for increased performance
- can store abilites in a permission store, including a YAML file, for easy administration
- works well with multiple user accounts and sub applications
- supports multiple Devise users
CanTango has been tested to work with Ruby 1.9+ and currently doesn’t support Ruby 1.8.7
If you require ruby 1.8.7 support, please help patch it and make a pull request ;)
gem install cantango
Insert into Gemfile
gem 'cantango'
Run bundler in a terminal/console from the folder of your Gemfile (root folder of app)
$ bundle
Version 0.9.4.2 has been released with the following features and improvements:
- Redesign of Cache and Ability execution
- Caching at the individual engine level that can be switched (configured) on/off
- Individual caching for each type of Permit in the Permit engine
- Each engine return a set of rules which are merged into one rule set for that particular execution mode
- Caching for the new User AC engine
- Ability to register your own Permit base classes simply by subclassing CanTango::Permit!
- This is useful if you want to go beyond the built in types, see the
custom_permit_spec.rb
for an example - Some bug fixes!
The :user_ac engine is a port of the Permission system from the Rails in Action book.
With this engine a user can have many permissions defined, where each such permission is a persisted Permission model instance that describes a ‘can’ action on a specific type of object.
The new modal Ability model allows you to define rules that are run in Cache mode and others that can be run in no-cache mode. This enables you to circumvent the previos restriction that didn’t allow you to use normal conditional ruby logic outside blocks if you enabled caching.
class UserPermit < CanTango::UserPermit def static_rules can :access, Article end module Cached def permit_rules can :read, Project end end module NonCached def permit_rules can :edit, Article end end end
Any rule method defined directly for the permit is run for any (or both) modes. To define rules specifically for cache or no-cache modes, you should place them in a nested module to signify this as shown in this example.
You can configure modes with the new config object CanTango.config.ability.modes
and set it via CanTango.config.ability.mode = :no_cache
. The valid modes are: :cache, :no_cache, and :both. You can similarly configure which modes each engine should participate in, fx via CanTango.config.permit_engine.mode = :cache
See the Quickstart guide in the wiki.
For devise integration, see Quickstart with Devise
The following scenarios demonstrate some of the problems CanTango can help solve in an elegant way
Cantango comes with a set of Generators to get your app dancing…
Simply start with:
- cantango:install
To use the Permit generators please see the Generators wiki page ;)
The CanTango Configuration consists of a nice DSL that let’s you configure most of the things we imagine you would want to customize. Feel free to suggest more configuration options!
Abilities are Access Control rules. With CanTango, the AC rules can be defined in both:
- Permissions (fx a yaml file)
- Permits (special classes)
Note: For the simplest cases, you can define a #permit_rules
instance method directly in CanTango::Ability
Abilities can be defined for the following conceptual entities:
- User models
- User Account models
- Roles
- Role groups
- Users
See Debugging permits
The default CanTango Ability pattern is simple.
1. Return cached ability rules for candidate if available
2. Generate rules for candidate
3. Cache rules for candidate
A candidate is typically either a user or an account instance.
Caching can be enabled or disabled. To generate the rules, one or more engines are executed.
CanTango comes with the following engines:
- Permit engine
- Permission engine
You can however freely plugin or unplug engines as you wish as described in Pluggable engines
CanTango had been designed to be minimally intrusive and not require too many external dependencies.
If you want to enable Moneta for caching or storage, you must execute an adapter macro: CanTango.adapter :moneta
This will setup lazy-loading of Moneta cache and Moneta store respectively.
If you want to enable compilation of dynamic rules (using blocks) you must use the :compiler
adapter
If you use any of these adapters, you must manually include the following in your Rails app Gemfile.
gem 'dkastner-moneta'
for moneta adapter and gem 'sourcify'
for the compiler adapter.
CanTango uses autoload_modules
from the sweetloader gem.
This ensures that all such modules are lazy-loaded. Thus if you configure CanTango to exclude an engine, the code for that engine will never be loaded, minimizing the load time and memory print.
Please post ideas, questions etc. in the cantango group on Google.
If you encounter bugs, raise an issue or:
- 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.
- Kristian Mandrup
- Stanislaw Pankevich
Copyright © 2010 Kristian Mandrup. See LICENSE for details.