No release in over 3 years
Low commit activity in last 3 years
Rails Action Authorization adds an authorization framework for controller actions. Rails Action Authorization is designed to be extremely lightweight and flexible, enabling developers to spend less time trying to build complex authorization systems. It's unopinionated design makes it easy to define any kind of authorization rules with minimal effort.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

Runtime

~> 6.0.2, >= 6.0.2.1
 Project Readme

Build Status codecov Maintainability

Rails Action Authorization

Rails Action Authorization is a rails plugin that gives developers a lightweight authorization framework.

While there are lots of rails plugins designed to do authorization, Rails Action Authorization strives to be the most intuitive while simultaneously allowing developers to write the smallest possible amount of code to have a functioning authorization system.

Usage

There are two parts to using rails-action-authorization. The first part is defining rules. Rules are defined on models, and they specify how actions determine how to authorize users (or other models).

The second parrt of using rails-action-authorization is on the controller side. In any action in which authorization is required, run the check_authorization method.

Step One, defining rules

Suppose we are writing the proverbial blogging application, and we need some way to determine whether a user is permitted to edit a post.

The first step is to define a rule for the action that will need authorization. In our case, we'll need authorization for the edit and update actions. To define a rule, we'll have to edit our Post model.

# models/Post.rb

class Post < ApplicationRecord
    ...
end

Rules are defined using the define_rule method. define_rule takes at least one argument that is a string or a symbol that represents the action that needs authorization in the format controller#action. In our case, we need to authorize the edit and update actions like so:

# models/Post.rb
class Post < ApplicationRecord
    ...
    define_rule 'posts#edit', 'posts#update' do |post, user|
        # Authorization code here
    end
end

define_rule can take as many arguments as desired, enabling developers to define authorization rules for multiple actions simultaneously.

The block must return true or false, true if the user is permitted to edit the post and false if the user is not permitted. The block itself will always yield the resource that is being authorized as the first argument and the actor requesting authorization as the second argument. The first argument should always be the type as the class in which define_rule is called (if you ever encounter a case where it is not, then please report it as a bug). The second argument could technically be any model, but will probably most often be a User instance.

Since we only want a post's author to be able to edit a post, we'll define our rule as follows:

# models/Post.rb
class Post < ApplicationRecord
    ...
    define_rule 'posts#edit', 'posts#update' do |post, user|
        post.author == user
    end
end

Next, we have to check the authorization of the user in each controller. The only thing required to do this is to invoke check_authorization somewhere in each action that requries authorization.

# controllers/posts_controller.rb
class PostsController < ApplicationController
    before_action :authorize_user, only: [:edit, :update]

    ...

    def edit
        ...
        #You will be able to reference @post in your views as usuals.
    end

    def update
        ...
    end

    private

    def authorize_user
        @post = check_authorization(Post.find_by(id: params[:id]), current_user) # Here, use your own method for getting the current user.

    end
end

Notice that we are able to call check_authorization in a before_action. This is because check_authorization knows how to identify the action it is called in without requiring developers to specify it themselves.

This will work great when the owner tries to edit his own posts, but if another user attempts to edit a post, the server will raise an error. rails-action-authorization raises a ForbiddenError if a user fails to be authorized in order to eliminate potential ambiguity of returning nil or some other value.

In order to handle authorization failures, we'll have to adapt our controller slightly:

# controllers/posts_controller.rb
class PostsController < ApplicationController
    before_action :authorize_user, only: [:edit, :update]
    rescue_from ActionAuthorization::ForbiddenError, with:
        :handle_forbidden

    ...

    def edit
        ...
        #You will be able to reference @post in your views as usuals.
    end

    def update
        ...
    end

    private

    def authorize_user
        @post = check_authorization(Post.find_by(id: params[:id]), current_user) # Here, use your own method for getting the current user.
    end

    def handle_forbidden
        render '403', status: 403
    end
end

This will cause the execution of any action to cease immediately when a user fails to authorize, and instead run the code in handle_forbidden.

Of course, the above example assumes that you have a template for a 403 error, but you can run whatever code is necessary in your case.

Installation

Add this line to your application's Gemfile:

gem 'rails-action-authorization'

And then execute:

$ bundle

Or install it yourself as:

$ gem install rails-action-authorization

License

The gem is available as open source under the terms of the MIT License.