action_policy 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|