https://github.com/hopsoft/perm
Simple authorization/permission management in Ruby
https://github.com/hopsoft/perm
authorization permissions ruby
Last synced: about 1 year ago
JSON representation
Simple authorization/permission management in Ruby
- Host: GitHub
- URL: https://github.com/hopsoft/perm
- Owner: hopsoft
- License: mit
- Created: 2014-11-09T07:45:17.000Z (over 11 years ago)
- Default Branch: master
- Last Pushed: 2018-11-12T21:42:02.000Z (over 7 years ago)
- Last Synced: 2025-03-30T07:12:11.469Z (about 1 year ago)
- Topics: authorization, permissions, ruby
- Language: Ruby
- Homepage:
- Size: 22.5 KB
- Stars: 14
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
[](http://blog.codinghorror.com/the-best-code-is-no-code-at-all/)
[](https://codeclimate.com/github/hopsoft/perm/maintainability)
[](https://travis-ci.org/hopsoft/perm)
[](https://coveralls.io/r/hopsoft/perm?branch=master)
[](http://rubygems.org/gems/perm)
# Perm
Incredibly simple permission management i.e. authorization.
## Quickstart
```sh
gem install perm
```
### Setup
Let's create a simple example with __users__ & __posts__.
```ruby
class User
attr_reader :roles, :posts
def initialize(roles: [])
@roles = roles
@posts = []
end
end
```
```ruby
class Post
attr_reader :user, :title
attr_accessor :published
def initialize(user:, title:)
@user = user
@title = title
@user.posts << self
end
end
```
Once our basic classes have be defined, we can create an authorized user to manage permissions.
```ruby
class AuthorizedUser < Perm::Authorized
def can_read?(post)
return true if user.roles.include?(:admin)
return true if user.roles.include?(:editor)
return true if user == post.user
post.published
end
def can_update?(post)
return true if user.roles.include?(:admin)
return true if user.roles.include?(:editor)
user == post.user
end
def can_delete?(post)
return true if user.roles.include?(:admin)
user == post.user
end
end
```
Authorized users do the following.
- wrap user objects — _somewhat like the presenter pattern_
- add behavior to wrapped users
- respond to authorization methods defined as `can_OPERATION?`
- secure by default _i.e. authorization checks return false until implemented_
### Usage
#### Create some users
```ruby
mary = User.new(roles: [:admin])
john = User.new(roles: [:editor, :writer])
beth = User.new(roles: [:writer])
drew = User.new
```
#### Create a post
```ruby
post = Post.new(user: beth, title: "Authorization made easy")
```
#### Wrap each user with an authorizer
```ruby
authorized_mary = AuthorizedUser.new(mary)
authorized_john = AuthorizedUser.new(john)
authorized_beth = AuthorizedUser.new(beth)
authorized_drew = AuthorizedUser.new(drew)
# wrapped users continue to act like users
authorized_beth.posts # => [# true
authorized_mary.can_update?(post) # => true
authorized_mary.can_delete?(post) # => true
authorized_john.can_read?(post) # => true
authorized_john.can_update?(post) # => true
authorized_john.can_delete?(post) # => false
authorized_beth.can_read?(post) # => true
authorized_beth.can_update?(post) # => true
authorized_beth.can_delete?(post) # => true
authorized_drew.can_read?(post) # => false
authorized_drew.can_update?(post) # => false
authorized_drew.can_delete?(post) # => false
post.published = true
authorized_drew.can_read?(post) # => true
# we can also check unimplemented permissions
authorized_mary.can_create?(post) # => false
authorized_john.can_view?(post) # => false
```