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
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionPolicy # :nodoc:
|
4
|
+
require "action_policy/rails/controller"
|
5
|
+
require "action_policy/rails/channel"
|
6
|
+
|
7
|
+
class Railtie < ::Rails::Railtie # :nodoc:
|
8
|
+
# Provides Rails-specific configuration,
|
9
|
+
# accessible through `Rails.application.config.action_policy`
|
10
|
+
module Config
|
11
|
+
class << self
|
12
|
+
# Define whether we need to extend ApplicationController::Base
|
13
|
+
# with the default authorization logic
|
14
|
+
attr_accessor :auto_inject_into_controller
|
15
|
+
|
16
|
+
# Define whether we want to specify `current_user` as
|
17
|
+
# the default authorization context in controller
|
18
|
+
attr_accessor :controller_authorize_current_user
|
19
|
+
|
20
|
+
# Define whether we need to include ActionCable::Channel::Base
|
21
|
+
# with the default authorization logic
|
22
|
+
attr_accessor :auto_inject_into_channel
|
23
|
+
|
24
|
+
# Define whether we want to specify `current_user` as
|
25
|
+
# the default authorization context in channels
|
26
|
+
attr_accessor :channel_authorize_current_user
|
27
|
+
|
28
|
+
def cache_store=(store, *args)
|
29
|
+
if store.is_a?(Symbol)
|
30
|
+
store = ActiveSupport::Cache.lookup_store(
|
31
|
+
store, *args
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
ActionPolicy.cache_store = store
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
self.auto_inject_into_controller = true
|
40
|
+
self.controller_authorize_current_user = true
|
41
|
+
self.auto_inject_into_channel = true
|
42
|
+
self.channel_authorize_current_user = true
|
43
|
+
end
|
44
|
+
|
45
|
+
config.action_policy = Config
|
46
|
+
|
47
|
+
initializer "action_policy.clear_per_thread_cache" do |app|
|
48
|
+
app.executor.to_run { ActionPolicy::PerThreadCache.clear_all }
|
49
|
+
app.executor.to_complete { ActionPolicy::PerThreadCache.clear_all }
|
50
|
+
end
|
51
|
+
|
52
|
+
config.after_initialize do |_app|
|
53
|
+
ActiveSupport.on_load(:action_controller) do
|
54
|
+
next unless Rails.application.config.action_policy.auto_inject_into_controller
|
55
|
+
|
56
|
+
ActionController::Base.include ActionPolicy::Controller
|
57
|
+
|
58
|
+
next unless Rails.application.config.action_policy.controller_authorize_current_user
|
59
|
+
|
60
|
+
ActionController::Base.authorize :user, through: :current_user
|
61
|
+
end
|
62
|
+
|
63
|
+
ActiveSupport.on_load(:action_cable) do
|
64
|
+
next unless Rails.application.config.action_policy.auto_inject_into_channel
|
65
|
+
|
66
|
+
ActionCable::Channel::Base.include ActionPolicy::Channel
|
67
|
+
|
68
|
+
next unless Rails.application.config.action_policy.channel_authorize_current_user
|
69
|
+
|
70
|
+
ActionCable::Channel::Base.authorize :user, through: :current_user
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "action_policy/testing"
|
4
|
+
|
5
|
+
module ActionPolicy
|
6
|
+
module RSpec
|
7
|
+
# Authorization matcher `be_authorized_to`.
|
8
|
+
#
|
9
|
+
# Verifies that a block of code has been authorized using specific policy.
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# # in controller/request specs
|
14
|
+
# subject { patch :update, id: product.id }
|
15
|
+
#
|
16
|
+
# it "is authorized" do
|
17
|
+
# expect { subject }
|
18
|
+
# .to be_authorized_to(:manage?, product)
|
19
|
+
# .with(ProductPolicy)
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
class BeAuthorizedTo < ::RSpec::Matchers::BuiltIn::BaseMatcher
|
23
|
+
attr_reader :rule, :target, :policy, :actual_calls
|
24
|
+
|
25
|
+
def initialize(rule, target)
|
26
|
+
@rule = rule
|
27
|
+
@target = target
|
28
|
+
end
|
29
|
+
|
30
|
+
def with(policy)
|
31
|
+
@policy = policy
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def match(_expected, actual)
|
36
|
+
raise "This matcher only supports block expectations" unless actual.is_a?(Proc)
|
37
|
+
|
38
|
+
@policy ||= ::ActionPolicy.lookup(target)
|
39
|
+
|
40
|
+
begin
|
41
|
+
ActionPolicy::Testing::AuthorizeTracker.tracking { actual.call }
|
42
|
+
rescue ActionPolicy::Unauthorized # rubocop: disable Lint/HandleExceptions
|
43
|
+
# we don't want to care about authorization result
|
44
|
+
end
|
45
|
+
|
46
|
+
@actual_calls = ActionPolicy::Testing::AuthorizeTracker.calls
|
47
|
+
|
48
|
+
actual_calls.any? { |call| call.matches?(policy, rule, target) }
|
49
|
+
end
|
50
|
+
|
51
|
+
def does_not_match?(*)
|
52
|
+
raise "This matcher doesn't support negation"
|
53
|
+
end
|
54
|
+
|
55
|
+
def supports_block_expectations?
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
def failure_message
|
60
|
+
"expected #{formatted_record} " \
|
61
|
+
"to be authorized with #{policy}##{rule}, " \
|
62
|
+
"but #{actual_calls_message}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def actual_calls_message
|
66
|
+
if actual_calls.empty?
|
67
|
+
"no authorization calls have been made"
|
68
|
+
else
|
69
|
+
"the following calls were encountered:\n" \
|
70
|
+
"#{formatted_calls}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def formatted_calls
|
75
|
+
actual_calls.map do |acall|
|
76
|
+
" - #{acall.inspect}"
|
77
|
+
end.join("\n")
|
78
|
+
end
|
79
|
+
|
80
|
+
def formatted_record(record = target)
|
81
|
+
::RSpec::Support::ObjectFormatter.format(record)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
RSpec.configure do |config|
|
88
|
+
config.include(Module.new do
|
89
|
+
def be_authorized_to(rule, target)
|
90
|
+
ActionPolicy::RSpec::BeAuthorizedTo.new(rule, target)
|
91
|
+
end
|
92
|
+
end)
|
93
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionPolicy
|
4
|
+
module RSpec
|
5
|
+
# Adds Pundit-style syntax for testing policies
|
6
|
+
module PunditSyntax # :nodoc: all
|
7
|
+
module Matchers
|
8
|
+
extend ::RSpec::Matchers::DSL
|
9
|
+
|
10
|
+
matcher :permit do |user, record|
|
11
|
+
match do |policy|
|
12
|
+
permissions.all? do |permission|
|
13
|
+
policy.new(record, user: user).apply(permission)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module DSL
|
20
|
+
def permissions(*list, &block)
|
21
|
+
describe list.to_sentence do
|
22
|
+
let(:permissions) { list }
|
23
|
+
|
24
|
+
instance_eval(&block)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module PolicyExampleGroup
|
30
|
+
include Matchers
|
31
|
+
|
32
|
+
def self.included(base)
|
33
|
+
base.metadata[:type] = :policy
|
34
|
+
base.extend DSL
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
RSpec.configure do |config|
|
43
|
+
config.include(
|
44
|
+
ActionPolicy::RSpec::PunditSyntax::PolicyExampleGroup,
|
45
|
+
type: :policy,
|
46
|
+
example_group: { file_path: %r{spec/policies} }
|
47
|
+
)
|
48
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "action_policy/testing"
|
4
|
+
|
5
|
+
module ActionPolicy
|
6
|
+
# Provides assertions for policies usage
|
7
|
+
module TestHelper
|
8
|
+
# Asserts that the given policy was used to authorize the given target.
|
9
|
+
#
|
10
|
+
# def test_authorize
|
11
|
+
# assert_authorized_to(:show?, user, with: UserPolicy) do
|
12
|
+
# get :show, id: user.id
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# You can omit the policy (then it would be inferred from the target):
|
17
|
+
#
|
18
|
+
# assert_authorized_to(:show?, user) do
|
19
|
+
# get :show, id: user.id
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# rubocop: disable Metrics/MethodLength
|
23
|
+
def assert_authorized_to(rule, target, with: nil)
|
24
|
+
raise ArgumentError, "Block is required" unless block_given?
|
25
|
+
|
26
|
+
policy = with || ::ActionPolicy.lookup(target)
|
27
|
+
|
28
|
+
begin
|
29
|
+
ActionPolicy::Testing::AuthorizeTracker.tracking { yield }
|
30
|
+
rescue ActionPolicy::Unauthorized # rubocop: disable Lint/HandleExceptions
|
31
|
+
# we don't want to care about authorization result
|
32
|
+
end
|
33
|
+
|
34
|
+
actual_calls = ActionPolicy::Testing::AuthorizeTracker.calls
|
35
|
+
|
36
|
+
assert(
|
37
|
+
actual_calls.any? { |call| call.matches?(policy, rule, target) },
|
38
|
+
"Expected #{target.inspect} to be authorized with #{policy}##{rule}, " \
|
39
|
+
"but no such authorization has been made.\n" \
|
40
|
+
"Registered authorizations: " \
|
41
|
+
"#{actual_calls.empty? ? 'none' : actual_calls.map(&:inspect).join(',')}"
|
42
|
+
)
|
43
|
+
end
|
44
|
+
# rubocop: enable Metrics/MethodLength
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionPolicy
|
4
|
+
# Testing utils
|
5
|
+
module Testing
|
6
|
+
# Collects all Authorizer calls
|
7
|
+
module AuthorizeTracker
|
8
|
+
class Call # :nodoc:
|
9
|
+
attr_reader :policy, :rule
|
10
|
+
|
11
|
+
def initialize(policy, rule)
|
12
|
+
@policy = policy
|
13
|
+
@rule = rule
|
14
|
+
end
|
15
|
+
|
16
|
+
def matches?(policy_class, actual_rule, target)
|
17
|
+
policy_class == policy.class &&
|
18
|
+
target == policy.record &&
|
19
|
+
rule == actual_rule
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
"#{policy.record.inspect} was authorized with #{policy.class}##{rule}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class << self
|
28
|
+
# Wrap code under inspection into this method
|
29
|
+
# to track authorize! calls
|
30
|
+
def tracking
|
31
|
+
calls.clear
|
32
|
+
Thread.current[:__action_policy_tracking] = true
|
33
|
+
yield
|
34
|
+
ensure
|
35
|
+
Thread.current[:__action_policy_tracking] = false
|
36
|
+
end
|
37
|
+
|
38
|
+
# Called from Authorizer
|
39
|
+
def track(policy, rule)
|
40
|
+
return unless tracking?
|
41
|
+
calls << Call.new(policy, rule)
|
42
|
+
end
|
43
|
+
|
44
|
+
def calls
|
45
|
+
Thread.current[:__action_policy_calls] ||= []
|
46
|
+
end
|
47
|
+
|
48
|
+
def tracking?
|
49
|
+
Thread.current[:__action_policy_tracking] == true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Extend authorizer to add tracking functionality
|
55
|
+
module AuthorizerExt
|
56
|
+
def call(*args)
|
57
|
+
AuthorizeTracker.track(*args)
|
58
|
+
super
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
ActionPolicy::Authorizer.singleton_class.prepend(AuthorizerExt)
|
63
|
+
end
|
64
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: action_policy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Dementyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-04-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.15'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5.0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,20 +53,48 @@ dependencies:
|
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '10.0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
56
|
+
name: rspec
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - "~>"
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
61
|
+
version: '3.3'
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
55
|
-
|
68
|
+
version: '3.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.51'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.51'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-md
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.2'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.2'
|
97
|
+
description: Authorization framework for Ruby/Rails application
|
56
98
|
email:
|
57
99
|
- dementiev.vm@gmail.com
|
58
100
|
executables: []
|
@@ -60,7 +102,9 @@ extensions: []
|
|
60
102
|
extra_rdoc_files: []
|
61
103
|
files:
|
62
104
|
- ".gitignore"
|
105
|
+
- ".rubocop.yml"
|
63
106
|
- ".travis.yml"
|
107
|
+
- CHANGELOG.md
|
64
108
|
- Gemfile
|
65
109
|
- LICENSE.txt
|
66
110
|
- README.md
|
@@ -68,7 +112,69 @@ files:
|
|
68
112
|
- action_policy.gemspec
|
69
113
|
- bin/console
|
70
114
|
- bin/setup
|
115
|
+
- docs/.nojekyll
|
116
|
+
- docs/CNAME
|
117
|
+
- docs/README.md
|
118
|
+
- docs/_sidebar.md
|
119
|
+
- docs/aliases.md
|
120
|
+
- docs/assets/docsify.min.js
|
121
|
+
- docs/assets/fonts/FiraCode-Medium.woff
|
122
|
+
- docs/assets/fonts/FiraCode-Regular.woff
|
123
|
+
- docs/assets/images/cache.png
|
124
|
+
- docs/assets/images/cache.svg
|
125
|
+
- docs/assets/images/layer.png
|
126
|
+
- docs/assets/images/layer.svg
|
127
|
+
- docs/assets/prism-ruby.min.js
|
128
|
+
- docs/assets/styles.css
|
129
|
+
- docs/assets/vue.min.css
|
130
|
+
- docs/authorization_context.md
|
131
|
+
- docs/caching.md
|
132
|
+
- docs/custom_lookup_chain.md
|
133
|
+
- docs/custom_policy.md
|
134
|
+
- docs/favicon.ico
|
135
|
+
- docs/i18n.md
|
136
|
+
- docs/index.html
|
137
|
+
- docs/instrumentation.md
|
138
|
+
- docs/lookup_chain.md
|
139
|
+
- docs/namespaces.md
|
140
|
+
- docs/non_rails.md
|
141
|
+
- docs/pre_checks.md
|
142
|
+
- docs/quick_start.md
|
143
|
+
- docs/rails.md
|
144
|
+
- docs/reasons.md
|
145
|
+
- docs/testing.md
|
146
|
+
- docs/writing_policies.md
|
147
|
+
- gemfiles/jruby.gemfile
|
148
|
+
- gemfiles/rails42.gemfile
|
149
|
+
- gemfiles/railsmaster.gemfile
|
71
150
|
- lib/action_policy.rb
|
151
|
+
- lib/action_policy/authorizer.rb
|
152
|
+
- lib/action_policy/base.rb
|
153
|
+
- lib/action_policy/behaviour.rb
|
154
|
+
- lib/action_policy/behaviours/memoized.rb
|
155
|
+
- lib/action_policy/behaviours/namespaced.rb
|
156
|
+
- lib/action_policy/behaviours/policy_for.rb
|
157
|
+
- lib/action_policy/behaviours/thread_memoized.rb
|
158
|
+
- lib/action_policy/ext/module_namespace.rb
|
159
|
+
- lib/action_policy/ext/policy_cache_key.rb
|
160
|
+
- lib/action_policy/ext/string_constantize.rb
|
161
|
+
- lib/action_policy/lookup_chain.rb
|
162
|
+
- lib/action_policy/policy/aliases.rb
|
163
|
+
- lib/action_policy/policy/authorization.rb
|
164
|
+
- lib/action_policy/policy/cache.rb
|
165
|
+
- lib/action_policy/policy/cached_apply.rb
|
166
|
+
- lib/action_policy/policy/core.rb
|
167
|
+
- lib/action_policy/policy/defaults.rb
|
168
|
+
- lib/action_policy/policy/pre_check.rb
|
169
|
+
- lib/action_policy/policy/reasons.rb
|
170
|
+
- lib/action_policy/rails/channel.rb
|
171
|
+
- lib/action_policy/rails/controller.rb
|
172
|
+
- lib/action_policy/railtie.rb
|
173
|
+
- lib/action_policy/rspec.rb
|
174
|
+
- lib/action_policy/rspec/be_authorized_to.rb
|
175
|
+
- lib/action_policy/rspec/pundit_syntax.rb
|
176
|
+
- lib/action_policy/test_helper.rb
|
177
|
+
- lib/action_policy/testing.rb
|
72
178
|
- lib/action_policy/version.rb
|
73
179
|
homepage: https://github.com/palkan/action-policy
|
74
180
|
licenses:
|
@@ -82,7 +188,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
82
188
|
requirements:
|
83
189
|
- - ">="
|
84
190
|
- !ruby/object:Gem::Version
|
85
|
-
version:
|
191
|
+
version: 2.3.0
|
86
192
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
193
|
requirements:
|
88
194
|
- - ">="
|
@@ -90,8 +196,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
196
|
version: '0'
|
91
197
|
requirements: []
|
92
198
|
rubyforge_project:
|
93
|
-
rubygems_version: 2.
|
199
|
+
rubygems_version: 2.7.4
|
94
200
|
signing_key:
|
95
201
|
specification_version: 4
|
96
|
-
summary:
|
202
|
+
summary: Authorization framework for Ruby/Rails application
|
97
203
|
test_files: []
|