forest_admin_agent 1.37.2 → 1.37.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/lib/forest_admin_agent/routes/capabilities/collections.rb +3 -2
- data/lib/forest_admin_agent/routes/charts/api_chart_datasource.rb +6 -8
- data/lib/forest_admin_agent/routes/resources/related/associate_related.rb +2 -2
- data/lib/forest_admin_agent/routes/resources/related/dissociate_related.rb +1 -1
- data/lib/forest_admin_agent/routes/resources/related/update_related.rb +30 -9
- data/lib/forest_admin_agent/routes/security/scope_invalidation.rb +2 -3
- data/lib/forest_admin_agent/utils/caller_parser.rb +2 -0
- data/lib/forest_admin_agent/utils/schema/schema_emitter.rb +1 -1
- data/lib/forest_admin_agent/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: e658e8812d89132182a96392c58221793cf5991bd95b4c0d3170dff0676a693c
|
|
4
|
+
data.tar.gz: b7cf6705ebdda5d3785e78290f1b1f4b762b1eac7b157c999bbbde4b6206b8f3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2feb766efd70870058a92d79ebde8cc3a41cc83452767a7478f6d5a4e66aa72346c0b1208364696fe67c5b4d4378439797240cf387d4462ea198a4f5df521152
|
|
7
|
+
data.tar.gz: d49ef0aca2acdb55a4c6b8d5ac58861165017f424958787064635322ff2fe961ecaa6e206ecc80c4fc495a5986434615f1aa5b9b599d62ce390733b0a4bb89e8
|
|
@@ -2,7 +2,7 @@ require 'json'
|
|
|
2
2
|
module ForestAdminAgent
|
|
3
3
|
module Routes
|
|
4
4
|
module Capabilities
|
|
5
|
-
class Collections <
|
|
5
|
+
class Collections < AbstractAuthenticatedRoute
|
|
6
6
|
include ForestAdminDatasourceToolkit::Schema
|
|
7
7
|
include ForestAdminDatasourceToolkit::Schema::Relations
|
|
8
8
|
|
|
@@ -16,7 +16,8 @@ module ForestAdminAgent
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def handle_request(args = {})
|
|
19
|
-
|
|
19
|
+
context = build(args)
|
|
20
|
+
datasource = context.datasource
|
|
20
21
|
collections = args[:params]['collectionNames'] || []
|
|
21
22
|
|
|
22
23
|
connections = datasource.live_query_connections.keys.map { |connection_name| { name: connection_name } }
|
|
@@ -37,14 +37,13 @@ module ForestAdminAgent
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def handle_api_chart(args = {})
|
|
40
|
-
|
|
40
|
+
context = build(args)
|
|
41
41
|
parameters = Utils::QueryStringParser.parse_chart_parameters(args)
|
|
42
|
-
datasource = ForestAdminAgent::Facades::Container.datasource
|
|
43
42
|
|
|
44
43
|
{
|
|
45
44
|
content: Serializer::ForestChartSerializer.serialize(
|
|
46
|
-
datasource.render_chart(
|
|
47
|
-
caller,
|
|
45
|
+
context.datasource.render_chart(
|
|
46
|
+
context.caller,
|
|
48
47
|
@chart_name,
|
|
49
48
|
parameters
|
|
50
49
|
)
|
|
@@ -53,13 +52,12 @@ module ForestAdminAgent
|
|
|
53
52
|
end
|
|
54
53
|
|
|
55
54
|
def handle_smart_chart(args = {})
|
|
56
|
-
|
|
55
|
+
context = build(args)
|
|
57
56
|
parameters = Utils::QueryStringParser.parse_chart_parameters(args)
|
|
58
|
-
datasource = ForestAdminAgent::Facades::Container.datasource
|
|
59
57
|
|
|
60
58
|
{
|
|
61
|
-
content: datasource.render_chart(
|
|
62
|
-
caller,
|
|
59
|
+
content: context.datasource.render_chart(
|
|
60
|
+
context.caller,
|
|
63
61
|
@chart_name,
|
|
64
62
|
parameters
|
|
65
63
|
)
|
|
@@ -50,7 +50,7 @@ module ForestAdminAgent
|
|
|
50
50
|
condition_tree: ConditionTree::ConditionTreeFactory.intersect(
|
|
51
51
|
[
|
|
52
52
|
ConditionTree::Nodes::ConditionTreeLeaf.new(id, 'Equal', value),
|
|
53
|
-
context.permissions.get_scope(context.
|
|
53
|
+
context.permissions.get_scope(context.child_collection)
|
|
54
54
|
]
|
|
55
55
|
)
|
|
56
56
|
)
|
|
@@ -67,7 +67,7 @@ module ForestAdminAgent
|
|
|
67
67
|
condition_tree: ConditionTree::ConditionTreeFactory.intersect(
|
|
68
68
|
[
|
|
69
69
|
ConditionTree::Nodes::ConditionTreeLeaf.new(id, 'Equal', value),
|
|
70
|
-
context.permissions.get_scope(context.
|
|
70
|
+
context.permissions.get_scope(context.child_collection)
|
|
71
71
|
]
|
|
72
72
|
)
|
|
73
73
|
)
|
|
@@ -29,7 +29,7 @@ module ForestAdminAgent
|
|
|
29
29
|
if is_delete_mode
|
|
30
30
|
context.permissions.can?(:delete, context.child_collection)
|
|
31
31
|
else
|
|
32
|
-
context.permissions.can?(:edit, context.
|
|
32
|
+
context.permissions.can?(:edit, context.child_collection)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
filter = get_base_foreign_filter(args, context)
|
|
@@ -22,9 +22,12 @@ module ForestAdminAgent
|
|
|
22
22
|
|
|
23
23
|
def handle_request(args = {})
|
|
24
24
|
context = build(args)
|
|
25
|
-
context.permissions.can?(:edit, context.collection)
|
|
26
25
|
|
|
27
26
|
relation = context.collection.schema[:fields][args[:params]['relation_name']]
|
|
27
|
+
|
|
28
|
+
# Must run before unpack_id: unauthorized callers get a 403, not a validation error
|
|
29
|
+
context.permissions.can?(:edit, mutated_collection(relation, context))
|
|
30
|
+
|
|
28
31
|
parent_primary_key_values = Utils::Id.unpack_id(context.collection, args[:params]['id'])
|
|
29
32
|
|
|
30
33
|
linked_primary_key_values = if (id = args.dig(:params, 'data', 'id'))
|
|
@@ -47,13 +50,32 @@ module ForestAdminAgent
|
|
|
47
50
|
|
|
48
51
|
private
|
|
49
52
|
|
|
53
|
+
def mutated_collection(relation, context)
|
|
54
|
+
return context.child_collection if ['OneToOne', 'PolymorphicOneToOne'].include?(relation.type)
|
|
55
|
+
|
|
56
|
+
context.collection
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def scoped_fk_owner_filter(parent_primary_key_values, context)
|
|
60
|
+
fk_owner = ConditionTree::ConditionTreeFactory.match_ids(context.collection, [parent_primary_key_values])
|
|
61
|
+
|
|
62
|
+
Filter.new(
|
|
63
|
+
condition_tree: ConditionTree::ConditionTreeFactory.intersect(
|
|
64
|
+
[
|
|
65
|
+
context.permissions.get_scope(context.collection),
|
|
66
|
+
fk_owner
|
|
67
|
+
]
|
|
68
|
+
)
|
|
69
|
+
)
|
|
70
|
+
end
|
|
71
|
+
|
|
50
72
|
def update_many_to_one(relation, parent_primary_key_values, linked_primary_key_values, context)
|
|
51
73
|
foreign_value = if linked_primary_key_values
|
|
52
74
|
Collection.get_value(context.child_collection, context.caller, linked_primary_key_values,
|
|
53
75
|
relation.foreign_key_target)
|
|
54
76
|
end
|
|
55
|
-
|
|
56
|
-
context.collection.update(context.caller,
|
|
77
|
+
|
|
78
|
+
context.collection.update(context.caller, scoped_fk_owner_filter(parent_primary_key_values, context),
|
|
57
79
|
{ relation.foreign_key => foreign_value })
|
|
58
80
|
end
|
|
59
81
|
|
|
@@ -68,10 +90,9 @@ module ForestAdminAgent
|
|
|
68
90
|
end
|
|
69
91
|
|
|
70
92
|
polymorphic_type = context.child_collection.name.gsub('__', '::')
|
|
71
|
-
fk_owner = ConditionTree::ConditionTreeFactory.match_ids(context.collection, [parent_primary_key_values])
|
|
72
93
|
context.collection.update(
|
|
73
94
|
context.caller,
|
|
74
|
-
|
|
95
|
+
scoped_fk_owner_filter(parent_primary_key_values, context),
|
|
75
96
|
{
|
|
76
97
|
relation.foreign_key => foreign_value,
|
|
77
98
|
relation.foreign_key_type_field => polymorphic_type
|
|
@@ -101,7 +122,7 @@ module ForestAdminAgent
|
|
|
101
122
|
old_fk_owner_filter = Filter.new(
|
|
102
123
|
condition_tree: ConditionTree::ConditionTreeFactory.intersect(
|
|
103
124
|
[
|
|
104
|
-
context.permissions.get_scope(context.
|
|
125
|
+
context.permissions.get_scope(context.child_collection),
|
|
105
126
|
ConditionTree::Nodes::ConditionTreeBranch.new(
|
|
106
127
|
'And',
|
|
107
128
|
[
|
|
@@ -150,7 +171,7 @@ module ForestAdminAgent
|
|
|
150
171
|
Filter.new(
|
|
151
172
|
condition_tree: ConditionTree::ConditionTreeFactory.intersect(
|
|
152
173
|
[
|
|
153
|
-
context.permissions.get_scope(context.
|
|
174
|
+
context.permissions.get_scope(context.child_collection), new_fk_owner
|
|
154
175
|
]
|
|
155
176
|
)
|
|
156
177
|
),
|
|
@@ -164,7 +185,7 @@ module ForestAdminAgent
|
|
|
164
185
|
old_fk_owner_filter = Filter.new(
|
|
165
186
|
condition_tree: ConditionTree::ConditionTreeFactory.intersect(
|
|
166
187
|
[
|
|
167
|
-
context.permissions.get_scope(context.
|
|
188
|
+
context.permissions.get_scope(context.child_collection),
|
|
168
189
|
ConditionTree::Nodes::ConditionTreeLeaf.new(
|
|
169
190
|
relation.origin_key,
|
|
170
191
|
ConditionTree::Operators::EQUAL,
|
|
@@ -198,7 +219,7 @@ module ForestAdminAgent
|
|
|
198
219
|
context.caller,
|
|
199
220
|
Filter.new(condition_tree: ConditionTree::ConditionTreeFactory.intersect(
|
|
200
221
|
[
|
|
201
|
-
context.permissions.get_scope(context.
|
|
222
|
+
context.permissions.get_scope(context.child_collection),
|
|
202
223
|
new_fk_owner
|
|
203
224
|
]
|
|
204
225
|
)),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module ForestAdminAgent
|
|
2
2
|
module Routes
|
|
3
3
|
module Security
|
|
4
|
-
class ScopeInvalidation <
|
|
4
|
+
class ScopeInvalidation < AbstractAuthenticatedRoute
|
|
5
5
|
include ForestAdminAgent::Builder
|
|
6
6
|
include ForestAdminAgent::Services
|
|
7
7
|
|
|
@@ -17,8 +17,7 @@ module ForestAdminAgent
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def handle_request(args)
|
|
20
|
-
|
|
21
|
-
Utils::QueryStringParser.parse_caller(args)
|
|
20
|
+
build(args)
|
|
22
21
|
Permissions.invalidate_cache('forest.rendering')
|
|
23
22
|
|
|
24
23
|
{ content: nil, status: 204 }
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: forest_admin_agent
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.37.
|
|
4
|
+
version: 1.37.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Matthieu
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: exe
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2026-08-
|
|
12
|
+
date: 2026-08-11 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: activesupport
|