action_policy 0.7.7 → 0.7.8
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 +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/.rbnext/3.0/action_policy/behaviours/policy_for.rb +10 -6
- data/lib/.rbnext/3.0/action_policy/behaviours/thread_memoized.rb +6 -5
- data/lib/.rbnext/3.0/action_policy/ext/policy_cache_key.rb +1 -5
- data/lib/.rbnext/3.1/action_policy/behaviours/memoized.rb +52 -0
- data/lib/.rbnext/3.1/action_policy/behaviours/policy_for.rb +10 -6
- data/lib/.rbnext/3.1/action_policy/behaviours/thread_memoized.rb +60 -0
- data/lib/.rbnext/3.2/action_policy/ext/policy_cache_key.rb +1 -5
- data/lib/action_policy/behaviours/memoized.rb +5 -5
- data/lib/action_policy/behaviours/policy_for.rb +10 -6
- data/lib/action_policy/behaviours/thread_memoized.rb +6 -5
- data/lib/action_policy/ext/policy_cache_key.rb +1 -5
- data/lib/action_policy/rails/ext/active_record.rb +5 -5
- data/lib/action_policy/version.rb +1 -1
- metadata +3 -4
- data/lib/.rbnext/3.1/action_policy/ext/policy_cache_key.rb +0 -72
- data/lib/.rbnext/3.2/action_policy/behaviours/policy_for.rb +0 -70
- data/lib/.rbnext/3.4/action_policy/behaviours/policy_for.rb +0 -70
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4a3a3b344c3b13973dae50a7a0400d1de1bc6547bddbf5870d2547b701a222f6
|
|
4
|
+
data.tar.gz: d9293952684089a73a27678e54b4a5c2b981117cc49b079821249c9af2d4feae
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ae6665c68d31d55c44e730624bc6dd4cf1e460f9ed26bbdda249189aec7c89258589079f2646f9c5ce9265f57668e046354cd49ae801db0bdd129937f9fab916
|
|
7
|
+
data.tar.gz: 9dbd344bc5f8bad378bdd40d899726a1dcf1136990a586be4a2a3db0bb9a061f56b19825387c7028743fce0e9d5d70d3497e373b40a96edf53a29f4d30bd38e9
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## master
|
|
4
4
|
|
|
5
|
+
## 0.7.8 (2026-11-03)
|
|
6
|
+
|
|
7
|
+
- Improve policy caching (less key calculations, fixed collisions). ([@palkan][])
|
|
8
|
+
|
|
9
|
+
- Fix `ActiveModel::MissingAttributeError` when authorizing a partially selected Active Record model from a memoized context. ([@czj][])
|
|
10
|
+
|
|
5
11
|
## 0.7.7 (2026-09-03)
|
|
6
12
|
|
|
7
13
|
- Fix caching non-persistent Active Record objects as the same entry ([@palkan][])
|
|
@@ -566,3 +572,4 @@ This value is now stored in a cache (if any) instead of just the call result (`t
|
|
|
566
572
|
[@stephannv]: https://github.com/stephannv
|
|
567
573
|
[@sedubois]: https://github.com/sedubois
|
|
568
574
|
[@Pagehey]: https://github.com/Pagehey
|
|
575
|
+
[@czj]: https://github.com/czj
|
|
@@ -8,14 +8,14 @@ module ActionPolicy
|
|
|
8
8
|
using ActionPolicy::Ext::PolicyCacheKey
|
|
9
9
|
|
|
10
10
|
# Returns policy instance for the record.
|
|
11
|
-
def policy_for(record:, with: nil, namespace: authorization_namespace, context: nil, allow_nil: false, default: default_authorization_policy_class, strict_namespace: authorization_strict_namespace)
|
|
12
|
-
|
|
11
|
+
def policy_for(record:, with: nil, namespace: authorization_namespace, context: nil, allow_nil: false, default: default_authorization_policy_class, strict_namespace: authorization_strict_namespace, cache_key: nil, resolved_context: nil)
|
|
12
|
+
resolved_context ||= policy_for_context(context)
|
|
13
13
|
|
|
14
14
|
policy_class = with || ::ActionPolicy.lookup(
|
|
15
15
|
record,
|
|
16
|
-
namespace: namespace, context:
|
|
16
|
+
namespace: namespace, context: resolved_context, allow_nil: allow_nil, default: default, strict_namespace: strict_namespace
|
|
17
17
|
)
|
|
18
|
-
policy_class&.new(record, **
|
|
18
|
+
policy_class&.new(record, **resolved_context)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def authorization_context ; @authorization_context ||= build_authorization_context; end
|
|
@@ -59,12 +59,16 @@ module ActionPolicy
|
|
|
59
59
|
)
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
def policy_for_cache_key(record:, with: nil, namespace:
|
|
62
|
+
def policy_for_cache_key(record:, context:, with: nil, namespace: authorization_namespace, **opts)
|
|
63
63
|
record_key = record._policy_cache_key(use_object_id: true)
|
|
64
|
-
context_key = context.
|
|
64
|
+
context_key = context.map { |k, v| "#{k}:#{v._policy_cache_key(use_object_id: true)}" }.join(".")
|
|
65
65
|
|
|
66
66
|
"#{namespace}/#{with}/#{context_key}/#{record_key}"
|
|
67
67
|
end
|
|
68
|
+
|
|
69
|
+
def policy_for_context(context)
|
|
70
|
+
context ? build_authorization_context.merge(context) : authorization_context
|
|
71
|
+
end
|
|
68
72
|
end
|
|
69
73
|
end
|
|
70
74
|
end
|
|
@@ -44,14 +44,15 @@ module ActionPolicy
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
module InstanceMethods # :nodoc:
|
|
47
|
-
def policy_for(record:, **opts)
|
|
48
|
-
|
|
47
|
+
def policy_for(record:, context: nil, resolved_context: nil, cache_key: nil, **opts)
|
|
48
|
+
resolved_context ||= policy_for_context(context)
|
|
49
|
+
cache_key ||= policy_for_cache_key(record: record, context: resolved_context, **opts)
|
|
50
|
+
|
|
51
|
+
__policy_thread_memoize__(cache_key) { super(record: record, **opts, resolved_context: resolved_context, cache_key: cache_key) }
|
|
49
52
|
end
|
|
50
53
|
end
|
|
51
54
|
|
|
52
|
-
def __policy_thread_memoize__(
|
|
53
|
-
cache_key = policy_for_cache_key(record: record, **options)
|
|
54
|
-
|
|
55
|
+
def __policy_thread_memoize__(cache_key)
|
|
55
56
|
ActionPolicy::PerThreadCache.fetch(cache_key) { yield }
|
|
56
57
|
end
|
|
57
58
|
end
|
|
@@ -10,7 +10,7 @@ module ActionPolicy
|
|
|
10
10
|
#
|
|
11
11
|
# Raises ArgumentError otherwise.
|
|
12
12
|
module PolicyCacheKey # :nodoc: all
|
|
13
|
-
|
|
13
|
+
refine Object do
|
|
14
14
|
def _policy_cache_key(use_object_id: false)
|
|
15
15
|
return policy_cache_key if respond_to?(:policy_cache_key)
|
|
16
16
|
return cache_key_with_version if respond_to?(:cache_key_with_version)
|
|
@@ -22,10 +22,6 @@ module ActionPolicy
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
refine Object do
|
|
26
|
-
::RubyNext::Core.import_methods(ObjectExt, binding)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
25
|
refine NilClass do
|
|
30
26
|
def _policy_cache_key(*__rest__) ; ""; end
|
|
31
27
|
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActionPolicy
|
|
4
|
+
module Behaviours
|
|
5
|
+
# Per-instance memoization for policies.
|
|
6
|
+
#
|
|
7
|
+
# Used by `policy_for` to re-use policy object for records.
|
|
8
|
+
#
|
|
9
|
+
# Example:
|
|
10
|
+
#
|
|
11
|
+
# include ActionPolicy::Behaviour
|
|
12
|
+
# include ActionPolicy::Memoized
|
|
13
|
+
#
|
|
14
|
+
# record = User.first
|
|
15
|
+
# policy = policy_for(record)
|
|
16
|
+
# policy2 = policy_for(record)
|
|
17
|
+
#
|
|
18
|
+
# policy.equal?(policy) #=> true
|
|
19
|
+
#
|
|
20
|
+
# policy.equal?(policy_for(record, with: CustomPolicy)) #=> false
|
|
21
|
+
module Memoized
|
|
22
|
+
class << self
|
|
23
|
+
def prepended(base)
|
|
24
|
+
base.prepend InstanceMethods
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
alias_method :included, :prepended
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
module InstanceMethods # :nodoc:
|
|
31
|
+
def policy_for(record:, context: nil, resolved_context: nil, cache_key: nil, **opts)
|
|
32
|
+
resolved_context ||= policy_for_context(context)
|
|
33
|
+
cache_key ||= policy_for_cache_key(record: record, context: resolved_context, **opts)
|
|
34
|
+
__policy_memoize__(cache_key) { super(record: record, **opts, resolved_context: resolved_context, cache_key: cache_key) }
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def __policy_memoize__(cache_key)
|
|
39
|
+
return __policies_cache__[cache_key] if
|
|
40
|
+
__policies_cache__.key?(cache_key)
|
|
41
|
+
|
|
42
|
+
policy = yield
|
|
43
|
+
|
|
44
|
+
__policies_cache__[cache_key] = policy
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def __policies_cache__
|
|
48
|
+
@__policies_cache__ ||= {}
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -8,14 +8,14 @@ module ActionPolicy
|
|
|
8
8
|
using ActionPolicy::Ext::PolicyCacheKey
|
|
9
9
|
|
|
10
10
|
# Returns policy instance for the record.
|
|
11
|
-
def policy_for(record:, with: nil, namespace: authorization_namespace, context: nil, allow_nil: false, default: default_authorization_policy_class, strict_namespace: authorization_strict_namespace)
|
|
12
|
-
|
|
11
|
+
def policy_for(record:, with: nil, namespace: authorization_namespace, context: nil, allow_nil: false, default: default_authorization_policy_class, strict_namespace: authorization_strict_namespace, cache_key: nil, resolved_context: nil)
|
|
12
|
+
resolved_context ||= policy_for_context(context)
|
|
13
13
|
|
|
14
14
|
policy_class = with || ::ActionPolicy.lookup(
|
|
15
15
|
record,
|
|
16
|
-
namespace: namespace, context:
|
|
16
|
+
namespace: namespace, context: resolved_context, allow_nil: allow_nil, default: default, strict_namespace: strict_namespace
|
|
17
17
|
)
|
|
18
|
-
policy_class&.new(record, **
|
|
18
|
+
policy_class&.new(record, **resolved_context)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def authorization_context = @authorization_context ||= build_authorization_context
|
|
@@ -59,12 +59,16 @@ module ActionPolicy
|
|
|
59
59
|
)
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
def policy_for_cache_key(record:, with: nil, namespace:
|
|
62
|
+
def policy_for_cache_key(record:, context:, with: nil, namespace: authorization_namespace, **opts)
|
|
63
63
|
record_key = record._policy_cache_key(use_object_id: true)
|
|
64
|
-
context_key = context.
|
|
64
|
+
context_key = context.map { |k, v| "#{k}:#{v._policy_cache_key(use_object_id: true)}" }.join(".")
|
|
65
65
|
|
|
66
66
|
"#{namespace}/#{with}/#{context_key}/#{record_key}"
|
|
67
67
|
end
|
|
68
|
+
|
|
69
|
+
def policy_for_context(context)
|
|
70
|
+
context ? build_authorization_context.merge(context) : authorization_context
|
|
71
|
+
end
|
|
68
72
|
end
|
|
69
73
|
end
|
|
70
74
|
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActionPolicy
|
|
4
|
+
module PerThreadCache # :nodoc:
|
|
5
|
+
CACHE_KEY = "action_policy.per_thread_cache"
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
attr_writer :enabled
|
|
9
|
+
|
|
10
|
+
def enabled?() = @enabled == true
|
|
11
|
+
|
|
12
|
+
def fetch(key)
|
|
13
|
+
return yield unless enabled?
|
|
14
|
+
|
|
15
|
+
store = (Thread.current[CACHE_KEY] ||= {})
|
|
16
|
+
|
|
17
|
+
return store[key] if store.key?(key)
|
|
18
|
+
|
|
19
|
+
store[key] = yield
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def clear_all
|
|
23
|
+
Thread.current[CACHE_KEY] = {}
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Turn off by default in test env
|
|
28
|
+
self.enabled = !(ENV["RAILS_ENV"] == "test" || ENV["RACK_ENV"] == "test")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
module Behaviours
|
|
32
|
+
# Per-thread memoization for policies.
|
|
33
|
+
#
|
|
34
|
+
# Used by `policy_for` to re-use policy object for records.
|
|
35
|
+
#
|
|
36
|
+
# NOTE: don't forget to clear thread cache with ActionPolicy::PerThreadCache.clear_all
|
|
37
|
+
module ThreadMemoized
|
|
38
|
+
class << self
|
|
39
|
+
def prepended(base)
|
|
40
|
+
base.prepend InstanceMethods
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
alias_method :included, :prepended
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
module InstanceMethods # :nodoc:
|
|
47
|
+
def policy_for(record:, context: nil, resolved_context: nil, cache_key: nil, **opts)
|
|
48
|
+
resolved_context ||= policy_for_context(context)
|
|
49
|
+
cache_key ||= policy_for_cache_key(record: record, context: resolved_context, **opts)
|
|
50
|
+
|
|
51
|
+
__policy_thread_memoize__(cache_key) { super(record: record, **opts, resolved_context: resolved_context, cache_key: cache_key) }
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def __policy_thread_memoize__(cache_key)
|
|
56
|
+
ActionPolicy::PerThreadCache.fetch(cache_key) { yield }
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -10,7 +10,7 @@ module ActionPolicy
|
|
|
10
10
|
#
|
|
11
11
|
# Raises ArgumentError otherwise.
|
|
12
12
|
module PolicyCacheKey # :nodoc: all
|
|
13
|
-
|
|
13
|
+
refine Object do
|
|
14
14
|
def _policy_cache_key(use_object_id: false)
|
|
15
15
|
return policy_cache_key if respond_to?(:policy_cache_key)
|
|
16
16
|
return cache_key_with_version if respond_to?(:cache_key_with_version)
|
|
@@ -22,10 +22,6 @@ module ActionPolicy
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
refine Object do
|
|
26
|
-
import_methods ObjectExt
|
|
27
|
-
end
|
|
28
|
-
|
|
29
25
|
refine NilClass do
|
|
30
26
|
def _policy_cache_key(*__rest__) = ""
|
|
31
27
|
end
|
|
@@ -28,14 +28,14 @@ module ActionPolicy
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
module InstanceMethods # :nodoc:
|
|
31
|
-
def policy_for(record:, **opts)
|
|
32
|
-
|
|
31
|
+
def policy_for(record:, context: nil, resolved_context: nil, cache_key: nil, **opts)
|
|
32
|
+
resolved_context ||= policy_for_context(context)
|
|
33
|
+
cache_key ||= policy_for_cache_key(record:, context: resolved_context, **opts)
|
|
34
|
+
__policy_memoize__(cache_key) { super(record:, **opts, resolved_context:, cache_key:) }
|
|
33
35
|
end
|
|
34
36
|
end
|
|
35
37
|
|
|
36
|
-
def __policy_memoize__(
|
|
37
|
-
cache_key = policy_for_cache_key(record: record, **options)
|
|
38
|
-
|
|
38
|
+
def __policy_memoize__(cache_key)
|
|
39
39
|
return __policies_cache__[cache_key] if
|
|
40
40
|
__policies_cache__.key?(cache_key)
|
|
41
41
|
|
|
@@ -8,14 +8,14 @@ module ActionPolicy
|
|
|
8
8
|
using ActionPolicy::Ext::PolicyCacheKey
|
|
9
9
|
|
|
10
10
|
# Returns policy instance for the record.
|
|
11
|
-
def policy_for(record:, with: nil, namespace: authorization_namespace, context: nil, allow_nil: false, default: default_authorization_policy_class, strict_namespace: authorization_strict_namespace)
|
|
12
|
-
|
|
11
|
+
def policy_for(record:, with: nil, namespace: authorization_namespace, context: nil, allow_nil: false, default: default_authorization_policy_class, strict_namespace: authorization_strict_namespace, cache_key: nil, resolved_context: nil)
|
|
12
|
+
resolved_context ||= policy_for_context(context)
|
|
13
13
|
|
|
14
14
|
policy_class = with || ::ActionPolicy.lookup(
|
|
15
15
|
record,
|
|
16
|
-
namespace:, context
|
|
16
|
+
namespace:, context: resolved_context, allow_nil:, default:, strict_namespace:
|
|
17
17
|
)
|
|
18
|
-
policy_class&.new(record, **
|
|
18
|
+
policy_class&.new(record, **resolved_context)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def authorization_context = @authorization_context ||= build_authorization_context
|
|
@@ -59,12 +59,16 @@ module ActionPolicy
|
|
|
59
59
|
)
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
def policy_for_cache_key(record:, with: nil, namespace:
|
|
62
|
+
def policy_for_cache_key(record:, context:, with: nil, namespace: authorization_namespace, **opts)
|
|
63
63
|
record_key = record._policy_cache_key(use_object_id: true)
|
|
64
|
-
context_key = context.
|
|
64
|
+
context_key = context.map { |k, v| "#{k}:#{v._policy_cache_key(use_object_id: true)}" }.join(".")
|
|
65
65
|
|
|
66
66
|
"#{namespace}/#{with}/#{context_key}/#{record_key}"
|
|
67
67
|
end
|
|
68
|
+
|
|
69
|
+
def policy_for_context(context)
|
|
70
|
+
context ? build_authorization_context.merge(context) : authorization_context
|
|
71
|
+
end
|
|
68
72
|
end
|
|
69
73
|
end
|
|
70
74
|
end
|
|
@@ -44,14 +44,15 @@ module ActionPolicy
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
module InstanceMethods # :nodoc:
|
|
47
|
-
def policy_for(record:, **opts)
|
|
48
|
-
|
|
47
|
+
def policy_for(record:, context: nil, resolved_context: nil, cache_key: nil, **opts)
|
|
48
|
+
resolved_context ||= policy_for_context(context)
|
|
49
|
+
cache_key ||= policy_for_cache_key(record:, context: resolved_context, **opts)
|
|
50
|
+
|
|
51
|
+
__policy_thread_memoize__(cache_key) { super(record:, **opts, resolved_context:, cache_key:) }
|
|
49
52
|
end
|
|
50
53
|
end
|
|
51
54
|
|
|
52
|
-
def __policy_thread_memoize__(
|
|
53
|
-
cache_key = policy_for_cache_key(record: record, **options)
|
|
54
|
-
|
|
55
|
+
def __policy_thread_memoize__(cache_key)
|
|
55
56
|
ActionPolicy::PerThreadCache.fetch(cache_key) { yield }
|
|
56
57
|
end
|
|
57
58
|
end
|
|
@@ -10,7 +10,7 @@ module ActionPolicy
|
|
|
10
10
|
#
|
|
11
11
|
# Raises ArgumentError otherwise.
|
|
12
12
|
module PolicyCacheKey # :nodoc: all
|
|
13
|
-
|
|
13
|
+
refine Object do
|
|
14
14
|
def _policy_cache_key(use_object_id: false)
|
|
15
15
|
return policy_cache_key if respond_to?(:policy_cache_key)
|
|
16
16
|
return cache_key_with_version if respond_to?(:cache_key_with_version)
|
|
@@ -22,10 +22,6 @@ module ActionPolicy
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
refine Object do
|
|
26
|
-
import_methods ObjectExt
|
|
27
|
-
end
|
|
28
|
-
|
|
29
25
|
refine NilClass do
|
|
30
26
|
def _policy_cache_key(*) = ""
|
|
31
27
|
end
|
|
@@ -19,10 +19,10 @@ end)
|
|
|
19
19
|
# Ensure non-persistent models are not cached as a single entry
|
|
20
20
|
ActiveRecord::Base.include(Module.new do
|
|
21
21
|
def policy_cache_key
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
return object_id.to_s unless persisted?
|
|
23
|
+
# A select leaving updated_at out makes cache_version raise MissingAttributeError
|
|
24
|
+
return object_id.to_s if !has_attribute?("updated_at") && self.class.attribute_types.key?("updated_at")
|
|
25
|
+
|
|
26
|
+
cache_key_with_version
|
|
27
27
|
end
|
|
28
28
|
end)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: action_policy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.7.
|
|
4
|
+
version: 0.7.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vladimir Dementyev
|
|
@@ -149,19 +149,18 @@ files:
|
|
|
149
149
|
- lib/.rbnext/3.0/action_policy/rspec/have_authorized_scope.rb
|
|
150
150
|
- lib/.rbnext/3.0/action_policy/utils/pretty_print.rb
|
|
151
151
|
- lib/.rbnext/3.0/action_policy/utils/suggest_message.rb
|
|
152
|
+
- lib/.rbnext/3.1/action_policy/behaviours/memoized.rb
|
|
152
153
|
- lib/.rbnext/3.1/action_policy/behaviours/policy_for.rb
|
|
153
154
|
- lib/.rbnext/3.1/action_policy/behaviours/scoping.rb
|
|
155
|
+
- lib/.rbnext/3.1/action_policy/behaviours/thread_memoized.rb
|
|
154
156
|
- lib/.rbnext/3.1/action_policy/ext/module_namespace.rb
|
|
155
|
-
- lib/.rbnext/3.1/action_policy/ext/policy_cache_key.rb
|
|
156
157
|
- lib/.rbnext/3.1/action_policy/policy/authorization.rb
|
|
157
|
-
- lib/.rbnext/3.2/action_policy/behaviours/policy_for.rb
|
|
158
158
|
- lib/.rbnext/3.2/action_policy/ext/policy_cache_key.rb
|
|
159
159
|
- lib/.rbnext/3.2/action_policy/lookup_chain.rb
|
|
160
160
|
- lib/.rbnext/3.2/action_policy/policy/core.rb
|
|
161
161
|
- lib/.rbnext/3.2/action_policy/rspec/be_authorized_to.rb
|
|
162
162
|
- lib/.rbnext/3.2/action_policy/rspec/have_authorized_scope.rb
|
|
163
163
|
- lib/.rbnext/3.2/action_policy/utils/suggest_message.rb
|
|
164
|
-
- lib/.rbnext/3.4/action_policy/behaviours/policy_for.rb
|
|
165
164
|
- lib/.rbnext/3.4/action_policy/i18n.rb
|
|
166
165
|
- lib/.rbnext/3.4/action_policy/policy/cache.rb
|
|
167
166
|
- lib/.rbnext/3.4/action_policy/policy/pre_check.rb
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module ActionPolicy
|
|
4
|
-
module Ext
|
|
5
|
-
# Adds #_policy_cache_key method to Object,
|
|
6
|
-
# which just call #policy_cache_key or #cache_key
|
|
7
|
-
# or #object_id (if `use_object_id` parameter is set to true).
|
|
8
|
-
#
|
|
9
|
-
# For other core classes returns string representation.
|
|
10
|
-
#
|
|
11
|
-
# Raises ArgumentError otherwise.
|
|
12
|
-
module PolicyCacheKey # :nodoc: all
|
|
13
|
-
module ObjectExt
|
|
14
|
-
def _policy_cache_key(use_object_id: false)
|
|
15
|
-
return policy_cache_key if respond_to?(:policy_cache_key)
|
|
16
|
-
return cache_key_with_version if respond_to?(:cache_key_with_version)
|
|
17
|
-
return cache_key if respond_to?(:cache_key)
|
|
18
|
-
|
|
19
|
-
return object_id.to_s if use_object_id == true
|
|
20
|
-
|
|
21
|
-
raise ArgumentError, "object is not cacheable"
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
refine Object do
|
|
26
|
-
::RubyNext::Core.import_methods(ObjectExt, binding)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
refine NilClass do
|
|
30
|
-
def _policy_cache_key(*__rest__) = ""
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
refine TrueClass do
|
|
34
|
-
def _policy_cache_key(*__rest__) = "t"
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
refine FalseClass do
|
|
38
|
-
def _policy_cache_key(*__rest__) = "f"
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
refine String do
|
|
42
|
-
def _policy_cache_key(*__rest__) = self
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
refine Symbol do
|
|
46
|
-
def _policy_cache_key(*__rest__) = to_s
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
if RUBY_PLATFORM.match?(/java/i)
|
|
50
|
-
refine Integer do
|
|
51
|
-
def _policy_cache_key(*__rest__) = to_s
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
refine Float do
|
|
55
|
-
def _policy_cache_key(*__rest__) = to_s
|
|
56
|
-
end
|
|
57
|
-
else
|
|
58
|
-
refine Numeric do
|
|
59
|
-
def _policy_cache_key(*__rest__) = to_s
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
refine Time do
|
|
64
|
-
def _policy_cache_key(*__rest__) = to_s
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
refine Module do
|
|
68
|
-
def _policy_cache_key(*__rest__) = name
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module ActionPolicy
|
|
4
|
-
module Behaviours
|
|
5
|
-
# Adds `policy_for` method
|
|
6
|
-
module PolicyFor
|
|
7
|
-
require "action_policy/ext/policy_cache_key"
|
|
8
|
-
using ActionPolicy::Ext::PolicyCacheKey
|
|
9
|
-
|
|
10
|
-
# Returns policy instance for the record.
|
|
11
|
-
def policy_for(record:, with: nil, namespace: authorization_namespace, context: nil, allow_nil: false, default: default_authorization_policy_class, strict_namespace: authorization_strict_namespace)
|
|
12
|
-
context = context ? build_authorization_context.merge(context) : authorization_context
|
|
13
|
-
|
|
14
|
-
policy_class = with || ::ActionPolicy.lookup(
|
|
15
|
-
record,
|
|
16
|
-
namespace:, context:, allow_nil:, default:, strict_namespace:
|
|
17
|
-
)
|
|
18
|
-
policy_class&.new(record, **context)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def authorization_context = @authorization_context ||= build_authorization_context
|
|
22
|
-
|
|
23
|
-
def build_authorization_context
|
|
24
|
-
Kernel.raise NotImplementedError, "Please, define `build_authorization_context` method!"
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def authorization_namespace
|
|
28
|
-
# override to provide specific authorization namespace
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def default_authorization_policy_class
|
|
32
|
-
# override to provide a policy class use when no policy found
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def authorization_strict_namespace
|
|
36
|
-
# override to provide strict namespace lookup option
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# Override this method to provide implicit authorization target
|
|
40
|
-
# that would be used in case `record` is not specified in
|
|
41
|
-
# `authorize!` and `allowed_to?` call.
|
|
42
|
-
#
|
|
43
|
-
# It is also used to infer a policy for scoping (in `authorized_scope` method).
|
|
44
|
-
def implicit_authorization_target
|
|
45
|
-
# no-op
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# Return implicit authorization target or raises an exception if it's nil
|
|
49
|
-
def implicit_authorization_target!
|
|
50
|
-
implicit_authorization_target || Kernel.raise(
|
|
51
|
-
NotFound,
|
|
52
|
-
[
|
|
53
|
-
self,
|
|
54
|
-
"Couldn't find implicit authorization target " \
|
|
55
|
-
"for #{self.class}. " \
|
|
56
|
-
"Please, provide policy class explicitly using `with` option or " \
|
|
57
|
-
"define the `implicit_authorization_target` method."
|
|
58
|
-
]
|
|
59
|
-
)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def policy_for_cache_key(record:, with: nil, namespace: nil, context: authorization_context, **__kwrest__)
|
|
63
|
-
record_key = record._policy_cache_key(use_object_id: true)
|
|
64
|
-
context_key = context.values.map { |it| it._policy_cache_key(use_object_id: true) }.join(".")
|
|
65
|
-
|
|
66
|
-
"#{namespace}/#{with}/#{context_key}/#{record_key}"
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module ActionPolicy
|
|
4
|
-
module Behaviours
|
|
5
|
-
# Adds `policy_for` method
|
|
6
|
-
module PolicyFor
|
|
7
|
-
require "action_policy/ext/policy_cache_key"
|
|
8
|
-
using ActionPolicy::Ext::PolicyCacheKey
|
|
9
|
-
|
|
10
|
-
# Returns policy instance for the record.
|
|
11
|
-
def policy_for(record:, with: nil, namespace: authorization_namespace, context: nil, allow_nil: false, default: default_authorization_policy_class, strict_namespace: authorization_strict_namespace)
|
|
12
|
-
context = context ? build_authorization_context.merge(context) : authorization_context
|
|
13
|
-
|
|
14
|
-
policy_class = with || ::ActionPolicy.lookup(
|
|
15
|
-
record,
|
|
16
|
-
namespace:, context:, allow_nil:, default:, strict_namespace:
|
|
17
|
-
)
|
|
18
|
-
policy_class&.new(record, **context)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def authorization_context = @authorization_context ||= build_authorization_context
|
|
22
|
-
|
|
23
|
-
def build_authorization_context
|
|
24
|
-
Kernel.raise NotImplementedError, "Please, define `build_authorization_context` method!"
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def authorization_namespace
|
|
28
|
-
# override to provide specific authorization namespace
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def default_authorization_policy_class
|
|
32
|
-
# override to provide a policy class use when no policy found
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def authorization_strict_namespace
|
|
36
|
-
# override to provide strict namespace lookup option
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# Override this method to provide implicit authorization target
|
|
40
|
-
# that would be used in case `record` is not specified in
|
|
41
|
-
# `authorize!` and `allowed_to?` call.
|
|
42
|
-
#
|
|
43
|
-
# It is also used to infer a policy for scoping (in `authorized_scope` method).
|
|
44
|
-
def implicit_authorization_target
|
|
45
|
-
# no-op
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# Return implicit authorization target or raises an exception if it's nil
|
|
49
|
-
def implicit_authorization_target!
|
|
50
|
-
implicit_authorization_target || Kernel.raise(
|
|
51
|
-
NotFound,
|
|
52
|
-
[
|
|
53
|
-
self,
|
|
54
|
-
"Couldn't find implicit authorization target " \
|
|
55
|
-
"for #{self.class}. " \
|
|
56
|
-
"Please, provide policy class explicitly using `with` option or " \
|
|
57
|
-
"define the `implicit_authorization_target` method."
|
|
58
|
-
]
|
|
59
|
-
)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def policy_for_cache_key(record:, with: nil, namespace: nil, context: authorization_context, **)
|
|
63
|
-
record_key = record._policy_cache_key(use_object_id: true)
|
|
64
|
-
context_key = context.values.map { |it| it._policy_cache_key(use_object_id: true) }.join(".")
|
|
65
|
-
|
|
66
|
-
"#{namespace}/#{with}/#{context_key}/#{record_key}"
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|