Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ez-engines/ez-permissions
Ez Permissions (read as "easy permissions") - one of the ez-engines collection that helps easily add permissions interface to your Rails application.
https://github.com/ez-engines/ez-permissions
easy engines ez rails
Last synced: 23 days ago
JSON representation
Ez Permissions (read as "easy permissions") - one of the ez-engines collection that helps easily add permissions interface to your Rails application.
- Host: GitHub
- URL: https://github.com/ez-engines/ez-permissions
- Owner: ez-engines
- License: mit
- Created: 2017-06-20T07:03:17.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2023-03-08T20:05:19.000Z (almost 2 years ago)
- Last Synced: 2024-04-26T11:47:05.157Z (10 months ago)
- Topics: easy, engines, ez, rails
- Language: Ruby
- Homepage: https://github.com/ez-engines/ez-permissions
- Size: 191 KB
- Stars: 4
- Watchers: 5
- Forks: 1
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- License: MIT-LICENSE
Awesome Lists containing this project
README
# Ez::Permissions
[![Gem Version](https://badge.fury.io/rb/ez-permissions.svg)](https://badge.fury.io/rb/ez-permissions)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Build Status](https://travis-ci.org/ez-engines/ez-permissions.svg?branch=master)](https://travis-ci.org/ez-engines/ez-permissions)**Ez Permissions** (read as "easy permissions") - one of the [ez-engines](https://github.com/ez-engines) collection that helps easily add permissions interface to your [Rails](http://rubyonrails.org/) application.
- Most advanced RBAC model:
- Flexible tool with simple DSL and configuration
- All in one solution
- Convention over configuration principles.
- Depends on [ez-core](https://github.com/ez-engines/ez-core)## Installation
Add this line to your application's Gemfile:
```ruby
gem 'ez-permissions'
```## Generators
Generate configuration file:
```bash
rails generate ez:permissions:install
```### Configuration
Configuration interface allows you to change default behavior
```ruby
Ez::Permissions.configure do |config|
# If in generated migrations you changed table names, please configure them here:
config.permissions_table_name = 'my_permissions'
config.roles_table_name = 'my_roles'
config.models_roles_table_name = 'my_model_roles'
config.permissions_roles_table_name = 'my_permissions_roles'# Suppress STDOUT messages for test environment
config.mute_stdout = true if Rails.env.test?# Define your custom callbacks
config.handle_no_permission_model = lambda { |context|
raise 'User not exist'
}config.handle_not_authorized = lambda { |context|
raise 'Not authorized'
}
end```
### ActiveRecord migrations:**If you need change table names, please change configuration first**
And run
```bash
rails generate ez:permissions:migrations
```## DSL
Simple DSL for definition of permission relationships
```ruby
Ez::Permissions::DSL.define do |setup|
# You need add all resources of your application and possible actions
setup.add :roles, actions: %i[create read]# Use `crud` for adding default `create`, `read`, `update` and `delete` actions
# And any your custom action
setup.add :permissions, actions: %i[crud my_custom_action]# Actions option are not required. In such case you add all crud actions by default
setup.add :users, group: :accounts # You can group resources
setup.add :projects # Resource without a group will get "others" group
end
```## Permission model
In your application, you usually have `User` model.
```ruby
class User < ActiveRecord::Base
include Ez::Permissions::Model
enduser = User.first
# User model become permission model
user.roles #=> [application level roles]
user.assigned_roles #=> [user owned roles, global and scoped]
user.permissions #=> [user available permissions through assigned_roles]
```## API
**Please, do not use direct rails code like:** `Ez::Permissions::Permission.create(name: 'admin')`
Instead you should use `Ez::Permissions` public API. Please, extend your custom module with `API` mixin
```ruby
# Use engine facade methods
Ez::Permissions::API# or extend your own module and keep your code clean
module Permissions
extend Ez::Permissions::API::Roles
extend Ez::Permissions::API::Permissions
extend Ez::Permissions::API::Models
extend Ez::Permissions::API::Authorize
end
```### Roles
```ruby
# Create regular role
Permissions.create_role(:user)
Permissions.create_role(:admin)# List all roles
Permissions.list_roles # => [# false
# Because user has scoped role in the project and don't has global role.# and for simple cases you can always ask if user can something
Permissions.can?(user, :create, :users) => # true
Permissions.can?(user, :create, :users, scoped: project) => # false
```### Caching user permissions
If in one HTTP request (e.g. navigation menu rendering) you don't want to hit the database with dozens of queries, you can cache all user permission in a hash
```ruby
user_permissions = Permissions.model_permissions(user)
user_permissions # => # { :read_users => true}# and the in your code just fetch by the key:
if user_permissions.permissions_map[:read_users]
# execute authorized code
end# or user #can? and #authorize! helper methods
user_permissions.can?(:read, :users) # => true
user_permissions.can?(:create, :users) # => false
user_permissions.can?(:create, :users, scoped: project) # => false
user_permissions.authorize!(:create, :users) # => raise Ez::Permissions::NotAuthorized
```### Testing
EzPermissions ships with bunch of RSpec helper methods that helps mock permission.
For large test suite (more than 5000 specs) it saves up to 30% of test runs time.Add test helpers to your rspec config
```ruby
require 'ez/permissions/rspec_helpers'RSpec.configure do |config|
config.include Ez::Permissions::RSpecHelpers
end```
Examples:
```ruby
user = User.first
project = Project.first# Mock role, model role, all permissions and user assigned role. DB will not be touched.
assume_user_permissions(user, :admin, :all)# In case when you need real records data to be stored in DB, use
seed_user_permissions(user, :admin, :create, :update, :users, scoped: project)# Mock role and who possible could has or not this role
mock_role(:manager, has: [user], has_not: [User.second], scoped: project)# Mock model (user) role assignment
mock_model_role(:worker, user)# Mock permissions for resources/action
mock_permission(:users, :create)
```### Cleanup redundant permissions
If you changed your permissions DSL and removed redundant resources and actions```sh
rake ez:permissions:outdated # display list of outdated permissions
rake ez:permissions:cleanup # remove outdated permissions from the DB
```### Keep it explicit!
You can wonder, why we just not add authorization methods to user instance, like:
```ruby
user.can?(:something)
```
Because ez-permissions engine don't want pollute your application and keep implementation isolated in external modules.
Of course, you can use them as mixins, but it's up to you.## Understanding scoped roles
- System have many roles
- User has many assigned roles
- User can has role in scope of some resource (Project, Company, Business, etc.)
- User can has role in global scope (without scope)
- If user want access data in scope of resource - user must has assigned role scoped for this resource
- If user want access data in global scope - user must has assigned role without any scoped resource (global role)
- User with global role - can't access scoped resources.
- User with scoped role - can't access global resources.## TODO
- [ ] Add helper methods for seed grant permissions## Contributing
Contribution directions go here.## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).