ree_lib 1.3.3 → 1.3.4
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/Gemfile.lock +1 -1
- data/lib/ree_lib/packages/ree_roda/package/ree_roda/plugins/ree_routes.rb +137 -64
- data/lib/ree_lib/packages/ree_roda/package/ree_roda/services/build_routing_tree.rb +110 -57
- data/lib/ree_lib/packages/ree_roda/spec/ree_roda/app_spec.rb +86 -1
- data/lib/ree_lib/packages/ree_roda/spec/ree_roda/services/build_routing_tree_spec.rb +3 -2
- data/lib/ree_lib/packages/ree_routes/package/ree_routes/dsl.rb +5 -5
- data/lib/ree_lib/packages/ree_routes/package/ree_routes/route.rb +15 -3
- data/lib/ree_lib/packages/ree_routes/package/ree_routes/route_builder.rb +4 -4
- data/lib/ree_lib/packages/ree_routes/spec/ree_routes/dsl_spec.rb +4 -2
- data/lib/ree_lib/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 73ca3b1fae54a13391bda2954179e4b66a784b170b8461eddb3acb4378f03b24
|
|
4
|
+
data.tar.gz: 5a3fc79a3201395824ae4575fb7b2ed7bf5ec3e0755db1572b078e34d4a347fa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d0b903a2f014d8f9f2473c91df8e0d26c33bda0cbc8eb61dcf9b6d6515498b1693aa3075da58695e71b825792474747bbb54363d081d86d858e00b427c53b350
|
|
7
|
+
data.tar.gz: 7abbef08143f8bc981a6eabd8934937fd1ec541a52f4a44814fbe18cfdf606d4fc95ec4b28a5febd8ffd7b0842f5e19bbb282f82e00405dd9d4ec50c8b71b416
|
data/Gemfile.lock
CHANGED
|
@@ -58,11 +58,13 @@ class Roda
|
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
route_tree_proc = build_traverse_tree_proc(routing_tree, context)
|
|
61
|
+
routing_trees = ReeRoda::BuildRoutingTree.new.call(@ree_routes)
|
|
63
62
|
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
routing_trees.each do |routing_tree|
|
|
64
|
+
route_tree_proc = build_traverse_tree_proc(routing_tree, context)
|
|
65
|
+
list << Proc.new do |r|
|
|
66
|
+
r.instance_exec(r, &route_tree_proc)
|
|
67
|
+
end
|
|
66
68
|
end
|
|
67
69
|
|
|
68
70
|
opts[:ree_routes_proc] = list
|
|
@@ -75,10 +77,28 @@ class Roda
|
|
|
75
77
|
r.instance_exec(r, &route.override)
|
|
76
78
|
else
|
|
77
79
|
r.send(route.respond_to) do
|
|
78
|
-
|
|
80
|
+
authenticated_user = nil
|
|
81
|
+
authenticated_scope = nil
|
|
82
|
+
|
|
83
|
+
route.warden_scopes.each do |scope|
|
|
84
|
+
if r.env["warden"].authenticate(scope: scope)
|
|
85
|
+
user = r.env["warden"].user(scope)
|
|
86
|
+
if user
|
|
87
|
+
authenticated_user = user
|
|
88
|
+
authenticated_scope = scope
|
|
89
|
+
break
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# all scopes are failed, throwing failure
|
|
95
|
+
if authenticated_user.nil?
|
|
96
|
+
r.env["warden"].custom_failure!
|
|
97
|
+
throw(:warden, scope: route.warden_scopes.first, reason: "authentication_failed")
|
|
98
|
+
end
|
|
79
99
|
|
|
80
100
|
if context.opts[:ree_routes_before]
|
|
81
|
-
r.instance_exec(@_request,
|
|
101
|
+
r.instance_exec(@_request, authenticated_scope, &r.scope.opts[:ree_routes_before])
|
|
82
102
|
end
|
|
83
103
|
|
|
84
104
|
params = r.params
|
|
@@ -99,7 +119,7 @@ class Roda
|
|
|
99
119
|
v.is_a?(Array) ? v.select { not_blank.call(_1) } : v
|
|
100
120
|
end
|
|
101
121
|
|
|
102
|
-
accessor =
|
|
122
|
+
accessor = authenticated_user
|
|
103
123
|
action_result = get_cached_action(route).call(accessor, filtered_params)
|
|
104
124
|
|
|
105
125
|
if route.serializer
|
|
@@ -128,98 +148,151 @@ class Roda
|
|
|
128
148
|
end
|
|
129
149
|
|
|
130
150
|
def build_traverse_tree_proc(tree, context)
|
|
131
|
-
|
|
132
|
-
route_parts = has_arbitrary_param ? tree.values.map { _1.gsub(":", "") } : tree.values
|
|
133
|
-
procs = []
|
|
151
|
+
return Proc.new {} if tree.nil?
|
|
134
152
|
|
|
135
|
-
|
|
136
|
-
|
|
153
|
+
if tree.depth == 0
|
|
154
|
+
process_root_node(tree, context)
|
|
155
|
+
else
|
|
156
|
+
process_nested_node(tree, context)
|
|
137
157
|
end
|
|
158
|
+
end
|
|
138
159
|
|
|
139
|
-
|
|
140
|
-
|
|
160
|
+
def process_root_node(tree, context)
|
|
161
|
+
root_value = tree.values[0]
|
|
162
|
+
has_arbitrary_param = root_value.start_with?(":")
|
|
163
|
+
|
|
164
|
+
child_procs = build_child_procs(tree, context)
|
|
165
|
+
route_procs = build_route_procs(tree, context)
|
|
166
|
+
|
|
167
|
+
if has_arbitrary_param
|
|
168
|
+
build_param_root_proc(root_value, child_procs, route_procs)
|
|
169
|
+
else
|
|
170
|
+
build_string_root_proc(root_value, child_procs, route_procs)
|
|
141
171
|
end
|
|
172
|
+
end
|
|
142
173
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
Proc.new do |r|
|
|
146
|
-
r.on String do |param_val|
|
|
147
|
-
route_parts.each do |route_part|
|
|
148
|
-
r.params[route_part] = param_val
|
|
149
|
-
end
|
|
174
|
+
def process_nested_node(tree, context)
|
|
175
|
+
has_arbitrary_param = tree.values[0].start_with?(":")
|
|
150
176
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
end
|
|
177
|
+
child_procs = build_child_procs(tree, context)
|
|
178
|
+
route_procs = build_route_procs(tree, context)
|
|
154
179
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
180
|
+
if has_arbitrary_param
|
|
181
|
+
build_param_nested_proc(tree, child_procs, route_procs)
|
|
182
|
+
else
|
|
183
|
+
build_string_nested_proc(tree, child_procs, route_procs)
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def build_param_root_proc(root_value, child_procs, route_procs)
|
|
188
|
+
param_name = root_value.gsub(":", "")
|
|
189
|
+
|
|
190
|
+
Proc.new do |r|
|
|
191
|
+
r.on String do |param_val|
|
|
192
|
+
r.params[param_name] = param_val
|
|
193
|
+
|
|
194
|
+
child_procs.each do |child_proc|
|
|
195
|
+
r.instance_exec(r, &child_proc)
|
|
196
|
+
end
|
|
159
197
|
|
|
160
|
-
|
|
198
|
+
if route_procs.any?
|
|
199
|
+
r.is do
|
|
200
|
+
route_procs.each do |route_proc|
|
|
201
|
+
r.instance_exec(r, &route_proc)
|
|
161
202
|
end
|
|
162
203
|
|
|
163
204
|
nil
|
|
164
205
|
end
|
|
165
206
|
end
|
|
166
|
-
else
|
|
167
|
-
Proc.new do |r|
|
|
168
|
-
r.on route_parts[0] do
|
|
169
|
-
child_procs.each do |child_proc|
|
|
170
|
-
r.instance_exec(r, &child_proc)
|
|
171
|
-
end
|
|
172
207
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
208
|
+
nil
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def build_string_root_proc(root_value, child_procs, route_procs)
|
|
214
|
+
Proc.new do |r|
|
|
215
|
+
r.on root_value do
|
|
216
|
+
child_procs.each do |child_proc|
|
|
217
|
+
r.instance_exec(r, &child_proc)
|
|
218
|
+
end
|
|
177
219
|
|
|
178
|
-
|
|
220
|
+
if route_procs.any?
|
|
221
|
+
r.is do
|
|
222
|
+
route_procs.each do |route_proc|
|
|
223
|
+
r.instance_exec(r, &route_proc)
|
|
179
224
|
end
|
|
180
225
|
|
|
181
226
|
nil
|
|
182
227
|
end
|
|
183
228
|
end
|
|
229
|
+
|
|
230
|
+
nil
|
|
184
231
|
end
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
if has_arbitrary_param
|
|
188
|
-
r.is String do |param_val|
|
|
189
|
-
route_parts.each do |route_part|
|
|
190
|
-
r.params[route_part] = param_val
|
|
191
|
-
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
192
234
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
235
|
+
def build_param_nested_proc(tree, child_procs, route_procs)
|
|
236
|
+
route_parts = tree.values.map { |v| v.gsub(":", "") }
|
|
237
|
+
|
|
238
|
+
Proc.new do |r|
|
|
239
|
+
r.on String do |param_val|
|
|
240
|
+
route_parts.each do |route_part|
|
|
241
|
+
r.params[route_part] = param_val
|
|
242
|
+
end
|
|
197
243
|
|
|
198
|
-
|
|
244
|
+
child_procs.each do |child_proc|
|
|
245
|
+
r.instance_exec(r, &child_proc)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
if route_procs.any?
|
|
249
|
+
r.is do
|
|
250
|
+
route_procs.each do |route_proc|
|
|
251
|
+
r.instance_exec(r, &route_proc)
|
|
199
252
|
end
|
|
200
253
|
|
|
201
254
|
nil
|
|
202
255
|
end
|
|
203
|
-
|
|
204
|
-
r.is route_parts[0] do
|
|
205
|
-
r.is do
|
|
206
|
-
route_procs.each do |route_proc|
|
|
207
|
-
r.instance_exec(r, &route_proc)
|
|
208
|
-
end
|
|
256
|
+
end
|
|
209
257
|
|
|
210
|
-
|
|
258
|
+
nil
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def build_string_nested_proc(tree, child_procs, route_procs)
|
|
264
|
+
route_part = tree.values[0]
|
|
265
|
+
|
|
266
|
+
Proc.new do |r|
|
|
267
|
+
r.on route_part do
|
|
268
|
+
child_procs.each do |child_proc|
|
|
269
|
+
r.instance_exec(r, &child_proc)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
if route_procs.any?
|
|
273
|
+
r.is do
|
|
274
|
+
route_procs.each do |route_proc|
|
|
275
|
+
r.instance_exec(r, &route_proc)
|
|
211
276
|
end
|
|
212
277
|
|
|
213
278
|
nil
|
|
214
279
|
end
|
|
215
280
|
end
|
|
281
|
+
|
|
282
|
+
nil
|
|
216
283
|
end
|
|
217
284
|
end
|
|
285
|
+
end
|
|
218
286
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
287
|
+
def build_child_procs(tree, context)
|
|
288
|
+
tree.children.map do |child|
|
|
289
|
+
build_traverse_tree_proc(child, context)
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
def build_route_procs(tree, context)
|
|
294
|
+
tree.routes.map do |route|
|
|
295
|
+
route_proc(route, context)
|
|
223
296
|
end
|
|
224
297
|
end
|
|
225
298
|
end
|
|
@@ -251,4 +324,4 @@ class Roda
|
|
|
251
324
|
|
|
252
325
|
register_plugin(:ree_routes, Roda::RodaPlugins::ReeRoutes)
|
|
253
326
|
end
|
|
254
|
-
end
|
|
327
|
+
end
|
|
@@ -59,7 +59,24 @@ class ReeRoda::BuildRoutingTree
|
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def print_tree(tree = self)
|
|
62
|
-
|
|
62
|
+
if tree.is_a?(Array)
|
|
63
|
+
puts "Multiple trees:"
|
|
64
|
+
tree.each_with_index do |t, i|
|
|
65
|
+
puts "\nTree #{i + 1}:"
|
|
66
|
+
print_tree(t)
|
|
67
|
+
end
|
|
68
|
+
return nil
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
puts "#{get_offset(tree.depth)}#{tree.values.inspect} - depth: #{tree.depth}, type: #{tree.type}"
|
|
72
|
+
|
|
73
|
+
if tree.routes.any?
|
|
74
|
+
tree.routes.each do |route|
|
|
75
|
+
puts "#{get_offset(tree.depth + 1)}- #{route.request_method} #{route.path}"
|
|
76
|
+
puts "#{get_offset(tree.depth + 2)} summary: #{route.summary}"
|
|
77
|
+
puts "#{get_offset(tree.depth + 2)} override: #{route.override ? 'YES' : 'NO'}"
|
|
78
|
+
end
|
|
79
|
+
end
|
|
63
80
|
|
|
64
81
|
if tree.children.length > 0
|
|
65
82
|
tree.children.each do |child|
|
|
@@ -70,48 +87,76 @@ class ReeRoda::BuildRoutingTree
|
|
|
70
87
|
nil
|
|
71
88
|
end
|
|
72
89
|
|
|
73
|
-
def print_proc_tree(tree = self)
|
|
74
|
-
|
|
90
|
+
def print_proc_tree(tree = self, is_root_array: false)
|
|
91
|
+
if tree.is_a?(Array)
|
|
92
|
+
puts "Multiple root trees found:"
|
|
93
|
+
tree.each_with_index do |t, i|
|
|
94
|
+
puts "\nTree #{i + 1}:"
|
|
95
|
+
print_proc_tree(t)
|
|
96
|
+
end
|
|
97
|
+
return nil
|
|
98
|
+
end
|
|
75
99
|
|
|
76
|
-
if tree.
|
|
77
|
-
|
|
78
|
-
puts "#{get_offset(tree.depth)}r.on #{param_value} do"
|
|
100
|
+
if tree.depth == 0
|
|
101
|
+
param_value = tree.values[0].start_with?(":") ? String : "\"#{tree.values[0]}\""
|
|
79
102
|
|
|
80
|
-
|
|
81
|
-
print_proc_tree(child)
|
|
82
|
-
end
|
|
103
|
+
puts "r.on #{param_value} do"
|
|
83
104
|
|
|
84
|
-
|
|
105
|
+
tree.children.each do |child|
|
|
106
|
+
print_proc_tree(child)
|
|
85
107
|
end
|
|
86
108
|
|
|
87
|
-
|
|
109
|
+
if tree.routes.any?
|
|
110
|
+
puts " r.is do"
|
|
111
|
+
tree.routes.each do |route|
|
|
112
|
+
puts " r.#{route.request_method} do"
|
|
113
|
+
if route.override
|
|
114
|
+
puts " # OVERRIDE: custom logic"
|
|
115
|
+
puts " # Summary: #{route.summary}"
|
|
116
|
+
else
|
|
117
|
+
puts " # Action: #{route.action&.name}"
|
|
118
|
+
puts " # Serializer: #{route.serializer&.name}" if route.serializer
|
|
119
|
+
puts " # Warden scope: #{route.warden_scope}"
|
|
120
|
+
end
|
|
121
|
+
puts " end"
|
|
122
|
+
end
|
|
123
|
+
puts " end"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
puts "end"
|
|
127
|
+
|
|
88
128
|
else
|
|
89
|
-
|
|
90
|
-
|
|
129
|
+
has_arbitrary_param = tree.values[0].start_with?(":")
|
|
130
|
+
param_value = has_arbitrary_param ? String : "\"#{tree.values[0]}\""
|
|
131
|
+
|
|
132
|
+
indent = " " * tree.depth
|
|
133
|
+
|
|
134
|
+
if tree.children.length > 0 || tree.routes.length > 0
|
|
135
|
+
puts "#{indent}r.on #{param_value} do"
|
|
136
|
+
|
|
91
137
|
|
|
92
138
|
tree.children.each do |child|
|
|
93
139
|
print_proc_tree(child)
|
|
94
140
|
end
|
|
95
141
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
puts "#{
|
|
142
|
+
if tree.routes.any?
|
|
143
|
+
puts "#{indent} r.is do"
|
|
144
|
+
tree.routes.each do |route|
|
|
145
|
+
puts "#{indent} r.#{route.request_method} do"
|
|
146
|
+
if route.override
|
|
147
|
+
puts "#{indent} # OVERRIDE: custom logic"
|
|
148
|
+
puts "#{indent} # Summary: #{route.summary}"
|
|
149
|
+
else
|
|
150
|
+
puts "#{indent} # Action: #{route.action&.name}"
|
|
151
|
+
puts "#{indent} # Serializer: #{route.serializer&.name}" if route.serializer
|
|
152
|
+
puts "#{indent} # Warden scope: #{route.warden_scope}"
|
|
153
|
+
end
|
|
154
|
+
puts "#{indent} end"
|
|
155
|
+
end
|
|
156
|
+
puts "#{indent} end"
|
|
111
157
|
end
|
|
112
|
-
puts "#{get_offset(tree.depth + 1)}end"
|
|
113
158
|
|
|
114
|
-
puts "#{
|
|
159
|
+
puts "#{indent}end"
|
|
115
160
|
end
|
|
116
161
|
end
|
|
117
162
|
|
|
@@ -125,46 +170,54 @@ class ReeRoda::BuildRoutingTree
|
|
|
125
170
|
end
|
|
126
171
|
end
|
|
127
172
|
|
|
128
|
-
contract(ArrayOf[ReeRoutes::Route] =>
|
|
173
|
+
contract(ArrayOf[ReeRoutes::Route] => ArrayOf[RoutingTree])
|
|
129
174
|
def call(routes)
|
|
130
|
-
|
|
175
|
+
trees = []
|
|
131
176
|
|
|
132
177
|
routes.each do |route|
|
|
133
|
-
splitted = route.path.split("/")
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
178
|
+
splitted = route.path.split("/").reject(&:empty?)
|
|
179
|
+
matched_tree = nil
|
|
180
|
+
|
|
181
|
+
root_part = splitted[0]
|
|
182
|
+
|
|
183
|
+
# find tree for root segment
|
|
184
|
+
trees.each do |tree|
|
|
185
|
+
if tree.values.include?(root_part)
|
|
186
|
+
matched_tree = tree
|
|
187
|
+
break
|
|
141
188
|
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
if matched_tree.nil?
|
|
192
|
+
# create new tree for root
|
|
193
|
+
matched_tree = RoutingTree.new([root_part], 0, :string)
|
|
194
|
+
trees << matched_tree
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
parent_tree = matched_tree
|
|
142
198
|
|
|
143
|
-
|
|
199
|
+
# process other parts
|
|
200
|
+
splitted[1..-1].each_with_index do |v, i|
|
|
201
|
+
current = parent_tree.find_by_value(value: v, depth: i+1)
|
|
144
202
|
|
|
145
203
|
if current
|
|
146
204
|
parent_tree = current
|
|
147
|
-
current.add_route(route) if j == (splitted.length - 1)
|
|
148
205
|
else
|
|
149
|
-
if
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
next
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
new_tree = parent_tree.add_child(v, j, v.start_with?(":") ? :param : :string)
|
|
206
|
+
# check if we can add it to existing param node
|
|
207
|
+
if parent_tree.children.any? { |c| c.type == :param } && v.start_with?(":")
|
|
208
|
+
param_child = parent_tree.children.find { |c| c.type == :param }
|
|
209
|
+
param_child.values << v if !param_child.values.include?(v)
|
|
210
|
+
parent_tree = param_child
|
|
211
|
+
else
|
|
212
|
+
new_tree = parent_tree.add_child(v, i+1, v.start_with?(":") ? :param : :string)
|
|
160
213
|
parent_tree = new_tree
|
|
161
214
|
end
|
|
162
|
-
|
|
163
|
-
parent_tree.add_route(route) if j == (splitted.length - 1)
|
|
164
215
|
end
|
|
165
216
|
end
|
|
217
|
+
|
|
218
|
+
parent_tree.add_route(route)
|
|
166
219
|
end
|
|
167
220
|
|
|
168
|
-
|
|
221
|
+
trees
|
|
169
222
|
end
|
|
170
|
-
end
|
|
223
|
+
end
|
|
@@ -75,6 +75,21 @@ RSpec.describe ReeRoda::App do
|
|
|
75
75
|
end
|
|
76
76
|
end
|
|
77
77
|
|
|
78
|
+
class ReeRodaTest::WardenScopeCmd
|
|
79
|
+
include ReeActions::DSL
|
|
80
|
+
|
|
81
|
+
action :warden_scope_cmd
|
|
82
|
+
|
|
83
|
+
ActionCaster = build_mapper.use(:cast) do
|
|
84
|
+
string? :user
|
|
85
|
+
string? :another_user
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def call(access, attrs)
|
|
89
|
+
{result: access.to_s}
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
78
93
|
class ReeRodaTest::ActionCmd
|
|
79
94
|
include ReeActions::DSL
|
|
80
95
|
|
|
@@ -110,6 +125,19 @@ RSpec.describe ReeRoda::App do
|
|
|
110
125
|
default_warden_scope :identity
|
|
111
126
|
opts = {from: :ree_roda_test}
|
|
112
127
|
|
|
128
|
+
get "some_other_route" do
|
|
129
|
+
summary "Another route"
|
|
130
|
+
warden_scope :visitor
|
|
131
|
+
sections "some_action"
|
|
132
|
+
action :cmd, **opts
|
|
133
|
+
override do |r|
|
|
134
|
+
r.json do
|
|
135
|
+
r.response.status = 200
|
|
136
|
+
"hello"
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
113
141
|
get "api/action/:id" do
|
|
114
142
|
summary "Some action"
|
|
115
143
|
warden_scope :visitor
|
|
@@ -187,6 +215,13 @@ RSpec.describe ReeRoda::App do
|
|
|
187
215
|
action :serializer_error_cmd, **opts
|
|
188
216
|
serializer :serializer, **opts
|
|
189
217
|
end
|
|
218
|
+
|
|
219
|
+
get "check_warden" do
|
|
220
|
+
summary "Action to check Warden scopes"
|
|
221
|
+
warden_scope :user, :another_user
|
|
222
|
+
sections "some_action"
|
|
223
|
+
action :warden_scope_cmd, **opts
|
|
224
|
+
end
|
|
190
225
|
end
|
|
191
226
|
end
|
|
192
227
|
|
|
@@ -202,13 +237,43 @@ RSpec.describe ReeRoda::App do
|
|
|
202
237
|
end
|
|
203
238
|
end
|
|
204
239
|
|
|
240
|
+
class UserStrategy < Warden::Strategies::Base
|
|
241
|
+
include Ree::LinkDSL
|
|
242
|
+
|
|
243
|
+
def valid?
|
|
244
|
+
params = request.params
|
|
245
|
+
return true if !params["user"].nil?
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def authenticate!
|
|
249
|
+
success!({user: "user"})
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
class AnotherUserStrategy < Warden::Strategies::Base
|
|
254
|
+
include Ree::LinkDSL
|
|
255
|
+
|
|
256
|
+
def valid?
|
|
257
|
+
params = request.params
|
|
258
|
+
return true if !params["another_user"].nil?
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def authenticate!
|
|
262
|
+
success!({user: "another_user"})
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
205
266
|
Warden::Strategies.add(:visitor, VisitorStrategy)
|
|
267
|
+
Warden::Strategies.add(:user, UserStrategy)
|
|
268
|
+
Warden::Strategies.add(:another_user, AnotherUserStrategy)
|
|
206
269
|
|
|
207
270
|
class TestApp < ReeRoda::App
|
|
208
271
|
use Warden::Manager do |config|
|
|
209
272
|
config.default_strategies :visitor
|
|
210
273
|
config.default_scope = :visitor
|
|
211
274
|
config.scope_defaults :visitor, strategies: [:visitor], store: false
|
|
275
|
+
config.scope_defaults :user, strategies: [:user], store: false
|
|
276
|
+
config.scope_defaults :another_user, strategies: [:another_user], store: false
|
|
212
277
|
|
|
213
278
|
config.failure_app = -> (env) {
|
|
214
279
|
[
|
|
@@ -292,4 +357,24 @@ RSpec.describe ReeRoda::App do
|
|
|
292
357
|
get "api/serializer_error"
|
|
293
358
|
expect(last_response.status).to eq(500)
|
|
294
359
|
}
|
|
295
|
-
|
|
360
|
+
|
|
361
|
+
it {
|
|
362
|
+
get "some_other_route"
|
|
363
|
+
expect(last_response.status).to eq(200)
|
|
364
|
+
expect(last_response.status).not_to eq(404)
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
it {
|
|
368
|
+
# first scope is passed
|
|
369
|
+
get "check_warden?user=hello"
|
|
370
|
+
expect(last_response.status).to eq(200)
|
|
371
|
+
|
|
372
|
+
# second scope is passed
|
|
373
|
+
get "check_warden?another_user=hello"
|
|
374
|
+
expect(last_response.status).to eq(200)
|
|
375
|
+
|
|
376
|
+
# all scopes failed
|
|
377
|
+
get "check_warden"
|
|
378
|
+
expect(last_response.status).to eq(401)
|
|
379
|
+
}
|
|
380
|
+
end
|
|
@@ -231,8 +231,9 @@ RSpec.describe :build_routing_tree do
|
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
it {
|
|
234
|
-
|
|
234
|
+
trees = build_routing_tree(routes)
|
|
235
235
|
|
|
236
|
+
tree = trees.first
|
|
236
237
|
# check that all end nodes have routes
|
|
237
238
|
# and that not end nodes don't have route
|
|
238
239
|
id_nodes = [*tree.find_by_value(value: ":id", depth: 2), *tree.find_by_value(value: ":id", depth: 4)]
|
|
@@ -273,4 +274,4 @@ RSpec.describe :build_routing_tree do
|
|
|
273
274
|
res = TestErrorApp.app.call(env)
|
|
274
275
|
expect(res).to eq [404, {"content-length"=>"0", "content-type"=>"text/html"}, []]
|
|
275
276
|
}
|
|
276
|
-
end
|
|
277
|
+
end
|
|
@@ -44,8 +44,8 @@ module ReeRoutes
|
|
|
44
44
|
Ree.container.compile(@dsl.package, name)
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
def default_warden_scope(
|
|
48
|
-
@
|
|
47
|
+
def default_warden_scope(*method_names)
|
|
48
|
+
@default_warden_scopes = method_names
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
[:get, :post, :put, :delete, :patch, :head, :options].each do |request_method|
|
|
@@ -66,8 +66,8 @@ module ReeRoutes
|
|
|
66
66
|
builder = ReeRoutes::RouteBuilder.new
|
|
67
67
|
builder.instance_exec(&proc)
|
|
68
68
|
|
|
69
|
-
if @
|
|
70
|
-
builder.warden_scope(
|
|
69
|
+
if @default_warden_scopes && (!builder.get_route.warden_scopes || builder.get_route.warden_scopes.empty?)
|
|
70
|
+
builder.warden_scope(*@default_warden_scopes)
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
uri = URI.parse(path) rescue nil
|
|
@@ -100,4 +100,4 @@ module ReeRoutes
|
|
|
100
100
|
end
|
|
101
101
|
end
|
|
102
102
|
end
|
|
103
|
-
end
|
|
103
|
+
end
|
|
@@ -2,9 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
class ReeRoutes::Route
|
|
4
4
|
attr_accessor :summary, :request_method, :serializer, :respond_to,
|
|
5
|
-
:sections, :action, :route, :
|
|
5
|
+
:sections, :action, :route, :warden_scopes, :path, :override
|
|
6
6
|
|
|
7
7
|
def valid?
|
|
8
|
-
!action.nil? && !summary.nil? && !
|
|
8
|
+
!action.nil? && !summary.nil? && !warden_scopes.nil? && !warden_scopes.empty?
|
|
9
9
|
end
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
def warden_scopes=(scopes)
|
|
12
|
+
@warden_scopes = Array(scopes)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def warden_scope
|
|
16
|
+
@warden_scopes&.first
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def warden_scope=(scope)
|
|
20
|
+
@warden_scopes = Array(scope)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -10,9 +10,9 @@ class ReeRoutes::RouteBuilder
|
|
|
10
10
|
@route.respond_to = :json
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
contract Symbol => Symbol
|
|
14
|
-
def warden_scope(
|
|
15
|
-
@route.
|
|
13
|
+
contract SplatOf[Symbol] => ArrayOf[Symbol]
|
|
14
|
+
def warden_scope(*scopes)
|
|
15
|
+
@route.warden_scopes = scopes.flatten
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
contract Symbol => Symbol
|
|
@@ -68,4 +68,4 @@ class ReeRoutes::RouteBuilder
|
|
|
68
68
|
@route.redirect = Redirect.new(path, code)
|
|
69
69
|
nil
|
|
70
70
|
end
|
|
71
|
-
end
|
|
71
|
+
end
|
|
@@ -50,18 +50,20 @@ RSpec.describe ReeRoutes::DSL, type: [:autoclean] do
|
|
|
50
50
|
include ReeRoutes::DSL
|
|
51
51
|
|
|
52
52
|
routes :routes do
|
|
53
|
-
default_warden_scope :user
|
|
53
|
+
default_warden_scope :identity, :user
|
|
54
54
|
|
|
55
55
|
post "users" do
|
|
56
56
|
summary "Test route"
|
|
57
57
|
action :cmd, from: :ree_routes_test
|
|
58
58
|
serializer :serializer, from: :ree_routes_test
|
|
59
|
+
warden_scope :identity, :user
|
|
59
60
|
respond_to :json
|
|
60
61
|
end
|
|
61
62
|
|
|
62
63
|
get "files.csv" do
|
|
63
64
|
summary "Test route"
|
|
64
65
|
action :cmd, from: :ree_routes_test
|
|
66
|
+
warden_scope :user
|
|
65
67
|
respond_to :csv
|
|
66
68
|
end
|
|
67
69
|
end
|
|
@@ -90,4 +92,4 @@ RSpec.describe ReeRoutes::DSL, type: [:autoclean] do
|
|
|
90
92
|
|
|
91
93
|
expect(csv_route.respond_to).to eq(:csv)
|
|
92
94
|
}
|
|
93
|
-
end
|
|
95
|
+
end
|
data/lib/ree_lib/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ree_lib
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.3.
|
|
4
|
+
version: 1.3.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ruslan Gatiyatov
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 2026-02-03 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: ree
|