
Product
Rust Support Now in Beta
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.
Add this line to your application's Gemfile:
gem 'controller_policies', '~> 1.0'
This gem takes advantage of placing all your policy definitions for controllers in one folder (app/policies
). To generate a policy, run:
rails g policy_definition my/namespace
This will generate a file: app/policies/my/namespace/definitions.rb
For controllers without a namespace (root-level controllers), you can generate a root-level definitions file:
rails g policy_definition root
# or simply
rails g policy_definition
This will generate a file: app/policies/definitions.rb
The developer should edit this file and add the policies for the app. It is important to note that the location of the definitions file should reflect the namespace of the associated controllers.
actions
keyThe actions
key is an array of strings that contain a list of supported controller actions for automation of policy checking.
For example, you have this definition:
module Policies
module Base
DEFINITIONS = {
code: 'policy_code',
name: 'Policy Name',
description: 'I am a policy.',
actions: ['feature_app/users', 'data_app/products#index', 'subscriptions']
}
end
end
The above definition will have enforced policies on Base::FeatureApp::UsersController
(all actions), Base::DataApp::ProductsController
(index
action) and Base::SubscriptionController
.
For root-level controllers (controllers without a namespace), you can define policies directly in the Policies
module:
module Policies
DEFINITIONS = [
{
code: 'user_management',
name: 'User Management',
description: 'Allows user management operations',
actions: ['users', 'profiles#show', 'dashboard']
}
]
end
The above definition will have enforced policies on UsersController
(all actions), ProfilesController
(show
action) and DashboardController
.
Do note that the actions
array implement Regular Expression Matching. That means that if you have multiple controllers with the same name on their parent namespace, the parent will be matched first. To avoid this problem, simply add the namespace to match the intended child instead.
module Policies
module Base
DEFINITIONS = {
code: 'policy_code',
name: 'Policy Name',
description: 'I am a policy.',
actions: ['feature_app/users', 'another_base/data_app/products#index', 'base/subscriptions']
}
end
end
Simply add the line has_enforced_policies
, and pass a block with one argument (ability_code
), or override the ability?(ability_code)
method.
class MyController < ApplicationController
has_enforced_policies do |ability_code|
render 'unauthorized' unless current_user.abilities.include? ability_code
end
# ...
end
class MyController < ApplicationController
has_enforced_policies
def ability?(ability_code)
render 'unauthorized' unless current_user.abilities.include? ability_code
end
# ...
end
It is recommended to use render
or redirect_to
within this block to prevent the controllers from executing the action when the ability did not exist in the data. The ability checking is done in a before_action
callback, hence using render
or redirect_to
will stop further controller actions. This is a Rails behavior.
Since storing abilities are very flexible and there are truly infinite ways of doing it, this gem did not support that feature. Instead, the developer must define their own ability checking.
There might be an event where there is a need to skip automatic policy enforcements in certain actions. As explained above, the policy enforcement is done in a before_action
callback. To skip a policy enforcement, simply use the skip_before_action :check_abilities_by_definition
method from Rails. The :only
and :except
options are also available to filter actions.
class MyOtherController < MyController
skip_before_action :check_abilities_by_definition, only: [:new, :edit]
# ...
end
The Ability class is a model for abilities that come from the definition files.
Get all abilities from all definitions.
Ability.all
Get all ability codes from all definitions.
Ability.all_codes
Filter abilities based on namespace. queries
can be an array of Strings, Modules or Classes.
Ability.where(Policies::FeatureOne, Policies::FeatureTwo, Policies::FeatureOne::SubFeatureA)
Ability.where('/feature_one', '/feature_two', '/feature_one/sub_feature_a')
Match abilities based on a matching string or regex. The matcher is based on the namespace. expression
can be a Regexp or String.
Ability.match(/Policies::FeatureOne(::)?(.)*/)
The code of the ability.
ability.code
The name of the ability.
ability.name
The description of the ability.
ability.description
Controller actions that the ability can check against.
ability.actions
Bug reports and pull requests are welcome on GitHub at https://github.com/tieeeeen1994/controller_policies. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
The gem is available as open source under the terms of the MIT License.
Everyone interacting in the ControllerPolicies project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.
FAQs
Unknown package
We found that controller_policies demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.
Product
Socket Fix 2.0 brings targeted CVE remediation, smarter upgrade planning, and broader ecosystem support to help developers get to zero alerts.
Security News
Socket CEO Feross Aboukhadijeh joins Risky Business Weekly to unpack recent npm phishing attacks, their limited impact, and the risks if attackers get smarter.