Minimalistic authorization library for Ruby and Rails applications. It
provides methods authorize_if
and authorize
, that evaluate inline or
pre-defined authorization rules and raise exception if rule evaluates
to false
.
authorize_if
- inline authorization
authorize
- authorization using pre-defined authorization rules
Accepts any truthy
or falsey
Ruby object.
class ArticlesController < ActionController::Base
def index
authorize_if current_user
# ...
end
def show
article = Article.find(params[:id])
authorize_if article.authored_by?(current_user) ||
article.published?
# ...
end
def edit
article = Article.find(params[:id])
authorize_if can_manage?(article)
# ...
end
private
def can_manage?(article)
# ...
end
end
It raises AuthorizeIf::NotAuthorizedError
exception, which you can
rescue right in the controller action
class ArticlesController < ApplicationController
def index
authorize_if current_user
# ...
rescue AuthorizeIf::NotAuthorizedError
head 404
end
end
or with rescue_from
in ApplicationController
:
class ApplicationController < ActionController::Base
rescue_from AuthorizeIf::NotAuthorizedError do |exception|
head 404
end
end
If block is given, authorize_if
yields the block with an exception
object. This allows to set custom error message, which is going to be
used when exception is raised.
Also you can use key-value store(plain Ruby hash), context
, to store
any data, and access it in the exception handling block.
class ArticlesController < ApplicationController
def index
authorize_if(current_user) do |exception|
exception.message = "You are not authorized!"
exception.context[:request_ip] = "192.168.1.1"
end
# ...
end
end
class ApplicationController < ActionController::Base
rescue_from AuthorizeIf::NotAuthorizedError do |exception|
exception.message
# => "You are not authorized!"
exception.context[:request_ip]
# => "192.168.1.1"
end
end
You can define authorization rules for controller actions like this
And then call authorize
, which is going to find and evaluate
corresponding authorization rule.
class ArticlesController < ActionController::Base
def index
authorize
# ...
end
private
def authorize_index?
current_user.present?
end
end
authorize
accepts any arguments and passes them to authorization
rule.
class ArticlesController < ActionController::Base
def edit
article = Article.find(params[:id])
authorize(article)
# ...
end
private
def authorize_edit?(article)
article.author == current_user
end
end
It also accepts customization block, and yields an exception object:
class ArticlesController < ActionController::Base
def edit
article = Article.find(params[:id])
authorize(article) do |exception|
exception.message = "You are not authorized!"
exception.context[:request_ip] = "192.168.1.1"
end
rescue AuthorizeIf::NotAuthorizedError => e
e.message
# => "You are not authorized!"
e.context[:request_ip]
# => "192.168.1.1"
end
private
def authorize_edit?(article)
article.author == current_user
end
end
You can extract rules into a module and include it to the controller.
class ArticlesController < ActionController::Base
include AuthorizationRules
def index
authorize
# ...
end
end
module AuthorizationRules
def authorize_index?
current_user.present?
end
end
Add gem to your application's Gemfile
:
gem 'authorize_if'
And then execute:
$ bundle
Or install it manually:
$ gem install authorize_if
Include AuthorizeIf
module, provided by gem, to any Ruby class and
you'll get authorize
and authorize_if
methods.
- Fork it ( https://github.com/vrybas/authorize_if/fork )
- 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 a new Pull Request
Copyright 2016 Vladimir Rybas. MIT License (see LICENSE for details).