forest_liana 6.6.0 → 7.0.0.beta.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/forest_liana/actions_controller.rb +44 -29
  3. data/app/controllers/forest_liana/application_controller.rb +2 -2
  4. data/app/controllers/forest_liana/associations_controller.rb +1 -1
  5. data/app/controllers/forest_liana/base_controller.rb +1 -1
  6. data/app/controllers/forest_liana/resources_controller.rb +7 -6
  7. data/app/serializers/forest_liana/intercom_attribute_serializer.rb +1 -1
  8. data/app/serializers/forest_liana/intercom_conversation_serializer.rb +1 -1
  9. data/app/serializers/forest_liana/mixpanel_event_serializer.rb +1 -1
  10. data/app/serializers/forest_liana/serializer_factory.rb +1 -1
  11. data/app/serializers/forest_liana/stat_serializer.rb +1 -1
  12. data/app/serializers/forest_liana/stripe_bank_account_serializer.rb +1 -1
  13. data/app/serializers/forest_liana/stripe_card_serializer.rb +1 -1
  14. data/app/serializers/forest_liana/stripe_invoice_serializer.rb +1 -1
  15. data/app/serializers/forest_liana/stripe_payment_serializer.rb +1 -1
  16. data/app/serializers/forest_liana/stripe_subscription_serializer.rb +1 -1
  17. data/app/services/forest_liana/apimap_sorter.rb +1 -0
  18. data/app/services/forest_liana/permissions_checker.rb +40 -34
  19. data/app/services/forest_liana/permissions_formatter.rb +1 -1
  20. data/app/services/forest_liana/permissions_getter.rb +1 -4
  21. data/app/services/forest_liana/smart_action_field_validator.rb +49 -0
  22. data/config/initializers/errors.rb +17 -0
  23. data/lib/forest_liana/bootstrapper.rb +2 -2
  24. data/lib/forest_liana/schema_file_updater.rb +8 -0
  25. data/lib/forest_liana/version.rb +1 -1
  26. data/spec/lib/forest_liana/schema_file_updater_spec.rb +94 -0
  27. data/spec/requests/actions_controller_spec.rb +22 -20
  28. data/spec/services/forest_liana/permissions_checker_acl_disabled_spec.rb +45 -69
  29. data/spec/services/forest_liana/permissions_checker_acl_enabled_spec.rb +39 -63
  30. data/spec/services/forest_liana/permissions_checker_live_queries_spec.rb +3 -3
  31. data/spec/services/forest_liana/permissions_formatter_spec.rb +11 -11
  32. data/spec/services/forest_liana/smart_action_field_validator_spec.rb +70 -0
  33. metadata +119 -117
  34. data/app/helpers/forest_liana/is_same_data_structure_helper.rb +0 -44
  35. data/spec/helpers/forest_liana/is_same_data_structure_helper_spec.rb +0 -87
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 227b165dca7f2b6a28257f98ebbfbf4f152745a327c8d82ffe6d8f64bb2fe67a
4
- data.tar.gz: 43d2076643edb2137ee860e003c35542fba8515169e6079b57779873adf3bf9c
3
+ metadata.gz: 3115af32c59b5bf0e32218f3d40cb661809d58316714654520bde1bfee235098
4
+ data.tar.gz: 850a6dbc96d8ff1e74ffe7970dc98ff2bd721d6b834087353052208722b55810
5
5
  SHA512:
6
- metadata.gz: 6667cc6071555e01d31b6216f73fa25d0b5c0c602eab664f3cedf1314f104b47d4f683ae811a2be8b53be5333c39ed4de63f970a0f3b5330dd92953b9c719b53
7
- data.tar.gz: 2998830f37f29dcc1ebd28c9dcdb29e663443b5b2757632c50dffa41d20f889b1f400297344ff3cedd6ee607d82e2d2060ef80ebc4efa9d7417845d992a278e3
6
+ metadata.gz: ea018906c77a41db7a7dc1022cd6485e5f9a293763c1822a64706092f8be74d1046230198af6d0041277cb8f2b852115633b96f622f69a192dc99f911cd31178
7
+ data.tar.gz: cf12c7f0821b3e9232fe884e3d5c04470f6467d4a571ffc88ce2f6e36c9edac6704dcdd9a0c431dd222435bac1c31b512a5585bc9fb99f141e309e41f9ff8696
@@ -27,34 +27,45 @@ module ForestLiana
27
27
  end
28
28
 
29
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))
30
+ fields = fields.map do |field|
31
+ ForestLiana::WidgetsHelper.set_field_widget(field)
32
+ field[:value] = nil unless field[:value]
33
+ field
33
34
  end
34
35
  {:record => get_record, :fields => fields}
35
36
  end
36
37
 
37
- def get_smart_action_change_ctx(fields)
38
- fields = fields.reduce({}) do |p, c|
39
- field = c.permit!.to_h.symbolize_keys
38
+ def get_smart_action_change_ctx(fields, field_changed)
39
+ found_field_changed = fields.find{|field| field[:field] == field_changed}
40
+ fields = fields.map do |field|
41
+ field = field.permit!.to_h.symbolize_keys
40
42
  ForestLiana::WidgetsHelper.set_field_widget(field)
41
- p.update(c[:field] => field)
43
+ field
42
44
  end
43
- {:record => get_record, :fields => fields}
45
+ {:record => get_record, :field_changed => found_field_changed, :fields => fields}
44
46
  end
45
47
 
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' }
48
+ def handle_result(result, action)
49
+ if result.nil? || !result.is_a?(Array)
50
+ return render status: 500, json: { error: 'Error in smart action load hook: hook must return an array of fields' }
49
51
  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)' }
52
+
53
+ # Validate that the fields are well formed.
54
+ begin
55
+ # action.hooks[:change] is a hashmap here
56
+ # to do the validation, only the hook names are require
57
+ change_hooks_name = action.hooks[:change].nil? ? nil : action.hooks[:change].keys
58
+ ForestLiana::SmartActionFieldValidator.validate_smart_action_fields(result, action.name, change_hooks_name)
59
+ rescue ForestLiana::Errors::SmartActionInvalidFieldError => invalid_field_error
60
+ FOREST_LOGGER.warn invalid_field_error.message
61
+ rescue ForestLiana::Errors::SmartActionInvalidFieldHookError => invalid_hook_error
62
+ FOREST_LOGGER.error invalid_hook_error.message
63
+ return render status: 500, json: { error: invalid_hook_error.message }
53
64
  end
54
65
 
55
66
  # 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]]
67
+ fields = result.map do |field|
68
+ updated_field = result.find{|f| f[:field] == field[:field]}
58
69
 
59
70
  # Reset `value` when not present in `enums` (which means `enums` has changed).
60
71
  if updated_field[:enums].is_a?(Array)
@@ -72,7 +83,7 @@ module ForestLiana
72
83
  updated_field
73
84
  end
74
85
 
75
- render serializer: nil, json: { fields: fields}, status: :ok
86
+ render serializer: nil, json: { fields: fields }, status: :ok
76
87
  end
77
88
 
78
89
  def load
@@ -81,14 +92,13 @@ module ForestLiana
81
92
  if !action
82
93
  render status: 500, json: {error: 'Error in smart action load hook: cannot retrieve action from collection'}
83
94
  else
84
- # Transform fields from array to an object to ease usage in hook, adds null value.
95
+ # Get the smart action hook load context
85
96
  context = get_smart_action_load_ctx(action.fields)
86
- formatted_fields = context[:fields].clone # clone for following test on is_same_data_structure
87
97
 
88
98
  # Call the user-defined load hook.
89
99
  result = action.hooks[:load].(context)
90
100
 
91
- handle_result(result, formatted_fields, action)
101
+ handle_result(result, action)
92
102
  end
93
103
  end
94
104
 
@@ -96,17 +106,22 @@ module ForestLiana
96
106
  action = get_action(params[:collectionName])
97
107
 
98
108
  if !action
99
- render status: 500, json: {error: 'Error in smart action change hook: cannot retrieve action from collection'}
100
- else
101
- # Transform fields from array to an object to ease usage in hook.
102
- context = get_smart_action_change_ctx(params[:fields])
103
- formatted_fields = context[:fields].clone # clone for following test on is_same_data_structure
109
+ return render status: 500, json: {error: 'Error in smart action change hook: cannot retrieve action from collection'}
110
+ elsif params[:fields].nil?
111
+ return render status: 500, json: {error: 'Error in smart action change hook: fields params is mandatory'}
112
+ elsif !params[:fields].is_a?(Array)
113
+ return render status: 500, json: {error: 'Error in smart action change hook: fields params must be an array'}
114
+ end
104
115
 
105
- # Call the user-defined change hook.
106
- result = action.hooks[:change][params[:changedField]].(context)
116
+ # Get the smart action hook change context
117
+ context = get_smart_action_change_ctx(params[:fields], params[:changedField])
107
118
 
108
- handle_result(result, formatted_fields, action)
109
- end
119
+ field_changed_hook = context[:field_changed][:hook]
120
+
121
+ # Call the user-defined change hook.
122
+ result = action.hooks[:change][field_changed_hook].(context)
123
+
124
+ handle_result(result, action)
110
125
  end
111
126
  end
112
127
  end
@@ -34,14 +34,14 @@ module ForestLiana
34
34
 
35
35
  def serialize_model(record, options = {})
36
36
  options[:is_collection] = false
37
- json = JSONAPI::Serializer.serialize(record, options)
37
+ json = ForestAdmin::JSONAPI::Serializer.serialize(record, options)
38
38
 
39
39
  force_utf8_encoding(json)
40
40
  end
41
41
 
42
42
  def serialize_models(records, options = {}, fields_searched = [])
43
43
  options[:is_collection] = true
44
- json = JSONAPI::Serializer.serialize(records, options)
44
+ json = ForestAdmin::JSONAPI::Serializer.serialize(records, options)
45
45
 
46
46
  if options[:params] && options[:params][:search]
47
47
  # NOTICE: Add the Smart Fields with a 'String' type.
@@ -41,7 +41,7 @@ module ForestLiana
41
41
  updater.perform
42
42
 
43
43
  if updater.errors
44
- render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
44
+ render serializer: nil, json: ForestAdmin::JSONAPI::Serializer.serialize_errors(
45
45
  updater.errors), status: 422
46
46
  else
47
47
  head :no_content
@@ -24,7 +24,7 @@ module ForestLiana
24
24
  end
25
25
  end
26
26
  rescue ForestLiana::Errors::ExpectedError => exception
27
- error_data = JSONAPI::Serializer.serialize_errors([{
27
+ error_data = ForestAdmin::JSONAPI::Serializer.serialize_errors([{
28
28
  status: exception.error_code,
29
29
  detail: exception.message
30
30
  }])
@@ -41,7 +41,7 @@ module ForestLiana
41
41
  status: :unprocessable_entity, serializer: nil
42
42
  rescue ForestLiana::Errors::ExpectedError => error
43
43
  error.display_error
44
- error_data = JSONAPI::Serializer.serialize_errors([{
44
+ error_data = ForestAdmin::JSONAPI::Serializer.serialize_errors([{
45
45
  status: error.error_code,
46
46
  detail: error.message
47
47
  }])
@@ -73,7 +73,7 @@ module ForestLiana
73
73
  status: :unprocessable_entity, serializer: nil
74
74
  rescue ForestLiana::Errors::ExpectedError => error
75
75
  error.display_error
76
- error_data = JSONAPI::Serializer.serialize_errors([{
76
+ error_data = ForestAdmin::JSONAPI::Serializer.serialize_errors([{
77
77
  status: error.error_code,
78
78
  detail: error.message
79
79
  }])
@@ -108,12 +108,12 @@ module ForestLiana
108
108
  creator.perform
109
109
 
110
110
  if creator.errors
111
- render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
111
+ render serializer: nil, json: ForestAdmin::JSONAPI::Serializer.serialize_errors(
112
112
  creator.errors), status: 400
113
113
  elsif creator.record.valid?
114
114
  render serializer: nil, json: render_record_jsonapi(creator.record)
115
115
  else
116
- render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
116
+ render serializer: nil, json: ForestAdmin::JSONAPI::Serializer.serialize_errors(
117
117
  creator.record.errors), status: 400
118
118
  end
119
119
  rescue => error
@@ -131,12 +131,12 @@ module ForestLiana
131
131
  updater.perform
132
132
 
133
133
  if updater.errors
134
- render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
134
+ render serializer: nil, json: ForestAdmin::JSONAPI::Serializer.serialize_errors(
135
135
  updater.errors), status: 400
136
136
  elsif updater.record.valid?
137
137
  render serializer: nil, json: render_record_jsonapi(updater.record)
138
138
  else
139
- render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
139
+ render serializer: nil, json: ForestAdmin::JSONAPI::Serializer.serialize_errors(
140
140
  updater.record.errors), status: 400
141
141
  end
142
142
  rescue => error
@@ -249,6 +249,7 @@ module ForestLiana
249
249
  {
250
250
  user_id: user['id'],
251
251
  filters: collection_list_request[:filters],
252
+ segmentQuery: collection_list_request[:segmentQuery],
252
253
  }
253
254
  end
254
255
  end
@@ -1,6 +1,6 @@
1
1
  module ForestLiana
2
2
  class IntercomAttributeSerializer
3
- include JSONAPI::Serializer
3
+ include ForestAdmin::JSONAPI::Serializer
4
4
 
5
5
  attribute :session_count
6
6
  attribute :last_seen_ip
@@ -1,6 +1,6 @@
1
1
  module ForestLiana
2
2
  class IntercomConversationSerializer
3
- include JSONAPI::Serializer
3
+ include ForestAdmin::JSONAPI::Serializer
4
4
 
5
5
  attribute :created_at
6
6
  attribute :updated_at
@@ -1,6 +1,6 @@
1
1
  module ForestLiana
2
2
  class MixpanelEventSerializer
3
- include JSONAPI::Serializer
3
+ include ForestAdmin::JSONAPI::Serializer
4
4
 
5
5
  attribute :id
6
6
  attribute :event
@@ -53,7 +53,7 @@ module ForestLiana
53
53
 
54
54
  def serializer_for(active_record_class)
55
55
  serializer = Class.new {
56
- include JSONAPI::Serializer
56
+ include ForestAdmin::JSONAPI::Serializer
57
57
 
58
58
  def self_link
59
59
  "/forest#{super.underscore}"
@@ -1,6 +1,6 @@
1
1
  module ForestLiana
2
2
  class StatSerializer
3
- include JSONAPI::Serializer
3
+ include ForestAdmin::JSONAPI::Serializer
4
4
 
5
5
  attribute :value
6
6
 
@@ -1,6 +1,6 @@
1
1
  module ForestLiana
2
2
  class StripeBankAccountSerializer
3
- include JSONAPI::Serializer
3
+ include ForestAdmin::JSONAPI::Serializer
4
4
 
5
5
  attribute :account_holder_name
6
6
  attribute :account_holder_type
@@ -1,6 +1,6 @@
1
1
  module ForestLiana
2
2
  class StripeCardSerializer
3
- include JSONAPI::Serializer
3
+ include ForestAdmin::JSONAPI::Serializer
4
4
 
5
5
  attribute :last4
6
6
  attribute :brand
@@ -1,6 +1,6 @@
1
1
  module ForestLiana
2
2
  class StripeInvoiceSerializer
3
- include JSONAPI::Serializer
3
+ include ForestAdmin::JSONAPI::Serializer
4
4
 
5
5
  attribute :amount_due
6
6
  attribute :amount_paid
@@ -1,6 +1,6 @@
1
1
  module ForestLiana
2
2
  class StripePaymentSerializer
3
- include JSONAPI::Serializer
3
+ include ForestAdmin::JSONAPI::Serializer
4
4
 
5
5
  attribute :description
6
6
  attribute :refunded
@@ -1,6 +1,6 @@
1
1
  module ForestLiana
2
2
  class StripeSubscriptionSerializer
3
- include JSONAPI::Serializer
3
+ include ForestAdmin::JSONAPI::Serializer
4
4
 
5
5
  attribute :cancel_at_period_end
6
6
  attribute :canceled_at
@@ -52,6 +52,7 @@ module ForestLiana
52
52
  'description',
53
53
  'position',
54
54
  'widget',
55
+ 'hook',
55
56
  ]
56
57
  KEYS_SEGMENT = ['name']
57
58
 
@@ -1,12 +1,12 @@
1
1
  module ForestLiana
2
2
  class PermissionsChecker
3
3
  @@permissions_cached = Hash.new
4
- @@scopes_cached = Hash.new
4
+ @@renderings_cached = Hash.new
5
5
  @@roles_acl_activated = false
6
- # TODO: handle cache scopes per rendering
6
+
7
7
  @@expiration_in_seconds = (ENV['FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS'] || 3600).to_i
8
8
 
9
- def initialize(resource, permission_name, rendering_id, user_id: nil, smart_action_request_info: nil, collection_list_parameters: nil, query_request_info: nil)
9
+ def initialize(resource, permission_name, rendering_id, user_id: nil, smart_action_request_info: nil, collection_list_parameters: Hash.new, query_request_info: nil)
10
10
 
11
11
  @collection_name = resource.present? ? ForestLiana.name_for(resource) : nil
12
12
  @permission_name = permission_name
@@ -39,13 +39,16 @@ module ForestLiana
39
39
  permissions['data'] = ForestLiana::PermissionsFormatter.convert_to_new_format(permissions['data'], @rendering_id)
40
40
  @@permissions_cached[@rendering_id] = permissions
41
41
  end
42
- add_scopes_to_cache(permissions)
42
+
43
+ # NOTICE: Add stats permissions to the RenderingPermissions
44
+ permissions['data']['renderings'][@rendering_id]['stats'] = permissions['stats']
45
+ add_rendering_permissions_to_cache(permissions)
43
46
  end
44
47
 
45
- def add_scopes_to_cache(permissions)
48
+ def add_rendering_permissions_to_cache(permissions)
46
49
  permissions['data']['renderings'].keys.each { |rendering_id|
47
- @@scopes_cached[rendering_id] = permissions['data']['renderings'][rendering_id]
48
- @@scopes_cached[rendering_id]['last_fetch'] = Time.now
50
+ @@renderings_cached[rendering_id] = permissions['data']['renderings'][rendering_id]
51
+ @@renderings_cached[rendering_id]['last_fetch'] = Time.now
49
52
  } if permissions['data']['renderings']
50
53
  end
51
54
 
@@ -59,20 +62,17 @@ module ForestLiana
59
62
  return stat_with_parameters_allowed?
60
63
  end
61
64
 
62
-
63
-
64
65
  if permissions && permissions[@collection_name] &&
65
66
  permissions[@collection_name]['collection']
66
67
  if @permission_name === 'actions'
67
68
  return smart_action_allowed?(permissions[@collection_name]['actions'])
68
69
  else
69
70
  if @permission_name === 'browseEnabled'
70
- refresh_scope_cache if scope_cache_expired?
71
- scope_permissions = get_scope_in_permissions
72
- if scope_permissions
73
- # NOTICE: current_scope will either contains conditions filter and
74
- # dynamic user values definition, or null for collection that does not use scopes
75
- return false unless are_scopes_valid?(scope_permissions)
71
+ refresh_rendering_cache if rendering_cache_expired?
72
+
73
+ # NOTICE: In this case we need to check that that query is allowed
74
+ if @collection_list_parameters[:segmentQuery].present?
75
+ return false unless segment_query_allowed?
76
76
  end
77
77
  end
78
78
  return is_user_allowed(permissions[@collection_name]['collection'][@permission_name])
@@ -82,23 +82,27 @@ module ForestLiana
82
82
  end
83
83
  end
84
84
 
85
- def get_scope_in_permissions
86
- @@scopes_cached[@rendering_id] &&
87
- @@scopes_cached[@rendering_id][@collection_name] &&
88
- @@scopes_cached[@rendering_id][@collection_name]['scope']
85
+ def get_segments_in_permissions
86
+ @@renderings_cached[@rendering_id] &&
87
+ @@renderings_cached[@rendering_id][@collection_name] &&
88
+ @@renderings_cached[@rendering_id][@collection_name]['segments']
89
89
  end
90
90
 
91
- def scope_cache_expired?
92
- return true unless @@scopes_cached[@rendering_id] && @@scopes_cached[@rendering_id]['last_fetch']
91
+ def rendering_cache_expired?
92
+ return true unless @@renderings_cached[@rendering_id] && @@renderings_cached[@rendering_id]['last_fetch']
93
93
 
94
- elapsed_seconds = date_difference_in_seconds(Time.now, @@scopes_cached[@rendering_id]['last_fetch'])
94
+ elapsed_seconds = date_difference_in_seconds(Time.now, @@renderings_cached[@rendering_id]['last_fetch'])
95
95
  elapsed_seconds >= @@expiration_in_seconds
96
96
  end
97
97
 
98
- # This will happen only on rolesACLActivated (as scope cache will always be up to date on disabled)
99
- def refresh_scope_cache
98
+ # This will happen only on rolesACLActivated (as segments cache will always be up to date on disabled)
99
+ def refresh_rendering_cache
100
100
  permissions = ForestLiana::PermissionsGetter::get_permissions_for_rendering(@rendering_id, rendering_specific_only: true)
101
- add_scopes_to_cache(permissions)
101
+
102
+ # NOTICE: Add stats permissions to the RenderingPermissions
103
+ permissions['data']['renderings'][@rendering_id]['stats'] = permissions['stats']
104
+
105
+ add_rendering_permissions_to_cache(permissions)
102
106
  end
103
107
 
104
108
  # When acl disabled permissions are stored and retrieved by rendering
@@ -112,12 +116,12 @@ module ForestLiana
112
116
  end
113
117
 
114
118
  def get_live_query_permissions_content
115
- permissions = get_permissions
119
+ permissions = @@renderings_cached[@rendering_id]
116
120
  permissions && permissions['stats'] && permissions['stats']['queries']
117
121
  end
118
122
 
119
123
  def get_stat_with_parameters_content(statPermissionType)
120
- permissions = get_permissions
124
+ permissions = @@renderings_cached[@rendering_id]
121
125
  permissions && permissions['stats'] && permissions['stats'][statPermissionType]
122
126
  end
123
127
 
@@ -154,11 +158,13 @@ module ForestLiana
154
158
  is_user_allowed(smart_action_permissions['triggerEnabled'])
155
159
  end
156
160
 
157
- def are_scopes_valid?(scope_permissions)
158
- return ForestLiana::ScopeValidator.new(
159
- scope_permissions['filter'],
160
- scope_permissions['dynamicScopesValues']['users']
161
- ).is_scope_in_request?(@collection_list_parameters)
161
+ def segment_query_allowed?
162
+ segments_queries_permissions = get_segments_in_permissions
163
+
164
+ return false unless segments_queries_permissions
165
+
166
+ # NOTICE: @query_request_info matching an existing segment query
167
+ return segments_queries_permissions.include? @collection_list_parameters[:segmentQuery]
162
168
  end
163
169
 
164
170
  def live_query_allowed?
@@ -177,7 +183,7 @@ module ForestLiana
177
183
  return false unless pool_permissions
178
184
 
179
185
  # NOTICE: equivalent to Object.values in js & removes nil values
180
- array_permission_infos = @query_request_info.values.filter_map{ |x| x unless x.nil? }
186
+ array_permission_infos = @query_request_info.values.select{ |x| !x.nil? }
181
187
 
182
188
  # NOTICE: Is there any pool_permissions containing the array_permission_infos
183
189
  return pool_permissions.any? {
@@ -201,7 +207,7 @@ module ForestLiana
201
207
  # Used only for testing purpose
202
208
  def self.empty_cache
203
209
  @@permissions_cached = Hash.new
204
- @@scopes_cached = Hash.new
210
+ @@renderings_cached = Hash.new
205
211
  @@roles_acl_activated = false
206
212
  @@expiration_in_seconds = (ENV['FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS'] || 3600).to_i
207
213
  end