forest_liana 6.0.0.pre.beta.2 → 6.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/forest_liana/actions_controller.rb +105 -0
  3. data/app/controllers/forest_liana/authentication_controller.rb +5 -5
  4. data/app/controllers/forest_liana/resources_controller.rb +14 -17
  5. data/app/controllers/forest_liana/smart_actions_controller.rb +10 -5
  6. data/app/helpers/forest_liana/is_same_data_structure_helper.rb +44 -0
  7. data/app/helpers/forest_liana/widgets_helper.rb +59 -0
  8. data/app/models/forest_liana/model/action.rb +2 -1
  9. data/app/serializers/forest_liana/stripe_invoice_serializer.rb +5 -5
  10. data/app/services/forest_liana/apimap_sorter.rb +1 -0
  11. data/app/services/forest_liana/authentication.rb +0 -2
  12. data/app/services/forest_liana/authorization_getter.rb +23 -21
  13. data/app/services/forest_liana/oidc_client_manager.rb +9 -5
  14. data/app/services/forest_liana/permissions_checker.rb +117 -56
  15. data/app/services/forest_liana/permissions_formatter.rb +52 -0
  16. data/app/services/forest_liana/permissions_getter.rb +52 -17
  17. data/app/services/forest_liana/resource_creator.rb +1 -1
  18. data/app/services/forest_liana/resource_updater.rb +3 -3
  19. data/app/services/forest_liana/resources_getter.rb +3 -3
  20. data/app/services/forest_liana/schema_utils.rb +8 -3
  21. data/app/services/forest_liana/scope_validator.rb +8 -7
  22. data/app/services/forest_liana/stripe_invoice_getter.rb +1 -1
  23. data/app/services/forest_liana/stripe_invoices_getter.rb +1 -1
  24. data/app/services/forest_liana/stripe_source_getter.rb +1 -1
  25. data/app/services/forest_liana/stripe_sources_getter.rb +1 -1
  26. data/app/services/forest_liana/utils/beta_schema_utils.rb +13 -0
  27. data/config/initializers/error-messages.rb +3 -0
  28. data/config/initializers/errors.rb +21 -2
  29. data/config/routes.rb +2 -4
  30. data/lib/forest_liana.rb +1 -0
  31. data/lib/forest_liana/bootstrapper.rb +31 -5
  32. data/lib/forest_liana/schema_file_updater.rb +1 -0
  33. data/lib/forest_liana/version.rb +1 -1
  34. data/lib/generators/forest_liana/install_generator.rb +13 -5
  35. data/spec/dummy/app/assets/config/manifest.js +1 -0
  36. data/spec/dummy/config/application.rb +1 -1
  37. data/spec/dummy/db/migrate/20190226172951_create_user.rb +1 -1
  38. data/spec/dummy/db/migrate/20190226173051_create_isle.rb +1 -1
  39. data/spec/dummy/db/migrate/20190226174951_create_tree.rb +1 -1
  40. data/spec/dummy/db/migrate/20190716130830_add_age_to_tree.rb +1 -1
  41. data/spec/dummy/db/migrate/20190716135241_add_type_to_user.rb +1 -1
  42. data/spec/dummy/db/schema.rb +18 -20
  43. data/spec/helpers/forest_liana/is_same_data_structure_helper_spec.rb +87 -0
  44. data/spec/requests/actions_controller_spec.rb +222 -0
  45. data/spec/requests/authentications_spec.rb +12 -13
  46. data/spec/requests/resources_spec.rb +4 -4
  47. data/spec/services/forest_liana/apimap_sorter_spec.rb +6 -4
  48. data/spec/services/forest_liana/permissions_checker_acl_disabled_spec.rb +711 -0
  49. data/spec/services/forest_liana/permissions_checker_acl_enabled_spec.rb +831 -0
  50. data/spec/services/forest_liana/permissions_formatter_spec.rb +222 -0
  51. data/spec/services/forest_liana/permissions_getter_spec.rb +83 -0
  52. data/spec/spec_helper.rb +3 -0
  53. data/test/dummy/app/assets/config/manifest.js +1 -0
  54. data/test/dummy/config/application.rb +1 -1
  55. data/test/dummy/db/migrate/20150608130516_create_date_field.rb +1 -1
  56. data/test/dummy/db/migrate/20150608131430_create_integer_field.rb +1 -1
  57. data/test/dummy/db/migrate/20150608131603_create_decimal_field.rb +1 -1
  58. data/test/dummy/db/migrate/20150608131610_create_float_field.rb +1 -1
  59. data/test/dummy/db/migrate/20150608132159_create_boolean_field.rb +1 -1
  60. data/test/dummy/db/migrate/20150608132621_create_string_field.rb +1 -1
  61. data/test/dummy/db/migrate/20150608133038_create_belongs_to_field.rb +1 -1
  62. data/test/dummy/db/migrate/20150608133044_create_has_one_field.rb +1 -1
  63. data/test/dummy/db/migrate/20150608150016_create_has_many_field.rb +1 -1
  64. data/test/dummy/db/migrate/20150609114636_create_belongs_to_class_name_field.rb +1 -1
  65. data/test/dummy/db/migrate/20150612112520_create_has_and_belongs_to_many_field.rb +1 -1
  66. data/test/dummy/db/migrate/20150616150629_create_polymorphic_field.rb +1 -1
  67. data/test/dummy/db/migrate/20150623115554_create_has_many_class_name_field.rb +1 -1
  68. data/test/dummy/db/migrate/20150814081918_create_has_many_through_field.rb +1 -1
  69. data/test/dummy/db/migrate/20160627172810_create_owner.rb +1 -1
  70. data/test/dummy/db/migrate/20160627172951_create_tree.rb +1 -1
  71. data/test/dummy/db/migrate/20160628173505_add_timestamps.rb +1 -1
  72. data/test/dummy/db/migrate/20170614141921_create_serialize_field.rb +1 -1
  73. data/test/dummy/db/migrate/20181111162121_create_references_table.rb +1 -1
  74. data/test/routing/route_test.rb +0 -12
  75. data/test/services/forest_liana/resources_getter_test.rb +1 -1
  76. metadata +132 -147
  77. data/app/controllers/forest_liana/sessions_controller.rb +0 -95
  78. data/app/serializers/forest_liana/session_serializer.rb +0 -33
  79. data/app/services/forest_liana/login_handler.rb +0 -99
  80. data/app/services/forest_liana/two_factor_registration_confirmer.rb +0 -36
  81. data/app/services/forest_liana/user_secret_creator.rb +0 -26
  82. data/spec/requests/sessions_spec.rb +0 -55
@@ -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