forest_liana 7.8.0 → 8.0.0.beta.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 +4 -4
- data/app/controllers/forest_liana/actions_controller.rb +5 -3
- data/app/controllers/forest_liana/application_controller.rb +15 -0
- data/app/controllers/forest_liana/resources_controller.rb +31 -57
- data/app/controllers/forest_liana/smart_actions_controller.rb +44 -58
- data/app/controllers/forest_liana/stats_controller.rb +14 -58
- data/app/services/forest_liana/ability/exceptions/access_denied.rb +16 -0
- data/app/services/forest_liana/ability/exceptions/action_condition_error.rb +16 -0
- data/app/services/forest_liana/ability/exceptions/require_approval.rb +18 -0
- data/app/services/forest_liana/ability/exceptions/trigger_forbidden.rb +16 -0
- data/app/services/forest_liana/ability/fetch.rb +23 -0
- data/app/services/forest_liana/ability/permission/request_permission.rb +19 -0
- data/app/services/forest_liana/ability/permission/smart_action_checker.rb +71 -0
- data/app/services/forest_liana/ability/permission.rb +148 -0
- data/app/services/forest_liana/ability.rb +24 -0
- data/app/services/forest_liana/filters_parser.rb +7 -7
- data/app/services/forest_liana/leaderboard_stat_getter.rb +7 -7
- data/app/services/forest_liana/line_stat_getter.rb +8 -8
- data/app/services/forest_liana/pie_stat_getter.rb +17 -17
- data/app/services/forest_liana/stat_getter.rb +1 -2
- data/app/services/forest_liana/value_stat_getter.rb +7 -7
- data/lib/forest_liana/bootstrapper.rb +1 -1
- data/lib/forest_liana/version.rb +1 -1
- data/spec/dummy/lib/forest_liana/collections/island.rb +1 -1
- data/spec/requests/actions_controller_spec.rb +3 -4
- data/spec/requests/count_spec.rb +5 -9
- data/spec/requests/resources_spec.rb +55 -11
- data/spec/requests/stats_spec.rb +103 -42
- data/spec/services/forest_liana/ability/ability_spec.rb +48 -0
- data/spec/services/forest_liana/ability/permission/smart_action_checker_spec.rb +357 -0
- data/spec/services/forest_liana/ability/permission_spec.rb +332 -0
- data/spec/services/forest_liana/filters_parser_spec.rb +0 -12
- data/spec/services/forest_liana/line_stat_getter_spec.rb +9 -9
- data/spec/services/forest_liana/pie_stat_getter_spec.rb +7 -7
- data/spec/services/forest_liana/value_stat_getter_spec.rb +11 -11
- data/spec/spec_helper.rb +1 -0
- metadata +33 -17
- data/app/services/forest_liana/permissions_checker.rb +0 -223
- data/app/services/forest_liana/permissions_formatter.rb +0 -52
- data/app/services/forest_liana/permissions_getter.rb +0 -59
- data/spec/services/forest_liana/permissions_checker_acl_disabled_spec.rb +0 -713
- data/spec/services/forest_liana/permissions_checker_acl_enabled_spec.rb +0 -845
- data/spec/services/forest_liana/permissions_checker_live_queries_spec.rb +0 -175
- data/spec/services/forest_liana/permissions_formatter_spec.rb +0 -222
- data/spec/services/forest_liana/permissions_getter_spec.rb +0 -83
@@ -1,713 +0,0 @@
|
|
1
|
-
module ForestLiana
|
2
|
-
describe PermissionsChecker do
|
3
|
-
before(:each) do
|
4
|
-
described_class.empty_cache
|
5
|
-
end
|
6
|
-
|
7
|
-
let(:user) { { 'id' => '1' } }
|
8
|
-
let(:schema) {
|
9
|
-
[
|
10
|
-
ForestLiana::Model::Collection.new({
|
11
|
-
name: 'all_rights_collection',
|
12
|
-
fields: [],
|
13
|
-
actions: [
|
14
|
-
ForestLiana::Model::Action.new({
|
15
|
-
name: 'Test',
|
16
|
-
endpoint: 'forest/actions/Test',
|
17
|
-
http_method: 'POST'
|
18
|
-
}), ForestLiana::Model::Action.new({
|
19
|
-
name: 'TestPut',
|
20
|
-
endpoint: 'forest/actions/Test',
|
21
|
-
http_method: 'PUT'
|
22
|
-
}), ForestLiana::Model::Action.new({
|
23
|
-
name: 'TestRestricted',
|
24
|
-
endpoint: 'forest/actions/TestRestricted',
|
25
|
-
http_method: 'POST'
|
26
|
-
}), ForestLiana::Model::Action.new({
|
27
|
-
name: 'Test Default Values',
|
28
|
-
})
|
29
|
-
]
|
30
|
-
}), ForestLiana::Model::Collection.new({
|
31
|
-
name: 'no_rights_collection',
|
32
|
-
fields: [],
|
33
|
-
actions: [
|
34
|
-
ForestLiana::Model::Action.new({
|
35
|
-
name: 'Test',
|
36
|
-
endpoint: 'forest/actions/Test',
|
37
|
-
http_method: 'POST'
|
38
|
-
})
|
39
|
-
]
|
40
|
-
}), ForestLiana::Model::Collection.new({
|
41
|
-
name: 'custom',
|
42
|
-
fields: [],
|
43
|
-
actions: []
|
44
|
-
})
|
45
|
-
]
|
46
|
-
}
|
47
|
-
let(:default_api_permissions) {
|
48
|
-
{
|
49
|
-
"data" => {
|
50
|
-
"all_rights_collection" => {
|
51
|
-
"collection" => {
|
52
|
-
"list" => true,
|
53
|
-
"show" => true,
|
54
|
-
"create" => true,
|
55
|
-
"update" => true,
|
56
|
-
"delete" => true,
|
57
|
-
"export" => true,
|
58
|
-
"searchToEdit" => true
|
59
|
-
},
|
60
|
-
"actions" => {
|
61
|
-
"Test" => {
|
62
|
-
"allowed" => true,
|
63
|
-
"users" => nil
|
64
|
-
},
|
65
|
-
"TestPut" => {
|
66
|
-
"allowed" => false,
|
67
|
-
"users" => nil
|
68
|
-
},
|
69
|
-
"TestRestricted" => {
|
70
|
-
"allowed" => true,
|
71
|
-
"users" => [1]
|
72
|
-
},
|
73
|
-
"Test Default Values" => {
|
74
|
-
"allowed" => true,
|
75
|
-
"users" => nil
|
76
|
-
},
|
77
|
-
},
|
78
|
-
"segments" => nil
|
79
|
-
},
|
80
|
-
"no_rights_collection" => {
|
81
|
-
"collection" => {
|
82
|
-
"list" => false,
|
83
|
-
"show" => false,
|
84
|
-
"create" => false,
|
85
|
-
"update" => false,
|
86
|
-
"delete" => false,
|
87
|
-
"export" => false,
|
88
|
-
"searchToEdit" => false
|
89
|
-
},
|
90
|
-
"actions" => {
|
91
|
-
"Test" => {
|
92
|
-
"allowed" => false,
|
93
|
-
"users" => nil
|
94
|
-
}
|
95
|
-
},
|
96
|
-
"segments" => nil
|
97
|
-
},
|
98
|
-
},
|
99
|
-
"meta" => {
|
100
|
-
"rolesACLActivated" => false
|
101
|
-
}
|
102
|
-
}
|
103
|
-
}
|
104
|
-
|
105
|
-
before do
|
106
|
-
allow(ForestLiana).to receive(:name_for).and_return(collection_name)
|
107
|
-
allow(ForestLiana).to receive(:apimap).and_return(schema)
|
108
|
-
end
|
109
|
-
|
110
|
-
describe 'handling cache' do
|
111
|
-
let(:collection_name) { 'all_rights_collection' }
|
112
|
-
let(:fake_ressource) { collection_name }
|
113
|
-
let(:default_rendering_id) { 1 }
|
114
|
-
|
115
|
-
context 'when calling twice the same permissions' do
|
116
|
-
before do
|
117
|
-
# clones is called to duplicate the returned value and not use to same (which results in an error
|
118
|
-
# as the permissions is edited through the formatter)
|
119
|
-
allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering) { default_api_permissions.clone }
|
120
|
-
end
|
121
|
-
|
122
|
-
context 'after expiration time' do
|
123
|
-
before do
|
124
|
-
allow(ENV).to receive(:[]).with('FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS').and_return('-1')
|
125
|
-
# Needed to enforce ENV stub
|
126
|
-
described_class.empty_cache
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'should call the API twice' do
|
130
|
-
described_class.new(fake_ressource, 'exportEnabled', default_rendering_id, user: user).is_authorized?
|
131
|
-
described_class.new(fake_ressource, 'exportEnabled', default_rendering_id, user: user).is_authorized?
|
132
|
-
|
133
|
-
expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).twice
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
context 'before expiration time' do
|
138
|
-
it 'should call the API only once' do
|
139
|
-
described_class.new(fake_ressource, 'exportEnabled', default_rendering_id, user: user).is_authorized?
|
140
|
-
described_class.new(fake_ressource, 'exportEnabled', default_rendering_id, user: user).is_authorized?
|
141
|
-
|
142
|
-
expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).once
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
context 'with permissions coming from 2 different renderings' do
|
148
|
-
let(:collection_name) { 'custom' }
|
149
|
-
|
150
|
-
let(:segments_permissions) { nil }
|
151
|
-
let(:api_permissions_rendering_1) {
|
152
|
-
{
|
153
|
-
"data" => {
|
154
|
-
"custom" => {
|
155
|
-
"collection" => {
|
156
|
-
"list" => true,
|
157
|
-
"show" => true,
|
158
|
-
"create" => true,
|
159
|
-
"update" => true,
|
160
|
-
"delete" => true,
|
161
|
-
"export" => true,
|
162
|
-
"searchToEdit" => true
|
163
|
-
},
|
164
|
-
"actions" => { },
|
165
|
-
"segments" => segments_permissions
|
166
|
-
},
|
167
|
-
},
|
168
|
-
"meta" => {
|
169
|
-
"rolesACLActivated" => false
|
170
|
-
}
|
171
|
-
}
|
172
|
-
}
|
173
|
-
let(:api_permissions_rendering_2) {
|
174
|
-
api_permissions_rendering_2 = api_permissions_rendering_1.deep_dup
|
175
|
-
api_permissions_rendering_2['data']['custom']['collection']['export'] = false
|
176
|
-
api_permissions_rendering_2
|
177
|
-
}
|
178
|
-
let(:authorized_to_export_rendering_1) { described_class.new(fake_ressource, 'exportEnabled', 1, user: user).is_authorized? }
|
179
|
-
let(:authorized_to_export_rendering_2) { described_class.new(fake_ressource, 'exportEnabled', 2, user: user).is_authorized? }
|
180
|
-
|
181
|
-
before do
|
182
|
-
allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering)
|
183
|
-
allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(1).and_return(api_permissions_rendering_1)
|
184
|
-
allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(2).and_return(api_permissions_rendering_2)
|
185
|
-
end
|
186
|
-
|
187
|
-
it 'should return 2 different values' do
|
188
|
-
expect(authorized_to_export_rendering_1).to eq true
|
189
|
-
expect(authorized_to_export_rendering_2).to eq false
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
context 'renderings cache' do
|
195
|
-
let(:fake_ressource) { collection_name }
|
196
|
-
let(:rendering_id) { 1 }
|
197
|
-
let(:collection_name) { 'custom' }
|
198
|
-
let(:segments_permissions) { { rendering_id => { 'custom' => nil } } }
|
199
|
-
let(:api_permissions) {
|
200
|
-
{
|
201
|
-
"data" => {
|
202
|
-
"custom" => {
|
203
|
-
"collection" => {
|
204
|
-
"list" => true,
|
205
|
-
"show" => true,
|
206
|
-
"create" => true,
|
207
|
-
"update" => true,
|
208
|
-
"delete" => true,
|
209
|
-
"export" => true,
|
210
|
-
"searchToEdit" => true
|
211
|
-
},
|
212
|
-
"actions" => { },
|
213
|
-
"segments" => nil
|
214
|
-
},
|
215
|
-
},
|
216
|
-
"meta" => {
|
217
|
-
"rolesACLActivated" => false
|
218
|
-
}
|
219
|
-
}
|
220
|
-
}
|
221
|
-
let(:api_permissions_rendering_only) {
|
222
|
-
{
|
223
|
-
"data" => {
|
224
|
-
'collections' => { },
|
225
|
-
'renderings' => segments_permissions
|
226
|
-
},
|
227
|
-
"meta" => {
|
228
|
-
"rolesACLActivated" => false
|
229
|
-
}
|
230
|
-
}
|
231
|
-
}
|
232
|
-
|
233
|
-
before do
|
234
|
-
# clones is called to duplicate the returned value and not use to same (which results in an error
|
235
|
-
# as the permissions is edited through the formatter)
|
236
|
-
allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(rendering_id) { api_permissions.clone }
|
237
|
-
allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(rendering_id, rendering_specific_only: true).and_return(api_permissions_rendering_only)
|
238
|
-
end
|
239
|
-
|
240
|
-
context 'when checking once for authorization' do
|
241
|
-
context 'when checking browseEnabled' do
|
242
|
-
context 'when expiration value is set to its default' do
|
243
|
-
it 'should not call the API to refresh the renderings cache' do
|
244
|
-
described_class.new(fake_ressource, 'browseEnabled', rendering_id, user: user).is_authorized?
|
245
|
-
|
246
|
-
expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id).once
|
247
|
-
expect(ForestLiana::PermissionsGetter).not_to have_received(:get_permissions_for_rendering).with(rendering_id, rendering_specific_only: true)
|
248
|
-
end
|
249
|
-
end
|
250
|
-
|
251
|
-
context 'when expiration value is set in the past' do
|
252
|
-
before do
|
253
|
-
allow(ENV).to receive(:[]).with('FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS').and_return('-1')
|
254
|
-
# Needed to enforce ENV stub
|
255
|
-
described_class.empty_cache
|
256
|
-
end
|
257
|
-
|
258
|
-
it 'should call the API to refresh the renderings cache' do
|
259
|
-
described_class.new(fake_ressource, 'browseEnabled', rendering_id, user: user).is_authorized?
|
260
|
-
|
261
|
-
expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id).once
|
262
|
-
expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id, rendering_specific_only: true).once
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
# Only browse permission requires segments
|
268
|
-
context 'when checking exportEnabled' do
|
269
|
-
context 'when expiration value is set in the past' do
|
270
|
-
before do
|
271
|
-
allow(ENV).to receive(:[]).with('FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS').and_return('-1')
|
272
|
-
# Needed to enforce ENV stub
|
273
|
-
described_class.empty_cache
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
it 'should NOT call the API to refresh the renderings cache' do
|
278
|
-
described_class.new(fake_ressource, 'exportEnabled', rendering_id, user: user).is_authorized?
|
279
|
-
|
280
|
-
expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id).once
|
281
|
-
expect(ForestLiana::PermissionsGetter).not_to have_received(:get_permissions_for_rendering).with(rendering_id, rendering_specific_only: true)
|
282
|
-
end
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
|
-
context 'when checking twice for authorization' do
|
287
|
-
context 'on the same rendering' do
|
288
|
-
context 'when renderings permission has NOT expired' do
|
289
|
-
it 'should NOT call the API to refresh the renderings permissions' do
|
290
|
-
described_class.new(fake_ressource, 'browseEnabled', rendering_id, user: user).is_authorized?
|
291
|
-
described_class.new(fake_ressource, 'browseEnabled', rendering_id, user: user).is_authorized?
|
292
|
-
|
293
|
-
expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id).once
|
294
|
-
expect(ForestLiana::PermissionsGetter).not_to have_received(:get_permissions_for_rendering).with(rendering_id, rendering_specific_only: true)
|
295
|
-
end
|
296
|
-
end
|
297
|
-
|
298
|
-
context 'when renderings permission has expired' do
|
299
|
-
before do
|
300
|
-
allow(ENV).to receive(:[]).with('FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS').and_return('-1')
|
301
|
-
# Needed to enforce ENV stub
|
302
|
-
described_class.empty_cache
|
303
|
-
end
|
304
|
-
|
305
|
-
it 'should call the API to refresh the renderings permissions' do
|
306
|
-
described_class.new(fake_ressource, 'browseEnabled', rendering_id, user: user).is_authorized?
|
307
|
-
described_class.new(fake_ressource, 'browseEnabled', rendering_id, user: user).is_authorized?
|
308
|
-
|
309
|
-
expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id).twice
|
310
|
-
expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id, rendering_specific_only: true).twice
|
311
|
-
end
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
context 'on two different renderings' do
|
316
|
-
let(:other_rendering_id) { 2 }
|
317
|
-
let(:api_permissions_rendering_only) {
|
318
|
-
{
|
319
|
-
"data" => {
|
320
|
-
'collections' => { },
|
321
|
-
'renderings' => {
|
322
|
-
'2' => { 'custom' => nil }
|
323
|
-
}
|
324
|
-
},
|
325
|
-
"meta" => {
|
326
|
-
"rolesACLActivated" => false
|
327
|
-
}
|
328
|
-
}
|
329
|
-
}
|
330
|
-
let(:api_permissions_copy) { api_permissions.clone }
|
331
|
-
|
332
|
-
before do
|
333
|
-
allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(other_rendering_id).and_return(api_permissions_copy)
|
334
|
-
allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(other_rendering_id, rendering_specific_only: true).and_return(api_permissions_rendering_only)
|
335
|
-
end
|
336
|
-
|
337
|
-
it 'should not call the API to refresh the rederings permissions' do
|
338
|
-
described_class.new(fake_ressource, 'browseEnabled', rendering_id, user: user).is_authorized?
|
339
|
-
described_class.new(fake_ressource, 'browseEnabled', other_rendering_id, user: user).is_authorized?
|
340
|
-
|
341
|
-
expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id).once
|
342
|
-
expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(other_rendering_id).once
|
343
|
-
expect(ForestLiana::PermissionsGetter).not_to have_received(:get_permissions_for_rendering).with(rendering_id, rendering_specific_only: true)
|
344
|
-
expect(ForestLiana::PermissionsGetter).not_to have_received(:get_permissions_for_rendering).with(other_rendering_id, rendering_specific_only: true)
|
345
|
-
end
|
346
|
-
end
|
347
|
-
end
|
348
|
-
end
|
349
|
-
|
350
|
-
describe '#is_authorized?' do
|
351
|
-
# Resource is only used to retrieve the collection name as it's stubbed it does not
|
352
|
-
# need to be defined
|
353
|
-
let(:fake_ressource) { collection_name }
|
354
|
-
let(:default_rendering_id) { 1 }
|
355
|
-
let(:api_permissions) { default_api_permissions }
|
356
|
-
let(:collection_name) { 'all_rights_collection' }
|
357
|
-
|
358
|
-
before do
|
359
|
-
allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).and_return(api_permissions)
|
360
|
-
end
|
361
|
-
|
362
|
-
context 'when permissions does NOT have rolesACLActivated' do
|
363
|
-
describe 'exportEnabled permission' do
|
364
|
-
subject { described_class.new(fake_ressource, 'exportEnabled', default_rendering_id, user: user) }
|
365
|
-
|
366
|
-
context 'when user has the required permission' do
|
367
|
-
it 'should be authorized' do
|
368
|
-
expect(subject.is_authorized?).to be true
|
369
|
-
end
|
370
|
-
end
|
371
|
-
|
372
|
-
context 'when user has not the required permission' do
|
373
|
-
let(:collection_name) { 'no_rights_collection' }
|
374
|
-
|
375
|
-
it 'should NOT be authorized' do
|
376
|
-
expect(subject.is_authorized?).to be false
|
377
|
-
end
|
378
|
-
end
|
379
|
-
end
|
380
|
-
|
381
|
-
describe 'browseEnabled permission' do
|
382
|
-
let(:collection_name) { 'custom' }
|
383
|
-
subject { described_class.new(fake_ressource, 'browseEnabled', default_rendering_id, user: user) }
|
384
|
-
let(:segments_permissions) { nil }
|
385
|
-
let(:default_api_permissions) {
|
386
|
-
{
|
387
|
-
"data" => {
|
388
|
-
"custom" => {
|
389
|
-
"collection" => collection_permissions,
|
390
|
-
"actions" => { },
|
391
|
-
"segments" => segments_permissions
|
392
|
-
},
|
393
|
-
},
|
394
|
-
"meta" => {
|
395
|
-
"rolesACLActivated" => false
|
396
|
-
}
|
397
|
-
}
|
398
|
-
}
|
399
|
-
|
400
|
-
context 'when user has list permission' do
|
401
|
-
let(:collection_permissions) {
|
402
|
-
{
|
403
|
-
"list" => true,
|
404
|
-
"show" => false,
|
405
|
-
"create" => false,
|
406
|
-
"update" => false,
|
407
|
-
"delete" => false,
|
408
|
-
"export" => false,
|
409
|
-
"searchToEdit" => false
|
410
|
-
}
|
411
|
-
}
|
412
|
-
|
413
|
-
it 'should be authorized' do
|
414
|
-
expect(subject.is_authorized?).to be true
|
415
|
-
end
|
416
|
-
end
|
417
|
-
|
418
|
-
context 'when user has searchToEdit permission' do
|
419
|
-
let(:collection_permissions) {
|
420
|
-
{
|
421
|
-
"list" => false,
|
422
|
-
"show" => false,
|
423
|
-
"create" => false,
|
424
|
-
"update" => false,
|
425
|
-
"delete" => false,
|
426
|
-
"export" => false,
|
427
|
-
"searchToEdit" => true
|
428
|
-
}
|
429
|
-
}
|
430
|
-
|
431
|
-
it 'should be authorized' do
|
432
|
-
expect(subject.is_authorized?).to be true
|
433
|
-
end
|
434
|
-
end
|
435
|
-
|
436
|
-
context 'when user has not the list nor the searchToEdit permission' do
|
437
|
-
let(:collection_permissions) {
|
438
|
-
{
|
439
|
-
"list" => false,
|
440
|
-
"show" => false,
|
441
|
-
"create" => false,
|
442
|
-
"update" => false,
|
443
|
-
"delete" => false,
|
444
|
-
"export" => false,
|
445
|
-
"searchToEdit" => false
|
446
|
-
}
|
447
|
-
}
|
448
|
-
|
449
|
-
it 'should be NOT authorized' do
|
450
|
-
expect(subject.is_authorized?).to be false
|
451
|
-
end
|
452
|
-
end
|
453
|
-
|
454
|
-
context 'when providing collection_list_parameters' do
|
455
|
-
let(:collection_permissions) {
|
456
|
-
{
|
457
|
-
"list" => true,
|
458
|
-
"show" => false,
|
459
|
-
"create" => false,
|
460
|
-
"update" => false,
|
461
|
-
"delete" => false,
|
462
|
-
"export" => false,
|
463
|
-
"searchToEdit" => false
|
464
|
-
}
|
465
|
-
}
|
466
|
-
let(:collection_list_parameters) { { :user => ["id" => "1"], :filters => nil } }
|
467
|
-
|
468
|
-
subject {
|
469
|
-
described_class.new(
|
470
|
-
fake_ressource,
|
471
|
-
'browseEnabled',
|
472
|
-
default_rendering_id,
|
473
|
-
user: user,
|
474
|
-
collection_list_parameters: collection_list_parameters
|
475
|
-
)
|
476
|
-
}
|
477
|
-
|
478
|
-
context 'when user has the required permission' do
|
479
|
-
it 'should be authorized' do
|
480
|
-
expect(subject.is_authorized?).to be true
|
481
|
-
end
|
482
|
-
end
|
483
|
-
|
484
|
-
context 'when user has no segments and param segmentQuery is there' do
|
485
|
-
let(:segmentQuery) { 'SELECT * FROM products;' }
|
486
|
-
let(:collection_list_parameters) { { :user => ["id" => "1"], :segmentQuery => segmentQuery } }
|
487
|
-
it 'should be authorized' do
|
488
|
-
expect(subject.is_authorized?).to be false
|
489
|
-
end
|
490
|
-
end
|
491
|
-
|
492
|
-
context 'when segments are defined' do
|
493
|
-
let(:segments_permissions) { ['SELECT * FROM products;', 'SELECT * FROM sellers;'] }
|
494
|
-
let(:collection_list_parameters) { { :user => ["id" => "1"], :segmentQuery => segmentQuery } }
|
495
|
-
|
496
|
-
context 'when segments are passing validation' do
|
497
|
-
let(:segmentQuery) { 'SELECT * FROM products;' }
|
498
|
-
it 'should return true' do
|
499
|
-
expect(subject.is_authorized?).to be true
|
500
|
-
end
|
501
|
-
end
|
502
|
-
|
503
|
-
context 'when segments are NOT passing validation' do
|
504
|
-
let(:segmentQuery) { 'SELECT * FROM rockets WHERE name = "Starship";' }
|
505
|
-
it 'should return false' do
|
506
|
-
expect(subject.is_authorized?).to be false
|
507
|
-
end
|
508
|
-
end
|
509
|
-
|
510
|
-
context 'when received union segments NOT passing validation' do
|
511
|
-
let(:segmentQuery) { 'SELECT * FROM sellers/*MULTI-SEGMENTS-QUERIES-UNION*/ UNION SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2' }
|
512
|
-
it 'should return false' do
|
513
|
-
expect(subject.is_authorized?).to be false
|
514
|
-
end
|
515
|
-
end
|
516
|
-
|
517
|
-
context 'when received union segments passing validation' do
|
518
|
-
let(:segmentQuery) { 'SELECT * FROM sellers/*MULTI-SEGMENTS-QUERIES-UNION*/ UNION SELECT * FROM products' }
|
519
|
-
it 'should return true' do
|
520
|
-
expect(subject.is_authorized?).to be true
|
521
|
-
end
|
522
|
-
end
|
523
|
-
context 'when received union segments with UNION inside passing validation' do
|
524
|
-
let(:segmentQuery) { 'SELECT COUNT(*) AS value FROM products/*MULTI-SEGMENTS-QUERIES-UNION*/ UNION SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2' }
|
525
|
-
let(:segments_permissions) { ['SELECT COUNT(*) AS value FROM products;', 'SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2;', 'SELECT * FROM products;', 'SELECT * FROM sellers;'] }
|
526
|
-
it 'should return true' do
|
527
|
-
expect(subject.is_authorized?).to be true
|
528
|
-
end
|
529
|
-
end
|
530
|
-
end
|
531
|
-
|
532
|
-
context 'when user has not the required permission' do
|
533
|
-
let(:collection_permissions) {
|
534
|
-
{
|
535
|
-
"list" => false,
|
536
|
-
"show" => false,
|
537
|
-
"create" => false,
|
538
|
-
"update" => false,
|
539
|
-
"delete" => false,
|
540
|
-
"export" => false,
|
541
|
-
"searchToEdit" => false
|
542
|
-
}
|
543
|
-
}
|
544
|
-
|
545
|
-
it 'should NOT be authorized' do
|
546
|
-
expect(subject.is_authorized?).to be false
|
547
|
-
end
|
548
|
-
end
|
549
|
-
end
|
550
|
-
end
|
551
|
-
|
552
|
-
describe 'readEnabled permission' do
|
553
|
-
subject { described_class.new(fake_ressource, 'readEnabled', default_rendering_id, user: user) }
|
554
|
-
|
555
|
-
context 'when user has the required permission' do
|
556
|
-
it 'should be authorized' do
|
557
|
-
expect(subject.is_authorized?).to be true
|
558
|
-
end
|
559
|
-
end
|
560
|
-
|
561
|
-
context 'when user has not the required permission' do
|
562
|
-
let(:collection_name) { 'no_rights_collection' }
|
563
|
-
|
564
|
-
it 'should NOT be authorized' do
|
565
|
-
expect(subject.is_authorized?).to be false
|
566
|
-
end
|
567
|
-
end
|
568
|
-
end
|
569
|
-
|
570
|
-
describe 'addEnabled permission' do
|
571
|
-
subject { described_class.new(fake_ressource, 'addEnabled', default_rendering_id, user: user) }
|
572
|
-
|
573
|
-
context 'when user has the required permission' do
|
574
|
-
it 'should be authorized' do
|
575
|
-
expect(subject.is_authorized?).to be true
|
576
|
-
end
|
577
|
-
end
|
578
|
-
|
579
|
-
context 'when user has not the required permission' do
|
580
|
-
let(:collection_name) { 'no_rights_collection' }
|
581
|
-
|
582
|
-
it 'should NOT be authorized' do
|
583
|
-
expect(subject.is_authorized?).to be false
|
584
|
-
end
|
585
|
-
end
|
586
|
-
end
|
587
|
-
|
588
|
-
describe 'editEnabled permission' do
|
589
|
-
subject { described_class.new(fake_ressource, 'editEnabled', default_rendering_id, user: user) }
|
590
|
-
|
591
|
-
context 'when user has the required permission' do
|
592
|
-
it 'should be authorized' do
|
593
|
-
expect(subject.is_authorized?).to be true
|
594
|
-
end
|
595
|
-
end
|
596
|
-
|
597
|
-
context 'when user has not the required permission' do
|
598
|
-
let(:collection_name) { 'no_rights_collection' }
|
599
|
-
|
600
|
-
it 'should NOT be authorized' do
|
601
|
-
expect(subject.is_authorized?).to be false
|
602
|
-
end
|
603
|
-
end
|
604
|
-
end
|
605
|
-
|
606
|
-
describe 'deleteEnabled permission' do
|
607
|
-
subject { described_class.new(fake_ressource, 'deleteEnabled', default_rendering_id, user: user) }
|
608
|
-
|
609
|
-
context 'when user has the required permission' do
|
610
|
-
it 'should be authorized' do
|
611
|
-
expect(subject.is_authorized?).to be true
|
612
|
-
end
|
613
|
-
end
|
614
|
-
|
615
|
-
context 'when user has not the required permission' do
|
616
|
-
let(:collection_name) { 'no_rights_collection' }
|
617
|
-
|
618
|
-
it 'should NOT be authorized' do
|
619
|
-
expect(subject.is_authorized?).to be false
|
620
|
-
end
|
621
|
-
end
|
622
|
-
end
|
623
|
-
|
624
|
-
describe 'actions permission' do
|
625
|
-
let(:smart_action_request_info) { { endpoint: 'forest/actions/Test', http_method: 'POST' } }
|
626
|
-
subject {
|
627
|
-
described_class.new(
|
628
|
-
fake_ressource,
|
629
|
-
'actions',
|
630
|
-
default_rendering_id,
|
631
|
-
user: user,
|
632
|
-
smart_action_request_info: smart_action_request_info
|
633
|
-
)
|
634
|
-
}
|
635
|
-
|
636
|
-
context 'when user has the required permission' do
|
637
|
-
|
638
|
-
it 'should be authorized' do
|
639
|
-
expect(subject.is_authorized?).to be true
|
640
|
-
end
|
641
|
-
end
|
642
|
-
|
643
|
-
context 'when user has not the required permission' do
|
644
|
-
let(:collection_name) { 'no_rights_collection' }
|
645
|
-
|
646
|
-
it 'should NOT be authorized' do
|
647
|
-
expect(subject.is_authorized?).to be false
|
648
|
-
end
|
649
|
-
end
|
650
|
-
|
651
|
-
context 'when endpoint is missing from smart action parameters' do
|
652
|
-
let(:smart_action_request_info) { { http_method: 'POST' } }
|
653
|
-
|
654
|
-
it 'user should NOT be authorized' do
|
655
|
-
expect(subject.is_authorized?).to be false
|
656
|
-
end
|
657
|
-
end
|
658
|
-
|
659
|
-
context 'when http_method is missing from smart action parameters' do
|
660
|
-
let(:smart_action_request_info) { { endpoint: 'forest/actions/Test' } }
|
661
|
-
|
662
|
-
it 'user should NOT be authorized' do
|
663
|
-
expect(subject.is_authorized?).to be false
|
664
|
-
end
|
665
|
-
end
|
666
|
-
|
667
|
-
context 'when the provided endpoint is not part of the schema' do
|
668
|
-
let(:smart_action_request_info) { { endpoint: 'forest/actions/Test', http_method: 'DELETE' } }
|
669
|
-
|
670
|
-
it 'user should NOT be authorized' do
|
671
|
-
expect(subject.is_authorized?).to be false
|
672
|
-
end
|
673
|
-
end
|
674
|
-
|
675
|
-
context 'when the action permissions contains a list of user ids' do
|
676
|
-
context 'when user id is NOT part of the authorized users' do
|
677
|
-
let(:user) { { 'id' => '2' } }
|
678
|
-
let(:smart_action_request_info) { { endpoint: 'forest/actions/TestRestricted', http_method: 'POST' } }
|
679
|
-
|
680
|
-
it 'user should NOT be authorized' do
|
681
|
-
expect(subject.is_authorized?).to be false
|
682
|
-
end
|
683
|
-
end
|
684
|
-
|
685
|
-
context 'when user id is part of the authorized users' do
|
686
|
-
let(:smart_action_request_info) { { endpoint: 'forest/actions/TestRestricted', http_method: 'POST' } }
|
687
|
-
|
688
|
-
it 'user should be authorized' do
|
689
|
-
expect(subject.is_authorized?).to be true
|
690
|
-
end
|
691
|
-
end
|
692
|
-
end
|
693
|
-
|
694
|
-
context 'when the action has been created with default http endpoint and method in the schema' do
|
695
|
-
let(:smart_action_request_info) { { endpoint: 'forest/actions/test-default-values', http_method: 'POST' } }
|
696
|
-
|
697
|
-
it 'user should be authorized' do
|
698
|
-
expect(subject.is_authorized?).to be true
|
699
|
-
end
|
700
|
-
end
|
701
|
-
|
702
|
-
context 'when the action has the same enpoint as an other' do
|
703
|
-
let(:smart_action_request_info) { { endpoint: 'forest/actions/Test', http_method: 'PUT' } }
|
704
|
-
|
705
|
-
it 'user should NOT be authorized' do
|
706
|
-
expect(subject.is_authorized?).to be false
|
707
|
-
end
|
708
|
-
end
|
709
|
-
end
|
710
|
-
end
|
711
|
-
end
|
712
|
-
end
|
713
|
-
end
|