forest_liana 7.8.0 → 8.0.0.beta.2

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 +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({