forest_liana 9.3.12 → 9.3.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89d96f304e99993a29e7d20a7838db92f58cb19a31ff880357df3f0894139f43
4
- data.tar.gz: 72039990bc82a0ac239195c332bf4dd52067eed7d221013023ce4af5ade1829d
3
+ metadata.gz: a9d26eae41b148fe02b538ee3203010cf491e7a54ddc82f70bec65200864e693
4
+ data.tar.gz: e27a72bd11f586a440aed43f1e1ee9ce4abc2214e2bde575ab93c9b5a6c25e04
5
5
  SHA512:
6
- metadata.gz: 1ea962d090a1ef4f60ae877c2fba8f0674264a8271eddb6c6398979ceb2e52bb523a823f63abc15b47633c6096454227a98b580684d4255179ead3207607d62f
7
- data.tar.gz: 97f31c50316bb6f08d6f664ae06d40475142f877d2f9a5b20f565ab3fa4b162e3523f368fcfaa1596e085826e8b454e41c9ab39eec3b67355177137a19571c57
6
+ metadata.gz: ec6c3e5ae7cd26eb4299ae8cadacc08f1acd252f71c93d9a239b15b9273634b56aa8228ad272fcaef48db8d820f0b673bc55983df541201ab2702e8561a8e992
7
+ data.tar.gz: 2d31b0ed25ff8d6340ddd63d7656f159532ba05bd5a10d0e8f21d1d8f304469377e970334eecde63c29f2ee03cb41ef4a9acf7de8ccfe5b1e7ad25ebc19e9193
@@ -6,7 +6,8 @@ module ForestLiana
6
6
  rescue_from ForestLiana::Ability::Exceptions::AccessDenied, with: :render_error
7
7
  rescue_from ForestLiana::Errors::HTTP403Error, with: :render_error
8
8
  rescue_from ForestLiana::Errors::HTTP422Error, with: :render_error
9
- rescue_from ForestLiana::Errors::ExpectedError, with: :render_error
9
+ rescue_from ForestLiana::Ability::Exceptions::ActionConditionError, with: :render_error
10
+ rescue_from ForestLiana::Ability::Exceptions::UnknownCollection, with: :render_error
10
11
 
11
12
  def self.papertrail?
12
13
  Object.const_get('PaperTrail::Version').is_a?(Class) rescue false
@@ -0,0 +1,16 @@
1
+ module ForestLiana
2
+ module Ability
3
+ module Exceptions
4
+ class UnknownCollection < ForestLiana::Errors::ExpectedError
5
+ def initialize(collection_name)
6
+ super(
7
+ 409,
8
+ :conflict,
9
+ "The collection #{collection_name} doesn't exist",
10
+ 'collection not found'
11
+ )
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -25,8 +25,10 @@ module ForestLiana
25
25
  end
26
26
 
27
27
  is_allowed
28
+ rescue ForestLiana::Errors::ExpectedError => exception
29
+ raise exception
28
30
  rescue
29
- raise ForestLiana::Errors::ExpectedError.new(409, :conflict, "The collection #{collection_name} doesn't exist", 'collection not found')
31
+ raise ForestLiana::Ability::Exceptions::UnknownCollection.new(collection_name)
30
32
  end
31
33
  end
32
34
 
@@ -35,13 +37,16 @@ module ForestLiana
35
37
 
36
38
  user_data = get_user_data(user['id'])
37
39
  collections_data = get_collections_permissions_data
40
+ collection_name = ForestLiana.name_for(collection)
38
41
  begin
39
- action = find_action_from_endpoint(ForestLiana.name_for(collection), endpoint, http_method).name
42
+ action = find_action_from_endpoint(collection_name, endpoint, http_method).name
40
43
 
41
- smart_action_approval = SmartActionChecker.new(parameters, collection, collections_data[ForestLiana.name_for(collection)][:actions][action], user_data)
44
+ smart_action_approval = SmartActionChecker.new(parameters, collection, collections_data[collection_name][:actions][action], user_data)
42
45
  smart_action_approval.can_execute?
46
+ rescue ForestLiana::Errors::ExpectedError => exception
47
+ raise exception
43
48
  rescue
44
- raise ForestLiana::Errors::ExpectedError.new(409, :conflict, "The collection #{collection} doesn't exist", 'collection not found')
49
+ raise ForestLiana::Ability::Exceptions::UnknownCollection.new(collection_name)
45
50
  end
46
51
  end
47
52
 
@@ -66,7 +71,7 @@ module ForestLiana
66
71
 
67
72
  private
68
73
 
69
- def get_user_data(user_id)
74
+ def get_user_data(user_id, force_fetch = true)
70
75
  cache = Rails.cache.fetch('forest.users', expires_in: TTL) do
71
76
  users = {}
72
77
  get_permissions('/liana/v4/permissions/users').each do |user|
@@ -76,7 +81,12 @@ module ForestLiana
76
81
  users
77
82
  end
78
83
 
79
- cache[user_id.to_s]
84
+ if !cache.key?(user_id.to_s) && force_fetch
85
+ Rails.cache.delete('forest.users')
86
+ get_user_data(user_id, false)
87
+ else
88
+ cache[user_id.to_s]
89
+ end
80
90
  end
81
91
 
82
92
  def get_collections_permissions_data(force_fetch = false)
@@ -1,3 +1,3 @@
1
1
  module ForestLiana
2
- VERSION = "9.3.12"
2
+ VERSION = "9.3.14"
3
3
  end
@@ -2,4 +2,8 @@ class Forest::IslandsController < ForestLiana::SmartActionsController
2
2
  def test
3
3
  render json: { success: 'You are OK.' }
4
4
  end
5
+
6
+ def unknown_action
7
+ render json: { success: 'unknown action' }
8
+ end
5
9
  end
@@ -1,6 +1,7 @@
1
1
  Rails.application.routes.draw do
2
2
  namespace :forest do
3
3
  post '/actions/test' => 'islands#test'
4
+ post '/actions/unknown_action' => 'islands#unknown_action'
4
5
  get '/Owner/count' , to: 'owners#count'
5
6
  get '/Owner/:id/relationships/trees/count' , to: 'owner_trees#count'
6
7
  end
@@ -26,6 +26,8 @@ class Forest::Island
26
26
  enums: %w[a b c],
27
27
  }
28
28
 
29
+ action 'test'
30
+
29
31
  action 'my_action',
30
32
  fields: [foo],
31
33
  hooks: {
@@ -261,10 +261,6 @@ describe 'Requesting Actions routes', :type => :request do
261
261
  end
262
262
 
263
263
  describe 'calling the action' do
264
- before(:each) do
265
- allow_any_instance_of(ForestLiana::Ability).to receive(:forest_authorize!) { true }
266
- end
267
-
268
264
  let(:all_records) { false }
269
265
  let(:params) {
270
266
  {
@@ -283,13 +279,119 @@ describe 'Requesting Actions routes', :type => :request do
283
279
 
284
280
  describe 'without scopes' do
285
281
  it 'should respond 200 and perform the action' do
282
+ allow_any_instance_of(ForestLiana::Ability).to receive(:forest_authorize!) { true }
286
283
  post '/forest/actions/test', params: JSON.dump(params), headers: headers
287
284
  expect(response.status).to eq(200)
288
285
  expect(JSON.parse(response.body)).to eq({'success' => 'You are OK.'})
289
286
  end
287
+
288
+ let(:params) {
289
+ {
290
+ data: {
291
+ attributes: {
292
+ collection_name: 'Island',
293
+ ids: ['1'],
294
+ all_records: all_records,
295
+ smart_action_id: 'Island-Test'
296
+ },
297
+ type: 'custom-action-requests'
298
+ },
299
+ timezone: 'Europe/Paris'
300
+ }
301
+ }
302
+
303
+ describe 'with invalid conditions' do
304
+ it 'should respond a 409' do
305
+ Rails.cache.write('forest.has_permission', true)
306
+ Rails.cache.write('forest.users', {'38' => { 'id' => 38, 'roleId' => 1, 'rendering_id' => '13' }})
307
+ Rails.cache.write(
308
+ 'forest.collections',
309
+ {
310
+ 'Island' => {
311
+ :actions =>
312
+ {
313
+ 'test' => { 'triggerEnabled' => [1],
314
+ 'triggerConditions' => [],
315
+ 'approvalRequired' => [1],
316
+ 'approvalRequiredConditions' =>
317
+ [
318
+ { 'filter' =>
319
+ { 'field' => 'id',
320
+ 'value' => 2,
321
+ 'source' => 'data',
322
+ 'operator' => 'foo-greater-than'
323
+ },
324
+ 'roleId' => 1
325
+ }
326
+ ],
327
+ }
328
+ }
329
+ }
330
+ }
331
+ )
332
+
333
+ post '/forest/actions/test', params: JSON.dump(params), headers: headers
334
+
335
+ expect(response.status).to eq(409)
336
+ expect(JSON.parse(response.body)).to eq(
337
+ {
338
+ "errors" => [
339
+ {
340
+ "status" => 409,
341
+ "detail" => "The conditions to trigger this action cannot be verified. Please contact an administrator.",
342
+ "name" => "InvalidActionConditionError"
343
+ }
344
+ ]
345
+ }
346
+ )
347
+ end
348
+ end
349
+
350
+ describe 'with unknown action' do
351
+ it 'should respond a 409' do
352
+ Rails.cache.write('forest.has_permission', true)
353
+ Rails.cache.write('forest.users', {'38' => { 'id' => 38, 'roleId' => 1, 'rendering_id' => '13' }})
354
+ Rails.cache.write(
355
+ 'forest.collections',
356
+ {
357
+ 'Island' => {
358
+ :actions =>
359
+ {
360
+ 'test' => { 'triggerEnabled' => [1],
361
+ 'triggerConditions' => [],
362
+ 'approvalRequired' => [1],
363
+ 'approvalRequiredConditions' =>
364
+ [
365
+ { 'filter' =>
366
+ { 'field' => 'id',
367
+ 'value' => 2,
368
+ 'source' => 'data',
369
+ 'operator' => 'foo-greater-than'
370
+ },
371
+ 'roleId' => 1
372
+ }
373
+ ],
374
+ }
375
+ }
376
+ }
377
+ }
378
+ )
379
+
380
+ post '/forest/actions/unknown_action', params: JSON.dump(params), headers: headers
381
+
382
+ expect(response.status).to eq(409)
383
+ expect(JSON.parse(response.body)).to eq(
384
+ {"errors"=> [{"detail" => "The collection Island doesn't exist", "name" => "collection not found", "status" => 409}]}
385
+ )
386
+ end
387
+ end
290
388
  end
291
389
 
292
390
  describe 'with scopes' do
391
+ before(:each) do
392
+ allow_any_instance_of(ForestLiana::Ability).to receive(:forest_authorize!) { true }
393
+ end
394
+
293
395
  describe 'when record is in scope' do
294
396
  let(:scope_filters) {
295
397
  {
@@ -81,7 +81,11 @@ module ForestLiana
81
81
 
82
82
 
83
83
  it 'should throw an exception when the collection doesn\'t exist' do
84
- expect {dummy_class.is_crud_authorized?('browse', user, String)}.to raise_error(ForestLiana::Errors::ExpectedError, 'The collection String doesn\'t exist')
84
+ allow_any_instance_of(ForestLiana::Ability::Fetch)
85
+ .to receive(:get_permissions)
86
+ .and_return({ "collections" => {} })
87
+ expect {dummy_class.is_crud_authorized?('browse', user, String)}
88
+ .to raise_error(ForestLiana::Ability::Exceptions::UnknownCollection, 'The collection String doesn\'t exist')
85
89
  end
86
90
 
87
91
  it 'should re-fetch the permission once when user permission is not allowed' do
@@ -211,6 +215,30 @@ module ForestLiana
211
215
  expect(dummy_class.is_crud_authorized?('browse', user, Island)).to equal true
212
216
  end
213
217
 
218
+ it 'should re-fetch the users list once when user doesn\'t exist' do
219
+ Rails.cache.write('forest.users', {'2' => { 'id' => 2, 'roleId' => 1, 'rendering_id' => '1' }})
220
+ # Rails.cache.write('forest.users', {'1' => user})
221
+ Rails.cache.write(
222
+ 'forest.collections',
223
+ 'Island' => {
224
+ 'browse' => [1],
225
+ 'read' => [1],
226
+ 'edit' => [1],
227
+ 'add' => [1],
228
+ 'delete' => [1],
229
+ 'export' => [1],
230
+ }
231
+ )
232
+
233
+ allow_any_instance_of(ForestLiana::Ability::Fetch)
234
+ .to receive(:get_permissions)
235
+ .and_return(
236
+ [user]
237
+ )
238
+
239
+ expect(dummy_class.is_crud_authorized?('browse', user, Island)).to equal true
240
+ end
241
+
214
242
  it 'should return false when user permission is not allowed' do
215
243
  Rails.cache.delete('forest.users')
216
244
 
@@ -372,7 +400,8 @@ module ForestLiana
372
400
  end
373
401
 
374
402
  it 'should throw an exception when the collection doesn\'t exist' do
375
- expect {dummy_class.is_smart_action_authorized?(user, String, parameters, '/forest/actions/my_action', 'POST')}.to raise_error(ForestLiana::Errors::ExpectedError, 'The collection String doesn\'t exist')
403
+ expect {dummy_class.is_smart_action_authorized?(user, String, parameters, '/forest/actions/my_action', 'POST')}
404
+ .to raise_error(ForestLiana::Ability::Exceptions::UnknownCollection, 'The collection String doesn\'t exist')
376
405
  end
377
406
  end
378
407
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forest_liana
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.3.12
4
+ version: 9.3.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sandro Munda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-02 00:00:00.000000000 Z
11
+ date: 2024-08-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -263,6 +263,7 @@ files:
263
263
  - app/services/forest_liana/ability/exceptions/action_condition_error.rb
264
264
  - app/services/forest_liana/ability/exceptions/require_approval.rb
265
265
  - app/services/forest_liana/ability/exceptions/trigger_forbidden.rb
266
+ - app/services/forest_liana/ability/exceptions/unknown_collection.rb
266
267
  - app/services/forest_liana/ability/fetch.rb
267
268
  - app/services/forest_liana/ability/permission.rb
268
269
  - app/services/forest_liana/ability/permission/request_permission.rb