jsonapi-authorization 0.5.0 → 0.6.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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47495edb7695129cd3ddd577ce547db63df70b4f
|
4
|
+
data.tar.gz: 68f2686dfa2143ec831816e39b02a1c2170ec3a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79314420e9e62352436beca771f31823a9fc2bfb72122deada6a4bac09941ee4593b9f468747392ddfbe0169a6737f1d7b93a3b17c486000fcf223ca8faf1f19
|
7
|
+
data.tar.gz: 87389fd2aa637d0233666f747fab5c8aaded2371594d09915879d70d6d6e0120327b9a2cf3bd00bea35d17036cb34705aeeea7a7338f98024a9fecb8f5d2fcc5
|
data/bin/console
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require "bundler/setup"
|
4
|
+
require "rails/all"
|
4
5
|
require "jsonapi/authorization"
|
5
6
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
@@ -10,5 +11,5 @@ require "jsonapi/authorization"
|
|
10
11
|
# require "pry"
|
11
12
|
# Pry.start
|
12
13
|
|
13
|
-
require "
|
14
|
-
|
14
|
+
require "pry"
|
15
|
+
Pry.start
|
@@ -17,6 +17,32 @@ module JSONAPI
|
|
17
17
|
set_callback :remove_to_many_relationship_operation, :before, :authorize_remove_to_many_relationship
|
18
18
|
set_callback :remove_to_one_relationship_operation, :before, :authorize_remove_to_one_relationship
|
19
19
|
|
20
|
+
[
|
21
|
+
:find_operation,
|
22
|
+
:show_operation,
|
23
|
+
:show_related_resource_operation,
|
24
|
+
:show_related_resources_operation,
|
25
|
+
:create_resource_operation,
|
26
|
+
:replace_fields_operation
|
27
|
+
].each do |op_name|
|
28
|
+
set_callback op_name, :after, :authorize_include_directive
|
29
|
+
end
|
30
|
+
|
31
|
+
def authorize_include_directive
|
32
|
+
return if @result.is_a?(::JSONAPI::ErrorsOperationResult)
|
33
|
+
resources = Array.wrap(
|
34
|
+
if @result.respond_to?(:resources)
|
35
|
+
@result.resources
|
36
|
+
elsif @result.respond_to?(:resource)
|
37
|
+
@result.resource
|
38
|
+
end
|
39
|
+
)
|
40
|
+
|
41
|
+
resources.each do |resource|
|
42
|
+
authorize_model_includes(resource._model)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
20
46
|
def authorize_find
|
21
47
|
authorizer.find(@operation.resource_klass._model_class)
|
22
48
|
end
|
@@ -209,8 +235,12 @@ module JSONAPI
|
|
209
235
|
end
|
210
236
|
end
|
211
237
|
|
238
|
+
def resource_class_for_relationship(assoc_name)
|
239
|
+
@operation.resource_klass._relationship(assoc_name).resource_klass
|
240
|
+
end
|
241
|
+
|
212
242
|
def model_class_for_relationship(assoc_name)
|
213
|
-
|
243
|
+
resource_class_for_relationship(assoc_name)._model_class
|
214
244
|
end
|
215
245
|
|
216
246
|
def related_models
|
@@ -218,13 +248,71 @@ module JSONAPI
|
|
218
248
|
return [] if data.nil?
|
219
249
|
|
220
250
|
[:to_one, :to_many].flat_map do |rel_type|
|
221
|
-
data[rel_type].flat_map do |assoc_name,
|
222
|
-
|
223
|
-
#
|
224
|
-
|
251
|
+
data[rel_type].flat_map do |assoc_name, assoc_value|
|
252
|
+
case assoc_value
|
253
|
+
when Hash # polymorphic relationship
|
254
|
+
resource_class = @operation.resource_klass.resource_for(assoc_value[:type].to_s)
|
255
|
+
resource_class.find_by_key(assoc_value[:id], context: @operation.options[:context])._model
|
256
|
+
else
|
257
|
+
resource_class = resource_class_for_relationship(assoc_name)
|
258
|
+
primary_key = resource_class._primary_key
|
259
|
+
resource_class._model_class.where(primary_key => assoc_value)
|
260
|
+
end
|
225
261
|
end
|
226
262
|
end
|
227
263
|
end
|
264
|
+
|
265
|
+
def authorize_model_includes(source_record)
|
266
|
+
if @request.include_directives
|
267
|
+
@request.include_directives.model_includes.each do |include_item|
|
268
|
+
authorize_include_item(@operation.resource_klass, source_record, include_item)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
def authorize_include_item(resource_klass, source_record, include_item)
|
274
|
+
case include_item
|
275
|
+
when Hash
|
276
|
+
# e.g. {articles: [:comments, :author]} when ?include=articles.comments,articles.author
|
277
|
+
include_item.each do |rel_name, deep|
|
278
|
+
authorize_include_item(resource_klass, source_record, rel_name)
|
279
|
+
relationship = resource_klass._relationship(rel_name)
|
280
|
+
next_resource_klass = relationship.resource_klass
|
281
|
+
Array.wrap(
|
282
|
+
source_record.public_send(
|
283
|
+
relationship.relation_name(@operation.options[:context])
|
284
|
+
)
|
285
|
+
).each do |next_source_record|
|
286
|
+
deep.each do |next_include_item|
|
287
|
+
authorize_include_item(
|
288
|
+
next_resource_klass,
|
289
|
+
next_source_record,
|
290
|
+
next_include_item
|
291
|
+
)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
when Symbol
|
296
|
+
relationship = resource_klass._relationship(include_item)
|
297
|
+
case relationship
|
298
|
+
when JSONAPI::Relationship::ToOne
|
299
|
+
related_record = source_record.public_send(
|
300
|
+
relationship.relation_name(@operation.options[:context])
|
301
|
+
)
|
302
|
+
return if related_record.nil?
|
303
|
+
authorizer.include_has_one_resource(source_record, related_record)
|
304
|
+
when JSONAPI::Relationship::ToMany
|
305
|
+
authorizer.include_has_many_resource(
|
306
|
+
source_record,
|
307
|
+
relationship.resource_klass._model_class
|
308
|
+
)
|
309
|
+
else
|
310
|
+
raise "Unexpected relationship type: #{relationship.inspect}"
|
311
|
+
end
|
312
|
+
else
|
313
|
+
raise "Unknown include directive: #{include_item}"
|
314
|
+
end
|
315
|
+
end
|
228
316
|
end
|
229
317
|
end
|
230
318
|
end
|
@@ -190,6 +190,40 @@ module JSONAPI
|
|
190
190
|
def remove_to_one_relationship(source_record, related_record)
|
191
191
|
raise NotImplementedError
|
192
192
|
end
|
193
|
+
|
194
|
+
# Any request including <tt>?include=other-resources</tt>
|
195
|
+
#
|
196
|
+
# This will be called for each has_many relationship if the include goes
|
197
|
+
# deeper than one level until some authorization fails or the include
|
198
|
+
# directive has been travelled completely.
|
199
|
+
#
|
200
|
+
# We can't pass all the records of a +has_many+ association here due to
|
201
|
+
# performance reasons, so the class is passed instead.
|
202
|
+
#
|
203
|
+
# ==== Parameters
|
204
|
+
#
|
205
|
+
# * +source_record+ — The source relationship record, e.g. an Article in
|
206
|
+
# article.comments check
|
207
|
+
# * +record_class+ - The underlying record class for the relationships
|
208
|
+
# resource.
|
209
|
+
def include_has_many_resource(source_record, record_class)
|
210
|
+
::Pundit.authorize(user, record_class, 'index?')
|
211
|
+
end
|
212
|
+
|
213
|
+
# Any request including <tt>?include=another-resource</tt>
|
214
|
+
#
|
215
|
+
# This will be called for each has_one relationship if the include goes
|
216
|
+
# deeper than one level until some authorization fails or the include
|
217
|
+
# directive has been travelled completely.
|
218
|
+
#
|
219
|
+
# ==== Parameters
|
220
|
+
#
|
221
|
+
# * +source_record+ — The source relationship record, e.g. an Article in
|
222
|
+
# article.author check
|
223
|
+
# * +related_record+ - The associated record to return
|
224
|
+
def include_has_one_resource(source_record, related_record)
|
225
|
+
::Pundit.authorize(user, related_record, 'show?')
|
226
|
+
end
|
193
227
|
end
|
194
228
|
end
|
195
229
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonapi-authorization
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vesa Laakso
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-03-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: jsonapi-resources
|