deep_unrest 0.1.68 → 0.1.72
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/lib/deep_unrest/authorization/pundit_strategy.rb +11 -4
- data/lib/deep_unrest/read.rb +33 -10
- data/lib/deep_unrest/version.rb +1 -1
- data/lib/deep_unrest/write.rb +3 -3
- data/lib/deep_unrest.rb +21 -11
- metadata +18 -18
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 66699a186572baa00ca20f983f1fe7462ee35e59785c2c73d98a9d4502036890
|
|
4
|
+
data.tar.gz: 29406a1d5a62da44de4a744f8cc55c99d74e0d186f5c44459f067ce02e38e302
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 60c92b8c2f70f1c1e83e28666e01244f1db911c1dd49889f3b38961da959afc71bbd333dddc71fcdf7c07a804d463c9bb91786c5a01742c1524bfbd339f13990
|
|
7
|
+
data.tar.gz: 6423c1817958c40e37fa27eac897acf599d43131de15c60e05279502df269e8cdc94e969c56156cb9ab673795d9f234939c398341f84d5058a241901d7c1e7f7
|
|
@@ -17,12 +17,19 @@ module DeepUnrest
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def self.auth_error_message(user, scope)
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
if user
|
|
21
|
+
actor = "#{user.class.name} with id '#{user.id}' is"
|
|
22
|
+
else
|
|
23
|
+
actor = "Anonymous users are"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
target = (scope[:type] || scope[:key]).to_s.classify
|
|
22
27
|
unless %i[create update_all].include? scope[:scope_type]
|
|
23
|
-
|
|
28
|
+
target_id = (scope[:id] || scope.dig(:query, :id)).to_s.gsub('.', '')
|
|
29
|
+
target += " with id '#{target_id.to_s.gsub('.', '')}'"
|
|
24
30
|
end
|
|
25
|
-
|
|
31
|
+
|
|
32
|
+
msg = "#{actor} not authorized to #{scope[:scope_type].to_s.downcase} #{target}"
|
|
26
33
|
|
|
27
34
|
[{ title: msg,
|
|
28
35
|
source: { pointer: scope[:path] } }].to_json
|
data/lib/deep_unrest/read.rb
CHANGED
|
@@ -102,6 +102,11 @@ module DeepUnrest
|
|
|
102
102
|
end
|
|
103
103
|
end
|
|
104
104
|
|
|
105
|
+
def self.format_processor_results(resource_klass, processor_result)
|
|
106
|
+
results = processor_result.resource_set.resource_klasses[resource_klass] || {}
|
|
107
|
+
results.values.map {|r| r[:resource] }
|
|
108
|
+
end
|
|
109
|
+
|
|
105
110
|
def self.query_list(ctx, item, mappings, parent_context, included, meta, addr, parent)
|
|
106
111
|
base_query = item[:query].deep_dup
|
|
107
112
|
extension = base_query.dig(:extend, parent&.fetch(:record)&.id&.to_s&.underscore) || {}
|
|
@@ -111,28 +116,37 @@ module DeepUnrest
|
|
|
111
116
|
paginator = get_paginator(query, parent)
|
|
112
117
|
resource = item[:resource]
|
|
113
118
|
|
|
114
|
-
# monkey patch the resource to only show authorized records
|
|
115
119
|
r_metaclass = class << resource; self; end
|
|
116
|
-
r_metaclass.
|
|
120
|
+
if r_metaclass.method_defined? :records
|
|
121
|
+
r_metaclass.class_eval do
|
|
122
|
+
alias_method :records_original, :records
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
117
126
|
# TODO: find a way to do this that doesn't blow out the original :records method
|
|
118
|
-
|
|
119
|
-
|
|
127
|
+
resource.define_singleton_method(:records) { |ctx|
|
|
128
|
+
full_scope = if self.respond_to? :records_original
|
|
129
|
+
records_original(ctx)
|
|
130
|
+
else
|
|
131
|
+
super(ctx)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
item[:scope].merge(full_scope)
|
|
120
135
|
}
|
|
121
136
|
|
|
122
137
|
# transform sort value casing for rails
|
|
123
138
|
sort_criteria = query[:sort]&.map { |s| s.clone.merge(field: s[:field].underscore) }
|
|
124
|
-
|
|
139
|
+
serializer = JSONAPI::ResourceSerializer.new(resource)
|
|
125
140
|
processor = JSONAPI::Processor.new(resource,
|
|
126
141
|
:find,
|
|
127
142
|
filters: query[:filter] || {},
|
|
128
143
|
context: ctx,
|
|
129
144
|
sort_criteria: sort_criteria,
|
|
145
|
+
serializer: serializer,
|
|
130
146
|
paginator: paginator)
|
|
131
147
|
|
|
132
148
|
jsonapi_result = processor.process
|
|
133
|
-
|
|
134
|
-
# un-monkey patch the resource :records method
|
|
135
|
-
r_metaclass.send(:alias_method, :records, :records_original)
|
|
149
|
+
resource_results = format_processor_results(resource, jsonapi_result)
|
|
136
150
|
|
|
137
151
|
meta << {
|
|
138
152
|
addr: [*addr, item[:key], 'meta'],
|
|
@@ -146,14 +160,14 @@ module DeepUnrest
|
|
|
146
160
|
}
|
|
147
161
|
|
|
148
162
|
# make sure to return empty array if no results are found for this node
|
|
149
|
-
if
|
|
163
|
+
if resource_results.empty?
|
|
150
164
|
meta << {
|
|
151
165
|
addr: [*addr, item[:key], 'data'],
|
|
152
166
|
serialized_result: []
|
|
153
167
|
}
|
|
154
168
|
end
|
|
155
169
|
|
|
156
|
-
|
|
170
|
+
resource_results.each_with_index do |record, i|
|
|
157
171
|
next_addr = [*addr, item[:key], 'data[]', i]
|
|
158
172
|
result = {
|
|
159
173
|
**item,
|
|
@@ -164,6 +178,15 @@ module DeepUnrest
|
|
|
164
178
|
included << result
|
|
165
179
|
recurse_included_queries(ctx, result, mappings, parent_context, included, meta, [*next_addr, :include])
|
|
166
180
|
end
|
|
181
|
+
ensure
|
|
182
|
+
# un-monkey patch the resource :records method
|
|
183
|
+
if r_metaclass.method_defined? :records_original
|
|
184
|
+
r_metaclass.class_eval do
|
|
185
|
+
alias_method :records, :records_original
|
|
186
|
+
end
|
|
187
|
+
else
|
|
188
|
+
r_metaclass.undef_method :records
|
|
189
|
+
end
|
|
167
190
|
end
|
|
168
191
|
|
|
169
192
|
def self.get_query_type(item)
|
data/lib/deep_unrest/version.rb
CHANGED
data/lib/deep_unrest/write.rb
CHANGED
|
@@ -73,16 +73,16 @@ module DeepUnrest
|
|
|
73
73
|
attributes = item.dig(:query, :attributes) || {}
|
|
74
74
|
resource = item[:resource]
|
|
75
75
|
p = JSONAPI::RequestParser.new
|
|
76
|
-
p.
|
|
76
|
+
p.source_klass = resource
|
|
77
77
|
opts = if item[:scope_type] == :create
|
|
78
78
|
resource.creatable_fields(ctx)
|
|
79
79
|
else
|
|
80
80
|
resource.updatable_fields(ctx)
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
-
p.parse_params({ attributes: attributes }, opts)[:attributes]
|
|
83
|
+
p.parse_params(resource, { attributes: attributes }, opts)[:attributes]
|
|
84
84
|
rescue JSONAPI::Exceptions::ParameterNotAllowed
|
|
85
|
-
unpermitted_keys = attributes.keys.map(&:to_sym) - opts
|
|
85
|
+
unpermitted_keys = attributes.keys.map(&:underscore).map(&:to_sym) - opts
|
|
86
86
|
item[:errors] = unpermitted_keys.each_with_object({}) do |attr_key, memo|
|
|
87
87
|
memo[attr_key] = 'Unpermitted parameter'
|
|
88
88
|
end
|
data/lib/deep_unrest.rb
CHANGED
|
@@ -162,7 +162,7 @@ module DeepUnrest
|
|
|
162
162
|
def self.parse_attributes(type, scope_type, attributes, user)
|
|
163
163
|
p = JSONAPI::RequestParser.new
|
|
164
164
|
resource = get_resource(type)
|
|
165
|
-
p.
|
|
165
|
+
p.source_klass = resource
|
|
166
166
|
ctx = { current_user: user }
|
|
167
167
|
opts = if scope_type == :create
|
|
168
168
|
resource.creatable_fields(ctx)
|
|
@@ -170,7 +170,7 @@ module DeepUnrest
|
|
|
170
170
|
resource.updatable_fields(ctx)
|
|
171
171
|
end
|
|
172
172
|
|
|
173
|
-
p.parse_params({ attributes: attributes }, opts)[:attributes]
|
|
173
|
+
p.parse_params(resource, { attributes: attributes }, opts)[:attributes]
|
|
174
174
|
rescue JSONAPI::Exceptions::ParameterNotAllowed
|
|
175
175
|
unpermitted_keys = attributes.keys.map(&:to_sym) - opts
|
|
176
176
|
msg = "Attributes #{unpermitted_keys} of #{type.classify} not allowed"
|
|
@@ -558,6 +558,19 @@ module DeepUnrest
|
|
|
558
558
|
DeepUnrest::Write.write(ctx, params, user)
|
|
559
559
|
end
|
|
560
560
|
|
|
561
|
+
def self.serialize_resource(resource_klass, fields, id)
|
|
562
|
+
resource_identity = JSONAPI::ResourceIdentity.new(resource_klass, id)
|
|
563
|
+
id_tree = JSONAPI::PrimaryResourceIdTree.new
|
|
564
|
+
id_tree.add_resource_fragment(JSONAPI::ResourceFragment.new(resource_identity), {})
|
|
565
|
+
resource_set = JSONAPI::ResourceSet.new(id_tree)
|
|
566
|
+
serializer = JSONAPI::ResourceSerializer.new(
|
|
567
|
+
resource_klass,
|
|
568
|
+
fields: fields
|
|
569
|
+
)
|
|
570
|
+
resource_set.populate!(serializer, {}, {})
|
|
571
|
+
serializer.serialize_resource_set_to_hash_single(resource_set)['data'].except('links')
|
|
572
|
+
end
|
|
573
|
+
|
|
561
574
|
def self.serialize_changes(diffs, user)
|
|
562
575
|
ctx = { current_user: user }
|
|
563
576
|
diffs.each do |diff|
|
|
@@ -582,10 +595,7 @@ module DeepUnrest
|
|
|
582
595
|
keys = diff[:resource].keys.map(&:to_sym)
|
|
583
596
|
fields[to_assoc(diff[:klass].to_s.pluralize)] = keys
|
|
584
597
|
|
|
585
|
-
|
|
586
|
-
resource_klass,
|
|
587
|
-
fields: fields
|
|
588
|
-
).serialize_to_hash(resource_klass.new(diff[:model], ctx))[:data]
|
|
598
|
+
serialize_resource(resource_klass, fields, diff[:model].id)
|
|
589
599
|
end
|
|
590
600
|
resources.select { |item| item.dig('attributes') }.compact
|
|
591
601
|
end
|
|
@@ -692,10 +702,10 @@ module DeepUnrest
|
|
|
692
702
|
def self.serialize_result(ctx, item)
|
|
693
703
|
resource = item[:resource]
|
|
694
704
|
resource_instance = resource.new(item[:record], ctx)
|
|
695
|
-
fields =
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
).
|
|
705
|
+
fields = {}
|
|
706
|
+
keys = item[:query][:fields].map(&:underscore).map(&:to_sym)
|
|
707
|
+
fields[to_assoc(item[:key].pluralize)] = keys
|
|
708
|
+
|
|
709
|
+
serialize_resource(resource, fields, item[:record].id).except(:links)
|
|
700
710
|
end
|
|
701
711
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: deep_unrest
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.72
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lynn Hurley
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-08-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -16,28 +16,28 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: 6.1.3
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
26
|
+
version: 6.1.3
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: jsonapi-resources
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 0.
|
|
33
|
+
version: '0.10'
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: 0.
|
|
40
|
+
version: '0.10'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: sqlite3
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -58,42 +58,42 @@ dependencies:
|
|
|
58
58
|
requirements:
|
|
59
59
|
- - '='
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version:
|
|
61
|
+
version: 2.0.0
|
|
62
62
|
type: :development
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
66
|
- - '='
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version:
|
|
68
|
+
version: 2.0.0
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: pundit
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
73
|
- - '='
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version:
|
|
75
|
+
version: 2.1.0
|
|
76
76
|
type: :development
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
80
|
- - '='
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version:
|
|
82
|
+
version: 2.1.0
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
84
|
name: dragonfly
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
87
|
- - '='
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: 1.
|
|
89
|
+
version: 1.3.0
|
|
90
90
|
type: :development
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
94
|
- - '='
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: 1.
|
|
96
|
+
version: 1.3.0
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
98
|
name: database_cleaner
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -114,14 +114,14 @@ dependencies:
|
|
|
114
114
|
requirements:
|
|
115
115
|
- - '='
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
|
-
version:
|
|
117
|
+
version: 2.18.0
|
|
118
118
|
type: :development
|
|
119
119
|
prerelease: false
|
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
121
|
requirements:
|
|
122
122
|
- - '='
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
|
-
version:
|
|
124
|
+
version: 2.18.0
|
|
125
125
|
description: Update multiple or deeply nested JSONAPI resources
|
|
126
126
|
email:
|
|
127
127
|
- lynn.dylan.hurley@gmail.com
|
|
@@ -157,7 +157,7 @@ homepage: https://github.com/graveflex/deep_unrest
|
|
|
157
157
|
licenses:
|
|
158
158
|
- MIT
|
|
159
159
|
metadata: {}
|
|
160
|
-
post_install_message:
|
|
160
|
+
post_install_message:
|
|
161
161
|
rdoc_options: []
|
|
162
162
|
require_paths:
|
|
163
163
|
- lib
|
|
@@ -172,8 +172,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
172
172
|
- !ruby/object:Gem::Version
|
|
173
173
|
version: '0'
|
|
174
174
|
requirements: []
|
|
175
|
-
rubygems_version: 3.
|
|
176
|
-
signing_key:
|
|
175
|
+
rubygems_version: 3.2.3
|
|
176
|
+
signing_key:
|
|
177
177
|
specification_version: 4
|
|
178
178
|
summary: Update multiple or deeply nested JSONAPI resources
|
|
179
179
|
test_files: []
|