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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c4f5dd198db274bc38945cb0f30878d6636154086fbceed39b9f392c4cf2d9c7
4
- data.tar.gz: 07c78e436df2aa66b9dbeaa776ad9125d3ffc04f1b60531b96848a84a56dfda4
3
+ metadata.gz: 4e1a93b16b8c079a92000891ac73f8794fa87c2b6411e99a6e160d7f5e88e64d
4
+ data.tar.gz: 0b6853a6eda1fef9f395fa9f247b90273fef74fe8eb9e621ed4647d43832dc03
5
5
  SHA512:
6
- metadata.gz: 2f9023a07c00e560f87e04184b88d6c6294e076bf29900c03d07eaa5f564308843e17456b09469777209d953b695085ef5650dbcdea029c0c4f3c1ddbb9c1d32
7
- data.tar.gz: 0f1cdf525dedff5ec0d39f34952396263b3fe73ad25926eb47eef43641bd72835eb9ff87bde88d6864181cdab4fec7d654b5a4c8c9c1b9583ba34a9e262e419e
6
+ metadata.gz: 3e7aa35686573cce22819ea583a20c9d93afd39b72187aae0c618fd0e67e1494475435ae0ca9c8c892b7bbe3015c0e6ac0f220ca75b2526f66883f5a491f54f7
7
+ data.tar.gz: ffdcfcf09b90001e66bff1910a86d635def03cf718a9e13282061d4f9d5c4b0780058ba7462106ea6c4deb299e388bb3c32a3eec624d51bfd7b0420a85a60167
@@ -1,7 +1,102 @@
1
1
  module ForestLiana
2
2
  class ActionsController < ForestLiana::BaseController
3
+
3
4
  def values
4
5
  render serializer: nil, json: {}, status: :ok
5
6
  end
7
+
8
+ def get_collection(collection_name)
9
+ ForestLiana.apimap.find { |collection| collection.name.to_s == collection_name }
10
+ end
11
+
12
+ def get_action(collection_name)
13
+ collection = get_collection(collection_name)
14
+ begin
15
+ collection.actions.find {|action| ActiveSupport::Inflector.parameterize(action.name) == params[:action_name]}
16
+ rescue => error
17
+ FOREST_LOGGER.error "Smart Action get action retrieval error: #{error}"
18
+ nil
19
+ end
20
+ end
21
+
22
+ def get_record
23
+ model = ForestLiana::SchemaUtils.find_model_from_collection_name(params[:collectionName])
24
+ redord_getter = ForestLiana::ResourceGetter.new(model, {:id => params[:recordIds][0]})
25
+ redord_getter.perform
26
+ redord_getter.record
27
+ end
28
+
29
+ def get_smart_action_load_ctx(fields)
30
+ fields = fields.reduce({}) do |p, c|
31
+ ForestLiana::WidgetsHelper.set_field_widget(c)
32
+ p.update(c[:field] => c.merge!(value: nil))
33
+ end
34
+ {:record => get_record, :fields => fields}
35
+ end
36
+
37
+ def get_smart_action_change_ctx(fields)
38
+ fields = fields.reduce({}) do |p, c|
39
+ field = c.permit!.to_h.symbolize_keys
40
+ ForestLiana::WidgetsHelper.set_field_widget(field)
41
+ p.update(c[:field] => field)
42
+ end
43
+ {:record => get_record, :fields => fields}
44
+ end
45
+
46
+ def handle_result(result, formatted_fields, action)
47
+ if result.nil? || !result.is_a?(Hash)
48
+ return render status: 500, json: { error: 'Error in smart action load hook: hook must return an object' }
49
+ end
50
+ is_same_data_structure = ForestLiana::IsSameDataStructureHelper::Analyser.new(formatted_fields, result, 1)
51
+ unless is_same_data_structure.perform
52
+ return render status: 500, json: { error: 'Error in smart action hook: fields must be unchanged (no addition nor deletion allowed)' }
53
+ end
54
+
55
+ # Apply result on fields (transform the object back to an array), preserve order.
56
+ fields = action.fields.map do |field|
57
+ updated_field = result[field[:field]]
58
+ # Reset `value` when not present in `enums` (which means `enums` has changed).
59
+ if updated_field[:enums].is_a?(Array) && !updated_field[:enums].include?(updated_field[:value])
60
+ updated_field[:value] = nil
61
+ end
62
+ updated_field
63
+ end
64
+
65
+ render serializer: nil, json: { fields: fields}, status: :ok
66
+ end
67
+
68
+ def load
69
+ action = get_action(params[:collectionName])
70
+
71
+ if !action
72
+ render status: 500, json: {error: 'Error in smart action load hook: cannot retrieve action from collection'}
73
+ else
74
+ # Transform fields from array to an object to ease usage in hook, adds null value.
75
+ context = get_smart_action_load_ctx(action.fields)
76
+ formatted_fields = context[:fields].clone # clone for following test on is_same_data_structure
77
+
78
+ # Call the user-defined load hook.
79
+ result = action.hooks[:load].(context)
80
+
81
+ handle_result(result, formatted_fields, action)
82
+ end
83
+ end
84
+
85
+ def change
86
+ action = get_action(params[:collectionName])
87
+
88
+ if !action
89
+ render status: 500, json: {error: 'Error in smart action change hook: cannot retrieve action from collection'}
90
+ else
91
+ # Transform fields from array to an object to ease usage in hook.
92
+ context = get_smart_action_change_ctx(params[:fields])
93
+ formatted_fields = context[:fields].clone # clone for following test on is_same_data_structure
94
+
95
+ # Call the user-defined change hook.
96
+ result = action.hooks[:change][params[:changedField]].(context)
97
+
98
+ handle_result(result, formatted_fields, action)
99
+ end
100
+ end
6
101
  end
7
102
  end
@@ -16,18 +16,15 @@ module ForestLiana
16
16
  def index
17
17
  begin
18
18
  if request.format == 'csv'
19
- checker = ForestLiana::PermissionsChecker.new(@resource, 'export', @rendering_id)
20
- return head :forbidden unless checker.is_authorized?
21
- elsif params.has_key?(:searchToEdit)
22
- checker = ForestLiana::PermissionsChecker.new(@resource, 'searchToEdit', @rendering_id)
19
+ checker = ForestLiana::PermissionsChecker.new(@resource, 'exportEnabled', @rendering_id, user_id: forest_user['id'])
23
20
  return head :forbidden unless checker.is_authorized?
24
21
  else
25
22
  checker = ForestLiana::PermissionsChecker.new(
26
23
  @resource,
27
- 'list',
24
+ 'browseEnabled',
28
25
  @rendering_id,
29
- nil,
30
- get_collection_list_permission_info(forest_user, request)
26
+ user_id: forest_user['id'],
27
+ collection_list_parameters: get_collection_list_permission_info(forest_user, request)
31
28
  )
32
29
  return head :forbidden unless checker.is_authorized?
33
30
  end
@@ -59,10 +56,10 @@ module ForestLiana
59
56
  begin
60
57
  checker = ForestLiana::PermissionsChecker.new(
61
58
  @resource,
62
- 'list',
59
+ 'browseEnabled',
63
60
  @rendering_id,
64
- nil,
65
- get_collection_list_permission_info(forest_user, request)
61
+ user_id: forest_user['id'],
62
+ collection_list_parameters: get_collection_list_permission_info(forest_user, request)
66
63
  )
67
64
  return head :forbidden unless checker.is_authorized?
68
65
 
@@ -89,7 +86,7 @@ module ForestLiana
89
86
 
90
87
  def show
91
88
  begin
92
- checker = ForestLiana::PermissionsChecker.new(@resource, 'show', @rendering_id)
89
+ checker = ForestLiana::PermissionsChecker.new(@resource, 'readEnabled', @rendering_id, user_id: forest_user['id'])
93
90
  return head :forbidden unless checker.is_authorized?
94
91
 
95
92
  getter = ForestLiana::ResourceGetter.new(@resource, params)
@@ -104,7 +101,7 @@ module ForestLiana
104
101
 
105
102
  def create
106
103
  begin
107
- checker = ForestLiana::PermissionsChecker.new(@resource, 'create', @rendering_id)
104
+ checker = ForestLiana::PermissionsChecker.new(@resource, 'addEnabled', @rendering_id, user_id: forest_user['id'])
108
105
  return head :forbidden unless checker.is_authorized?
109
106
 
110
107
  creator = ForestLiana::ResourceCreator.new(@resource, params)
@@ -127,7 +124,7 @@ module ForestLiana
127
124
 
128
125
  def update
129
126
  begin
130
- checker = ForestLiana::PermissionsChecker.new(@resource, 'update', @rendering_id)
127
+ checker = ForestLiana::PermissionsChecker.new(@resource, 'editEnabled', @rendering_id, user_id: forest_user['id'])
131
128
  return head :forbidden unless checker.is_authorized?
132
129
 
133
130
  updater = ForestLiana::ResourceUpdater.new(@resource, params)
@@ -149,7 +146,7 @@ module ForestLiana
149
146
  end
150
147
 
151
148
  def destroy
152
- checker = ForestLiana::PermissionsChecker.new(@resource, 'delete', @rendering_id)
149
+ checker = ForestLiana::PermissionsChecker.new(@resource, 'deleteEnabled', @rendering_id, user_id: forest_user['id'])
153
150
  return head :forbidden unless checker.is_authorized?
154
151
 
155
152
  @resource.destroy(params[:id]) if @resource.exists?(params[:id])
@@ -161,7 +158,7 @@ module ForestLiana
161
158
  end
162
159
 
163
160
  def destroy_bulk
164
- checker = ForestLiana::PermissionsChecker.new(@resource, 'delete', @rendering_id)
161
+ checker = ForestLiana::PermissionsChecker.new(@resource, 'deleteEnabled', @rendering_id, user_id: forest_user['id'])
165
162
  return head :forbidden unless checker.is_authorized?
166
163
 
167
164
  ids = ForestLiana::ResourcesGetter.get_ids_from_request(params)
@@ -245,8 +242,8 @@ module ForestLiana
245
242
  @collection ||= ForestLiana.apimap.find { |collection| collection.name.to_s == collection_name }
246
243
  end
247
244
 
248
- # NOTICE: Return a formatted object containing the request condition filters and
249
- # the user id used by the scope validator class to validate if scope is
245
+ # NOTICE: Return a formatted object containing the request condition filters and
246
+ # the user id used by the scope validator class to validate if scope is
250
247
  # in request
251
248
  def get_collection_list_permission_info(user, collection_list_request)
252
249
  {
@@ -19,14 +19,15 @@ module ForestLiana
19
19
 
20
20
  def check_permission_for_smart_route
21
21
  begin
22
-
22
+
23
23
  smart_action_request = get_smart_action_request
24
24
  if !smart_action_request.nil? && smart_action_request.has_key?(:smart_action_id)
25
25
  checker = ForestLiana::PermissionsChecker.new(
26
26
  find_resource(smart_action_request[:collection_name]),
27
27
  'actions',
28
28
  @rendering_id,
29
- get_smart_action_permission_info(forest_user, smart_action_request)
29
+ user_id: forest_user['id'],
30
+ smart_action_request_info: get_smart_action_request_info
30
31
  )
31
32
  return head :forbidden unless checker.is_authorized?
32
33
  else
@@ -54,10 +55,14 @@ module ForestLiana
54
55
  end
55
56
  end
56
57
 
57
- def get_smart_action_permission_info(user, smart_action_request)
58
+ # smart action permissions are retrieved from the action's endpoint and http_method
59
+ def get_smart_action_request_info
60
+ endpoint = request.fullpath
61
+ # Trim starting '/'
62
+ endpoint[0] = '' if endpoint[0] == '/'
58
63
  {
59
- user_id: user['id'],
60
- action_id: smart_action_request[:smart_action_id],
64
+ endpoint: endpoint,
65
+ http_method: request.request_method
61
66
  }
62
67
  end
63
68
  end
@@ -0,0 +1,44 @@
1
+ require 'set'
2
+
3
+ module ForestLiana
4
+ module IsSameDataStructureHelper
5
+ class Analyser
6
+ def initialize(object, other, deep = 0)
7
+ @object = object
8
+ @other = other
9
+ @deep = deep
10
+ end
11
+
12
+ def are_objects(object, other)
13
+ object && other && object.is_a?(Hash) && other.is_a?(Hash)
14
+ end
15
+
16
+ def check_keys(object, other, step = 0)
17
+ unless are_objects(object, other)
18
+ return false
19
+ end
20
+
21
+ object_keys = object.keys
22
+ other_keys = other.keys
23
+
24
+ if object_keys.length != other_keys.length
25
+ return false
26
+ end
27
+
28
+ object_keys_set = object_keys.to_set
29
+ other_keys.each { |key|
30
+ if !object_keys_set.member?(key) || (step + 1 <= @deep && !check_keys(object[key], other[key], step + 1))
31
+ return false
32
+ end
33
+ }
34
+
35
+ return true
36
+ end
37
+
38
+ def perform
39
+ check_keys(@object, @other)
40
+ end
41
+ end
42
+ end
43
+ end
44
+
@@ -0,0 +1,59 @@
1
+ require 'set'
2
+
3
+ module ForestLiana
4
+ module WidgetsHelper
5
+
6
+ @widget_edit_list = [
7
+ 'address editor',
8
+ 'belongsto typeahead',
9
+ 'belongsto dropdown',
10
+ 'boolean editor',
11
+ 'checkboxes',
12
+ 'color editor',
13
+ 'date editor',
14
+ 'dropdown',
15
+ 'embedded document editor',
16
+ 'file picker',
17
+ 'json code editor',
18
+ 'input array',
19
+ 'multiple select',
20
+ 'number input',
21
+ 'point editor',
22
+ 'price editor',
23
+ 'radio button',
24
+ 'rich text',
25
+ 'text area editor',
26
+ 'text editor',
27
+ 'time input',
28
+ ]
29
+
30
+ @v1_to_v2_edit_widgets_mapping = {
31
+ address: 'address editor',
32
+ 'belongsto select': 'belongsto dropdown',
33
+ 'color picker': 'color editor',
34
+ 'date picker': 'date editor',
35
+ price: 'price editor',
36
+ 'JSON editor': 'json code editor',
37
+ 'rich text editor': 'rich text',
38
+ 'text area': 'text area editor',
39
+ 'text input': 'text editor',
40
+ }
41
+
42
+ def self.set_field_widget(field)
43
+
44
+ if field[:widget]
45
+ if @v1_to_v2_edit_widgets_mapping[field[:widget].to_sym]
46
+ field[:widgetEdit] = {name: @v1_to_v2_edit_widgets_mapping[field[:widget].to_sym], parameters: {}}
47
+ elsif @widget_edit_list.include?(field[:widget])
48
+ field[:widgetEdit] = {name: field[:widget], parameters: {}}
49
+ end
50
+ end
51
+
52
+ if !field.key?(:widgetEdit)
53
+ field[:widgetEdit] = nil
54
+ end
55
+
56
+ field.delete(:widget)
57
+ end
58
+ end
59
+ end
@@ -5,7 +5,7 @@ class ForestLiana::Model::Action
5
5
  extend ActiveModel::Naming
6
6
 
7
7
  attr_accessor :id, :name, :base_url, :endpoint, :http_method, :fields, :redirect,
8
- :type, :download
8
+ :type, :download, :hooks
9
9
 
10
10
  def initialize(attributes = {})
11
11
  if attributes.key?(:global)
@@ -66,6 +66,7 @@ class ForestLiana::Model::Action
66
66
  @base_url ||= nil
67
67
  @type ||= "bulk"
68
68
  @download ||= false
69
+ @hooks = !@hooks.nil? ? @hooks.symbolize_keys : nil
69
70
  end
70
71
 
71
72
  def persisted?
@@ -39,6 +39,7 @@ module ForestLiana
39
39
  'redirect',
40
40
  'download',
41
41
  'fields',
42
+ 'hooks',
42
43
  ]
43
44
  KEYS_ACTION_FIELD = [
44
45
  'field',
@@ -1,100 +1,162 @@
1
1
  module ForestLiana
2
2
  class PermissionsChecker
3
- @@permissions_per_rendering = Hash.new
3
+ @@permissions_cached = Hash.new
4
+ @@scopes_cached = Hash.new
5
+ @@roles_acl_activated = false
6
+ # TODO: handle cache scopes per rendering
4
7
  @@expiration_in_seconds = (ENV['FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS'] || 3600).to_i
5
8
 
6
- def initialize(resource, permission_name, rendering_id, smart_action_parameters = nil, collection_list_parameters = nil)
9
+ def initialize(resource, permission_name, rendering_id, user_id:, smart_action_request_info: nil, collection_list_parameters: nil)
10
+ @user_id = user_id
7
11
  @collection_name = ForestLiana.name_for(resource)
8
12
  @permission_name = permission_name
9
13
  @rendering_id = rendering_id
10
- @smart_action_parameters = smart_action_parameters
14
+ @smart_action_request_info = smart_action_request_info
11
15
  @collection_list_parameters = collection_list_parameters
12
16
  end
13
17
 
14
18
  def is_authorized?
15
- (is_permission_expired? || !is_allowed?) ? retrieve_permissions_and_check_allowed : true
16
- end
17
-
18
- private
19
+ # User is still authorized if he already was and the permission has not expire
20
+ # if !have_permissions_expired && is_allowed
21
+ return true unless have_permissions_expired? || !is_allowed
19
22
 
20
- def get_permissions
21
- @@permissions_per_rendering &&
22
- @@permissions_per_rendering[@rendering_id] &&
23
- @@permissions_per_rendering[@rendering_id]['data']
23
+ fetch_permissions
24
+ is_allowed
24
25
  end
25
26
 
26
- def get_last_retrieve
27
- @@permissions_per_rendering &&
28
- @@permissions_per_rendering[@rendering_id] &&
29
- @@permissions_per_rendering[@rendering_id]['last_retrieve']
30
- end
27
+ private
31
28
 
32
- def smart_action_allowed?(smart_actions_permissions)
33
- if !@smart_action_parameters||
34
- !@smart_action_parameters[:user_id] ||
35
- !@smart_action_parameters[:action_id] ||
36
- !smart_actions_permissions ||
37
- !smart_actions_permissions[@smart_action_parameters[:action_id]]
38
- return false
29
+ def fetch_permissions
30
+ permissions = ForestLiana::PermissionsGetter::get_permissions_for_rendering(@rendering_id)
31
+ @@roles_acl_activated = permissions['meta']['rolesACLActivated']
32
+ permissions['last_fetch'] = Time.now
33
+ if @@roles_acl_activated
34
+ @@permissions_cached = permissions
35
+ else
36
+ permissions['data'] = ForestLiana::PermissionsFormatter.convert_to_new_format(permissions['data'], @rendering_id)
37
+ @@permissions_cached[@rendering_id] = permissions
39
38
  end
40
-
41
- @user_id = @smart_action_parameters[:user_id]
42
- @action_id = @smart_action_parameters[:action_id]
43
- @smart_action_permissions = smart_actions_permissions[@action_id]
44
- @allowed = @smart_action_permissions['allowed']
45
- @users = @smart_action_permissions['users']
46
-
47
- return @allowed && (@users.nil?|| @users.include?(@user_id.to_i));
39
+ add_scopes_to_cache(permissions)
48
40
  end
49
41
 
50
- def collection_list_allowed?(scope_permissions)
51
- return ForestLiana::ScopeValidator.new(
52
- scope_permissions['filter'],
53
- scope_permissions['dynamicScopesValues']['users']
54
- ).is_scope_in_request?(@collection_list_parameters)
42
+ def add_scopes_to_cache(permissions)
43
+ permissions['data']['renderings'].keys.each { |rendering_id|
44
+ @@scopes_cached[rendering_id] = permissions['data']['renderings'][rendering_id]
45
+ @@scopes_cached[rendering_id]['last_fetch'] = Time.now
46
+ } if permissions['data']['renderings']
55
47
  end
56
48
 
57
- def is_allowed?
58
- permissions = get_permissions
49
+ def is_allowed
50
+ permissions = get_permissions_content
51
+
59
52
  if permissions && permissions[@collection_name] &&
60
53
  permissions[@collection_name]['collection']
61
54
  if @permission_name === 'actions'
62
55
  return smart_action_allowed?(permissions[@collection_name]['actions'])
63
- # NOTICE: Permissions[@collection_name]['scope'] will either contains conditions filter and
64
- # dynamic user values definition, or null for collection that does not use scopes
65
- elsif @permission_name === 'list' and permissions[@collection_name]['scope']
66
- return collection_list_allowed?(permissions[@collection_name]['scope'])
67
56
  else
68
- return permissions[@collection_name]['collection'][@permission_name]
57
+ if @permission_name === 'browseEnabled'
58
+ refresh_scope_cache if scope_cache_expired?
59
+ scope_permissions = get_scope_in_permissions
60
+ if scope_permissions
61
+ # NOTICE: current_scope will either contains conditions filter and
62
+ # dynamic user values definition, or null for collection that does not use scopes
63
+ return false unless are_scopes_valid?(scope_permissions)
64
+ end
65
+ end
66
+ return is_user_allowed(permissions[@collection_name]['collection'][@permission_name])
69
67
  end
70
68
  else
71
69
  false
72
70
  end
73
71
  end
74
72
 
75
- def retrieve_permissions
76
- @@permissions_per_rendering[@rendering_id] = Hash.new
77
- permissions = ForestLiana::PermissionsGetter.new(@rendering_id).perform()
78
- @@permissions_per_rendering[@rendering_id]['data'] = permissions
79
- @@permissions_per_rendering[@rendering_id]['last_retrieve'] = Time.now
73
+ def get_scope_in_permissions
74
+ @@scopes_cached[@rendering_id] &&
75
+ @@scopes_cached[@rendering_id][@collection_name] &&
76
+ @@scopes_cached[@rendering_id][@collection_name]['scope']
77
+ end
78
+
79
+ def scope_cache_expired?
80
+ return true unless @@scopes_cached[@rendering_id] && @@scopes_cached[@rendering_id]['last_fetch']
81
+
82
+ elapsed_seconds = date_difference_in_seconds(Time.now, @@scopes_cached[@rendering_id]['last_fetch'])
83
+ elapsed_seconds >= @@expiration_in_seconds
84
+ end
85
+
86
+ # This will happen only on rolesACLActivated (as scope cache will always be up to date on disabled)
87
+ def refresh_scope_cache
88
+ permissions = ForestLiana::PermissionsGetter::get_permissions_for_rendering(@rendering_id, rendering_specific_only: true)
89
+ add_scopes_to_cache(permissions)
90
+ end
91
+
92
+ # When acl disabled permissions are stored and retrieved by rendering
93
+ def get_permissions
94
+ @@roles_acl_activated ? @@permissions_cached : @@permissions_cached[@rendering_id]
95
+ end
96
+
97
+ def get_permissions_content
98
+ permissions = get_permissions
99
+ permissions && permissions['data'] && permissions['data']['collections']
100
+ end
101
+
102
+ def get_last_fetch
103
+ permissions = get_permissions
104
+ permissions && permissions['last_fetch']
105
+ end
106
+
107
+ def get_smart_action_permissions(smart_actions_permissions)
108
+ endpoint = @smart_action_request_info[:endpoint]
109
+ http_method = @smart_action_request_info[:http_method]
110
+
111
+ return nil unless endpoint && http_method
112
+
113
+ schema_smart_action = ForestLiana::Utils::BetaSchemaUtils.find_action_from_endpoint(@collection_name, endpoint, http_method)
114
+
115
+ schema_smart_action &&
116
+ schema_smart_action.name &&
117
+ smart_actions_permissions &&
118
+ smart_actions_permissions[schema_smart_action.name]
119
+ end
120
+
121
+ def is_user_allowed(permission_value)
122
+ return false if permission_value.nil?
123
+ return permission_value if permission_value.in? [true, false]
124
+ permission_value.include?(@user_id.to_i)
125
+ end
126
+
127
+ def smart_action_allowed?(smart_actions_permissions)
128
+ smart_action_permissions = get_smart_action_permissions(smart_actions_permissions)
129
+
130
+ return false unless smart_action_permissions
131
+
132
+ is_user_allowed(smart_action_permissions['triggerEnabled'])
133
+ end
134
+
135
+ def are_scopes_valid?(scope_permissions)
136
+ return ForestLiana::ScopeValidator.new(
137
+ scope_permissions['filter'],
138
+ scope_permissions['dynamicScopesValues']['users']
139
+ ).is_scope_in_request?(@collection_list_parameters)
80
140
  end
81
141
 
82
142
  def date_difference_in_seconds(date1, date2)
83
143
  (date1 - date2).to_i
84
144
  end
85
145
 
86
- def is_permission_expired?
87
- last_retrieve = get_last_retrieve
88
-
89
- return true if last_retrieve.nil?
146
+ def have_permissions_expired?
147
+ last_fetch = get_last_fetch
148
+ return true unless last_fetch
90
149
 
91
- elapsed_seconds = date_difference_in_seconds(Time.now, last_retrieve)
150
+ elapsed_seconds = date_difference_in_seconds(Time.now, last_fetch)
92
151
  elapsed_seconds >= @@expiration_in_seconds
93
152
  end
94
153
 
95
- def retrieve_permissions_and_check_allowed
96
- retrieve_permissions
97
- is_allowed?
154
+ # Used only for testing purpose
155
+ def self.empty_cache
156
+ @@permissions_cached = Hash.new
157
+ @@scopes_cached = Hash.new
158
+ @@roles_acl_activated = false
159
+ @@expiration_in_seconds = (ENV['FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS'] || 3600).to_i
98
160
  end
99
161
  end
100
162
  end