An access rights management tool.
Add this line to your application's Gemfile:
gem 'restricted_access'
And then execute:
$ bundle
Or install it yourself as:
$ gem install restricted_access
can be found here
Generate the config file with the generator, pass the resources as an argument.
rails g restricted_access:install -r user admin
# config/initializers/restricted_access.rb
RestrictedAccess.configure do |conf|
require 'restricted_access/orm/mongoid'
# require 'restricted_access/orm/active_record'
conf.resources = [:user, :admin]
end
You have to run a migration to add the :level
field to your model.
$ rails g migration AddLevelToAdmin
You can edit it this way :
class AddLevelToAdmins < ActiveRecord::Migration
def change
add_column :admins, :level, :integer
end
end
You need the mongoid-enum gem if you use mongoid. Just ad it to your gemfile.
gem 'mongoid-enum'
I didn't ship it as a dependency as it's useless for active_record users, and I didn't want to copy/paste some nice code done by someone else.
You must define the different levels of accesses in your model.
class Admin
include Mongoid::Document
access_levels mini: 0, normal: 1, super: 2
end
The module enhances the model with some methods and attributes.
Every model has now a :level attribute, by default the first defined by the class method.
You can set it like any attributes.
admin = Admin.first
admin.update(level: :super)
admin2 = Admin.last
admin.update(level: :mini)
The level defines its access rights.
Each instance has a :access
method, returning a RestrictedAccess::Access
instance.
admin.access
=> #<RestrictedAccess::Access:0x007fc255d36098 @level=:super, @power=2>
The RestrictedAccess::Access
class include comparable, so you can do such things :
admin.access > admin2.access
=> true
Admin.accesses.max
=> #<RestrictedAccess::Access:0x007fc255d36098 @level=:super, @power=2>
As the :level
attribute is an enum, you get this kind of methods :
admin.mini?
=> false
admin.super?
=> true
# scopes
Admin.mini # => Mongoid::Criteria
# or
Admin.super # => ActiveRecord::Relation
Controllers inheriting from ApplicationController have now a few more methods:
:prevent_#{level}_#{resource_name}_access
, which calls:restrict_#{current_resource.level}_#{resource_name}_access
if the:current_#{resource_name}
doesn't have enough access right.
If you use Devise, you already have a :current_#{resource_name}
method, if you don't use Devise, just implement the method.
class FrontController < ApplicationController
before_action :prevent_normal_admin_access, except: [:index]
# mini & normal admins will only be able to access index view
end
:restrict_#{level}_#{resource_name}_access
which redirect to theroot_path
.
You can override the method in your controller to do something else.
class FrontController < ApplicationController
before_action :prevent_normal_admin_access, except: [:index]
# Some code ...
private
def restrict_mini_admin_access
redirect_to some_path, notice: 'Nope dude' and return
end
def restrict_normal_admin_access
redirect_to some_other_path, notice: 'Nope dude' and return
end
end
You can also define a more global :restrict_#{resource_name}_access
method which applies to all concerned resources.
class FrontController < ApplicationController
private
# this method as a bigger precedency than the other one
def restrict_admin_access
redirect_to some_path, notice: 'Nope dude' and return
end
def restrict_normal_admin_access
redirect_to some_other_path, notice: 'Nope dude' and return
end
end
The gem provides a :available_for
method in the views, allowing you to hide some part of the view.
<!-- this div won't be seen be admins lower than super -->
<%= available_for :super, :admin do %>
<div>
I have something to hide here.
</div>
<%- end %>
- Fork it ( http://github.com/4nt1/restricted_access/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 new Pull Request