forest_liana 5.1.1 → 5.2.2
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 +5 -5
- data/app/controllers/forest_liana/resources_controller.rb +24 -2
- data/app/services/forest_liana/permissions_checker.rb +13 -1
- data/app/services/forest_liana/scope_validator.rb +97 -0
- data/lib/forest_liana/version.rb +1 -1
- data/test/services/forest_liana/scope_validator_test.rb +185 -0
- metadata +106 -114
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +0 -80
- data/spec/dummy/log/test.log +0 -39982
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/test.log +0 -13835
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 7cbeea2af710f9ca87cf5009df16da231a225ccc1770df2d32f3276ff40ad08c
|
|
4
|
+
data.tar.gz: 631aca45492967c964a97b22e32bccb61bea281be954956a766df500c1556931
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2b29604d71d4832141d2d5cc27efd79fb2c17471a0a75158e5100d220e4f4507b8f9e3494766a4de679900d1c62ff0cdb3cd5ac2d1c4e5c42b49aee2ad0d1e9e
|
|
7
|
+
data.tar.gz: 4afdc7851315ca16ecf4fe9ddaf771f853ba1db33d70875155f656e00c643de452527ed8efaa1dda9112f09c384c8a230e453218910fe5a9dd055f76da458d3d
|
|
@@ -22,7 +22,13 @@ module ForestLiana
|
|
|
22
22
|
checker = ForestLiana::PermissionsChecker.new(@resource, 'searchToEdit', @rendering_id)
|
|
23
23
|
return head :forbidden unless checker.is_authorized?
|
|
24
24
|
else
|
|
25
|
-
checker = ForestLiana::PermissionsChecker.new(
|
|
25
|
+
checker = ForestLiana::PermissionsChecker.new(
|
|
26
|
+
@resource,
|
|
27
|
+
'list',
|
|
28
|
+
@rendering_id,
|
|
29
|
+
nil,
|
|
30
|
+
get_collection_list_permission_info(forest_user, request)
|
|
31
|
+
)
|
|
26
32
|
return head :forbidden unless checker.is_authorized?
|
|
27
33
|
end
|
|
28
34
|
|
|
@@ -51,7 +57,13 @@ module ForestLiana
|
|
|
51
57
|
|
|
52
58
|
def count
|
|
53
59
|
begin
|
|
54
|
-
checker = ForestLiana::PermissionsChecker.new(
|
|
60
|
+
checker = ForestLiana::PermissionsChecker.new(
|
|
61
|
+
@resource,
|
|
62
|
+
'list',
|
|
63
|
+
@rendering_id,
|
|
64
|
+
nil,
|
|
65
|
+
get_collection_list_permission_info(forest_user, request)
|
|
66
|
+
)
|
|
55
67
|
return head :forbidden unless checker.is_authorized?
|
|
56
68
|
|
|
57
69
|
getter = ForestLiana::ResourcesGetter.new(@resource, params)
|
|
@@ -232,5 +244,15 @@ module ForestLiana
|
|
|
232
244
|
collection_name = ForestLiana.name_for(@resource)
|
|
233
245
|
@collection ||= ForestLiana.apimap.find { |collection| collection.name.to_s == collection_name }
|
|
234
246
|
end
|
|
247
|
+
|
|
248
|
+
# NOTICE: Return a formatted object containing the request condition filters and
|
|
249
|
+
# the user id used by the scope validator class to validate if scope is
|
|
250
|
+
# in request
|
|
251
|
+
def get_collection_list_permission_info(user, collection_list_request)
|
|
252
|
+
{
|
|
253
|
+
user_id: user['id'],
|
|
254
|
+
filters: collection_list_request[:filters],
|
|
255
|
+
}
|
|
256
|
+
end
|
|
235
257
|
end
|
|
236
258
|
end
|
|
@@ -3,11 +3,12 @@ module ForestLiana
|
|
|
3
3
|
@@permissions_per_rendering = Hash.new
|
|
4
4
|
@@expiration_in_seconds = (ENV['FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS'] || 3600).to_i
|
|
5
5
|
|
|
6
|
-
def initialize(resource, permission_name, rendering_id, smart_action_parameters = nil)
|
|
6
|
+
def initialize(resource, permission_name, rendering_id, smart_action_parameters = nil, collection_list_parameters = nil)
|
|
7
7
|
@collection_name = ForestLiana.name_for(resource)
|
|
8
8
|
@permission_name = permission_name
|
|
9
9
|
@rendering_id = rendering_id
|
|
10
10
|
@smart_action_parameters = smart_action_parameters
|
|
11
|
+
@collection_list_parameters = collection_list_parameters
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
def is_authorized?
|
|
@@ -46,12 +47,23 @@ module ForestLiana
|
|
|
46
47
|
return @allowed && (@users.nil?|| @users.include?(@user_id.to_i));
|
|
47
48
|
end
|
|
48
49
|
|
|
50
|
+
def collection_list_allowed?(scope_permissions)
|
|
51
|
+
return ForestLiana::ScopeValidator.new(
|
|
52
|
+
scope_permissions['filter'],
|
|
53
|
+
scope_permissions['dynamicScopesValues']['users']
|
|
54
|
+
).is_scope_in_request?(@collection_list_parameters)
|
|
55
|
+
end
|
|
56
|
+
|
|
49
57
|
def is_allowed?
|
|
50
58
|
permissions = get_permissions
|
|
51
59
|
if permissions && permissions[@collection_name] &&
|
|
52
60
|
permissions[@collection_name]['collection']
|
|
53
61
|
if @permission_name === 'actions'
|
|
54
62
|
return smart_action_allowed?(permissions[@collection_name]['actions'])
|
|
63
|
+
# NOTICE: Permissions[@collection_name]['scope'] will either contains conditions filter and
|
|
64
|
+
# dynamic user values definition, or null for collection that does not use scopes
|
|
65
|
+
elsif @permission_name === 'list' and permissions[@collection_name]['scope']
|
|
66
|
+
return collection_list_allowed?(permissions[@collection_name]['scope'])
|
|
55
67
|
else
|
|
56
68
|
return permissions[@collection_name]['collection'][@permission_name]
|
|
57
69
|
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
module ForestLiana
|
|
2
|
+
class ScopeValidator
|
|
3
|
+
def initialize(scope_permissions, users_variable_values)
|
|
4
|
+
@scope_filters = scope_permissions
|
|
5
|
+
@users_variable_values = users_variable_values
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def is_scope_in_request?(scope_request)
|
|
9
|
+
begin
|
|
10
|
+
filters = JSON.parse(scope_request[:filters])
|
|
11
|
+
rescue JSON::ParserError
|
|
12
|
+
raise ForestLiana::Errors::HTTP422Error.new('Invalid filters JSON format')
|
|
13
|
+
end
|
|
14
|
+
@computed_scope = compute_condition_filters_from_scope(scope_request[:user_id])
|
|
15
|
+
|
|
16
|
+
# NOTICE: Perfom a travel in the request condition filters tree to find the scope
|
|
17
|
+
tagged_scope_filters = get_scope_found_in_request(filters)
|
|
18
|
+
|
|
19
|
+
# NOTICE: Permission system always send an aggregator even if there is only one condition
|
|
20
|
+
# In that case, if the condition is valid, then request was not edited
|
|
21
|
+
return !tagged_scope_filters.nil? if @scope_filters['conditions'].length == 1
|
|
22
|
+
|
|
23
|
+
# NOTICE: If there is more than one condition, do a final validation on the condition filters
|
|
24
|
+
return tagged_scope_filters != nil &&
|
|
25
|
+
tagged_scope_filters[:aggregator] == @scope_filters['aggregator'] &&
|
|
26
|
+
tagged_scope_filters[:conditions] &&
|
|
27
|
+
tagged_scope_filters[:conditions].length == @scope_filters['conditions'].length
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def compute_condition_filters_from_scope(user_id)
|
|
33
|
+
computed_condition_filters = @scope_filters.clone
|
|
34
|
+
computed_condition_filters['conditions'].each do |condition|
|
|
35
|
+
if condition.include?('value') &&
|
|
36
|
+
!condition['value'].nil? &&
|
|
37
|
+
condition['value'].start_with?('$') &&
|
|
38
|
+
@users_variable_values.include?(user_id)
|
|
39
|
+
condition['value'] = @users_variable_values[user_id][condition['value']]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
return computed_condition_filters
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def get_scope_found_in_request(filters)
|
|
46
|
+
return nil unless filters
|
|
47
|
+
return search_scope_aggregation(filters)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def search_scope_aggregation(node)
|
|
51
|
+
ensure_valid_aggregation(node)
|
|
52
|
+
|
|
53
|
+
return is_scope_condition?(node) unless node['aggregator']
|
|
54
|
+
|
|
55
|
+
# NOTICE: Remove conditions that are not from the scope
|
|
56
|
+
filtered_conditions = node['conditions'].map { |condition|
|
|
57
|
+
search_scope_aggregation(condition)
|
|
58
|
+
}.select { |condition|
|
|
59
|
+
condition
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# NOTICE: If there is only one condition filter left and its current aggregator is
|
|
63
|
+
# an "and", this condition filter is the searched scope
|
|
64
|
+
if (filtered_conditions.length == 1 &&
|
|
65
|
+
filtered_conditions.first.is_a?(Hash) &&
|
|
66
|
+
filtered_conditions.first.include?(:aggregator) &&
|
|
67
|
+
node['aggregator'] == 'and')
|
|
68
|
+
return filtered_conditions.first
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# NOTICE: Otherwise, validate if the current node is the scope and return nil
|
|
72
|
+
# if it's not
|
|
73
|
+
return (filtered_conditions.length == @scope_filters['conditions'].length &&
|
|
74
|
+
node['aggregator'] == @scope_filters['aggregator']) ?
|
|
75
|
+
{ aggregator: node['aggregator'], conditions: filtered_conditions } :
|
|
76
|
+
nil
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def is_scope_condition?(condition)
|
|
80
|
+
ensure_valid_condition(condition)
|
|
81
|
+
return @computed_scope['conditions'].include?(condition)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def ensure_valid_aggregation(node)
|
|
85
|
+
raise ForestLiana::Errors::HTTP422Error.new('Filters cannot be a raw value') unless node.is_a?(Hash)
|
|
86
|
+
raise_empty_condition_in_filter_error if node.empty?
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def ensure_valid_condition(condition)
|
|
90
|
+
raise_empty_condition_in_filter_error if condition.empty?
|
|
91
|
+
raise ForestLiana::Errors::HTTP422Error.new('Condition cannot be a raw value') unless condition.is_a?(Hash)
|
|
92
|
+
unless condition['field'].is_a?(String) and condition['operator'].is_a?(String)
|
|
93
|
+
raise ForestLiana::Errors::HTTP422Error.new('Invalid condition format')
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
data/lib/forest_liana/version.rb
CHANGED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
module ForestLiana
|
|
2
|
+
class ScopeValidatorTest < ActiveSupport::TestCase
|
|
3
|
+
test 'Request with aggregated condition filters should be allowed if it matches the scope exactly' do
|
|
4
|
+
scope_validator = ForestLiana::ScopeValidator.new({
|
|
5
|
+
'aggregator' => 'and',
|
|
6
|
+
'conditions' => [
|
|
7
|
+
{ 'field' => 'name', 'value' => 'john', 'operator' => 'equal' },
|
|
8
|
+
{ 'field' => 'price', 'value' => '2500', 'operator' => 'equal' }
|
|
9
|
+
]
|
|
10
|
+
}, [])
|
|
11
|
+
|
|
12
|
+
allowed = scope_validator.is_scope_in_request?({
|
|
13
|
+
user_id: '1',
|
|
14
|
+
filters: JSON.generate({
|
|
15
|
+
aggregator: 'and',
|
|
16
|
+
conditions: [
|
|
17
|
+
{ field: 'name', value: 'john', operator: 'equal' },
|
|
18
|
+
{ field: 'price', value: '2500', operator: 'equal' }
|
|
19
|
+
]
|
|
20
|
+
})
|
|
21
|
+
})
|
|
22
|
+
assert allowed == true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
test 'Request with simple condition filter should be allowed if it matches the scope exactly' do
|
|
26
|
+
scope_validator = ForestLiana::ScopeValidator.new({
|
|
27
|
+
'aggregator' => 'and',
|
|
28
|
+
'conditions' => [
|
|
29
|
+
{ 'field' => 'field', 'value' => 'value', 'operator' => 'equal' }
|
|
30
|
+
]
|
|
31
|
+
}, [])
|
|
32
|
+
allowed = scope_validator.is_scope_in_request?({
|
|
33
|
+
user_id: '1',
|
|
34
|
+
filters: JSON.generate({
|
|
35
|
+
field: 'field', value: 'value', operator: 'equal'
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
assert allowed == true
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
test 'Request with multiples condition filters should be allowed if it contains the scope ' do
|
|
42
|
+
scope_validator = ForestLiana::ScopeValidator.new({
|
|
43
|
+
'aggregator' => 'and',
|
|
44
|
+
'conditions' => [
|
|
45
|
+
{ 'field' => 'name', 'value' => 'doe', 'operator' => 'equal' }
|
|
46
|
+
]
|
|
47
|
+
}, []
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
allowed = scope_validator.is_scope_in_request?({
|
|
51
|
+
user_id: '1',
|
|
52
|
+
filters: JSON.generate({
|
|
53
|
+
aggregator: 'and',
|
|
54
|
+
conditions: [
|
|
55
|
+
{ field: 'name', value: 'doe', operator: 'equal' },
|
|
56
|
+
{ field: 'field2', value: 'value2', operator: 'equal' }
|
|
57
|
+
]
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
assert allowed == true
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
test 'Request with dynamic user values should be allowed if it matches the scope exactly' do
|
|
64
|
+
scope_validator = ForestLiana::ScopeValidator.new({
|
|
65
|
+
'aggregator' => 'and',
|
|
66
|
+
'conditions' => [
|
|
67
|
+
{ 'field' => 'name', 'value' => '$currentUser.lastname', 'operator' => 'equal' }
|
|
68
|
+
],
|
|
69
|
+
}, {
|
|
70
|
+
'1' => { '$currentUser.lastname' => 'john' }
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
allowed = scope_validator.is_scope_in_request?({
|
|
74
|
+
user_id: '1',
|
|
75
|
+
filters: JSON.generate({
|
|
76
|
+
'field' => 'name', 'value' => 'john', 'operator' => 'equal'
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
assert allowed == true
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
test 'Request with multiples aggregation and dynamic values should be allowed if it contains the scope' do
|
|
83
|
+
scope_validator = ForestLiana::ScopeValidator.new({
|
|
84
|
+
'aggregator' => 'or',
|
|
85
|
+
'conditions' => [
|
|
86
|
+
{ 'field' => 'price', 'value' => '2500', 'operator' => 'equal' },
|
|
87
|
+
{ 'field' => 'name', 'value' => '$currentUser.lastname', 'operator' => 'equal' }
|
|
88
|
+
]
|
|
89
|
+
}, {
|
|
90
|
+
'1' => { '$currentUser.lastname' => 'john' }
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
allowed = scope_validator.is_scope_in_request?({
|
|
94
|
+
user_id: '1',
|
|
95
|
+
filters: JSON.generate({
|
|
96
|
+
aggregator: 'and',
|
|
97
|
+
conditions: [
|
|
98
|
+
{ field: 'field', value: 'value', operator: 'equal' },
|
|
99
|
+
{
|
|
100
|
+
aggregator: 'or',
|
|
101
|
+
conditions: [
|
|
102
|
+
{ field: 'price', value: '2500', operator: 'equal' },
|
|
103
|
+
{ field: 'name', value: 'john', operator: 'equal' }
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
assert allowed == true
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
test 'Request that does not match the expect scope should not be allowed' do
|
|
113
|
+
scope_validator = ForestLiana::ScopeValidator.new({
|
|
114
|
+
'aggregator' => 'and',
|
|
115
|
+
'conditions' => [
|
|
116
|
+
{ 'field' => 'name', 'value' => 'john', 'operator' => 'equal' },
|
|
117
|
+
{ 'field' => 'price', 'value' => '2500', 'operator' => 'equal' }
|
|
118
|
+
]
|
|
119
|
+
}, [])
|
|
120
|
+
|
|
121
|
+
allowed = scope_validator.is_scope_in_request?({
|
|
122
|
+
user_id: '1',
|
|
123
|
+
filters: JSON.generate({
|
|
124
|
+
aggregator: 'and',
|
|
125
|
+
conditions: [
|
|
126
|
+
{ field: 'name', value: 'definitely_not_john', operator: 'equal' },
|
|
127
|
+
{ field: 'price', value: '0', operator: 'equal' }
|
|
128
|
+
]
|
|
129
|
+
})
|
|
130
|
+
})
|
|
131
|
+
assert allowed == false
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
test 'Request that are missing part of the scope should not be allowed' do
|
|
135
|
+
scope_validator = ForestLiana::ScopeValidator.new({
|
|
136
|
+
'aggregator' => 'and',
|
|
137
|
+
'conditions' => [
|
|
138
|
+
{ 'field' => 'name', 'value' => 'john', 'operator' => 'equal' },
|
|
139
|
+
{ 'field' => 'price', 'value' => '2500', 'operator' => 'equal' }
|
|
140
|
+
]
|
|
141
|
+
}, [])
|
|
142
|
+
|
|
143
|
+
allowed = scope_validator.is_scope_in_request?({
|
|
144
|
+
user_id: '1',
|
|
145
|
+
filters: JSON.generate({
|
|
146
|
+
aggregator: 'and',
|
|
147
|
+
conditions: [
|
|
148
|
+
{ field: 'name', value: 'john', operator: 'equal' },
|
|
149
|
+
]
|
|
150
|
+
})
|
|
151
|
+
})
|
|
152
|
+
assert allowed == false
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
test 'Request that does not have a top aggregator being "and" should not be allowed' do
|
|
156
|
+
scope_validator = ForestLiana::ScopeValidator.new({
|
|
157
|
+
'aggregator' => 'and',
|
|
158
|
+
'conditions' => [
|
|
159
|
+
{ 'field' => 'price', 'value' => '2500', 'operator' => 'equal' },
|
|
160
|
+
{ 'field' => 'name', 'value' => '$currentUser.lastname', 'operator' => 'equal' }
|
|
161
|
+
]
|
|
162
|
+
}, {
|
|
163
|
+
'1' => { '$currentUser.lastname' => 'john' }
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
allowed = scope_validator.is_scope_in_request?({
|
|
167
|
+
user_id: '1',
|
|
168
|
+
filters: JSON.generate({
|
|
169
|
+
aggregator: 'or',
|
|
170
|
+
conditions: [
|
|
171
|
+
{ field: 'field', value: 'value', operator: 'equal' },
|
|
172
|
+
{
|
|
173
|
+
aggregator: 'and',
|
|
174
|
+
conditions: [
|
|
175
|
+
{ field: 'price', value: '2500', operator: 'equal' },
|
|
176
|
+
{ field: 'name', value: 'john', operator: 'equal' }
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
]
|
|
180
|
+
})
|
|
181
|
+
})
|
|
182
|
+
assert allowed == false
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: forest_liana
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sandro Munda
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-04
|
|
11
|
+
date: 2020-08-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -262,6 +262,7 @@ files:
|
|
|
262
262
|
- app/services/forest_liana/resources_getter.rb
|
|
263
263
|
- app/services/forest_liana/schema_adapter.rb
|
|
264
264
|
- app/services/forest_liana/schema_utils.rb
|
|
265
|
+
- app/services/forest_liana/scope_validator.rb
|
|
265
266
|
- app/services/forest_liana/search_query_builder.rb
|
|
266
267
|
- app/services/forest_liana/stat_getter.rb
|
|
267
268
|
- app/services/forest_liana/stripe_base_getter.rb
|
|
@@ -335,9 +336,6 @@ files:
|
|
|
335
336
|
- spec/dummy/db/migrate/20190716130830_add_age_to_tree.rb
|
|
336
337
|
- spec/dummy/db/migrate/20190716135241_add_type_to_user.rb
|
|
337
338
|
- spec/dummy/db/schema.rb
|
|
338
|
-
- spec/dummy/db/test.sqlite3
|
|
339
|
-
- spec/dummy/log/development.log
|
|
340
|
-
- spec/dummy/log/test.log
|
|
341
339
|
- spec/helpers/forest_liana/query_helper_spec.rb
|
|
342
340
|
- spec/helpers/forest_liana/schema_helper_spec.rb
|
|
343
341
|
- spec/rails_helper.rb
|
|
@@ -415,8 +413,6 @@ files:
|
|
|
415
413
|
- test/dummy/db/migrate/20170614141921_create_serialize_field.rb
|
|
416
414
|
- test/dummy/db/migrate/20181111162121_create_references_table.rb
|
|
417
415
|
- test/dummy/db/schema.rb
|
|
418
|
-
- test/dummy/db/test.sqlite3
|
|
419
|
-
- test/dummy/log/test.log
|
|
420
416
|
- test/dummy/public/404.html
|
|
421
417
|
- test/dummy/public/422.html
|
|
422
418
|
- test/dummy/public/500.html
|
|
@@ -437,6 +433,7 @@ files:
|
|
|
437
433
|
- test/services/forest_liana/resource_updater_test.rb
|
|
438
434
|
- test/services/forest_liana/resources_getter_test.rb
|
|
439
435
|
- test/services/forest_liana/schema_adapter_test.rb
|
|
436
|
+
- test/services/forest_liana/scope_validator_test.rb
|
|
440
437
|
- test/services/forest_liana/value_stat_getter_test.rb
|
|
441
438
|
- test/test_helper.rb
|
|
442
439
|
homepage: https://github.com/ForestAdmin/forest-rails
|
|
@@ -458,153 +455,148 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
458
455
|
- !ruby/object:Gem::Version
|
|
459
456
|
version: '0'
|
|
460
457
|
requirements: []
|
|
461
|
-
|
|
462
|
-
rubygems_version: 2.6.14
|
|
458
|
+
rubygems_version: 3.0.8
|
|
463
459
|
signing_key:
|
|
464
460
|
specification_version: 4
|
|
465
461
|
summary: Official Rails Liana for Forest
|
|
466
462
|
test_files:
|
|
467
|
-
- test/
|
|
468
|
-
- test/
|
|
463
|
+
- test/fixtures/owner.yml
|
|
464
|
+
- test/fixtures/belongs_to_field.yml
|
|
465
|
+
- test/fixtures/has_many_through_field.yml
|
|
466
|
+
- test/fixtures/tree.yml
|
|
467
|
+
- test/fixtures/has_one_field.yml
|
|
468
|
+
- test/fixtures/reference.yml
|
|
469
|
+
- test/fixtures/serialize_field.yml
|
|
470
|
+
- test/fixtures/has_many_field.yml
|
|
471
|
+
- test/fixtures/string_field.yml
|
|
472
|
+
- test/services/forest_liana/resources_getter_test.rb
|
|
473
|
+
- test/services/forest_liana/scope_validator_test.rb
|
|
474
|
+
- test/services/forest_liana/schema_adapter_test.rb
|
|
475
|
+
- test/services/forest_liana/has_many_getter_test.rb
|
|
476
|
+
- test/services/forest_liana/value_stat_getter_test.rb
|
|
477
|
+
- test/services/forest_liana/resource_updater_test.rb
|
|
478
|
+
- test/services/forest_liana/pie_stat_getter_test.rb
|
|
479
|
+
- test/test_helper.rb
|
|
480
|
+
- test/dummy/README.rdoc
|
|
481
|
+
- test/dummy/app/views/layouts/application.html.erb
|
|
469
482
|
- test/dummy/app/models/has_many_field.rb
|
|
470
|
-
- test/dummy/app/models/
|
|
483
|
+
- test/dummy/app/models/string_field.rb
|
|
471
484
|
- test/dummy/app/models/has_and_belongs_to_many_field.rb
|
|
472
|
-
- test/dummy/app/models/
|
|
473
|
-
- test/dummy/app/models/
|
|
474
|
-
- test/dummy/app/models/
|
|
475
|
-
- test/dummy/app/models/
|
|
485
|
+
- test/dummy/app/models/has_many_through_field.rb
|
|
486
|
+
- test/dummy/app/models/has_many_class_name_field.rb
|
|
487
|
+
- test/dummy/app/models/has_one_field.rb
|
|
488
|
+
- test/dummy/app/models/date_field.rb
|
|
476
489
|
- test/dummy/app/models/boolean_field.rb
|
|
477
|
-
- test/dummy/app/models/
|
|
478
|
-
- test/dummy/app/models/
|
|
490
|
+
- test/dummy/app/models/float_field.rb
|
|
491
|
+
- test/dummy/app/models/reference.rb
|
|
479
492
|
- test/dummy/app/models/belongs_to_class_name_field.rb
|
|
480
|
-
- test/dummy/app/models/decimal_field.rb
|
|
481
|
-
- test/dummy/app/models/has_one_field.rb
|
|
482
|
-
- test/dummy/app/models/string_field.rb
|
|
483
493
|
- test/dummy/app/models/polymorphic_field.rb
|
|
484
494
|
- test/dummy/app/models/tree.rb
|
|
485
|
-
- test/dummy/app/
|
|
486
|
-
- test/dummy/app/
|
|
495
|
+
- test/dummy/app/models/decimal_field.rb
|
|
496
|
+
- test/dummy/app/models/serialize_field.rb
|
|
497
|
+
- test/dummy/app/models/integer_field.rb
|
|
498
|
+
- test/dummy/app/models/belongs_to_field.rb
|
|
499
|
+
- test/dummy/app/models/owner.rb
|
|
500
|
+
- test/dummy/app/helpers/application_helper.rb
|
|
487
501
|
- test/dummy/app/assets/javascripts/application.js
|
|
488
502
|
- test/dummy/app/assets/stylesheets/application.css
|
|
489
|
-
- test/dummy/app/
|
|
503
|
+
- test/dummy/app/controllers/application_controller.rb
|
|
504
|
+
- test/dummy/Rakefile
|
|
490
505
|
- test/dummy/bin/rake
|
|
491
|
-
- test/dummy/bin/setup
|
|
492
506
|
- test/dummy/bin/bundle
|
|
493
507
|
- test/dummy/bin/rails
|
|
494
|
-
- test/dummy/
|
|
508
|
+
- test/dummy/bin/setup
|
|
509
|
+
- test/dummy/public/404.html
|
|
510
|
+
- test/dummy/public/500.html
|
|
511
|
+
- test/dummy/public/422.html
|
|
512
|
+
- test/dummy/public/favicon.ico
|
|
513
|
+
- test/dummy/config.ru
|
|
514
|
+
- test/dummy/db/migrate/20181111162121_create_references_table.rb
|
|
515
|
+
- test/dummy/db/migrate/20150608131430_create_integer_field.rb
|
|
516
|
+
- test/dummy/db/migrate/20160628173505_add_timestamps.rb
|
|
517
|
+
- test/dummy/db/migrate/20160627172810_create_owner.rb
|
|
518
|
+
- test/dummy/db/migrate/20150814081918_create_has_many_through_field.rb
|
|
519
|
+
- test/dummy/db/migrate/20150608132159_create_boolean_field.rb
|
|
520
|
+
- test/dummy/db/migrate/20150608131603_create_decimal_field.rb
|
|
521
|
+
- test/dummy/db/migrate/20150616150629_create_polymorphic_field.rb
|
|
522
|
+
- test/dummy/db/migrate/20150612112520_create_has_and_belongs_to_many_field.rb
|
|
523
|
+
- test/dummy/db/migrate/20150608131610_create_float_field.rb
|
|
524
|
+
- test/dummy/db/migrate/20150608133038_create_belongs_to_field.rb
|
|
525
|
+
- test/dummy/db/migrate/20150608150016_create_has_many_field.rb
|
|
526
|
+
- test/dummy/db/migrate/20150609114636_create_belongs_to_class_name_field.rb
|
|
527
|
+
- test/dummy/db/migrate/20170614141921_create_serialize_field.rb
|
|
528
|
+
- test/dummy/db/migrate/20150608132621_create_string_field.rb
|
|
529
|
+
- test/dummy/db/migrate/20150608133044_create_has_one_field.rb
|
|
530
|
+
- test/dummy/db/migrate/20150623115554_create_has_many_class_name_field.rb
|
|
531
|
+
- test/dummy/db/migrate/20150608130516_create_date_field.rb
|
|
532
|
+
- test/dummy/db/migrate/20160627172951_create_tree.rb
|
|
533
|
+
- test/dummy/db/schema.rb
|
|
495
534
|
- test/dummy/config/routes.rb
|
|
496
|
-
- test/dummy/config/locales/en.yml
|
|
497
|
-
- test/dummy/config/environments/production.rb
|
|
498
|
-
- test/dummy/config/environments/development.rb
|
|
499
|
-
- test/dummy/config/environments/test.rb
|
|
500
535
|
- test/dummy/config/environment.rb
|
|
536
|
+
- test/dummy/config/secrets.yml
|
|
501
537
|
- test/dummy/config/application.rb
|
|
502
|
-
- test/dummy/config/database.yml
|
|
503
538
|
- test/dummy/config/boot.rb
|
|
504
|
-
- test/dummy/config/
|
|
539
|
+
- test/dummy/config/environments/test.rb
|
|
540
|
+
- test/dummy/config/environments/development.rb
|
|
541
|
+
- test/dummy/config/environments/production.rb
|
|
542
|
+
- test/dummy/config/locales/en.yml
|
|
543
|
+
- test/dummy/config/initializers/wrap_parameters.rb
|
|
505
544
|
- test/dummy/config/initializers/mime_types.rb
|
|
506
545
|
- test/dummy/config/initializers/filter_parameter_logging.rb
|
|
507
|
-
- test/dummy/config/initializers/session_store.rb
|
|
508
|
-
- test/dummy/config/initializers/wrap_parameters.rb
|
|
509
546
|
- test/dummy/config/initializers/assets.rb
|
|
510
|
-
- test/dummy/config/initializers/
|
|
547
|
+
- test/dummy/config/initializers/session_store.rb
|
|
511
548
|
- test/dummy/config/initializers/inflections.rb
|
|
512
|
-
- test/dummy/config.
|
|
513
|
-
- test/dummy/
|
|
514
|
-
- test/dummy/
|
|
515
|
-
- test/dummy/public/422.html
|
|
516
|
-
- test/dummy/public/500.html
|
|
517
|
-
- test/dummy/public/404.html
|
|
518
|
-
- test/dummy/db/schema.rb
|
|
519
|
-
- test/dummy/db/test.sqlite3
|
|
520
|
-
- test/dummy/db/migrate/20150608133038_create_belongs_to_field.rb
|
|
521
|
-
- test/dummy/db/migrate/20150608130516_create_date_field.rb
|
|
522
|
-
- test/dummy/db/migrate/20160627172951_create_tree.rb
|
|
523
|
-
- test/dummy/db/migrate/20150608132621_create_string_field.rb
|
|
524
|
-
- test/dummy/db/migrate/20160627172810_create_owner.rb
|
|
525
|
-
- test/dummy/db/migrate/20150612112520_create_has_and_belongs_to_many_field.rb
|
|
526
|
-
- test/dummy/db/migrate/20150608132159_create_boolean_field.rb
|
|
527
|
-
- test/dummy/db/migrate/20181111162121_create_references_table.rb
|
|
528
|
-
- test/dummy/db/migrate/20160628173505_add_timestamps.rb
|
|
529
|
-
- test/dummy/db/migrate/20150608133044_create_has_one_field.rb
|
|
530
|
-
- test/dummy/db/migrate/20150814081918_create_has_many_through_field.rb
|
|
531
|
-
- test/dummy/db/migrate/20150609114636_create_belongs_to_class_name_field.rb
|
|
532
|
-
- test/dummy/db/migrate/20150608150016_create_has_many_field.rb
|
|
533
|
-
- test/dummy/db/migrate/20150608131430_create_integer_field.rb
|
|
534
|
-
- test/dummy/db/migrate/20170614141921_create_serialize_field.rb
|
|
535
|
-
- test/dummy/db/migrate/20150608131610_create_float_field.rb
|
|
536
|
-
- test/dummy/db/migrate/20150608131603_create_decimal_field.rb
|
|
537
|
-
- test/dummy/db/migrate/20150623115554_create_has_many_class_name_field.rb
|
|
538
|
-
- test/dummy/db/migrate/20150616150629_create_polymorphic_field.rb
|
|
539
|
-
- test/dummy/log/test.log
|
|
540
|
-
- test/dummy/README.rdoc
|
|
549
|
+
- test/dummy/config/initializers/cookies_serializer.rb
|
|
550
|
+
- test/dummy/config/initializers/backtrace_silencers.rb
|
|
551
|
+
- test/dummy/config/database.yml
|
|
541
552
|
- test/forest_liana_test.rb
|
|
542
|
-
- test/fixtures/has_many_through_field.yml
|
|
543
|
-
- test/fixtures/string_field.yml
|
|
544
|
-
- test/fixtures/belongs_to_field.yml
|
|
545
|
-
- test/fixtures/tree.yml
|
|
546
|
-
- test/fixtures/has_one_field.yml
|
|
547
|
-
- test/fixtures/reference.yml
|
|
548
|
-
- test/fixtures/owner.yml
|
|
549
|
-
- test/fixtures/has_many_field.yml
|
|
550
|
-
- test/fixtures/serialize_field.yml
|
|
551
|
-
- test/test_helper.rb
|
|
552
553
|
- test/routing/route_test.rb
|
|
553
|
-
-
|
|
554
|
-
-
|
|
555
|
-
-
|
|
556
|
-
-
|
|
557
|
-
- test/services/forest_liana/pie_stat_getter_test.rb
|
|
558
|
-
- test/services/forest_liana/resources_getter_test.rb
|
|
554
|
+
- spec/services/forest_liana/ip_whitelist_checker_spec.rb
|
|
555
|
+
- spec/services/forest_liana/schema_adapter_spec.rb
|
|
556
|
+
- spec/services/forest_liana/apimap_sorter_spec.rb
|
|
557
|
+
- spec/services/forest_liana/filters_parser_spec.rb
|
|
559
558
|
- spec/spec_helper.rb
|
|
560
|
-
- spec/
|
|
559
|
+
- spec/requests/resources_spec.rb
|
|
560
|
+
- spec/dummy/README.rdoc
|
|
561
|
+
- spec/dummy/app/views/layouts/application.html.erb
|
|
561
562
|
- spec/dummy/app/models/island.rb
|
|
562
563
|
- spec/dummy/app/models/user.rb
|
|
563
564
|
- spec/dummy/app/models/tree.rb
|
|
564
|
-
- spec/dummy/app/
|
|
565
|
-
- spec/dummy/app/views/layouts/application.html.erb
|
|
565
|
+
- spec/dummy/app/helpers/application_helper.rb
|
|
566
566
|
- spec/dummy/app/assets/javascripts/application.js
|
|
567
567
|
- spec/dummy/app/assets/stylesheets/application.css
|
|
568
|
-
- spec/dummy/app/
|
|
568
|
+
- spec/dummy/app/config/routes.rb
|
|
569
|
+
- spec/dummy/app/controllers/application_controller.rb
|
|
570
|
+
- spec/dummy/Rakefile
|
|
569
571
|
- spec/dummy/bin/rake
|
|
570
|
-
- spec/dummy/bin/setup
|
|
571
572
|
- spec/dummy/bin/bundle
|
|
572
573
|
- spec/dummy/bin/rails
|
|
573
|
-
- spec/dummy/
|
|
574
|
+
- spec/dummy/bin/setup
|
|
575
|
+
- spec/dummy/config.ru
|
|
576
|
+
- spec/dummy/db/migrate/20190226174951_create_tree.rb
|
|
577
|
+
- spec/dummy/db/migrate/20190716135241_add_type_to_user.rb
|
|
578
|
+
- spec/dummy/db/migrate/20190226173051_create_isle.rb
|
|
579
|
+
- spec/dummy/db/migrate/20190716130830_add_age_to_tree.rb
|
|
580
|
+
- spec/dummy/db/migrate/20190226172951_create_user.rb
|
|
581
|
+
- spec/dummy/db/schema.rb
|
|
574
582
|
- spec/dummy/config/routes.rb
|
|
575
|
-
- spec/dummy/config/environments/production.rb
|
|
576
|
-
- spec/dummy/config/environments/development.rb
|
|
577
|
-
- spec/dummy/config/environments/test.rb
|
|
578
583
|
- spec/dummy/config/environment.rb
|
|
584
|
+
- spec/dummy/config/secrets.yml
|
|
579
585
|
- spec/dummy/config/application.rb
|
|
580
|
-
- spec/dummy/config/database.yml
|
|
581
586
|
- spec/dummy/config/boot.rb
|
|
582
|
-
- spec/dummy/config/
|
|
587
|
+
- spec/dummy/config/environments/test.rb
|
|
588
|
+
- spec/dummy/config/environments/development.rb
|
|
589
|
+
- spec/dummy/config/environments/production.rb
|
|
590
|
+
- spec/dummy/config/initializers/wrap_parameters.rb
|
|
591
|
+
- spec/dummy/config/initializers/forest_liana.rb
|
|
583
592
|
- spec/dummy/config/initializers/mime_types.rb
|
|
584
593
|
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
|
585
|
-
- spec/dummy/config/initializers/session_store.rb
|
|
586
|
-
- spec/dummy/config/initializers/wrap_parameters.rb
|
|
587
594
|
- spec/dummy/config/initializers/assets.rb
|
|
588
|
-
- spec/dummy/config/initializers/
|
|
589
|
-
- spec/dummy/config/initializers/forest_liana.rb
|
|
595
|
+
- spec/dummy/config/initializers/session_store.rb
|
|
590
596
|
- spec/dummy/config/initializers/inflections.rb
|
|
591
|
-
- spec/dummy/config.
|
|
592
|
-
- spec/dummy/
|
|
593
|
-
- spec/dummy/
|
|
594
|
-
- spec/dummy/db/test.sqlite3
|
|
595
|
-
- spec/dummy/db/migrate/20190716130830_add_age_to_tree.rb
|
|
596
|
-
- spec/dummy/db/migrate/20190226173051_create_isle.rb
|
|
597
|
-
- spec/dummy/db/migrate/20190226174951_create_tree.rb
|
|
598
|
-
- spec/dummy/db/migrate/20190226172951_create_user.rb
|
|
599
|
-
- spec/dummy/db/migrate/20190716135241_add_type_to_user.rb
|
|
600
|
-
- spec/dummy/log/test.log
|
|
601
|
-
- spec/dummy/log/development.log
|
|
602
|
-
- spec/dummy/README.rdoc
|
|
603
|
-
- spec/requests/resources_spec.rb
|
|
604
|
-
- spec/rails_helper.rb
|
|
605
|
-
- spec/helpers/forest_liana/query_helper_spec.rb
|
|
597
|
+
- spec/dummy/config/initializers/cookies_serializer.rb
|
|
598
|
+
- spec/dummy/config/initializers/backtrace_silencers.rb
|
|
599
|
+
- spec/dummy/config/database.yml
|
|
606
600
|
- spec/helpers/forest_liana/schema_helper_spec.rb
|
|
607
|
-
- spec/
|
|
608
|
-
- spec/
|
|
609
|
-
- spec/services/forest_liana/filters_parser_spec.rb
|
|
610
|
-
- spec/services/forest_liana/ip_whitelist_checker_spec.rb
|
|
601
|
+
- spec/helpers/forest_liana/query_helper_spec.rb
|
|
602
|
+
- spec/rails_helper.rb
|