README.md
# Cannie
[![Build Status](https://travis-ci.org/hck/cannie.png)](https://travis-ci.org/hck/cannie) [![Code Climate](https://codeclimate.com/github/hck/cannie.png)](https://codeclimate.com/github/hck/cannie)
Cannie is a gem for authorization/permissions checking on per-controller/per-action basis.
## Installation
Add this line to your application's Gemfile:
gem 'cannie'
And then execute:
$ bundle
Or install it yourself as:
$ gem install cannie
## Usage
### Define permissions
Permissions are defined in Permissions class, which could be generated by Rails generator:
rails g cannie:permissions
Than you can define all the permissions you want:
class Permissions
include Cannie::Permissions
# allow action on controller
allow :index, on: :posts
# or if controller is namespaced
allow :index, on: 'namespace/controller'
# few actions for controller
allow [:index, :show], on: :posts
# many actions for many controllers
allow [:index, :show], on: [:posts, :comments]
# few rules inside controller scope
controller :posts do
allow :show
allow :new
end
# namespaced controllers
namespace :admin do
controller :users do
allow [:index, :show]
end
end
end
Also its possible to pass conditions for `allow` calls:
allow :index, on: :posts, if: ->{ user.admin? }
or
allow :index, on: :posts, unless: ->{ user.guest? }
or
allow :index, on: :posts, if: &:admin?
or
allow :index, on: :posts, unless: &:admin?
These conditions are executed in context of `Permissions` object and its possible to use `user` method to access user that was passed to `Permissions::initialize`.
### Checking permissions
To be sure that permissions checking is handled in each action of your controller, add `check_permissions` method call to your controllers:
class PostsController < ApplicationController
check_permissions
#...
end
It's also possible to set a condition by specifying `:if` or `:unless` options for `check_permissions` call:
class PostsController < ApplicationController
check_permissions if: :some_method
#...
end
or
class PostsController < ApplicationController
check_permissions if: ->(controller) { controller.some_method }
#...
end
or
class PostsController < ApplicationController
check_permissions unless: some_method
#...
end
or
class PostsController < ApplicationController
check_permissions unless: ->(controller) { controller.some_method }
#...
end
To skip checking permissions for controller, add `skip_check_permissions` method call:
class PagesController < ApplicationController
skip_check_permissions
#...
end
### Handling of unpermitted access
If user is not permitted for appropriate action, `Cannie::ActionForbidden` exception will be raised.
It can be handled globally by using `rescue_from` inside ApplicationController:
class ApplicationController < ActionController::Base
rescue_from Cannie::ActionForbidden do |exception|
redirect_to root_path, alert: exception.message
end
end
## Contributing
1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request