forest_liana 5.2.3 → 5.4.0

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.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/forest_liana/actions_controller.rb +95 -0
  3. data/app/controllers/forest_liana/resources_controller.rb +14 -17
  4. data/app/controllers/forest_liana/smart_actions_controller.rb +10 -5
  5. data/app/helpers/forest_liana/is_same_data_structure_helper.rb +44 -0
  6. data/app/helpers/forest_liana/widgets_helper.rb +59 -0
  7. data/app/models/forest_liana/model/action.rb +2 -1
  8. data/app/services/forest_liana/apimap_sorter.rb +1 -0
  9. data/app/services/forest_liana/permissions_checker.rb +118 -56
  10. data/app/services/forest_liana/permissions_formatter.rb +52 -0
  11. data/app/services/forest_liana/permissions_getter.rb +52 -17
  12. data/app/services/forest_liana/resources_getter.rb +3 -3
  13. data/app/services/forest_liana/scope_validator.rb +8 -7
  14. data/app/services/forest_liana/utils/beta_schema_utils.rb +13 -0
  15. data/config/routes.rb +2 -0
  16. data/lib/forest_liana/bootstrapper.rb +19 -0
  17. data/lib/forest_liana/schema_file_updater.rb +1 -0
  18. data/lib/forest_liana/version.rb +1 -1
  19. data/spec/helpers/forest_liana/is_same_data_structure_helper_spec.rb +87 -0
  20. data/spec/requests/actions_controller_spec.rb +174 -0
  21. data/spec/services/forest_liana/apimap_sorter_spec.rb +6 -4
  22. data/spec/services/forest_liana/permissions_checker_acl_disabled_spec.rb +711 -0
  23. data/spec/services/forest_liana/permissions_checker_acl_enabled_spec.rb +831 -0
  24. data/spec/services/forest_liana/permissions_formatter_spec.rb +222 -0
  25. data/spec/services/forest_liana/permissions_getter_spec.rb +82 -0
  26. data/spec/services/forest_liana/schema_adapter_spec.rb +1 -1
  27. data/spec/spec_helper.rb +3 -0
  28. metadata +18 -2
@@ -0,0 +1,831 @@
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_boolean',
12
+ fields: [],
13
+ actions: [
14
+ ForestLiana::Model::Action.new({
15
+ name: 'Test',
16
+ endpoint: 'forest/actions/Test',
17
+ http_method: 'POST'
18
+ })
19
+ ]
20
+ }), ForestLiana::Model::Collection.new({
21
+ name: 'no_rights_collection_boolean',
22
+ fields: [],
23
+ actions: [
24
+ ForestLiana::Model::Action.new({
25
+ name: 'Test',
26
+ endpoint: 'forest/actions/Test',
27
+ http_method: 'POST'
28
+ })
29
+ ]
30
+ }), ForestLiana::Model::Collection.new({
31
+ name: 'all_rights_collection_user_list',
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: 'no_rights_collection_user_list',
42
+ fields: [],
43
+ actions: [
44
+ ForestLiana::Model::Action.new({
45
+ name: 'Test',
46
+ endpoint: 'forest/actions/Test',
47
+ http_method: 'POST'
48
+ })
49
+ ]
50
+ })
51
+ ]
52
+ }
53
+ let(:scope_permissions) { nil }
54
+ let(:default_api_permissions) {
55
+ {
56
+ "data" => {
57
+ 'collections' => {
58
+ "all_rights_collection_boolean" => {
59
+ "collection" => {
60
+ "browseEnabled" => true,
61
+ "readEnabled" => true,
62
+ "editEnabled" => true,
63
+ "addEnabled" => true,
64
+ "deleteEnabled" => true,
65
+ "exportEnabled" => true
66
+ },
67
+ "actions" => {
68
+ "Test" => {
69
+ "triggerEnabled" => true
70
+ },
71
+ }
72
+ },
73
+ "all_rights_collection_user_list" => {
74
+ "collection" => {
75
+ "browseEnabled" => [1],
76
+ "readEnabled" => [1],
77
+ "editEnabled" => [1],
78
+ "addEnabled" => [1],
79
+ "deleteEnabled" => [1],
80
+ "exportEnabled" => [1]
81
+ },
82
+ "actions" => {
83
+ "Test" => {
84
+ "triggerEnabled" => [1]
85
+ },
86
+ }
87
+ },
88
+ "no_rights_collection_boolean" => {
89
+ "collection" => {
90
+ "browseEnabled" => false,
91
+ "readEnabled" => false,
92
+ "editEnabled" => false,
93
+ "addEnabled" => false,
94
+ "deleteEnabled" => false,
95
+ "exportEnabled" => false
96
+ },
97
+ "actions" => {
98
+ "Test" => {
99
+ "triggerEnabled" => false
100
+ },
101
+ }
102
+ },
103
+ "no_rights_collection_user_list" => {
104
+ "collection" => {
105
+ "browseEnabled" => [],
106
+ "readEnabled" => [],
107
+ "editEnabled" => [],
108
+ "addEnabled" => [],
109
+ "deleteEnabled" => [],
110
+ "exportEnabled" => []
111
+ },
112
+ "actions" => {
113
+ "Test" => {
114
+ "triggerEnabled" => []
115
+ },
116
+ }
117
+ },
118
+ },
119
+ 'renderings' => scope_permissions
120
+ },
121
+ "meta" => {
122
+ "rolesACLActivated" => true
123
+ }
124
+ }
125
+ }
126
+ let(:default_rendering_id) { 1 }
127
+
128
+ before do
129
+ allow(ForestLiana).to receive(:apimap).and_return(schema)
130
+ allow(ForestLiana).to receive(:name_for).and_return(collection_name)
131
+ end
132
+
133
+ describe 'handling cache' do
134
+ let(:collection_name) { 'all_rights_collection_boolean' }
135
+ let(:fake_ressource) { nil }
136
+ let(:default_rendering_id) { 1 }
137
+
138
+ context 'collections cache' do
139
+ context 'when calling twice the same permissions' do
140
+ before do
141
+ allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).and_return(default_api_permissions)
142
+ end
143
+
144
+ context 'after expiration time' do
145
+ before do
146
+ allow(ENV).to receive(:[]).with('FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS').and_return('-1')
147
+ # Needed to enforce ENV stub
148
+ described_class.empty_cache
149
+ end
150
+
151
+ it 'should call the API twice' do
152
+ described_class.new(fake_ressource, 'exportEnabled', default_rendering_id, user_id: user_id).is_authorized?
153
+ described_class.new(fake_ressource, 'exportEnabled', default_rendering_id, user_id: user_id).is_authorized?
154
+
155
+ expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).twice
156
+ end
157
+ end
158
+
159
+ context 'before expiration time' do
160
+ it 'should call the API only once' do
161
+ described_class.new(fake_ressource, 'exportEnabled', default_rendering_id, user_id: user_id).is_authorized?
162
+ described_class.new(fake_ressource, 'exportEnabled', default_rendering_id, user_id: user_id).is_authorized?
163
+
164
+ expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).once
165
+ end
166
+ end
167
+ end
168
+
169
+ context 'with permissions coming from 2 different renderings' do
170
+ before do
171
+ allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering)
172
+ allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(1).and_return(api_permissions_rendering_1)
173
+ allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(2).and_return(api_permissions_rendering_2)
174
+ end
175
+
176
+ let(:collection_name) { 'custom' }
177
+ let(:scope_permissions) { { default_rendering_id => { 'custom' => nil }, 2 => { 'custom' => nil } } }
178
+ let(:api_permissions_rendering_1) {
179
+ {
180
+ "data" => {
181
+ 'collections' => {
182
+ "custom" => {
183
+ "collection" => {
184
+ "browseEnabled" => false,
185
+ "readEnabled" => true,
186
+ "editEnabled" => true,
187
+ "addEnabled" => true,
188
+ "deleteEnabled" => true,
189
+ "exportEnabled" => true
190
+ },
191
+ "actions" => { }
192
+ },
193
+ },
194
+ 'renderings' => scope_permissions
195
+ },
196
+ "meta" => {
197
+ "rolesACLActivated" => true
198
+ }
199
+ }
200
+ }
201
+ let(:api_permissions_rendering_2) {
202
+ api_permissions_rendering_2 = api_permissions_rendering_1.deep_dup
203
+ api_permissions_rendering_2['data']['collections']['custom']['collection']['exportEnabled'] = false
204
+ api_permissions_rendering_2['data']['collections']['custom']['collection']['browseEnabled'] = true
205
+ api_permissions_rendering_2
206
+ }
207
+
208
+ context 'when the first call is authorized' do
209
+ let(:authorized_to_export_rendering_1) { described_class.new(fake_ressource, 'exportEnabled', 1, user_id: user_id).is_authorized? }
210
+ let(:authorized_to_export_rendering_2) { described_class.new(fake_ressource, 'exportEnabled', 2, user_id: user_id).is_authorized? }
211
+
212
+ # Even if the value are different, the permissions are cross rendering thus another call
213
+ # to the api wont be made until the permission expires
214
+ it 'should return the same value' do
215
+ expect(authorized_to_export_rendering_1).to eq true
216
+ expect(authorized_to_export_rendering_2).to eq true
217
+ end
218
+
219
+ it 'should call the API only once' do
220
+ authorized_to_export_rendering_1
221
+ authorized_to_export_rendering_2
222
+ expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).once
223
+ end
224
+ end
225
+
226
+ # If not authorized the cached version is not used
227
+ context 'when the first call is not authorized' do
228
+ let(:authorized_to_export_rendering_1) { described_class.new(fake_ressource, 'browseEnabled', 1, user_id: user_id).is_authorized? }
229
+ let(:authorized_to_export_rendering_2) { described_class.new(fake_ressource, 'browseEnabled', 2, user_id: user_id).is_authorized? }
230
+
231
+ it 'should return different value' do
232
+ expect(authorized_to_export_rendering_1).to eq false
233
+ expect(authorized_to_export_rendering_2).to eq true
234
+ end
235
+
236
+ it 'should call the API twice' do
237
+ authorized_to_export_rendering_1
238
+ authorized_to_export_rendering_2
239
+ expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).twice
240
+ end
241
+ end
242
+ end
243
+ end
244
+
245
+ context 'scopes cache' do
246
+ let(:rendering_id) { 1 }
247
+ let(:collection_name) { 'custom' }
248
+ let(:scope_permissions) { { rendering_id => { 'custom' => nil } } }
249
+ let(:api_permissions) {
250
+ {
251
+ "data" => {
252
+ 'collections' => {
253
+ "custom" => {
254
+ "collection" => {
255
+ "browseEnabled" => true,
256
+ "readEnabled" => true,
257
+ "editEnabled" => true,
258
+ "addEnabled" => true,
259
+ "deleteEnabled" => true,
260
+ "exportEnabled" => true
261
+ },
262
+ "actions" => { }
263
+ },
264
+ },
265
+ 'renderings' => scope_permissions
266
+ },
267
+ "meta" => {
268
+ "rolesACLActivated" => true
269
+ }
270
+ }
271
+ }
272
+ let(:api_permissions_scope_only) {
273
+ {
274
+ "data" => {
275
+ 'collections' => { },
276
+ 'renderings' => scope_permissions
277
+ },
278
+ "meta" => {
279
+ "rolesACLActivated" => true
280
+ }
281
+ }
282
+ }
283
+
284
+ before do
285
+ allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(rendering_id).and_return(api_permissions)
286
+ allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(rendering_id, rendering_specific_only: true).and_return(api_permissions_scope_only)
287
+ end
288
+
289
+ context 'when checking once for authorization' do
290
+ context 'when checking browseEnabled' do
291
+ context 'when expiration value is set to its default' do
292
+ it 'should not call the API to refresh the scopes cache' do
293
+ described_class.new(fake_ressource, 'browseEnabled', rendering_id, user_id: user_id).is_authorized?
294
+
295
+ expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id).once
296
+ expect(ForestLiana::PermissionsGetter).not_to have_received(:get_permissions_for_rendering).with(rendering_id, rendering_specific_only: true)
297
+ end
298
+ end
299
+
300
+ context 'when expiration value is set in the past' do
301
+ before do
302
+ allow(ENV).to receive(:[]).with('FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS').and_return('-1')
303
+ # Needed to enforce ENV stub
304
+ described_class.empty_cache
305
+ end
306
+
307
+ it 'should call the API to refresh the scopes cache' do
308
+ described_class.new(fake_ressource, 'browseEnabled', rendering_id, user_id: user_id).is_authorized?
309
+
310
+ expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id).once
311
+ expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id, rendering_specific_only: true).once
312
+ end
313
+ end
314
+ end
315
+
316
+ # Only browse permission requires scopes
317
+ context 'when checking exportEnabled' do
318
+ context 'when expiration value is set in the past' do
319
+ before do
320
+ allow(ENV).to receive(:[]).with('FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS').and_return('-1')
321
+ # Needed to enforce ENV stub
322
+ described_class.empty_cache
323
+ end
324
+ end
325
+
326
+ it 'should NOT call the API to refresh the scopes cache' do
327
+ described_class.new(fake_ressource, 'exportEnabled', rendering_id, user_id: user_id).is_authorized?
328
+
329
+ expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id).once
330
+ expect(ForestLiana::PermissionsGetter).not_to have_received(:get_permissions_for_rendering).with(rendering_id, rendering_specific_only: true)
331
+ end
332
+ end
333
+ end
334
+
335
+ context 'when checking twice for authorization' do
336
+ context 'on the same rendering' do
337
+ context 'when scopes permission has NOT expired' do
338
+ it 'should NOT call the API to refresh the scopes permissions' do
339
+ described_class.new(fake_ressource, 'browseEnabled', rendering_id, user_id: user_id).is_authorized?
340
+ described_class.new(fake_ressource, 'browseEnabled', rendering_id, user_id: user_id).is_authorized?
341
+
342
+ expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id).once
343
+ expect(ForestLiana::PermissionsGetter).not_to have_received(:get_permissions_for_rendering).with(rendering_id, rendering_specific_only: true)
344
+ end
345
+ end
346
+
347
+ context 'when scopes permission has expired' do
348
+ before do
349
+ allow(ENV).to receive(:[]).with('FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS').and_return('-1')
350
+ # Needed to enforce ENV stub
351
+ described_class.empty_cache
352
+ end
353
+
354
+ it 'should call the API to refresh the scopes permissions' do
355
+ described_class.new(fake_ressource, 'browseEnabled', rendering_id, user_id: user_id).is_authorized?
356
+ described_class.new(fake_ressource, 'browseEnabled', rendering_id, user_id: user_id).is_authorized?
357
+
358
+ expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id).twice
359
+ expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id, rendering_specific_only: true).twice
360
+ end
361
+ end
362
+ end
363
+
364
+ context 'on two different renderings' do
365
+ let(:other_rendering_id) { 2 }
366
+ let(:api_permissions_scope_only) {
367
+ {
368
+ "data" => {
369
+ 'collections' => { },
370
+ 'renderings' => {
371
+ '2' => { 'custom' => nil }
372
+ }
373
+ },
374
+ "meta" => {
375
+ "rolesACLActivated" => true
376
+ }
377
+ }
378
+ }
379
+
380
+ before do
381
+ allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).with(other_rendering_id, rendering_specific_only: true).and_return(api_permissions_scope_only)
382
+ end
383
+
384
+ it 'should call the API to refresh the scopes permissions' do
385
+ described_class.new(fake_ressource, 'browseEnabled', rendering_id, user_id: user_id).is_authorized?
386
+ described_class.new(fake_ressource, 'browseEnabled', other_rendering_id, user_id: user_id).is_authorized?
387
+
388
+ expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(rendering_id).once
389
+ expect(ForestLiana::PermissionsGetter).to have_received(:get_permissions_for_rendering).with(other_rendering_id, rendering_specific_only: true).once
390
+ end
391
+ end
392
+ end
393
+ end
394
+ end
395
+
396
+ describe '#is_authorized?' do
397
+ # Resource is only used to retrieve the collection name as it's stub it does not
398
+ # need to be defined
399
+ let(:fake_ressource) { nil }
400
+ let(:default_rendering_id) { nil }
401
+ let(:api_permissions) { default_api_permissions }
402
+
403
+ before do
404
+ allow(ForestLiana::PermissionsGetter).to receive(:get_permissions_for_rendering).and_return(api_permissions)
405
+ end
406
+
407
+ context 'when permissions have rolesACLActivated' do
408
+ context 'with true/false permission values' do
409
+ let(:collection_name) { 'all_rights_collection_boolean' }
410
+
411
+ describe 'exportEnabled permission' do
412
+ subject { described_class.new(fake_ressource, 'exportEnabled', default_rendering_id, user_id: user_id) }
413
+
414
+ context 'when user has the required permission' do
415
+ it 'should be authorized' do
416
+ expect(subject.is_authorized?).to be true
417
+ end
418
+ end
419
+
420
+ context 'when user has not the required permission' do
421
+ let(:collection_name) { 'no_rights_collection_boolean' }
422
+
423
+ it 'should NOT be authorized' do
424
+ expect(subject.is_authorized?).to be false
425
+ end
426
+ end
427
+ end
428
+
429
+ describe 'browseEnbled permission' do
430
+ let(:collection_list_parameters) { { :user_id => "1", :filters => nil } }
431
+ subject {
432
+ described_class.new(
433
+ fake_ressource,
434
+ 'browseEnabled',
435
+ default_rendering_id,
436
+ user_id: user_id,
437
+ collection_list_parameters: collection_list_parameters
438
+ )
439
+ }
440
+
441
+ context 'when user has the required permission' do
442
+ it 'should be authorized' do
443
+ expect(subject.is_authorized?).to be true
444
+ end
445
+ end
446
+
447
+ context 'when user has not the required permission' do
448
+ let(:collection_name) { 'no_rights_collection_boolean' }
449
+
450
+ it 'should NOT be authorized' do
451
+ expect(subject.is_authorized?).to be false
452
+ end
453
+ end
454
+
455
+ context 'when scopes are defined' do
456
+ let(:default_rendering_id) { 1 }
457
+ let(:scope_permissions) {
458
+ {
459
+ default_rendering_id => {
460
+ collection_name => {
461
+ 'scope' => {
462
+ 'dynamicScopesValues' => {},
463
+ 'filter' => { 'aggregator' => 'and', 'conditions' => [condition] }
464
+ }
465
+ }
466
+ }
467
+ }
468
+ }
469
+ let(:collection_list_parameters) { { :user_id => "1", :filters => JSON.generate(condition) } }
470
+
471
+ context 'when scopes are passing validation' do
472
+ context 'when scope value is a string' do
473
+ let(:condition) { { 'field' => 'field_1', 'operator' => 'equal', 'value' => true } }
474
+
475
+ it 'should return true' do
476
+ expect(subject.is_authorized?).to be true
477
+ end
478
+ end
479
+
480
+ context 'when scope value is a boolean' do
481
+ let(:condition) { { 'field' => 'field_1', 'operator' => 'equal', 'value' => 'true' } }
482
+
483
+ it 'should return true' do
484
+ expect(subject.is_authorized?).to be true
485
+ end
486
+ end
487
+ end
488
+
489
+ context 'when scopes are NOT passing validation' do
490
+ let(:condition) { { 'field' => 'field_1', 'operator' => 'equal', 'value' => true } }
491
+ let(:other_condition) {
492
+ {
493
+ aggregator: 'and',
494
+ conditions: [
495
+ { field: 'name', value: 'john', operator: 'equal' },
496
+ { field: 'price', value: '2500', operator: 'equal' }
497
+ ]
498
+ }
499
+ }
500
+ let(:collection_list_parameters) {
501
+ {
502
+ :user_id => "1",
503
+ :filters => JSON.generate(other_condition)
504
+ }
505
+ }
506
+
507
+ it 'should return false' do
508
+ expect(subject.is_authorized?).to be false
509
+ end
510
+ end
511
+ end
512
+ end
513
+
514
+ describe 'readEnabled permission' do
515
+ subject { described_class.new(fake_ressource, 'readEnabled', default_rendering_id, user_id: user_id) }
516
+
517
+ context 'when user has the required permission' do
518
+ it 'should be authorized' do
519
+ expect(subject.is_authorized?).to be true
520
+ end
521
+ end
522
+
523
+ context 'when user has not the required permission' do
524
+ let(:collection_name) { 'no_rights_collection_boolean' }
525
+
526
+ it 'should NOT be authorized' do
527
+ expect(subject.is_authorized?).to be false
528
+ end
529
+ end
530
+ end
531
+
532
+ describe 'addEnabled permission' do
533
+ subject { described_class.new(fake_ressource, 'addEnabled', default_rendering_id, user_id: user_id) }
534
+
535
+ context 'when user has the required permission' do
536
+ it 'should be authorized' do
537
+ expect(subject.is_authorized?).to be true
538
+ end
539
+ end
540
+
541
+ context 'when user has not the required permission' do
542
+ let(:collection_name) { 'no_rights_collection_boolean' }
543
+
544
+ it 'should NOT be authorized' do
545
+ expect(subject.is_authorized?).to be false
546
+ end
547
+ end
548
+ end
549
+
550
+ describe 'editEnabled permission' do
551
+ subject { described_class.new(fake_ressource, 'editEnabled', default_rendering_id, user_id: user_id) }
552
+
553
+ context 'when user has the required permission' do
554
+ it 'should be authorized' do
555
+ expect(subject.is_authorized?).to be true
556
+ end
557
+ end
558
+
559
+ context 'when user has not the required permission' do
560
+ let(:collection_name) { 'no_rights_collection_boolean' }
561
+
562
+ it 'should NOT be authorized' do
563
+ expect(subject.is_authorized?).to be false
564
+ end
565
+ end
566
+ end
567
+
568
+ describe 'deleteEnabled permission' do
569
+ subject { described_class.new(fake_ressource, 'deleteEnabled', default_rendering_id, user_id: user_id) }
570
+
571
+ context 'when user has the required permission' do
572
+ it 'should be authorized' do
573
+ expect(subject.is_authorized?).to be true
574
+ end
575
+ end
576
+
577
+ context 'when user has not the required permission' do
578
+ let(:collection_name) { 'no_rights_collection_boolean' }
579
+
580
+ it 'should NOT be authorized' do
581
+ expect(subject.is_authorized?).to be false
582
+ end
583
+ end
584
+ end
585
+
586
+ describe 'actions permission' do
587
+ let(:smart_action_request_info) { { endpoint: 'forest/actions/Test', http_method: 'POST' } }
588
+ subject {
589
+ described_class.new(
590
+ fake_ressource,
591
+ 'actions',
592
+ default_rendering_id,
593
+ user_id: user_id,
594
+ smart_action_request_info: smart_action_request_info
595
+ )
596
+ }
597
+
598
+ context 'when user has the required permission' do
599
+ it 'should be authorized' do
600
+ expect(subject.is_authorized?).to be true
601
+ end
602
+ end
603
+
604
+ context 'when user has not the required permission' do
605
+ let(:collection_name) { 'no_rights_collection_boolean' }
606
+
607
+ it 'should NOT be authorized' do
608
+ expect(subject.is_authorized?).to be false
609
+ end
610
+ end
611
+
612
+ context 'when endpoint is missing from smart action parameters' do
613
+ let(:smart_action_request_info) { { http_method: 'POST' } }
614
+
615
+ it 'user should NOT be authorized' do
616
+ expect(subject.is_authorized?).to be false
617
+ end
618
+ end
619
+
620
+ context 'when http_method is missing from smart action parameters' do
621
+ let(:smart_action_request_info) { { endpoint: 'forest/actions/Test' } }
622
+
623
+ it 'user should NOT be authorized' do
624
+ expect(subject.is_authorized?).to be false
625
+ end
626
+ end
627
+
628
+ context 'when the provided endpoint is not part of the schema' do
629
+ let(:smart_action_request_info) { { endpoint: 'forest/actions/Test', http_method: 'DELETE' } }
630
+
631
+ it 'user should NOT be authorized' do
632
+ expect(subject.is_authorized?).to be false
633
+ end
634
+ end
635
+ end
636
+ end
637
+
638
+ context 'with userId list permission values' do
639
+ let(:collection_name) { 'all_rights_collection_user_list' }
640
+
641
+ describe 'exportEnabled permission' do
642
+ subject { described_class.new(fake_ressource, 'exportEnabled', default_rendering_id, user_id: user_id) }
643
+
644
+ context 'when user has the required permission' do
645
+ it 'should be authorized' do
646
+ expect(subject.is_authorized?).to be true
647
+ end
648
+ end
649
+
650
+ context 'when user has not the required permission' do
651
+ let(:collection_name) { 'no_rights_collection_user_list' }
652
+
653
+ it 'should NOT be authorized' do
654
+ expect(subject.is_authorized?).to be false
655
+ end
656
+ end
657
+ end
658
+
659
+ describe 'browseEnabled permission' do
660
+ let(:collection_list_parameters) { { :user_id => "1", :filters => nil } }
661
+ subject {
662
+ described_class.new(
663
+ fake_ressource,
664
+ 'browseEnabled',
665
+ default_rendering_id,
666
+ user_id: user_id,
667
+ collection_list_parameters: collection_list_parameters
668
+ )
669
+ }
670
+
671
+ context 'when user has the required permission' do
672
+ it 'should be authorized' do
673
+ expect(subject.is_authorized?).to be true
674
+ end
675
+ end
676
+
677
+ context 'when user has not the required permission' do
678
+ let(:collection_name) { 'no_rights_collection_user_list' }
679
+
680
+ it 'should NOT be authorized' do
681
+ expect(subject.is_authorized?).to be false
682
+ end
683
+ end
684
+ end
685
+
686
+ describe 'readEnabled permission' do
687
+ subject { described_class.new(fake_ressource, 'readEnabled', default_rendering_id, user_id: user_id) }
688
+
689
+ context 'when user has the required permission' do
690
+ it 'should be authorized' do
691
+ expect(subject.is_authorized?).to be true
692
+ end
693
+ end
694
+
695
+ context 'when user has not the required permission' do
696
+ let(:collection_name) { 'no_rights_collection_user_list' }
697
+
698
+ it 'should NOT be authorized' do
699
+ expect(subject.is_authorized?).to be false
700
+ end
701
+ end
702
+ end
703
+
704
+ describe 'addEnabled permission' do
705
+ subject { described_class.new(fake_ressource, 'addEnabled', default_rendering_id, user_id: user_id) }
706
+
707
+ context 'when user has the required permission' do
708
+ it 'should be authorized' do
709
+ expect(subject.is_authorized?).to be true
710
+ end
711
+ end
712
+
713
+ context 'when user has not the required permission' do
714
+ let(:collection_name) { 'no_rights_collection_user_list' }
715
+
716
+ it 'should NOT be authorized' do
717
+ expect(subject.is_authorized?).to be false
718
+ end
719
+ end
720
+ end
721
+
722
+ describe 'editEnabled permission' do
723
+ subject { described_class.new(fake_ressource, 'editEnabled', default_rendering_id, user_id: user_id) }
724
+
725
+ context 'when user has the required permission' do
726
+ it 'should be authorized' do
727
+ expect(subject.is_authorized?).to be true
728
+ end
729
+ end
730
+
731
+ context 'when user has not the required permission' do
732
+ let(:collection_name) { 'no_rights_collection_user_list' }
733
+
734
+ it 'should NOT be authorized' do
735
+ expect(subject.is_authorized?).to be false
736
+ end
737
+ end
738
+ end
739
+
740
+ describe 'deleteEnabled permission' do
741
+ subject { described_class.new(fake_ressource, 'deleteEnabled', default_rendering_id, user_id: user_id) }
742
+
743
+ context 'when user has the required permission' do
744
+ it 'should be authorized' do
745
+ expect(subject.is_authorized?).to be true
746
+ end
747
+ end
748
+
749
+ context 'when user has not the required permission' do
750
+ let(:collection_name) { 'no_rights_collection_user_list' }
751
+
752
+ it 'should NOT be authorized' do
753
+ expect(subject.is_authorized?).to be false
754
+ end
755
+ end
756
+ end
757
+
758
+ describe 'actions permission' do
759
+ let(:smart_action_request_info) { { endpoint: 'forest/actions/Test', http_method: 'POST' } }
760
+ subject {
761
+ described_class.new(
762
+ fake_ressource,
763
+ 'actions',
764
+ default_rendering_id,
765
+ user_id: user_id,
766
+ smart_action_request_info: smart_action_request_info
767
+ )
768
+ }
769
+
770
+ context 'when user has the required permission' do
771
+ it 'should be authorized' do
772
+ expect(subject.is_authorized?).to be true
773
+ end
774
+ end
775
+
776
+ context 'when user has not the required permission' do
777
+ let(:collection_name) { 'no_rights_collection_user_list' }
778
+
779
+ it 'should NOT be authorized' do
780
+ expect(subject.is_authorized?).to be false
781
+ end
782
+ end
783
+
784
+ context 'when endpoint is missing from smart action parameters' do
785
+ let(:smart_action_request_info) { { http_method: 'POST' } }
786
+
787
+ it 'user should NOT be authorized' do
788
+ expect(subject.is_authorized?).to be false
789
+ end
790
+ end
791
+
792
+ context 'when http_method is missing from smart action parameters' do
793
+ let(:smart_action_request_info) { { endpoint: 'forest/actions/Test' } }
794
+
795
+ it 'user should NOT be authorized' do
796
+ expect(subject.is_authorized?).to be false
797
+ end
798
+ end
799
+
800
+ context 'when the provided endpoint is not part of the schema' do
801
+ let(:smart_action_request_info) { { endpoint: 'forest/actions/Test', http_method: 'DELETE' } }
802
+
803
+ it 'user should NOT be authorized' do
804
+ expect(subject.is_authorized?).to be false
805
+ end
806
+ end
807
+ end
808
+
809
+ # searchToEdit permission checker should not be called anymore once rolesAcl activated
810
+ describe 'searchToEdit permission' do
811
+ subject { described_class.new(fake_ressource, 'searchToEdit', default_rendering_id, user_id: user_id) }
812
+
813
+ context 'when user has all permissions' do
814
+ it 'should NOT be authorized' do
815
+ expect(subject.is_authorized?).to be false
816
+ end
817
+ end
818
+
819
+ context 'when user has no permissions' do
820
+ let(:collection_name) { 'no_rights_collection_user_list' }
821
+
822
+ it 'should NOT be authorized' do
823
+ expect(subject.is_authorized?).to be false
824
+ end
825
+ end
826
+ end
827
+ end
828
+ end
829
+ end
830
+ end
831
+ end