forest_liana 7.8.0 → 8.0.0.beta.2

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/forest_liana/actions_controller.rb +5 -3
  3. data/app/controllers/forest_liana/application_controller.rb +15 -0
  4. data/app/controllers/forest_liana/resources_controller.rb +31 -57
  5. data/app/controllers/forest_liana/smart_actions_controller.rb +44 -58
  6. data/app/controllers/forest_liana/stats_controller.rb +14 -58
  7. data/app/services/forest_liana/ability/exceptions/access_denied.rb +16 -0
  8. data/app/services/forest_liana/ability/exceptions/action_condition_error.rb +16 -0
  9. data/app/services/forest_liana/ability/exceptions/require_approval.rb +18 -0
  10. data/app/services/forest_liana/ability/exceptions/trigger_forbidden.rb +16 -0
  11. data/app/services/forest_liana/ability/fetch.rb +23 -0
  12. data/app/services/forest_liana/ability/permission/request_permission.rb +19 -0
  13. data/app/services/forest_liana/ability/permission/smart_action_checker.rb +71 -0
  14. data/app/services/forest_liana/ability/permission.rb +148 -0
  15. data/app/services/forest_liana/ability.rb +24 -0
  16. data/app/services/forest_liana/filters_parser.rb +7 -7
  17. data/app/services/forest_liana/leaderboard_stat_getter.rb +7 -7
  18. data/app/services/forest_liana/line_stat_getter.rb +8 -8
  19. data/app/services/forest_liana/pie_stat_getter.rb +17 -17
  20. data/app/services/forest_liana/stat_getter.rb +1 -2
  21. data/app/services/forest_liana/value_stat_getter.rb +7 -7
  22. data/lib/forest_liana/bootstrapper.rb +1 -1
  23. data/lib/forest_liana/version.rb +1 -1
  24. data/spec/dummy/lib/forest_liana/collections/island.rb +1 -1
  25. data/spec/requests/actions_controller_spec.rb +3 -4
  26. data/spec/requests/count_spec.rb +5 -9
  27. data/spec/requests/resources_spec.rb +55 -11
  28. data/spec/requests/stats_spec.rb +103 -42
  29. data/spec/services/forest_liana/ability/ability_spec.rb +48 -0
  30. data/spec/services/forest_liana/ability/permission/smart_action_checker_spec.rb +357 -0
  31. data/spec/services/forest_liana/ability/permission_spec.rb +332 -0
  32. data/spec/services/forest_liana/filters_parser_spec.rb +0 -12
  33. data/spec/services/forest_liana/line_stat_getter_spec.rb +9 -9
  34. data/spec/services/forest_liana/pie_stat_getter_spec.rb +7 -7
  35. data/spec/services/forest_liana/value_stat_getter_spec.rb +11 -11
  36. data/spec/spec_helper.rb +1 -0
  37. metadata +33 -17
  38. data/app/services/forest_liana/permissions_checker.rb +0 -223
  39. data/app/services/forest_liana/permissions_formatter.rb +0 -52
  40. data/app/services/forest_liana/permissions_getter.rb +0 -59
  41. data/spec/services/forest_liana/permissions_checker_acl_disabled_spec.rb +0 -713
  42. data/spec/services/forest_liana/permissions_checker_acl_enabled_spec.rb +0 -845
  43. data/spec/services/forest_liana/permissions_checker_live_queries_spec.rb +0 -175
  44. data/spec/services/forest_liana/permissions_formatter_spec.rb +0 -222
  45. data/spec/services/forest_liana/permissions_getter_spec.rb +0 -83
@@ -0,0 +1,148 @@
1
+ require 'digest'
2
+ require 'deepsort'
3
+
4
+ module ForestLiana
5
+ module Ability
6
+ module Permission
7
+ include Fetch
8
+
9
+ TTL = (ENV['FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS'] || 1).to_i.second
10
+
11
+ def is_crud_authorized?(action, user, collection)
12
+ return true unless has_permission_system?
13
+
14
+ user_data = get_user_data(user['id'])
15
+ collections_data = get_collections_permissions_data
16
+
17
+ begin
18
+ is_allowed = collections_data[collection.name][action].include? user_data['roleId']
19
+ # re-fetch if user permission is not allowed (may have been changed)
20
+ unless is_allowed
21
+ collections_data = get_collections_permissions_data(true)
22
+ is_allowed = collections_data[collection.name][action].include? user_data['roleId']
23
+ end
24
+
25
+ is_allowed
26
+ rescue
27
+ raise ForestLiana::Errors::ExpectedError.new(409, :conflict, "The collection #{collection} doesn't exist", 'collection not found')
28
+ end
29
+ end
30
+
31
+ def is_smart_action_authorized?(user, collection, parameters, endpoint, http_method)
32
+ user_data = get_user_data(user['id'])
33
+ collections_data = get_collections_permissions_data
34
+ begin
35
+ action = find_action_from_endpoint(collection.name, endpoint, http_method).name
36
+
37
+ smart_action_approval = SmartActionChecker.new(parameters, collection, collections_data[collection.name][:actions][action], user_data)
38
+ smart_action_approval.can_execute?
39
+ rescue
40
+ raise ForestLiana::Errors::ExpectedError.new(409, :conflict, "The collection #{collection} doesn't exist", 'collection not found')
41
+ end
42
+ end
43
+
44
+ def is_chart_authorized?(user, parameters)
45
+ parameters = parameters.to_h
46
+ parameters.delete('timezone')
47
+ parameters.delete('controller')
48
+ parameters.delete('action')
49
+ parameters.delete('collection')
50
+ parameters.delete('contextVariables')
51
+
52
+
53
+ hash_request = "#{parameters['type']}:#{Digest::SHA1.hexdigest(parameters.deep_sort.to_s)}"
54
+ allowed = get_chart_data(user['rendering_id']).to_s.include? hash_request
55
+
56
+ unless allowed
57
+ allowed = get_chart_data(user['rendering_id'], true).to_s.include? hash_request
58
+ end
59
+
60
+ allowed
61
+ end
62
+
63
+ private
64
+
65
+ def get_user_data(user_id)
66
+ cache = Rails.cache.fetch('forest.users', expires_in: TTL) do
67
+ users = {}
68
+ get_permissions('/liana/v4/permissions/users').each do |user|
69
+ users[user['id'].to_s] = user
70
+ end
71
+
72
+ users
73
+ end
74
+
75
+ cache[user_id.to_s]
76
+ end
77
+
78
+ def get_collections_permissions_data(force_fetch = false)
79
+ Rails.cache.delete('forest.collections') if force_fetch == true
80
+ cache = Rails.cache.fetch('forest.collections', expires_in: TTL) do
81
+ collections = {}
82
+ get_permissions('/liana/v4/permissions/environment')['collections'].each do |name, collection|
83
+ collections[name] = format_collection_crud_permission(collection).merge!(format_collection_action_permission(collection))
84
+ end
85
+
86
+ collections
87
+ end
88
+
89
+ cache
90
+ end
91
+
92
+ def get_chart_data(rendering_id, force_fetch = false)
93
+ Rails.cache.delete('forest.stats') if force_fetch == true
94
+ Rails.cache.fetch('forest.stats', expires_in: TTL) do
95
+ stat_hash = []
96
+ get_permissions('/liana/v4/permissions/renderings/' + rendering_id)['stats'].each do |stat|
97
+ stat_hash << "#{stat['type']}:#{Digest::SHA1.hexdigest(stat.sort.to_h.to_s)}"
98
+ end
99
+
100
+ stat_hash
101
+ end
102
+ end
103
+
104
+ def has_permission_system?
105
+ Rails.cache.fetch('forest.has_permission') do
106
+ (get_permissions('/liana/v4/permissions/environment') == true) ? false : true
107
+ end
108
+ end
109
+
110
+ def format_collection_crud_permission(collection)
111
+ {
112
+ 'browse' => collection['collection']['browseEnabled']['roles'],
113
+ 'read' => collection['collection']['readEnabled']['roles'],
114
+ 'edit' => collection['collection']['editEnabled']['roles'],
115
+ 'add' => collection['collection']['addEnabled']['roles'],
116
+ 'delete' => collection['collection']['deleteEnabled']['roles'],
117
+ 'export' => collection['collection']['exportEnabled']['roles'],
118
+ }
119
+ end
120
+
121
+ def format_collection_action_permission(collection)
122
+ actions = {}
123
+ actions[:actions] = {}
124
+ collection['actions'].each do |id, action|
125
+ actions[:actions][id] = {
126
+ 'triggerEnabled' => action['triggerEnabled']['roles'],
127
+ 'triggerConditions' => action['triggerConditions'],
128
+ 'approvalRequired' => action['approvalRequired']['roles'],
129
+ 'approvalRequiredConditions' => action['approvalRequiredConditions'],
130
+ 'userApprovalEnabled' => action['userApprovalEnabled']['roles'],
131
+ 'userApprovalConditions' => action['userApprovalConditions'],
132
+ 'selfApprovalEnabled' => action['selfApprovalEnabled']['roles'],
133
+ }
134
+ end
135
+
136
+ actions
137
+ end
138
+
139
+ def find_action_from_endpoint(collection_name, endpoint, http_method)
140
+ collection = ForestLiana.apimap.find { |collection| collection.name.to_s == collection_name }
141
+
142
+ return nil unless collection
143
+
144
+ collection.actions.find { |action| (action.endpoint == endpoint || "/#{action.endpoint}" == endpoint) && action.http_method == http_method }
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,24 @@
1
+ module ForestLiana
2
+ module Ability
3
+ include ForestLiana::Ability::Permission
4
+
5
+ ALLOWED_PERMISSION_LEVELS = %w[admin editor developer].freeze
6
+
7
+ def forest_authorize!(action, user, collection, args = {})
8
+ case action
9
+ when 'browse', 'read', 'edit', 'add', 'delete', 'export'
10
+ raise ForestLiana::Ability::Exceptions::AccessDenied.new unless is_crud_authorized?(action, user, collection)
11
+ when 'chart'
12
+ if ALLOWED_PERMISSION_LEVELS.exclude?(user['permission_level'])
13
+ raise ForestLiana::Errors::HTTP422Error.new('The argument parameters is missing') if args[:parameters].nil?
14
+ raise ForestLiana::Ability::Exceptions::AccessDenied.new unless is_chart_authorized?(user, args[:parameters])
15
+ end
16
+ when 'action'
17
+ raise ForestLiana::Errors::HTTP422Error.new('You must implement the arguments : parameters, endpoint & http_method') if args[:parameters].nil? || args[:endpoint].nil? || args[:http_method].nil?
18
+ is_smart_action_authorized?(user, collection, args[:parameters], args[:endpoint], args[:http_method])
19
+ else
20
+ raise ForestLiana::Ability::Exceptions::AccessDenied.new
21
+ end
22
+ end
23
+ end
24
+ end
@@ -2,13 +2,9 @@ module ForestLiana
2
2
  class FiltersParser
3
3
  AGGREGATOR_OPERATOR = %w(and or)
4
4
 
5
- def initialize(filters, resource, timezone)
6
- begin
7
- @filters = JSON.parse(filters)
8
- rescue JSON::ParserError
9
- raise ForestLiana::Errors::HTTP422Error.new('Invalid filters JSON format')
10
- end
11
-
5
+ def initialize(filters, resource, timezone, params = nil)
6
+ @filters = filters.instance_of?(ActionController::Parameters) ? filters.to_h : JSON.parse(filters)
7
+ @params = params
12
8
  @resource = resource
13
9
  @operator_date_parser = OperatorDateIntervalParser.new(timezone)
14
10
  @joins = []
@@ -91,6 +87,10 @@ module ForestLiana
91
87
  value = condition['value']
92
88
  field_name = condition['field']
93
89
 
90
+ if value.is_a?(String) && value.start_with?('{{')
91
+ value = @params[:contextVariables][value.gsub(/[{}]/, '')]
92
+ end
93
+
94
94
  if @operator_date_parser.is_date_operator?(operator)
95
95
  condition = @operator_date_parser.get_date_filter(operator, value)
96
96
  return "#{parse_field_name(field_name)} #{condition}"
@@ -2,13 +2,13 @@ module ForestLiana
2
2
  class LeaderboardStatGetter < StatGetter
3
3
  def initialize(parent_model, params, forest_user)
4
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
5
+ child_model = @scoped_parent_model.reflect_on_association(params[:relationshipFieldName]).klass
6
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]
7
+ @label_field = params[:labelFieldName]
8
+ @aggregate = params[:aggregator].downcase
9
+ @aggregate_field = params[:aggregateFieldName]
10
10
  @limit = params[:limit]
11
- @groub_by = "#{@scoped_parent_model.table_name}.#{@label_field}"
11
+ @group_by = "#{@scoped_parent_model.table_name}.#{@label_field}"
12
12
  end
13
13
 
14
14
  def perform
@@ -17,7 +17,7 @@ module ForestLiana
17
17
  result = @scoped_child_model
18
18
  .joins(includes)
19
19
  .where({ @scoped_parent_model.name.downcase.to_sym => @scoped_parent_model })
20
- .group(@groub_by)
20
+ .group(@group_by)
21
21
  .order(order)
22
22
  .limit(@limit)
23
23
  .send(@aggregate, @aggregate_field)
@@ -31,7 +31,7 @@ module ForestLiana
31
31
 
32
32
  return model.unscoped if scope_filters.blank?
33
33
 
34
- FiltersParser.new(scope_filters, model, timezone).apply_filters
34
+ FiltersParser.new(scope_filters, model, timezone, @params).apply_filters
35
35
  end
36
36
 
37
37
  def order
@@ -10,7 +10,7 @@ module ForestLiana
10
10
  end
11
11
 
12
12
  def get_format
13
- case @params[:time_range].try(:downcase)
13
+ case @params[:timeRange].try(:downcase)
14
14
  when 'day'
15
15
  '%d/%m/%Y'
16
16
  when 'week'
@@ -25,17 +25,17 @@ module ForestLiana
25
25
  def perform
26
26
  value = get_resource()
27
27
 
28
- filters = ForestLiana::ScopeManager.append_scope_for_user(@params[:filters], @user, @resource.name)
28
+ filters = ForestLiana::ScopeManager.append_scope_for_user(@params[:filter], @user, @resource.name)
29
29
 
30
30
  unless filters.blank?
31
- value = FiltersParser.new(filters, @resource, @params[:timezone]).apply_filters
31
+ value = FiltersParser.new(filters, @resource, @params[:timezone], @params).apply_filters
32
32
  end
33
33
 
34
34
  Groupdate.week_start = :monday
35
35
 
36
- value = value.send(time_range, group_by_date_field, time_zone: client_timezone)
36
+ value = value.send(timeRange, group_by_date_field, time_zone: client_timezone)
37
37
 
38
- value = value.send(@params[:aggregate].downcase, @params[:aggregate_field])
38
+ value = value.send(@params[:aggregator].downcase, @params[:aggregateFieldName])
39
39
  .map do |k, v|
40
40
  { label: k.strftime(get_format), values: { value: v }}
41
41
  end
@@ -46,11 +46,11 @@ module ForestLiana
46
46
  private
47
47
 
48
48
  def group_by_date_field
49
- "#{@resource.table_name}.#{@params[:group_by_date_field]}"
49
+ "#{@resource.table_name}.#{@params[:groupByFieldName]}"
50
50
  end
51
51
 
52
- def time_range
53
- "group_by_#{@params[:time_range].try(:downcase) || 'month'}"
52
+ def timeRange
53
+ "group_by_#{@params[:timeRange].try(:downcase) || 'month'}"
54
54
  end
55
55
 
56
56
  end
@@ -3,30 +3,30 @@ module ForestLiana
3
3
  attr_accessor :record
4
4
 
5
5
  def perform
6
- if @params[:group_by_field]
6
+ if @params[:groupByFieldName]
7
7
  timezone_offset = @params[:timezone].to_i
8
8
  resource = optimize_record_loading(@resource, get_resource)
9
9
 
10
- filters = ForestLiana::ScopeManager.append_scope_for_user(@params[:filters], @user, @resource.name)
10
+ filters = ForestLiana::ScopeManager.append_scope_for_user(@params[:filter], @user, @resource.name)
11
11
 
12
12
  unless filters.blank?
13
- resource = FiltersParser.new(filters, resource, @params[:timezone]).apply_filters
13
+ resource = FiltersParser.new(filters, resource, @params[:timezone], @params).apply_filters
14
14
  end
15
15
 
16
16
  result = resource
17
- .group(group_by_field)
17
+ .group(groupByFieldName)
18
18
  .order(order)
19
- .send(@params[:aggregate].downcase, @params[:aggregate_field])
19
+ .send(@params[:aggregator].downcase, @params[:aggregateFieldName])
20
20
  .map do |key, value|
21
21
  # NOTICE: Display the enum name instead of an integer if it is an
22
22
  # "Enum" field type on old Rails version (before Rails
23
23
  # 5.1.3).
24
24
  if @resource.respond_to?(:defined_enums) &&
25
- @resource.defined_enums.has_key?(@params[:group_by_field]) &&
25
+ @resource.defined_enums.has_key?(@params[:groupByFieldName]) &&
26
26
  key.is_a?(Integer)
27
- key = @resource.defined_enums[@params[:group_by_field]].invert[key]
28
- elsif @resource.columns_hash[@params[:group_by_field]] &&
29
- @resource.columns_hash[@params[:group_by_field]].type == :datetime
27
+ key = @resource.defined_enums[@params[:groupByFieldName]].invert[key]
28
+ elsif @resource.columns_hash[@params[:groupByFieldName]] &&
29
+ @resource.columns_hash[@params[:groupByFieldName]].type == :datetime
30
30
  key = (key + timezone_offset.hours).strftime('%d/%m/%Y %T')
31
31
  end
32
32
 
@@ -37,13 +37,13 @@ module ForestLiana
37
37
  end
38
38
  end
39
39
 
40
- def group_by_field
41
- if @params[:group_by_field].include? ':'
42
- association, field = @params[:group_by_field].split ':'
40
+ def groupByFieldName
41
+ if @params[:groupByFieldName].include? ':'
42
+ association, field = @params[:groupByFieldName].split ':'
43
43
  resource = @resource.reflect_on_association(association.to_sym)
44
44
  "#{resource.table_name}.#{field}"
45
45
  else
46
- "#{@resource.table_name}.#{@params[:group_by_field]}"
46
+ "#{@resource.table_name}.#{@params[:groupByFieldName]}"
47
47
  end
48
48
  end
49
49
 
@@ -51,14 +51,14 @@ module ForestLiana
51
51
  order = 'DESC'
52
52
 
53
53
  # NOTICE: The generated alias for a count is "count_all", for a sum the
54
- # alias looks like "sum_#{aggregate_field}"
55
- if @params[:aggregate].downcase == 'sum'
56
- field = @params[:aggregate_field].downcase
54
+ # alias looks like "sum_#{aggregateFieldName}"
55
+ if @params[:aggregator].downcase == 'sum'
56
+ field = @params[:aggregateFieldName].downcase
57
57
  else
58
58
  # `count_id` is required only for rails v5
59
59
  field = Rails::VERSION::MAJOR == 5 || @includes.size > 0 ? 'id' : 'all'
60
60
  end
61
- "#{@params[:aggregate].downcase}_#{field} #{order}"
61
+ "#{@params[:aggregator].downcase}_#{field} #{order}"
62
62
  end
63
63
 
64
64
  end
@@ -6,13 +6,12 @@ module ForestLiana
6
6
  @resource = resource
7
7
  @params = params
8
8
  @user = forest_user
9
- compute_includes()
9
+ compute_includes
10
10
  end
11
11
 
12
12
  def get_resource
13
13
  super
14
14
  @resource.reorder('')
15
15
  end
16
-
17
16
  end
18
17
  end
@@ -3,13 +3,13 @@ module ForestLiana
3
3
  attr_accessor :record
4
4
 
5
5
  def perform
6
- return if @params[:aggregate].blank?
6
+ return if @params[:aggregator].blank?
7
7
  resource = optimize_record_loading(@resource, get_resource)
8
8
 
9
- filters = ForestLiana::ScopeManager.append_scope_for_user(@params[:filters], @user, @resource.name)
9
+ filters = ForestLiana::ScopeManager.append_scope_for_user(@params[:filter], @user, @resource.name)
10
10
 
11
11
  unless filters.blank?
12
- filter_parser = FiltersParser.new(filters, resource, @params[:timezone])
12
+ filter_parser = FiltersParser.new(filters, resource, @params[:timezone], @params)
13
13
  resource = filter_parser.apply_filters
14
14
  raw_previous_interval = filter_parser.get_previous_interval_condition
15
15
 
@@ -27,21 +27,21 @@ module ForestLiana
27
27
  private
28
28
 
29
29
  def count(value)
30
- uniq = @params[:aggregate].downcase == 'count'
30
+ uniq = @params[:aggregator].downcase == 'count'
31
31
 
32
32
  if Rails::VERSION::MAJOR >= 4
33
33
  if uniq
34
34
  # NOTICE: uniq is deprecated since Rails 5.0
35
35
  value = Rails::VERSION::MAJOR >= 5 ? value.distinct : value.uniq
36
36
  end
37
- value.send(@params[:aggregate].downcase, aggregate_field)
37
+ value.send(@params[:aggregator].downcase, aggregate_field)
38
38
  else
39
- value.send(@params[:aggregate].downcase, aggregate_field, distinct: uniq)
39
+ value.send(@params[:aggregator].downcase, aggregate_field, distinct: uniq)
40
40
  end
41
41
  end
42
42
 
43
43
  def aggregate_field
44
- @params[:aggregate_field] || @resource.primary_key
44
+ @params[:aggregateFieldName] || @resource.primary_key
45
45
  end
46
46
 
47
47
  end
@@ -202,7 +202,7 @@ module ForestLiana
202
202
  def setup_forest_liana_meta
203
203
  ForestLiana.meta = {
204
204
  liana: 'forest-rails',
205
- liana_version: ForestLiana::VERSION,
205
+ liana_version: ForestLiana::VERSION.sub!('.beta', '-beta'),
206
206
  stack: {
207
207
  database_type: database_type,
208
208
  orm_version: Gem.loaded_specs["activerecord"].version.version,
@@ -1,3 +1,3 @@
1
1
  module ForestLiana
2
- VERSION = "7.8.0"
2
+ VERSION = "8.0.0.beta.2"
3
3
  end
@@ -3,5 +3,5 @@ class Forest::Island
3
3
 
4
4
  collection :Island
5
5
 
6
- action 'Test'
6
+ action 'my_action'
7
7
  end
@@ -171,10 +171,9 @@ describe 'Requesting Actions routes', :type => :request do
171
171
  expect(JSON.parse(response.body)).to eq({'fields' => [foo.merge({:value => nil}).transform_keys { |key| key.to_s.camelize(:lower) }.stringify_keys]})
172
172
  end
173
173
 
174
- it 'should respond 500 with bad params' do
174
+ it 'should respond 422 with bad params' do
175
175
  post '/forest/actions/my_action/hooks/load', params: {}, headers: headers
176
- expect(response.status).to eq(500)
177
- expect(JSON.parse(response.body)).to eq({'error' => 'Error in smart action load hook: cannot retrieve action from collection'})
176
+ expect(response.status).to eq(422)
178
177
  end
179
178
 
180
179
  it 'should respond 500 with bad hook result type' do
@@ -315,7 +314,7 @@ describe 'Requesting Actions routes', :type => :request do
315
314
 
316
315
  describe 'calling the action' do
317
316
  before(:each) do
318
- allow_any_instance_of(ForestLiana::PermissionsChecker).to receive(:is_authorized?) { true }
317
+ allow_any_instance_of(ForestLiana::Ability).to receive(:forest_authorize!) { true }
319
318
  end
320
319
 
321
320
  let(:all_records) { false }
@@ -2,22 +2,18 @@ require 'rails_helper'
2
2
 
3
3
  describe 'Requesting Owner', :type => :request do
4
4
  before(:each) do
5
+ Owner.destroy_all
6
+
5
7
  1.upto(10) do |i|
6
8
  owner = Owner.create(name: "Owner #{i}")
7
9
  Tree.create(name: "Tree #{i}", owner_id: owner.id)
8
10
  end
9
- end
10
11
 
11
- after(:each) do
12
- Owner.destroy_all
13
- end
14
-
15
- before(:each) do
16
12
  allow(ForestLiana::IpWhitelist).to receive(:retrieve) { true }
17
13
  allow(ForestLiana::IpWhitelist).to receive(:is_ip_whitelist_retrieved) { true }
18
14
  allow(ForestLiana::IpWhitelist).to receive(:is_ip_valid) { true }
19
15
 
20
- allow_any_instance_of(ForestLiana::PermissionsChecker).to receive(:is_authorized?) { true }
16
+ allow_any_instance_of(ForestLiana::Ability).to receive(:forest_authorize!) { true }
21
17
 
22
18
  allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return({})
23
19
  end
@@ -68,12 +64,12 @@ describe 'Requesting Owner', :type => :request do
68
64
  }
69
65
 
70
66
  it 'should respond 200' do
71
- get '/forest/Owner/1/relationships/trees/count', params: params, headers: headers
67
+ get '/forest/Owner/5/relationships/trees/count', params: params, headers: headers
72
68
  expect(response.status).to eq(200)
73
69
  end
74
70
 
75
71
  it 'should equal to 1' do
76
- get '/forest/Owner/1/relationships/trees/count', params: params, headers: headers
72
+ get '/forest/Owner/5/relationships/trees/count', params: params, headers: headers
77
73
  expect(response.body).to eq('{"count":1}')
78
74
  end
79
75
  end
@@ -1,28 +1,42 @@
1
1
  require 'rails_helper'
2
2
 
3
3
  describe 'Requesting Tree resources', :type => :request do
4
- before(:each) do
4
+
5
+ before do
5
6
  user = User.create(name: 'Michel')
6
7
  tree = Tree.create(name: 'Lemon Tree', owner: user, cutter: user)
7
- end
8
8
 
9
- after(:each) do
10
- User.destroy_all
11
- Tree.destroy_all
12
- end
9
+ Rails.cache.write('forest.users', {'1' => { 'id' => 1, 'roleId' => 1, 'rendering_id' => '1' }})
10
+ Rails.cache.write('forest.has_permission', true)
11
+ Rails.cache.write(
12
+ 'forest.collections',
13
+ {
14
+ 'Tree' => {
15
+ 'browse' => [1],
16
+ 'read' => [1],
17
+ 'edit' => [1],
18
+ 'add' => [1],
19
+ 'delete' => [1],
20
+ 'export' => [1],
21
+ 'actions' => {}
22
+ }
23
+ }
24
+ )
13
25
 
14
- before(:each) do
15
26
  allow(ForestLiana::IpWhitelist).to receive(:retrieve) { true }
16
27
  allow(ForestLiana::IpWhitelist).to receive(:is_ip_whitelist_retrieved) { true }
17
28
  allow(ForestLiana::IpWhitelist).to receive(:is_ip_valid) { true }
18
-
19
- allow_any_instance_of(ForestLiana::PermissionsChecker).to receive(:is_authorized?) { true }
20
-
29
+ # allow_any_instance_of(ForestLiana::Ability).to receive(:forest_authorize!) { true }
21
30
  allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return({})
22
31
  end
23
32
 
33
+ after do
34
+ User.destroy_all
35
+ Tree.destroy_all
36
+ end
37
+
24
38
  token = JWT.encode({
25
- id: 38,
39
+ id: 1,
26
40
  email: 'michael.kelso@that70.show',
27
41
  first_name: 'Michael',
28
42
  last_name: 'Kelso',
@@ -53,6 +67,36 @@ describe 'Requesting Tree resources', :type => :request do
53
67
  expect(response.status).to eq(200)
54
68
  end
55
69
 
70
+ it 'should return 403 when user permission is not allowed' do
71
+ Rails.cache.delete('forest.users')
72
+ Rails.cache.write('forest.users', {'1' => { 'id' => 1, 'roleId' => 2, 'rendering_id' => '1' }})
73
+ allow_any_instance_of(ForestLiana::Ability::Fetch)
74
+ .to receive(:get_permissions)
75
+ .with('/liana/v4/permissions/environment')
76
+ .and_return(
77
+ {
78
+ "collections" => {
79
+ "Tree" => {
80
+ "collection" => {
81
+ "browseEnabled" => { "roles" => [1] },
82
+ "readEnabled" => { "roles" => [1] },
83
+ "editEnabled" => { "roles" => [1] },
84
+ "addEnabled" => { "roles" => [1] },
85
+ "deleteEnabled" => { "roles" => [1] },
86
+ "exportEnabled" => { "roles" => [1] }
87
+ },
88
+ "actions"=> {}
89
+ }
90
+ }
91
+ }
92
+ )
93
+
94
+ get '/forest/Tree', params: params, headers: headers
95
+
96
+ expect(response.status).to eq(403)
97
+ expect(JSON.parse(response.body)['errors'][0]['detail']).to eq 'You don\'t have permission to access this resource'
98
+ end
99
+
56
100
  it 'should respond the tree data' do
57
101
  get '/forest/Tree', params: params, headers: headers
58
102
  expect(JSON.parse(response.body)).to eq({