jsonapi-authorization 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
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
|