forest_liana 7.0.0.beta.4 → 7.0.0.beta.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/forest_liana/actions_controller.rb +2 -2
  3. data/app/controllers/forest_liana/associations_controller.rb +2 -2
  4. data/app/controllers/forest_liana/resources_controller.rb +15 -6
  5. data/app/controllers/forest_liana/scopes_controller.rb +20 -0
  6. data/app/controllers/forest_liana/smart_actions_controller.rb +39 -3
  7. data/app/controllers/forest_liana/stats_controller.rb +5 -5
  8. data/app/services/forest_liana/filters_parser.rb +8 -4
  9. data/app/services/forest_liana/has_many_dissociator.rb +2 -2
  10. data/app/services/forest_liana/has_many_getter.rb +2 -2
  11. data/app/services/forest_liana/leaderboard_stat_getter.rb +20 -14
  12. data/app/services/forest_liana/line_stat_getter.rb +4 -2
  13. data/app/services/forest_liana/permissions_checker.rb +3 -4
  14. data/app/services/forest_liana/permissions_getter.rb +2 -2
  15. data/app/services/forest_liana/pie_stat_getter.rb +6 -3
  16. data/app/services/forest_liana/resource_getter.rb +6 -3
  17. data/app/services/forest_liana/resource_updater.rb +5 -2
  18. data/app/services/forest_liana/resources_getter.rb +6 -5
  19. data/app/services/forest_liana/scope_manager.rb +102 -0
  20. data/app/services/forest_liana/search_query_builder.rb +6 -3
  21. data/app/services/forest_liana/stat_getter.rb +2 -1
  22. data/app/services/forest_liana/value_stat_getter.rb +4 -2
  23. data/config/routes.rb +3 -0
  24. data/lib/forest_liana/version.rb +1 -1
  25. data/spec/dummy/app/controllers/forest/islands_controller.rb +5 -0
  26. data/spec/dummy/config/routes.rb +4 -0
  27. data/spec/dummy/lib/forest_liana/collections/island.rb +7 -0
  28. data/spec/requests/actions_controller_spec.rb +100 -12
  29. data/spec/requests/resources_spec.rb +2 -0
  30. data/spec/services/forest_liana/filters_parser_spec.rb +1 -1
  31. data/spec/services/forest_liana/has_many_getter_spec.rb +116 -0
  32. data/spec/services/forest_liana/line_stat_getter_spec.rb +14 -6
  33. data/spec/services/forest_liana/permissions_checker_acl_disabled_spec.rb +1 -3
  34. data/spec/services/forest_liana/pie_stat_getter_spec.rb +114 -0
  35. data/spec/services/forest_liana/resource_updater_spec.rb +116 -0
  36. data/spec/services/forest_liana/resources_getter_spec.rb +68 -1
  37. data/spec/services/forest_liana/scope_manager_spec.rb +232 -0
  38. data/spec/services/forest_liana/value_stat_getter_spec.rb +96 -0
  39. metadata +18 -13
  40. data/app/services/forest_liana/scope_validator.rb +0 -98
  41. data/test/services/forest_liana/has_many_getter_test.rb +0 -75
  42. data/test/services/forest_liana/pie_stat_getter_test.rb +0 -29
  43. data/test/services/forest_liana/resource_updater_test.rb +0 -86
  44. data/test/services/forest_liana/scope_validator_test.rb +0 -185
  45. data/test/services/forest_liana/value_stat_getter_test.rb +0 -71
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0bf8bedca443e88f415a14995d430f5ba021cfe846d8471588680c5f35e619eb
4
- data.tar.gz: f68ffb4494911b3b674965b3370988c4505be91673f7d67e194482b0975226e2
3
+ metadata.gz: 36a124d9be3926a24e7ab38fa5921f90a4fa62eb1a037513237db19137c08e6c
4
+ data.tar.gz: 11555d1d6818160acd6024f76acbf38746a9e7ccda11b7b14126834cf29dc576
5
5
  SHA512:
6
- metadata.gz: 97aeec5fc463e97cc3b8475c0f09228ea131a322d458104f2cf28306d390b904fd433a78e2a53b7baf34aaf05c6f66d7783e15a36b1f464790ab78bc5bd60ea6
7
- data.tar.gz: 9339a84947baea79f91ebb48716760eee7f8e2acee6fc473b881904001c7f3f6bd6f1a1de6603df63eeba15967fcf6d982a60a7f42c049f007b958d60ff9732e
6
+ metadata.gz: 98ab606746f67e5bf1beec87b7ff67233d4d47b6d0456d87ff8e4f5d77c7d3f198b12a9873f6f73d7777f44b93c0c449b3cff229afae88937126b05a8e865ffc
7
+ data.tar.gz: 7f9f8ef793f09b227a9b8ad5c66e2c70e11c25453bb974838d43aa2e1dc3d538c6d0f8d29816e470ccd3ff22c4f77e8b178b618b87e26f4e307c5fcc60282612
@@ -1,5 +1,5 @@
1
1
  module ForestLiana
2
- class ActionsController < ForestLiana::BaseController
2
+ class ActionsController < ApplicationController
3
3
 
4
4
  def get_smart_action_hook_request
5
5
  begin
@@ -17,7 +17,7 @@ module ForestLiana
17
17
  def get_action(collection_name)
18
18
  collection = get_collection(collection_name)
19
19
  begin
20
- collection.actions.find {|action| ActiveSupport::Inflector.parameterize(action.name) == params[:action_name]}
20
+ collection.actions.find {|action| ActiveSupport::Inflector.parameterize(action.name) == params[:action_name]}
21
21
  rescue => error
22
22
  FOREST_LOGGER.error "Smart Action get action retrieval error: #{error}"
23
23
  nil
@@ -10,7 +10,7 @@ module ForestLiana
10
10
 
11
11
  def index
12
12
  begin
13
- getter = HasManyGetter.new(@resource, @association, params)
13
+ getter = HasManyGetter.new(@resource, @association, params, forest_user)
14
14
  getter.perform
15
15
 
16
16
  respond_to do |format|
@@ -25,7 +25,7 @@ module ForestLiana
25
25
 
26
26
  def count
27
27
  begin
28
- getter = HasManyGetter.new(@resource, @association, params)
28
+ getter = HasManyGetter.new(@resource, @association, params, forest_user)
29
29
  getter.count
30
30
 
31
31
  render serializer: nil, json: { count: getter.records_count }
@@ -29,7 +29,7 @@ module ForestLiana
29
29
  return head :forbidden unless checker.is_authorized?
30
30
  end
31
31
 
32
- getter = ForestLiana::ResourcesGetter.new(@resource, params)
32
+ getter = ForestLiana::ResourcesGetter.new(@resource, params, forest_user)
33
33
  getter.perform
34
34
 
35
35
  respond_to do |format|
@@ -63,7 +63,7 @@ module ForestLiana
63
63
  )
64
64
  return head :forbidden unless checker.is_authorized?
65
65
 
66
- getter = ForestLiana::ResourcesGetter.new(@resource, params)
66
+ getter = ForestLiana::ResourcesGetter.new(@resource, params, forest_user)
67
67
  getter.count
68
68
 
69
69
  render serializer: nil, json: { count: getter.records_count }
@@ -89,10 +89,12 @@ module ForestLiana
89
89
  checker = ForestLiana::PermissionsChecker.new(@resource, 'readEnabled', @rendering_id, user_id: forest_user['id'])
90
90
  return head :forbidden unless checker.is_authorized?
91
91
 
92
- getter = ForestLiana::ResourceGetter.new(@resource, params)
92
+ getter = ForestLiana::ResourceGetter.new(@resource, params, forest_user)
93
93
  getter.perform
94
94
 
95
95
  render serializer: nil, json: render_record_jsonapi(getter.record)
96
+ rescue ActiveRecord::RecordNotFound
97
+ render serializer: nil, json: { status: 404 }, status: :not_found
96
98
  rescue => error
97
99
  FOREST_LOGGER.error "Record Show error: #{error}\n#{format_stacktrace(error)}"
98
100
  internal_server_error
@@ -127,7 +129,7 @@ module ForestLiana
127
129
  checker = ForestLiana::PermissionsChecker.new(@resource, 'editEnabled', @rendering_id, user_id: forest_user['id'])
128
130
  return head :forbidden unless checker.is_authorized?
129
131
 
130
- updater = ForestLiana::ResourceUpdater.new(@resource, params)
132
+ updater = ForestLiana::ResourceUpdater.new(@resource, params, forest_user)
131
133
  updater.perform
132
134
 
133
135
  if updater.errors
@@ -149,7 +151,14 @@ module ForestLiana
149
151
  checker = ForestLiana::PermissionsChecker.new(@resource, 'deleteEnabled', @rendering_id, user_id: forest_user['id'])
150
152
  return head :forbidden unless checker.is_authorized?
151
153
 
152
- @resource.destroy(params[:id]) if @resource.exists?(params[:id])
154
+ collection_name = ForestLiana.name_for(@resource)
155
+ scoped_records = ForestLiana::ScopeManager.apply_scopes_on_records(@resource, forest_user, collection_name, params[:timezone])
156
+
157
+ unless scoped_records.exists?(params[:id])
158
+ return render serializer: nil, json: { status: 404 }, status: :not_found
159
+ end
160
+
161
+ scoped_records.destroy(params[:id])
153
162
 
154
163
  head :no_content
155
164
  rescue => error
@@ -161,7 +170,7 @@ module ForestLiana
161
170
  checker = ForestLiana::PermissionsChecker.new(@resource, 'deleteEnabled', @rendering_id, user_id: forest_user['id'])
162
171
  return head :forbidden unless checker.is_authorized?
163
172
 
164
- ids = ForestLiana::ResourcesGetter.get_ids_from_request(params)
173
+ ids = ForestLiana::ResourcesGetter.get_ids_from_request(params, forest_user)
165
174
  @resource.destroy(ids) if ids&.any?
166
175
 
167
176
  head :no_content
@@ -0,0 +1,20 @@
1
+ module ForestLiana
2
+ class ScopesController < ForestLiana::ApplicationController
3
+ def invalidate_scope_cache
4
+ begin
5
+ rendering_id = params[:renderingId]
6
+
7
+ unless rendering_id
8
+ FOREST_LOGGER.error 'Missing renderingId'
9
+ return render serializer: nil, json: { status: 400 }, status: :bad_request
10
+ end
11
+
12
+ ForestLiana::ScopeManager.invalidate_scope_cache(rendering_id)
13
+ return render serializer: nil, json: { status: 200 }, status: :ok
14
+ rescue => error
15
+ FOREST_LOGGER.error "Error during scope cache invalidation: #{error.message}"
16
+ render serializer: nil, json: {status: 500 }, status: :internal_server_error
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,9 +1,9 @@
1
1
  module ForestLiana
2
2
  class SmartActionsController < ForestLiana::ApplicationController
3
3
  if Rails::VERSION::MAJOR < 4
4
- before_filter :check_permission_for_smart_route
4
+ before_filter :smart_action_pre_perform_checks
5
5
  else
6
- before_action :check_permission_for_smart_route
6
+ before_action :smart_action_pre_perform_checks
7
7
  end
8
8
 
9
9
  private
@@ -17,6 +17,41 @@ module ForestLiana
17
17
  end
18
18
  end
19
19
 
20
+ def smart_action_pre_perform_checks
21
+ check_permission_for_smart_route
22
+ ensure_record_ids_in_scope
23
+ end
24
+
25
+ def ensure_record_ids_in_scope
26
+ begin
27
+ attributes = get_smart_action_request
28
+
29
+ # if performing a `selectAll` let the `get_ids_from_request` handle the scopes
30
+ return if attributes[:all_records]
31
+
32
+ resource = find_resource(attributes[:collection_name])
33
+
34
+ # user is using the composite_primary_keys gem
35
+ if resource.primary_key.kind_of?(Array)
36
+ # TODO: handle primary keys
37
+ return
38
+ end
39
+
40
+ filter = JSON.generate({ 'field' => resource.primary_key, 'operator' => 'in', 'value' => attributes[:ids] })
41
+
42
+ resources_getter = ForestLiana::ResourcesGetter.new(resource, { :filters => filter, :timezone => attributes[:timezone] }, forest_user)
43
+
44
+ # resources getter will return records inside the scope. if the length differs then ids are out of scope
45
+ return if resources_getter.count == attributes[:ids].length
46
+
47
+ # target records are out of scope
48
+ render serializer: nil, json: { error: 'Smart Action: target record not found' }, status: :bad_request
49
+ rescue => error
50
+ FOREST_LOGGER.error "Smart Action: #{error}\n#{format_stacktrace(error)}"
51
+ render serializer: nil, json: { error: 'Smart Action: failed to evaluate permissions' }, status: :internal_server_error
52
+ end
53
+ end
54
+
20
55
  def check_permission_for_smart_route
21
56
  begin
22
57
 
@@ -58,7 +93,8 @@ module ForestLiana
58
93
  # smart action permissions are retrieved from the action's endpoint and http_method
59
94
  def get_smart_action_request_info
60
95
  {
61
- endpoint: request.fullpath,
96
+ # trim query params to get the endpoint
97
+ endpoint: request.fullpath.split('?').first,
62
98
  http_method: request.request_method
63
99
  }
64
100
  end
@@ -27,15 +27,15 @@ module ForestLiana
27
27
  def get
28
28
  case params[:type]
29
29
  when CHART_TYPE_VALUE
30
- stat = ValueStatGetter.new(@resource, params)
30
+ stat = ValueStatGetter.new(@resource, params, forest_user)
31
31
  when CHART_TYPE_PIE
32
- stat = PieStatGetter.new(@resource, params)
32
+ stat = PieStatGetter.new(@resource, params, forest_user)
33
33
  when CHART_TYPE_LINE
34
- stat = LineStatGetter.new(@resource, params)
34
+ stat = LineStatGetter.new(@resource, params, forest_user)
35
35
  when CHART_TYPE_OBJECTIVE
36
- stat = ObjectiveStatGetter.new(@resource, params)
36
+ stat = ObjectiveStatGetter.new(@resource, params, forest_user)
37
37
  when CHART_TYPE_LEADERBOARD
38
- stat = LeaderboardStatGetter.new(@resource, params)
38
+ stat = LeaderboardStatGetter.new(@resource, params, forest_user)
39
39
  end
40
40
 
41
41
  stat.perform
@@ -109,13 +109,15 @@ module ForestLiana
109
109
  parsed_value = parse_value(operator, value)
110
110
  field_and_operator = "#{parsed_field} #{parsed_operator}"
111
111
 
112
+ # parenthesis around the parsed_value are required to make the `IN` operator work
113
+ # and have no side effects on other requests
112
114
  if Rails::VERSION::MAJOR < 5
113
- "#{field_and_operator} #{ActiveRecord::Base.sanitize(parsed_value)}"
115
+ "#{field_and_operator} (#{ActiveRecord::Base.sanitize(parsed_value)})"
114
116
  # NOTICE: sanitize method as been removed in Rails 5.1 and sanitize_sql introduced in Rails 5.2.
115
117
  elsif Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR == 1
116
- "#{field_and_operator} #{ActiveRecord::Base.connection.quote(parsed_value)}"
118
+ "#{field_and_operator} (#{ActiveRecord::Base.connection.quote(parsed_value)})"
117
119
  else
118
- ActiveRecord::Base.sanitize_sql(["#{field_and_operator} ?", parsed_value])
120
+ ActiveRecord::Base.sanitize_sql(["#{field_and_operator} (?)", parsed_value])
119
121
  end
120
122
  end
121
123
 
@@ -147,6 +149,8 @@ module ForestLiana
147
149
  'IS'
148
150
  when 'present'
149
151
  'IS NOT'
152
+ when 'in'
153
+ 'IN'
150
154
  else
151
155
  raise_unknown_operator_error(operator)
152
156
  end
@@ -154,7 +158,7 @@ module ForestLiana
154
158
 
155
159
  def parse_value(operator, value)
156
160
  case operator
157
- when 'not', 'greater_than', 'less_than', 'not_equal', 'equal', 'before', 'after'
161
+ when 'not', 'greater_than', 'less_than', 'not_equal', 'equal', 'before', 'after', 'in'
158
162
  value
159
163
  when 'contains', 'not_contains'
160
164
  "%#{value}%"
@@ -1,5 +1,5 @@
1
1
  module ForestLiana
2
- class HasManyDissociator
2
+ class HasManyDissociator < ForestLiana::ApplicationController
3
3
  def initialize(resource, association, params)
4
4
  @resource = resource
5
5
  @association = association
@@ -17,7 +17,7 @@ module ForestLiana
17
17
  if @data.is_a?(Array)
18
18
  record_ids = @data.map { |record| record[:id] }
19
19
  elsif @data.dig('attributes').present?
20
- record_ids = ForestLiana::ResourcesGetter.get_ids_from_request(@params)
20
+ record_ids = ForestLiana::ResourcesGetter.get_ids_from_request(@params, forest_user)
21
21
  else
22
22
  record_ids = Array.new
23
23
  end
@@ -4,7 +4,7 @@ module ForestLiana
4
4
  attr_reader :includes
5
5
  attr_reader :records_count
6
6
 
7
- def initialize(resource, association, params)
7
+ def initialize(resource, association, params, forest_user)
8
8
  @resource = resource
9
9
  @association = association
10
10
  @params = params
@@ -13,7 +13,7 @@ module ForestLiana
13
13
  @collection = get_collection(@collection_name)
14
14
  compute_includes()
15
15
  includes_symbols = @includes.map { |include| include.to_sym }
16
- @search_query_builder = SearchQueryBuilder.new(@params, includes_symbols, @collection)
16
+ @search_query_builder = SearchQueryBuilder.new(@params, includes_symbols, @collection, forest_user)
17
17
 
18
18
  prepare_query()
19
19
  end
@@ -1,20 +1,22 @@
1
1
  module ForestLiana
2
2
  class LeaderboardStatGetter < StatGetter
3
- def initialize(resource, params)
4
- @resource = resource
5
- @params = params
6
- @model_relationship = @resource.reflect_on_association(@params[:relationship_field]).klass
7
- compute_includes()
8
- @label_field = @params[:label_field]
9
- @aggregate = @params[:aggregate].downcase
10
- @aggregate_field = @params[:aggregate_field]
11
- @limit = @params[:limit]
12
- @groub_by = "#{@resource.table_name}.#{@label_field}"
3
+ def initialize(parent_model, params, forest_user)
4
+ @scoped_parent_model = get_scoped_model(parent_model, forest_user, params[:timezone])
5
+ child_model = @scoped_parent_model.reflect_on_association(params[:relationship_field]).klass
6
+ @scoped_child_model = get_scoped_model(child_model, forest_user, params[:timezone])
7
+ @label_field = params[:label_field]
8
+ @aggregate = params[:aggregate].downcase
9
+ @aggregate_field = params[:aggregate_field]
10
+ @limit = params[:limit]
11
+ @groub_by = "#{@scoped_parent_model.table_name}.#{@label_field}"
13
12
  end
14
13
 
15
14
  def perform
16
- result = @model_relationship
17
- .joins(@includes)
15
+ includes = ForestLiana::QueryHelper.get_one_association_names_symbol(@scoped_child_model)
16
+
17
+ result = @scoped_child_model
18
+ .joins(includes)
19
+ .where({ @scoped_parent_model.name.downcase.to_sym => @scoped_parent_model })
18
20
  .group(@groub_by)
19
21
  .order(order)
20
22
  .limit(@limit)
@@ -24,8 +26,12 @@ module ForestLiana
24
26
  @record = Model::Stat.new(value: result)
25
27
  end
26
28
 
27
- def compute_includes
28
- @includes = ForestLiana::QueryHelper.get_one_association_names_symbol(@model_relationship)
29
+ def get_scoped_model(model, forest_user, timezone)
30
+ scope_filters = ForestLiana::ScopeManager.get_scope_for_user(forest_user, model.name, as_string: true)
31
+
32
+ return model.unscoped if scope_filters.blank?
33
+
34
+ FiltersParser.new(scope_filters, model, timezone).apply_filters
29
35
  end
30
36
 
31
37
  def order
@@ -25,8 +25,10 @@ module ForestLiana
25
25
  def perform
26
26
  value = get_resource().joins(@includes)
27
27
 
28
- unless @params[:filters].blank?
29
- value = FiltersParser.new(@params[:filters], value, @params[:timezone]).apply_filters
28
+ filters = ForestLiana::ScopeManager.append_scope_for_user(@params[:filters], @user, @resource.name)
29
+
30
+ unless filters.blank?
31
+ value = FiltersParser.new(filters, @resource, @params[:timezone]).apply_filters
30
32
  end
31
33
 
32
34
  Groupdate.week_start = :monday
@@ -7,7 +7,6 @@ module ForestLiana
7
7
  @@expiration_in_seconds = (ENV['FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS'] || 3600).to_i
8
8
 
9
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
-
11
10
  @collection_name = resource.present? ? ForestLiana.name_for(resource) : nil
12
11
  @permission_name = permission_name
13
12
  @rendering_id = rendering_id
@@ -119,7 +118,7 @@ module ForestLiana
119
118
  permissions = @@renderings_cached[@rendering_id]
120
119
  permissions && permissions['stats'] && permissions['stats']['queries']
121
120
  end
122
-
121
+
123
122
  def get_stat_with_parameters_content(statPermissionType)
124
123
  permissions = @@renderings_cached[@rendering_id]
125
124
  permissions && permissions['stats'] && permissions['stats'][statPermissionType]
@@ -163,7 +162,7 @@ module ForestLiana
163
162
 
164
163
  return false unless segments_queries_permissions
165
164
 
166
- # NOTICE: @query_request_info matching an existing segment query
165
+ # NOTICE: @query_request_info matching an existing segment query
167
166
  return segments_queries_permissions.include? @collection_list_parameters[:segmentQuery]
168
167
  end
169
168
 
@@ -172,7 +171,7 @@ module ForestLiana
172
171
 
173
172
  return false unless live_queries_permissions
174
173
 
175
- # NOTICE: @query_request_info matching an existing live query
174
+ # NOTICE: @query_request_info matching an existing live query
176
175
  return live_queries_permissions.include? @query_request_info
177
176
  end
178
177
 
@@ -23,7 +23,7 @@ module ForestLiana
23
23
  # },
24
24
  # },
25
25
  # },
26
- # rederings => {
26
+ # renderings => {
27
27
  # {rendering_id} => {
28
28
  # {collection_id} => {
29
29
  # segments => ['query1', 'query2']
@@ -32,7 +32,7 @@ module ForestLiana
32
32
  # }
33
33
  # }
34
34
  # With `rendering_specific_only` this returns only the permissions related data specific to the provided rendering
35
- # For now this only includes scopes
35
+ # For now this only includes scopes (but scopes are not used anymore in permissions)
36
36
  def get_permissions_for_rendering(rendering_id, rendering_specific_only: false)
37
37
  begin
38
38
  query_parameters = { 'renderingId' => rendering_id }
@@ -7,8 +7,10 @@ module ForestLiana
7
7
  timezone_offset = @params[:timezone].to_i
8
8
  resource = get_resource().eager_load(@includes)
9
9
 
10
- unless @params[:filters].blank?
11
- resource = FiltersParser.new(@params[:filters], resource, @params[:timezone]).apply_filters
10
+ filters = ForestLiana::ScopeManager.append_scope_for_user(@params[:filters], @user, @resource.name)
11
+
12
+ unless filters.blank?
13
+ resource = FiltersParser.new(filters, resource, @params[:timezone]).apply_filters
12
14
  end
13
15
 
14
16
  result = resource
@@ -53,7 +55,8 @@ module ForestLiana
53
55
  if @params[:aggregate].downcase == 'sum'
54
56
  field = @params[:aggregate_field].downcase
55
57
  else
56
- field = Rails::VERSION::MAJOR >= 5 || @includes.size > 0 ? 'id' : 'all'
58
+ # `count_id` is required only for rails v5
59
+ field = Rails::VERSION::MAJOR == 5 || @includes.size > 0 ? 'id' : 'all'
57
60
  end
58
61
  "#{@params[:aggregate].downcase}_#{field} #{order}"
59
62
  end
@@ -2,16 +2,19 @@ module ForestLiana
2
2
  class ResourceGetter < BaseGetter
3
3
  attr_accessor :record
4
4
 
5
- def initialize(resource, params)
5
+ def initialize(resource, params, forest_user)
6
6
  @resource = resource
7
7
  @params = params
8
- @collection_name = ForestLiana.name_for(@resource)
8
+ @collection_name = ForestLiana.name_for(resource)
9
+ @user = forest_user
9
10
  @collection = get_collection(@collection_name)
10
11
  compute_includes()
11
12
  end
12
13
 
13
14
  def perform
14
- @record = get_resource().eager_load(@includes).find(@params[:id])
15
+ records = get_resource().eager_load(@includes)
16
+ scoped_records = ForestLiana::ScopeManager.apply_scopes_on_records(records, @user, @collection_name, @params[:timezone])
17
+ @record = scoped_records.find(@params[:id])
15
18
  end
16
19
  end
17
20
  end