subroutine 2.0.1 → 2.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 +4 -4
- data/.ruby-version +1 -1
- data/CHANGELOG.MD +6 -0
- data/lib/subroutine/auth.rb +60 -32
- data/lib/subroutine/version.rb +2 -2
- data/test/subroutine/auth_test.rb +14 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be1eef70ae231ae5b344cf1400ed9ea17a60df49fd1243eb744c13e4aca5904e
|
4
|
+
data.tar.gz: 21f60843110c2b5f6c70281dc1999ed84923848f805cbd08472cb7a863a00a59
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cb5596227a06ddfdcca54205bb0c599919ffae5f29ef30ab25d437e7cf8cb03462c99015c957fdfce8d2a7a3ed910b013da7e84f6516a9f37a34a44fa44734b
|
7
|
+
data.tar.gz: 141e1f223f7da3dc7d080cbc891cd9533a905833ceb8a85e0941b06b6455cf83dea42aabe9f3eeaf977966ea227ead94446462c86ad28261b37436b389152c45
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.5
|
1
|
+
2.7.5
|
data/CHANGELOG.MD
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## Subroutine 2.0
|
2
|
+
|
3
|
+
The updates between 1.0 and 2.0 are relatively minor and are focused more on cleaning up the codebase and extending the use of the 0.9->1.0 refactor. There are, however, breaking changes to how associations are loaded. The association is no longer loaded via `find()` but rather `find_by!(id:)`. Given this, a major version was released.
|
4
|
+
|
5
|
+
**Note:** 2.0.0 was released with a bug and subsequently yanked. 2.0.1 is the first available 2.x version.
|
6
|
+
|
1
7
|
## Subroutine 1.0
|
2
8
|
|
3
9
|
A massive refactor took place between 0.9 and 1.0, including breaking changes. The goal was to reduce complexity, simplify backtraces, and increase the overall safety and reliability of the library.
|
data/lib/subroutine/auth.rb
CHANGED
@@ -9,11 +9,13 @@ module Subroutine
|
|
9
9
|
extend ActiveSupport::Concern
|
10
10
|
|
11
11
|
included do
|
12
|
-
class_attribute :
|
13
|
-
self.
|
12
|
+
class_attribute :authorization_checks
|
13
|
+
self.authorization_checks = []
|
14
14
|
|
15
15
|
class_attribute :user_class_name, instance_writer: false
|
16
16
|
self.user_class_name = "User"
|
17
|
+
|
18
|
+
validate :validate_authorization_checks, unless: :skip_auth_checks?
|
17
19
|
end
|
18
20
|
|
19
21
|
module ClassMethods
|
@@ -22,28 +24,24 @@ module Subroutine
|
|
22
24
|
[user_class_name, "Integer", "NilClass"].compact
|
23
25
|
end
|
24
26
|
|
25
|
-
def
|
26
|
-
|
27
|
+
def authorization_declared?
|
28
|
+
authorization_checks.any?
|
29
|
+
end
|
30
|
+
|
31
|
+
def authorize(check_name)
|
32
|
+
self.authorization_checks += [check_name.to_sym]
|
27
33
|
end
|
28
34
|
|
29
35
|
def no_user_requirements!
|
30
|
-
|
36
|
+
authorize :authorize_user_not_required
|
31
37
|
end
|
32
38
|
|
33
39
|
def require_user!
|
34
|
-
|
35
|
-
|
36
|
-
validate unless: :skip_auth_checks? do
|
37
|
-
unauthorized! unless current_user.present?
|
38
|
-
end
|
40
|
+
authorize :authorize_user_required
|
39
41
|
end
|
40
42
|
|
41
43
|
def require_no_user!
|
42
|
-
|
43
|
-
|
44
|
-
validate unless: :skip_auth_checks? do
|
45
|
-
unauthorized! :empty_unauthorized if current_user.present?
|
46
|
-
end
|
44
|
+
authorize :authorize_no_user_required
|
47
45
|
end
|
48
46
|
|
49
47
|
# policy :can_update_user
|
@@ -57,33 +55,45 @@ module Subroutine
|
|
57
55
|
if_conditionals = Array(opts[:if])
|
58
56
|
unless_conditionals = Array(opts[:unless])
|
59
57
|
|
60
|
-
|
61
|
-
|
62
|
-
|
58
|
+
meths.each do |meth|
|
59
|
+
normalized_meth = meth.to_s[0...-1] if meth.to_s.end_with?("?")
|
60
|
+
auth_method_name = :"authorize_#{policy_name}_#{normalized_meth}"
|
63
61
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end
|
62
|
+
define_method auth_method_name do
|
63
|
+
run_it = true
|
64
|
+
# http://guides.rubyonrails.org/active_record_validations.html#combining-validation-conditions
|
68
65
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
66
|
+
# The validation only runs when all the :if conditions evaluate to true
|
67
|
+
if if_conditionals.present?
|
68
|
+
run_it &&= if_conditionals.all? { |i| send(i) }
|
69
|
+
end
|
70
|
+
|
71
|
+
# and none of the :unless conditions are evaluated to true.
|
72
|
+
if unless_conditionals.present?
|
73
|
+
run_it &&= unless_conditionals.none? { |u| send(u) }
|
74
|
+
end
|
75
|
+
|
76
|
+
return unless run_it
|
77
|
+
|
78
|
+
p = send(policy_name)
|
79
|
+
unauthorized! unless p
|
73
80
|
|
74
|
-
|
81
|
+
result = if p.respond_to?("#{normalized_meth}?")
|
82
|
+
p.send("#{normalized_meth}?")
|
83
|
+
else
|
84
|
+
p.send(normalized_meth)
|
85
|
+
end
|
75
86
|
|
76
|
-
|
77
|
-
if !p || meths.any? { |m| !(p.respond_to?("#{m}?") ? p.send("#{m}?") : p.send(m)) }
|
78
|
-
unauthorized! opts[:error]
|
87
|
+
unauthorized! opts[:error] unless result
|
79
88
|
end
|
89
|
+
|
90
|
+
authorize auth_method_name
|
80
91
|
end
|
81
92
|
end
|
82
|
-
|
83
93
|
end
|
84
94
|
|
85
95
|
def initialize(*args, &block)
|
86
|
-
raise Subroutine::Auth::AuthorizationNotDeclaredError unless self.class.authorization_declared
|
96
|
+
raise Subroutine::Auth::AuthorizationNotDeclaredError unless self.class.authorization_declared?
|
87
97
|
|
88
98
|
@skip_auth_checks = false
|
89
99
|
|
@@ -124,5 +134,23 @@ module Subroutine
|
|
124
134
|
raise ::Subroutine::Auth::NotAuthorizedError, reason
|
125
135
|
end
|
126
136
|
|
137
|
+
def validate_authorization_checks
|
138
|
+
authorization_checks.each do |check|
|
139
|
+
send(check)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def authorize_user_not_required
|
144
|
+
true
|
145
|
+
end
|
146
|
+
|
147
|
+
def authorize_user_required
|
148
|
+
unauthorized! unless current_user.present?
|
149
|
+
end
|
150
|
+
|
151
|
+
def authorize_no_user_required
|
152
|
+
unauthorized! :empty_unauthorized if current_user.present?
|
153
|
+
end
|
154
|
+
|
127
155
|
end
|
128
156
|
end
|
data/lib/subroutine/version.rb
CHANGED
@@ -57,6 +57,16 @@ module Subroutine
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
+
def test_authorization_checks_are_registered_on_the_class
|
61
|
+
assert_equal false, MissingAuthOp.authorization_declared?
|
62
|
+
|
63
|
+
assert_equal true, CustomAuthorizeOp.authorization_declared?
|
64
|
+
assert_equal [:authorize_user_required, :authorize_user_is_correct], CustomAuthorizeOp.authorization_checks
|
65
|
+
|
66
|
+
assert_equal true, NoUserRequirementsOp.authorization_declared?
|
67
|
+
assert_equal [:authorize_user_not_required], NoUserRequirementsOp.authorization_checks
|
68
|
+
end
|
69
|
+
|
60
70
|
def test_the_current_user_can_be_defined_by_an_id
|
61
71
|
user = CustomAuthorizeOp.new(1).current_user
|
62
72
|
assert_equal 1, user.id
|
@@ -92,6 +102,10 @@ module Subroutine
|
|
92
102
|
op.submit!
|
93
103
|
end
|
94
104
|
|
105
|
+
def policy_invocations_are_registered_as_authorization_methods
|
106
|
+
assert PolicyOp.authorization_checks.include?(:authorize_policy_user_can_access)
|
107
|
+
end
|
108
|
+
|
95
109
|
def test_it_runs_policies_with_conditionals
|
96
110
|
# if: false
|
97
111
|
op = IfConditionalPolicyOp.new(user, check_policy: false)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: subroutine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Nelson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -218,7 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
218
218
|
- !ruby/object:Gem::Version
|
219
219
|
version: '0'
|
220
220
|
requirements: []
|
221
|
-
rubygems_version: 3.
|
221
|
+
rubygems_version: 3.1.6
|
222
222
|
signing_key:
|
223
223
|
specification_version: 4
|
224
224
|
summary: Feature-driven operation objects.
|