README.md

Summary

Maintainability
Test Coverage
# 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