action_policy 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +85 -0
- data/.travis.yml +25 -2
- data/CHANGELOG.md +7 -0
- data/Gemfile +12 -3
- data/README.md +71 -12
- data/Rakefile +9 -1
- data/action_policy.gemspec +11 -5
- data/docs/.nojekyll +0 -0
- data/docs/CNAME +1 -0
- data/docs/README.md +46 -0
- data/docs/_sidebar.md +19 -0
- data/docs/aliases.md +54 -0
- data/docs/assets/docsify.min.js +1 -0
- data/docs/assets/fonts/FiraCode-Medium.woff +0 -0
- data/docs/assets/fonts/FiraCode-Regular.woff +0 -0
- data/docs/assets/images/cache.png +0 -0
- data/docs/assets/images/cache.svg +70 -0
- data/docs/assets/images/layer.png +0 -0
- data/docs/assets/images/layer.svg +92 -0
- data/docs/assets/prism-ruby.min.js +1 -0
- data/docs/assets/styles.css +317 -0
- data/docs/assets/vue.min.css +1 -0
- data/docs/authorization_context.md +33 -0
- data/docs/caching.md +262 -0
- data/docs/custom_lookup_chain.md +48 -0
- data/docs/custom_policy.md +51 -0
- data/docs/favicon.ico +0 -0
- data/docs/i18n.md +3 -0
- data/docs/index.html +25 -0
- data/docs/instrumentation.md +3 -0
- data/docs/lookup_chain.md +16 -0
- data/docs/namespaces.md +69 -0
- data/docs/non_rails.md +29 -0
- data/docs/pre_checks.md +57 -0
- data/docs/quick_start.md +102 -0
- data/docs/rails.md +110 -0
- data/docs/reasons.md +67 -0
- data/docs/testing.md +116 -0
- data/docs/writing_policies.md +55 -0
- data/gemfiles/jruby.gemfile +5 -0
- data/gemfiles/rails42.gemfile +5 -0
- data/gemfiles/railsmaster.gemfile +6 -0
- data/lib/action_policy.rb +34 -2
- data/lib/action_policy/authorizer.rb +28 -0
- data/lib/action_policy/base.rb +24 -0
- data/lib/action_policy/behaviour.rb +94 -0
- data/lib/action_policy/behaviours/memoized.rb +56 -0
- data/lib/action_policy/behaviours/namespaced.rb +80 -0
- data/lib/action_policy/behaviours/policy_for.rb +23 -0
- data/lib/action_policy/behaviours/thread_memoized.rb +54 -0
- data/lib/action_policy/ext/module_namespace.rb +21 -0
- data/lib/action_policy/ext/policy_cache_key.rb +67 -0
- data/lib/action_policy/ext/string_constantize.rb +23 -0
- data/lib/action_policy/lookup_chain.rb +84 -0
- data/lib/action_policy/policy/aliases.rb +69 -0
- data/lib/action_policy/policy/authorization.rb +91 -0
- data/lib/action_policy/policy/cache.rb +74 -0
- data/lib/action_policy/policy/cached_apply.rb +28 -0
- data/lib/action_policy/policy/core.rb +64 -0
- data/lib/action_policy/policy/defaults.rb +37 -0
- data/lib/action_policy/policy/pre_check.rb +210 -0
- data/lib/action_policy/policy/reasons.rb +109 -0
- data/lib/action_policy/rails/channel.rb +15 -0
- data/lib/action_policy/rails/controller.rb +90 -0
- data/lib/action_policy/railtie.rb +74 -0
- data/lib/action_policy/rspec.rb +3 -0
- data/lib/action_policy/rspec/be_authorized_to.rb +93 -0
- data/lib/action_policy/rspec/pundit_syntax.rb +48 -0
- data/lib/action_policy/test_helper.rb +46 -0
- data/lib/action_policy/testing.rb +64 -0
- data/lib/action_policy/version.rb +3 -1
- metadata +115 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a039b5a6e9cdfa9821dfc8ac42d0e78f52239379d532e75e64e9a136123971f1
|
4
|
+
data.tar.gz: b756862f053a8ab07cc957813231988a8447dce8d2655a8d1f0171dda47ab957
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6855bd1057d2153300d0cc2d92fc7091bab8a49c6ac4d67fd805372e0fdb0caabb6dd38fc30f28f4bcc74d83b8e37d3dfc96e0410e7616f8e7ada2949c69d6e
|
7
|
+
data.tar.gz: b5ee9d56785412b634f405954b7bd456536d1564d31d8c0927926d045068ef67125e42b0674cdda574f6fefc366f30c94fb798e4f641235e95a31aa2c4f9a65c
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-md
|
3
|
+
|
4
|
+
AllCops:
|
5
|
+
Include:
|
6
|
+
- 'lib/**/*.rb'
|
7
|
+
- 'lib/**/*.rake'
|
8
|
+
- 'test/**/*.rb'
|
9
|
+
Exclude:
|
10
|
+
- 'bin/**/*'
|
11
|
+
- 'gemfiles/**/*'
|
12
|
+
- 'test/dummy/**/*'
|
13
|
+
- 'vendor/**/*'
|
14
|
+
- 'tmp/**/*'
|
15
|
+
DisplayCopNames: true
|
16
|
+
StyleGuideCopsOnly: false
|
17
|
+
TargetRubyVersion: 2.3
|
18
|
+
|
19
|
+
Rails:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Bundler/OrderedGems:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
Lint/Void:
|
26
|
+
Exclude:
|
27
|
+
- '**/*.md'
|
28
|
+
|
29
|
+
Lint/DuplicateMethods:
|
30
|
+
Exclude:
|
31
|
+
- '**/*.md'
|
32
|
+
|
33
|
+
Naming/FileName:
|
34
|
+
Exclude:
|
35
|
+
- 'Rakefile'
|
36
|
+
- 'Gemfile'
|
37
|
+
- '**/*.md'
|
38
|
+
|
39
|
+
Naming/UncommunicativeMethodParamName:
|
40
|
+
Enabled: false
|
41
|
+
|
42
|
+
Naming/VariableNumber:
|
43
|
+
Exclude:
|
44
|
+
- 'test/**/*.rb'
|
45
|
+
|
46
|
+
Style/SymbolArray:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
Style/Documentation:
|
50
|
+
Exclude:
|
51
|
+
- 'test/**/*.rb'
|
52
|
+
- '**/*.md'
|
53
|
+
|
54
|
+
Style/StringLiterals:
|
55
|
+
EnforcedStyle: double_quotes
|
56
|
+
|
57
|
+
Style/RegexpLiteral:
|
58
|
+
Enabled: false
|
59
|
+
|
60
|
+
Style/NumericPredicate:
|
61
|
+
Enabled: false
|
62
|
+
|
63
|
+
Style/Lambda:
|
64
|
+
Enabled: false
|
65
|
+
|
66
|
+
Layout/SpaceInsideStringInterpolation:
|
67
|
+
EnforcedStyle: no_space
|
68
|
+
|
69
|
+
Lint/AmbiguousRegexpLiteral:
|
70
|
+
Enabled: false
|
71
|
+
|
72
|
+
Metrics/LineLength:
|
73
|
+
Max: 100
|
74
|
+
|
75
|
+
Metrics/AbcSize:
|
76
|
+
Exclude:
|
77
|
+
- 'test/**/*.rb'
|
78
|
+
|
79
|
+
Metrics/BlockLength:
|
80
|
+
Exclude:
|
81
|
+
- 'spec/**/*.rb'
|
82
|
+
|
83
|
+
Metrics/MethodLength:
|
84
|
+
Exclude:
|
85
|
+
- 'test/**/*.rb'
|
data/.travis.yml
CHANGED
@@ -1,5 +1,28 @@
|
|
1
1
|
sudo: false
|
2
2
|
language: ruby
|
3
3
|
rvm:
|
4
|
-
- 2.
|
5
|
-
|
4
|
+
- 2.5.0
|
5
|
+
|
6
|
+
notifications:
|
7
|
+
email: false
|
8
|
+
|
9
|
+
matrix:
|
10
|
+
fast_finish: true
|
11
|
+
include:
|
12
|
+
- rvm: ruby-head
|
13
|
+
gemfile: gemfiles/railsmaster.gemfile
|
14
|
+
- rvm: jruby-9.1.0.0
|
15
|
+
gemfile: gemfiles/jruby.gemfile
|
16
|
+
- rvm: 2.5.0
|
17
|
+
gemfile: Gemfile
|
18
|
+
- rvm: 2.4.3
|
19
|
+
gemfile: Gemfile
|
20
|
+
- rvm: 2.3.1
|
21
|
+
gemfile: gemfiles/rails42.gemfile
|
22
|
+
allow_failures:
|
23
|
+
- rvm: 2.3.1
|
24
|
+
gemfile: gemfiles/rails42.gemfile
|
25
|
+
- rvm: ruby-head
|
26
|
+
gemfile: gemfiles/railsmaster.gemfile
|
27
|
+
- rvm: jruby-9.1.0.0
|
28
|
+
gemfile: gemfiles/jruby.gemfile
|
data/CHANGELOG.md
ADDED
data/Gemfile
CHANGED
@@ -1,6 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
source "https://rubygems.org"
|
4
4
|
|
5
|
-
# Specify your gem's dependencies in action_policy.gemspec
|
6
5
|
gemspec
|
6
|
+
|
7
|
+
gem "pry-byebug", platform: :mri
|
8
|
+
|
9
|
+
local_gemfile = File.join(__dir__, "Gemfile.local")
|
10
|
+
|
11
|
+
if File.exist?(local_gemfile)
|
12
|
+
eval(File.read(local_gemfile)) # rubocop:disable Security/Eval
|
13
|
+
else
|
14
|
+
gem "rails", "~> 5.0"
|
15
|
+
end
|
data/README.md
CHANGED
@@ -1,39 +1,98 @@
|
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/action_policy.svg)](https://badge.fury.io/rb/action_policy)
|
2
|
+
[![Build Status](https://travis-ci.org/palkan/action_policy.svg?branch=master)](https://travis-ci.org/palkan/action_policy)
|
3
|
+
[![Documentation](https://img.shields.io/badge/docs-link-brightgreen.svg)](http://actionpolicy.evilmartians.io)
|
4
|
+
|
1
5
|
# ActionPolicy
|
2
6
|
|
3
|
-
|
7
|
+
Action Policy is an authorization framework for Ruby and Rails applications.
|
8
|
+
|
9
|
+
📑 [Documentation][]
|
4
10
|
|
5
|
-
|
11
|
+
<a href="https://evilmartians.com/?utm_source=action_policy">
|
12
|
+
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
|
6
13
|
|
7
14
|
## Installation
|
8
15
|
|
9
|
-
Add this line to your application's Gemfile
|
16
|
+
Add this line to your application's `Gemfile`:
|
10
17
|
|
11
18
|
```ruby
|
12
|
-
gem
|
19
|
+
gem "action_policy"
|
13
20
|
```
|
14
21
|
|
15
22
|
And then execute:
|
16
23
|
|
17
24
|
$ bundle
|
18
25
|
|
19
|
-
|
26
|
+
## Usage
|
20
27
|
|
21
|
-
|
28
|
+
Action Policy relies on resource-specific policy classes (just like [Pundit](https://github.com/varvet/pundit)).
|
22
29
|
|
23
|
-
|
30
|
+
First, add an application-specific `ApplicationPolicy` with some global configuration to inherit from:
|
24
31
|
|
25
|
-
|
32
|
+
```ruby
|
33
|
+
class ApplicationPolicy < ActionPolicy::Base
|
34
|
+
end
|
35
|
+
```
|
26
36
|
|
27
|
-
|
37
|
+
Then write a policy for a resource. For example:
|
28
38
|
|
29
|
-
|
39
|
+
```ruby
|
40
|
+
class PostPolicy < ApplicationPolicy
|
41
|
+
# everyone can see any post
|
42
|
+
def show?
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
def update?
|
47
|
+
# `user` is a performing subject,
|
48
|
+
# `record` is a target object (post we want to update)
|
49
|
+
user.admin? || (user.id == record.user_id)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
```
|
30
53
|
|
31
|
-
|
54
|
+
Now you can easily add authorization to your Rails\* controller:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
class PostsController < ApplicationController
|
58
|
+
def update
|
59
|
+
@post = Post.find(params[:id])
|
60
|
+
authorize! @post
|
61
|
+
|
62
|
+
if @post.update(post_params)
|
63
|
+
redirect_to @post
|
64
|
+
else
|
65
|
+
render :edit
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
\* See [Non-Rails Usage](docs/non_rails.md) on how to add `authorize!` to any Ruby project.
|
72
|
+
|
73
|
+
|
74
|
+
When authorization is successful (i.e., the corresponding rule returns `true`), nothing happens, but in case of authorization failure `ActionPolicy::Unauthorized` error is raised.
|
75
|
+
|
76
|
+
There is also an `allowed_to?` method which returns `true` or `false`, and could be used, in views, for example:
|
77
|
+
|
78
|
+
```erb
|
79
|
+
<% @posts.each do |post| %>
|
80
|
+
<li><%= post.title %>
|
81
|
+
<% if allowed_to?(:edit?, post) %>
|
82
|
+
= link_to post, "Edit"
|
83
|
+
<% end %>
|
84
|
+
</li>
|
85
|
+
<% end %>
|
86
|
+
```
|
87
|
+
|
88
|
+
Read more in our [Documentation][].
|
32
89
|
|
33
90
|
## Contributing
|
34
91
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
92
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/palkan/action_policy.
|
36
93
|
|
37
94
|
## License
|
38
95
|
|
39
96
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
97
|
+
|
98
|
+
[Documentation]: http://actionpolicy.evilmartians.io
|
data/Rakefile
CHANGED
@@ -1,5 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "bundler/gem_tasks"
|
2
4
|
require "rake/testtask"
|
5
|
+
require "rubocop/rake_task"
|
6
|
+
require "rspec/core/rake_task"
|
7
|
+
|
8
|
+
RuboCop::RakeTask.new
|
9
|
+
|
10
|
+
RSpec::Core::RakeTask.new(:spec)
|
3
11
|
|
4
12
|
Rake::TestTask.new(:test) do |t|
|
5
13
|
t.libs << "test"
|
@@ -7,4 +15,4 @@ Rake::TestTask.new(:test) do |t|
|
|
7
15
|
t.test_files = FileList["test/**/*_test.rb"]
|
8
16
|
end
|
9
17
|
|
10
|
-
task :
|
18
|
+
task default: [:rubocop, :test, :spec]
|
data/action_policy.gemspec
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require "action_policy/version"
|
5
6
|
|
@@ -9,8 +10,8 @@ Gem::Specification.new do |spec|
|
|
9
10
|
spec.authors = ["Vladimir Dementyev"]
|
10
11
|
spec.email = ["dementiev.vm@gmail.com"]
|
11
12
|
|
12
|
-
spec.summary = "
|
13
|
-
spec.description = "
|
13
|
+
spec.summary = "Authorization framework for Ruby/Rails application"
|
14
|
+
spec.description = "Authorization framework for Ruby/Rails application"
|
14
15
|
spec.homepage = "https://github.com/palkan/action-policy"
|
15
16
|
spec.license = "MIT"
|
16
17
|
|
@@ -20,7 +21,12 @@ Gem::Specification.new do |spec|
|
|
20
21
|
|
21
22
|
spec.require_paths = ["lib"]
|
22
23
|
|
24
|
+
spec.required_ruby_version = ">= 2.3.0"
|
25
|
+
|
23
26
|
spec.add_development_dependency "bundler", "~> 1.15"
|
24
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
25
27
|
spec.add_development_dependency "minitest", "~> 5.0"
|
28
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
29
|
+
spec.add_development_dependency "rspec", "~> 3.3"
|
30
|
+
spec.add_development_dependency "rubocop", "~> 0.51"
|
31
|
+
spec.add_development_dependency "rubocop-md", "~> 0.2"
|
26
32
|
end
|
data/docs/.nojekyll
ADDED
File without changes
|
data/docs/CNAME
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
actionpolicy.evilmartians.io
|
data/docs/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/action_policy.svg)](https://badge.fury.io/rb/action_policy)
|
2
|
+
[![Build Status](https://travis-ci.org/palkan/action_policy.svg?branch=master)](https://travis-ci.org/palkan/action_policy)
|
3
|
+
|
4
|
+
## Action Policy
|
5
|
+
|
6
|
+
> Action Policy is an authorization framework for Ruby and Rails applications.
|
7
|
+
|
8
|
+
## What is it?
|
9
|
+
|
10
|
+
_Authorization_ is an act of giving **someone** official
|
11
|
+
permission to **do something** (to not be confused with [_authentication_](https://en.wikipedia.org/wiki/Authentication)).
|
12
|
+
|
13
|
+
Action Policy provides flexible tools to build an _authorization layer_ for your application.
|
14
|
+
|
15
|
+
<div class="chart-container">
|
16
|
+
<img src="assets/images/layer.svg" alt="Authorization layer" width="80%">
|
17
|
+
</div>
|
18
|
+
|
19
|
+
**NOTE:** Action Policy does not force you to use a specific authorization model (i.e., roles, permissions, etc.) and does not provide one. It only answers a single question: **How to verify access?**
|
20
|
+
|
21
|
+
## History
|
22
|
+
|
23
|
+
Action Policy gem is an _extraction_-kind of a library. Most of the code has been used in production for several years in different [Evil Martians][] projects.
|
24
|
+
|
25
|
+
We have decided to collect all our authorization techniques and pack them into a standalone gem–and that is how Action Policy was born!
|
26
|
+
|
27
|
+
## What about the existing solutions?
|
28
|
+
|
29
|
+
Why did we decide to build our own authorization gem instead of using the existing solutions, such as [Pundit][] and [CanCanCan][]?
|
30
|
+
|
31
|
+
**TL;DR they didn't solve all of our problems.**
|
32
|
+
|
33
|
+
[Pundit][] has been our framework of choice for a long time. Being too _dead-simple_, it required a lot of hacking to fulfill business logic requirements.
|
34
|
+
|
35
|
+
These _hacks_ later become into Action Policy (initially, we even called it "Pundit, re-visited").
|
36
|
+
|
37
|
+
We also took a few ideas from [CanCanCan][]—such as default rules and rule aliases.
|
38
|
+
|
39
|
+
It is also worth noting that Action Policy (despite from a _Railsy_ name) is designed to be **Rails-free**. On the other hand, it contains some Rails-specific extensions and seamlessly integrates into the framework.
|
40
|
+
|
41
|
+
<a href="https://evilmartians.com/?utm_source=action_policy">
|
42
|
+
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
|
43
|
+
|
44
|
+
[CanCanCan]: https://github.com/CanCanCommunity/cancancan
|
45
|
+
[Pundit]: https://github.com/varvet/pundit
|
46
|
+
[Evil Martians]: https://evilmartians.com
|
data/docs/_sidebar.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
* Getting Started
|
2
|
+
* [Quick Start](quick_start.md)
|
3
|
+
* [Writing Policies](writing_policies.md)
|
4
|
+
* [Rails Integration](rails.md)
|
5
|
+
* [Non-Rails Usage](non_rails.md)
|
6
|
+
* [Testing](testing.md)
|
7
|
+
* Features
|
8
|
+
* [Policy Lookup](lookup_chain.md)
|
9
|
+
* [Authorization Context](authorization_context.md)
|
10
|
+
* [Aliases](aliases.md)
|
11
|
+
* [Pre-Checks](pre_checks.md)
|
12
|
+
* [Caching](caching.md)
|
13
|
+
* [Namespaces](namespaces.md)
|
14
|
+
* [Failure Reasons](reasons.md)
|
15
|
+
* [Instrumentation](instrumentation.md)
|
16
|
+
* [I18n Support](i18n.md)
|
17
|
+
* Customize
|
18
|
+
* [Base Policy](custom_policy.md)
|
19
|
+
* [Lookup Chain](custom_lookup_chain.md)
|
data/docs/aliases.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# Rule Aliases
|
2
|
+
|
3
|
+
Action Policy allows you to add rule aliases. It is useful when you rely on _implicit_ rules in controllers. For example:
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
class PostsController < ApplicationController
|
7
|
+
before_action :load_post, only: [:edit, :update, :destroy]
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def load_post
|
12
|
+
@post = Post.find(params[:id])
|
13
|
+
# depending on action, an `edit?`, `update?` or `destroy?`
|
14
|
+
# rule would be applied
|
15
|
+
authorize! @post
|
16
|
+
end
|
17
|
+
end
|
18
|
+
```
|
19
|
+
|
20
|
+
In your policy, you can create aliases to avoid duplication:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
class PostPolicy < ApplicationPolicy
|
24
|
+
alias_rule :edit?, :destroy?, to: :update?
|
25
|
+
end
|
26
|
+
```
|
27
|
+
|
28
|
+
**NOTE**: `alias_rule` is available only if you inherit from `ActionPolicy::Base` or include `ActionPolicy::Policy::Aliases` into your `ApplicationPolicy`.
|
29
|
+
|
30
|
+
**Why not just use Ruby's `alias`?**
|
31
|
+
|
32
|
+
An alias created with `alias_rule` is resolved at _authorization time_ (during an `authorize!` or `allowed_to?` call), and it does not add an alias method to the class.
|
33
|
+
|
34
|
+
That allows us to write tests easier, as we should only test the rule, not the alias–and to leverage [caching](caching.md) better.
|
35
|
+
|
36
|
+
By default, `ActionPolicy::Base` adds one alias: `alias_rule :new?, to: :create?`.
|
37
|
+
|
38
|
+
## Default rule
|
39
|
+
|
40
|
+
You can add a _default_ rule–the rule that would be applied if the rule specified during authorization is missing (like a "wildcard" alias):
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
class PostPolicy < ApplicationPolicy
|
44
|
+
default_rule :manage?
|
45
|
+
|
46
|
+
def manage?
|
47
|
+
# ...
|
48
|
+
end
|
49
|
+
end
|
50
|
+
```
|
51
|
+
|
52
|
+
Now when you call `authorize! post` with any rule not explicitly defined in policy class, the `manage?` rule is applied.
|
53
|
+
|
54
|
+
By default, `ActionPolicy::Base` sets `manage?` as a default rule.
|