Permits
offers an ActiveRecord-based permissions system for Rails applications, with historic records (via Timelines::Ephemeral
) and a simple DSL for defining permissions and policies.
Set up the valid permits
values (roles/actions/levels):
# config/initializers/permits.rb
# user levels example
::Permits.configure do |config|
config.permit = %i[admin user super_user]
end
# user actions example
::Permits.configure do |config|
config.actions = %i[read write destroy]
end
# mixed example
::Permits.configure do |config|
config.roles = %i[admin super_user read write destroy]
end
Create a Permission
record to track an Owner's
access to a selected Resource
, and define the action/level that the Owner
is permitted to work with the Resource
:
Give a User
permission to do write
to a certain Resource
:
Permits::Permission.create(owner: owner, resource: resource, action: :write)
The Permits::Policy::Base
class provides two different class methods for authorizing access:
Permits::Policy::Base.authorize!
will raise anPermits::Policy::UnauthorizedError
if theOwner
does not have the required permissionPermits::Policy::Base.authorized?
will returntrue
if theOwner
has the required permission, andfalse
if not
Permits::Permission.create(owner: owner, resource: resource, action: :write)
Permits::Policy::Base.authorize!(owner, resource, :write) # => true
Permits::Policy::Base.authorize!(owner, resource, :read) # => Permits::Policy::UnauthorizedError
Permits::Policy::Base.authorize!(owner, other_resource, :write) # => Permits::Policy::UnauthorizedError
Permits::Policy::Base.authorized?(owner, resource, :write) # => true
Permits::Policy::Base.authorized?(owner, resource, :read) # => false
Permits::Policy::Base.authorized?(owner, resource, :write) # => false
You can define custom policies by subclassing Permits::Policy::Base
and defining an #{action_name}?
method. Furthermore you can still leverage the has_action_permissions?
method from the Base
class to perform the check that they have a suitable Permission
record while also making additional checks (such as checking they are an Admin, or checking that a resource is active/actionable)
# config/initializers/permits.rb
::Permits.configure do |config|
config.roles = %i[some_action]
end
# app/models/custom_policy.rb
class CustomPolicy < Permits::Policy::Base
def some_action?
owner == resource.owner || owner.admin?
end
def some_action_with_level?
owner.admin? && has_action_permissions?(:some_action)
end
end
# irb
Permits::Permission.create(owner: owner, resource: resource, action: :some_action)
CustomPolicy.authorize!(owner, resource, :some_action)
CustomPolicy.authorized?(owner, resource, :some_action)
Permits
provides a simple pre-permissioned Invite system, with a Permits::Invite
model, a Permits::Form::NewInviteForm
form object for creating new invites, and a Permits::Form::InviteForm
form object for accepting, declining and revoking invites. Invites can be pre-assigned permissions, so that when the invite is accepted, the invitee is automatically granted the permissions.
group = Group.create(name: "Group 1")
group_user = User.create(name: "User 1")
user_permission = Permits::Permission.create(owner: group_user, resource: group, action: :super_user)
NewInviteForm.new(
invited_by: group_user,
email: "invitee@email-address.com",
permission_attributes: {
group => [:read, :edit]
}
).save!
Add this line to your application's Gemfile:
gem "permits"
And then execute:
$ bundle
Or install it yourself as:
$ gem install permits
Install the required files to your project:
$ rails generate permits:install
Contribution directions go here.
The gem is available as open source under the terms of the MIT License.