forest_liana 5.4.4 → 6.0.0.pre.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/forest_liana/actions_controller.rb +0 -105
- data/app/controllers/forest_liana/resources_controller.rb +17 -14
- data/app/controllers/forest_liana/smart_actions_controller.rb +5 -10
- data/app/models/forest_liana/model/action.rb +1 -2
- data/app/serializers/forest_liana/stripe_invoice_serializer.rb +5 -5
- data/app/services/forest_liana/apimap_sorter.rb +0 -1
- data/app/services/forest_liana/permissions_checker.rb +56 -118
- data/app/services/forest_liana/permissions_getter.rb +17 -52
- data/app/services/forest_liana/resource_creator.rb +1 -1
- data/app/services/forest_liana/resource_updater.rb +3 -3
- data/app/services/forest_liana/resources_getter.rb +3 -3
- data/app/services/forest_liana/schema_utils.rb +3 -8
- data/app/services/forest_liana/scope_validator.rb +7 -8
- data/app/services/forest_liana/stripe_invoice_getter.rb +1 -1
- data/app/services/forest_liana/stripe_invoices_getter.rb +1 -1
- data/app/services/forest_liana/stripe_source_getter.rb +1 -1
- data/app/services/forest_liana/stripe_sources_getter.rb +1 -1
- data/config/routes.rb +0 -2
- data/lib/forest_liana/bootstrapper.rb +5 -24
- data/lib/forest_liana/schema_file_updater.rb +0 -1
- data/lib/forest_liana/version.rb +1 -1
- data/spec/dummy/config/application.rb +1 -1
- data/spec/dummy/db/migrate/20190226172951_create_user.rb +1 -1
- data/spec/dummy/db/migrate/20190226173051_create_isle.rb +1 -1
- data/spec/dummy/db/migrate/20190226174951_create_tree.rb +1 -1
- data/spec/dummy/db/migrate/20190716130830_add_age_to_tree.rb +1 -1
- data/spec/dummy/db/migrate/20190716135241_add_type_to_user.rb +1 -1
- data/spec/dummy/db/schema.rb +20 -18
- data/spec/requests/resources_spec.rb +4 -4
- data/spec/services/forest_liana/apimap_sorter_spec.rb +4 -6
- data/spec/services/forest_liana/schema_adapter_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -3
- data/test/dummy/config/application.rb +1 -1
- data/test/dummy/db/migrate/20150608130516_create_date_field.rb +1 -1
- data/test/dummy/db/migrate/20150608131430_create_integer_field.rb +1 -1
- data/test/dummy/db/migrate/20150608131603_create_decimal_field.rb +1 -1
- data/test/dummy/db/migrate/20150608131610_create_float_field.rb +1 -1
- data/test/dummy/db/migrate/20150608132159_create_boolean_field.rb +1 -1
- data/test/dummy/db/migrate/20150608132621_create_string_field.rb +1 -1
- data/test/dummy/db/migrate/20150608133038_create_belongs_to_field.rb +1 -1
- data/test/dummy/db/migrate/20150608133044_create_has_one_field.rb +1 -1
- data/test/dummy/db/migrate/20150608150016_create_has_many_field.rb +1 -1
- data/test/dummy/db/migrate/20150609114636_create_belongs_to_class_name_field.rb +1 -1
- data/test/dummy/db/migrate/20150612112520_create_has_and_belongs_to_many_field.rb +1 -1
- data/test/dummy/db/migrate/20150616150629_create_polymorphic_field.rb +1 -1
- data/test/dummy/db/migrate/20150623115554_create_has_many_class_name_field.rb +1 -1
- data/test/dummy/db/migrate/20150814081918_create_has_many_through_field.rb +1 -1
- data/test/dummy/db/migrate/20160627172810_create_owner.rb +1 -1
- data/test/dummy/db/migrate/20160627172951_create_tree.rb +1 -1
- data/test/dummy/db/migrate/20160628173505_add_timestamps.rb +1 -1
- data/test/dummy/db/migrate/20170614141921_create_serialize_field.rb +1 -1
- data/test/dummy/db/migrate/20181111162121_create_references_table.rb +1 -1
- data/test/services/forest_liana/resources_getter_test.rb +1 -1
- metadata +106 -126
- data/app/helpers/forest_liana/is_same_data_structure_helper.rb +0 -44
- data/app/helpers/forest_liana/widgets_helper.rb +0 -59
- data/app/services/forest_liana/permissions_formatter.rb +0 -52
- data/app/services/forest_liana/utils/beta_schema_utils.rb +0 -13
- data/spec/dummy/app/assets/config/manifest.js +0 -1
- data/spec/helpers/forest_liana/is_same_data_structure_helper_spec.rb +0 -87
- data/spec/requests/actions_controller_spec.rb +0 -222
- data/spec/services/forest_liana/permissions_checker_acl_disabled_spec.rb +0 -711
- data/spec/services/forest_liana/permissions_checker_acl_enabled_spec.rb +0 -831
- data/spec/services/forest_liana/permissions_formatter_spec.rb +0 -222
- data/spec/services/forest_liana/permissions_getter_spec.rb +0 -82
- data/test/dummy/app/assets/config/manifest.js +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a534b6abdb1a47d2690f785ef13dff74d97117fa7e1871b82659644ac9c1a53
|
4
|
+
data.tar.gz: 9d7c3281edc36a9aabf47f74851c3ba191d1e31c7bd29a0a4c7d9e8b6f3522f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c18f213548f7584a4dc7aabe121442d0e50270f29860c54164348bd45fca77810d5402284147b9a114d04f17b5314ee8d7f64daae1887e6f258cfd7663ba6c1f
|
7
|
+
data.tar.gz: 6edfe33f160b65de926013b45ef0ba4b7ae374a4446faf64ca6ffbd3a5e606845c89c9e30756fe8e26d4d420786ab09a36b38b0077d0c975a4d695b0aaa0c5ef
|
@@ -1,112 +1,7 @@
|
|
1
1
|
module ForestLiana
|
2
2
|
class ActionsController < ForestLiana::BaseController
|
3
|
-
|
4
3
|
def values
|
5
4
|
render serializer: nil, json: {}, status: :ok
|
6
5
|
end
|
7
|
-
|
8
|
-
def get_collection(collection_name)
|
9
|
-
ForestLiana.apimap.find { |collection| collection.name.to_s == collection_name }
|
10
|
-
end
|
11
|
-
|
12
|
-
def get_action(collection_name)
|
13
|
-
collection = get_collection(collection_name)
|
14
|
-
begin
|
15
|
-
collection.actions.find {|action| ActiveSupport::Inflector.parameterize(action.name) == params[:action_name]}
|
16
|
-
rescue => error
|
17
|
-
FOREST_LOGGER.error "Smart Action get action retrieval error: #{error}"
|
18
|
-
nil
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def get_record
|
23
|
-
model = ForestLiana::SchemaUtils.find_model_from_collection_name(params[:collectionName])
|
24
|
-
redord_getter = ForestLiana::ResourceGetter.new(model, {:id => params[:recordIds][0]})
|
25
|
-
redord_getter.perform
|
26
|
-
redord_getter.record
|
27
|
-
end
|
28
|
-
|
29
|
-
def get_smart_action_load_ctx(fields)
|
30
|
-
fields = fields.reduce({}) do |p, c|
|
31
|
-
ForestLiana::WidgetsHelper.set_field_widget(c)
|
32
|
-
p.update(c[:field] => c.merge!(value: nil))
|
33
|
-
end
|
34
|
-
{:record => get_record, :fields => fields}
|
35
|
-
end
|
36
|
-
|
37
|
-
def get_smart_action_change_ctx(fields)
|
38
|
-
fields = fields.reduce({}) do |p, c|
|
39
|
-
field = c.permit!.to_h.symbolize_keys
|
40
|
-
ForestLiana::WidgetsHelper.set_field_widget(field)
|
41
|
-
p.update(c[:field] => field)
|
42
|
-
end
|
43
|
-
{:record => get_record, :fields => fields}
|
44
|
-
end
|
45
|
-
|
46
|
-
def handle_result(result, formatted_fields, action)
|
47
|
-
if result.nil? || !result.is_a?(Hash)
|
48
|
-
return render status: 500, json: { error: 'Error in smart action load hook: hook must return an object' }
|
49
|
-
end
|
50
|
-
is_same_data_structure = ForestLiana::IsSameDataStructureHelper::Analyser.new(formatted_fields, result, 1)
|
51
|
-
unless is_same_data_structure.perform
|
52
|
-
return render status: 500, json: { error: 'Error in smart action hook: fields must be unchanged (no addition nor deletion allowed)' }
|
53
|
-
end
|
54
|
-
|
55
|
-
# Apply result on fields (transform the object back to an array), preserve order.
|
56
|
-
fields = action.fields.map do |field|
|
57
|
-
updated_field = result[field[:field]]
|
58
|
-
|
59
|
-
# Reset `value` when not present in `enums` (which means `enums` has changed).
|
60
|
-
if updated_field[:enums].is_a?(Array)
|
61
|
-
# `value` can be an array if the type of fields is `[x]`
|
62
|
-
if updated_field[:type].is_a?(Array) && updated_field[:value].is_a?(Array) && !(updated_field[:value] - updated_field[:enums]).empty?
|
63
|
-
updated_field[:value] = nil
|
64
|
-
end
|
65
|
-
|
66
|
-
# `value` can be any other value
|
67
|
-
if !updated_field[:type].is_a?(Array) && !updated_field[:enums].include?(updated_field[:value])
|
68
|
-
updated_field[:value] = nil
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
updated_field
|
73
|
-
end
|
74
|
-
|
75
|
-
render serializer: nil, json: { fields: fields}, status: :ok
|
76
|
-
end
|
77
|
-
|
78
|
-
def load
|
79
|
-
action = get_action(params[:collectionName])
|
80
|
-
|
81
|
-
if !action
|
82
|
-
render status: 500, json: {error: 'Error in smart action load hook: cannot retrieve action from collection'}
|
83
|
-
else
|
84
|
-
# Transform fields from array to an object to ease usage in hook, adds null value.
|
85
|
-
context = get_smart_action_load_ctx(action.fields)
|
86
|
-
formatted_fields = context[:fields].clone # clone for following test on is_same_data_structure
|
87
|
-
|
88
|
-
# Call the user-defined load hook.
|
89
|
-
result = action.hooks[:load].(context)
|
90
|
-
|
91
|
-
handle_result(result, formatted_fields, action)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def change
|
96
|
-
action = get_action(params[:collectionName])
|
97
|
-
|
98
|
-
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
|
104
|
-
|
105
|
-
# Call the user-defined change hook.
|
106
|
-
result = action.hooks[:change][params[:changedField]].(context)
|
107
|
-
|
108
|
-
handle_result(result, formatted_fields, action)
|
109
|
-
end
|
110
|
-
end
|
111
6
|
end
|
112
7
|
end
|
@@ -16,15 +16,18 @@ module ForestLiana
|
|
16
16
|
def index
|
17
17
|
begin
|
18
18
|
if request.format == 'csv'
|
19
|
-
checker = ForestLiana::PermissionsChecker.new(@resource, '
|
19
|
+
checker = ForestLiana::PermissionsChecker.new(@resource, 'export', @rendering_id)
|
20
|
+
return head :forbidden unless checker.is_authorized?
|
21
|
+
elsif params.has_key?(:searchToEdit)
|
22
|
+
checker = ForestLiana::PermissionsChecker.new(@resource, 'searchToEdit', @rendering_id)
|
20
23
|
return head :forbidden unless checker.is_authorized?
|
21
24
|
else
|
22
25
|
checker = ForestLiana::PermissionsChecker.new(
|
23
26
|
@resource,
|
24
|
-
'
|
27
|
+
'list',
|
25
28
|
@rendering_id,
|
26
|
-
|
27
|
-
|
29
|
+
nil,
|
30
|
+
get_collection_list_permission_info(forest_user, request)
|
28
31
|
)
|
29
32
|
return head :forbidden unless checker.is_authorized?
|
30
33
|
end
|
@@ -56,10 +59,10 @@ module ForestLiana
|
|
56
59
|
begin
|
57
60
|
checker = ForestLiana::PermissionsChecker.new(
|
58
61
|
@resource,
|
59
|
-
'
|
62
|
+
'list',
|
60
63
|
@rendering_id,
|
61
|
-
|
62
|
-
|
64
|
+
nil,
|
65
|
+
get_collection_list_permission_info(forest_user, request)
|
63
66
|
)
|
64
67
|
return head :forbidden unless checker.is_authorized?
|
65
68
|
|
@@ -86,7 +89,7 @@ module ForestLiana
|
|
86
89
|
|
87
90
|
def show
|
88
91
|
begin
|
89
|
-
checker = ForestLiana::PermissionsChecker.new(@resource, '
|
92
|
+
checker = ForestLiana::PermissionsChecker.new(@resource, 'show', @rendering_id)
|
90
93
|
return head :forbidden unless checker.is_authorized?
|
91
94
|
|
92
95
|
getter = ForestLiana::ResourceGetter.new(@resource, params)
|
@@ -101,7 +104,7 @@ module ForestLiana
|
|
101
104
|
|
102
105
|
def create
|
103
106
|
begin
|
104
|
-
checker = ForestLiana::PermissionsChecker.new(@resource, '
|
107
|
+
checker = ForestLiana::PermissionsChecker.new(@resource, 'create', @rendering_id)
|
105
108
|
return head :forbidden unless checker.is_authorized?
|
106
109
|
|
107
110
|
creator = ForestLiana::ResourceCreator.new(@resource, params)
|
@@ -124,7 +127,7 @@ module ForestLiana
|
|
124
127
|
|
125
128
|
def update
|
126
129
|
begin
|
127
|
-
checker = ForestLiana::PermissionsChecker.new(@resource, '
|
130
|
+
checker = ForestLiana::PermissionsChecker.new(@resource, 'update', @rendering_id)
|
128
131
|
return head :forbidden unless checker.is_authorized?
|
129
132
|
|
130
133
|
updater = ForestLiana::ResourceUpdater.new(@resource, params)
|
@@ -146,7 +149,7 @@ module ForestLiana
|
|
146
149
|
end
|
147
150
|
|
148
151
|
def destroy
|
149
|
-
checker = ForestLiana::PermissionsChecker.new(@resource, '
|
152
|
+
checker = ForestLiana::PermissionsChecker.new(@resource, 'delete', @rendering_id)
|
150
153
|
return head :forbidden unless checker.is_authorized?
|
151
154
|
|
152
155
|
@resource.destroy(params[:id]) if @resource.exists?(params[:id])
|
@@ -158,7 +161,7 @@ module ForestLiana
|
|
158
161
|
end
|
159
162
|
|
160
163
|
def destroy_bulk
|
161
|
-
checker = ForestLiana::PermissionsChecker.new(@resource, '
|
164
|
+
checker = ForestLiana::PermissionsChecker.new(@resource, 'delete', @rendering_id)
|
162
165
|
return head :forbidden unless checker.is_authorized?
|
163
166
|
|
164
167
|
ids = ForestLiana::ResourcesGetter.get_ids_from_request(params)
|
@@ -242,8 +245,8 @@ module ForestLiana
|
|
242
245
|
@collection ||= ForestLiana.apimap.find { |collection| collection.name.to_s == collection_name }
|
243
246
|
end
|
244
247
|
|
245
|
-
# NOTICE: Return a formatted object containing the request condition filters and
|
246
|
-
# the user id used by the scope validator class to validate if scope is
|
248
|
+
# NOTICE: Return a formatted object containing the request condition filters and
|
249
|
+
# the user id used by the scope validator class to validate if scope is
|
247
250
|
# in request
|
248
251
|
def get_collection_list_permission_info(user, collection_list_request)
|
249
252
|
{
|
@@ -19,15 +19,14 @@ module ForestLiana
|
|
19
19
|
|
20
20
|
def check_permission_for_smart_route
|
21
21
|
begin
|
22
|
-
|
22
|
+
|
23
23
|
smart_action_request = get_smart_action_request
|
24
24
|
if !smart_action_request.nil? && smart_action_request.has_key?(:smart_action_id)
|
25
25
|
checker = ForestLiana::PermissionsChecker.new(
|
26
26
|
find_resource(smart_action_request[:collection_name]),
|
27
27
|
'actions',
|
28
28
|
@rendering_id,
|
29
|
-
|
30
|
-
smart_action_request_info: get_smart_action_request_info
|
29
|
+
get_smart_action_permission_info(forest_user, smart_action_request)
|
31
30
|
)
|
32
31
|
return head :forbidden unless checker.is_authorized?
|
33
32
|
else
|
@@ -55,14 +54,10 @@ module ForestLiana
|
|
55
54
|
end
|
56
55
|
end
|
57
56
|
|
58
|
-
|
59
|
-
def get_smart_action_request_info
|
60
|
-
endpoint = request.fullpath
|
61
|
-
# Trim starting '/'
|
62
|
-
endpoint[0] = '' if endpoint[0] == '/'
|
57
|
+
def get_smart_action_permission_info(user, smart_action_request)
|
63
58
|
{
|
64
|
-
|
65
|
-
|
59
|
+
user_id: user['id'],
|
60
|
+
action_id: smart_action_request[:smart_action_id],
|
66
61
|
}
|
67
62
|
end
|
68
63
|
end
|
@@ -5,7 +5,7 @@ class ForestLiana::Model::Action
|
|
5
5
|
extend ActiveModel::Naming
|
6
6
|
|
7
7
|
attr_accessor :id, :name, :base_url, :endpoint, :http_method, :fields, :redirect,
|
8
|
-
:type, :download
|
8
|
+
:type, :download
|
9
9
|
|
10
10
|
def initialize(attributes = {})
|
11
11
|
if attributes.key?(:global)
|
@@ -66,7 +66,6 @@ class ForestLiana::Model::Action
|
|
66
66
|
@base_url ||= nil
|
67
67
|
@type ||= "bulk"
|
68
68
|
@download ||= false
|
69
|
-
@hooks = !@hooks.nil? ? @hooks.symbolize_keys : nil
|
70
69
|
end
|
71
70
|
|
72
71
|
def persisted?
|
@@ -3,20 +3,20 @@ module ForestLiana
|
|
3
3
|
include JSONAPI::Serializer
|
4
4
|
|
5
5
|
attribute :amount_due
|
6
|
-
attribute :amount_paid
|
7
|
-
attribute :amount_remaining
|
8
|
-
attribute :application_fee_amount
|
9
6
|
attribute :attempt_count
|
10
7
|
attribute :attempted
|
8
|
+
attribute :closed
|
11
9
|
attribute :currency
|
12
|
-
attribute :
|
10
|
+
attribute :date
|
11
|
+
attribute :forgiven
|
13
12
|
attribute :paid
|
14
13
|
attribute :period_end
|
15
14
|
attribute :period_start
|
16
|
-
attribute :status
|
17
15
|
attribute :subtotal
|
18
16
|
attribute :total
|
17
|
+
attribute :application_fee
|
19
18
|
attribute :tax
|
19
|
+
attribute :tax_percent
|
20
20
|
|
21
21
|
has_one :customer
|
22
22
|
|
@@ -1,162 +1,100 @@
|
|
1
1
|
module ForestLiana
|
2
2
|
class PermissionsChecker
|
3
|
-
@@
|
4
|
-
@@scopes_cached = Hash.new
|
5
|
-
@@roles_acl_activated = false
|
6
|
-
# TODO: handle cache scopes per rendering
|
3
|
+
@@permissions_per_rendering = Hash.new
|
7
4
|
@@expiration_in_seconds = (ENV['FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS'] || 3600).to_i
|
8
5
|
|
9
|
-
def initialize(resource, permission_name, rendering_id,
|
10
|
-
@user_id = user_id
|
6
|
+
def initialize(resource, permission_name, rendering_id, smart_action_parameters = nil, collection_list_parameters = nil)
|
11
7
|
@collection_name = ForestLiana.name_for(resource)
|
12
8
|
@permission_name = permission_name
|
13
9
|
@rendering_id = rendering_id
|
14
|
-
@
|
10
|
+
@smart_action_parameters = smart_action_parameters
|
15
11
|
@collection_list_parameters = collection_list_parameters
|
16
12
|
end
|
17
13
|
|
18
14
|
def is_authorized?
|
19
|
-
|
20
|
-
# if !have_permissions_expired && is_allowed
|
21
|
-
return true unless have_permissions_expired? || !is_allowed
|
22
|
-
|
23
|
-
fetch_permissions
|
24
|
-
is_allowed
|
15
|
+
(is_permission_expired? || !is_allowed?) ? retrieve_permissions_and_check_allowed : true
|
25
16
|
end
|
26
17
|
|
27
18
|
private
|
28
19
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
@@
|
38
|
-
|
39
|
-
add_scopes_to_cache(permissions)
|
20
|
+
def get_permissions
|
21
|
+
@@permissions_per_rendering &&
|
22
|
+
@@permissions_per_rendering[@rendering_id] &&
|
23
|
+
@@permissions_per_rendering[@rendering_id]['data']
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_last_retrieve
|
27
|
+
@@permissions_per_rendering &&
|
28
|
+
@@permissions_per_rendering[@rendering_id] &&
|
29
|
+
@@permissions_per_rendering[@rendering_id]['last_retrieve']
|
40
30
|
end
|
41
31
|
|
42
|
-
def
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
32
|
+
def smart_action_allowed?(smart_actions_permissions)
|
33
|
+
if !@smart_action_parameters||
|
34
|
+
!@smart_action_parameters[:user_id] ||
|
35
|
+
!@smart_action_parameters[:action_id] ||
|
36
|
+
!smart_actions_permissions ||
|
37
|
+
!smart_actions_permissions[@smart_action_parameters[:action_id]]
|
38
|
+
return false
|
39
|
+
end
|
40
|
+
|
41
|
+
@user_id = @smart_action_parameters[:user_id]
|
42
|
+
@action_id = @smart_action_parameters[:action_id]
|
43
|
+
@smart_action_permissions = smart_actions_permissions[@action_id]
|
44
|
+
@allowed = @smart_action_permissions['allowed']
|
45
|
+
@users = @smart_action_permissions['users']
|
46
|
+
|
47
|
+
return @allowed && (@users.nil?|| @users.include?(@user_id.to_i));
|
47
48
|
end
|
48
49
|
|
49
|
-
def
|
50
|
-
|
50
|
+
def collection_list_allowed?(scope_permissions)
|
51
|
+
return ForestLiana::ScopeValidator.new(
|
52
|
+
scope_permissions['filter'],
|
53
|
+
scope_permissions['dynamicScopesValues']['users']
|
54
|
+
).is_scope_in_request?(@collection_list_parameters)
|
55
|
+
end
|
51
56
|
|
57
|
+
def is_allowed?
|
58
|
+
permissions = get_permissions
|
52
59
|
if permissions && permissions[@collection_name] &&
|
53
60
|
permissions[@collection_name]['collection']
|
54
61
|
if @permission_name === 'actions'
|
55
62
|
return smart_action_allowed?(permissions[@collection_name]['actions'])
|
63
|
+
# NOTICE: Permissions[@collection_name]['scope'] will either contains conditions filter and
|
64
|
+
# dynamic user values definition, or null for collection that does not use scopes
|
65
|
+
elsif @permission_name === 'list' and permissions[@collection_name]['scope']
|
66
|
+
return collection_list_allowed?(permissions[@collection_name]['scope'])
|
56
67
|
else
|
57
|
-
|
58
|
-
refresh_scope_cache if scope_cache_expired?
|
59
|
-
scope_permissions = get_scope_in_permissions
|
60
|
-
if scope_permissions
|
61
|
-
# NOTICE: current_scope will either contains conditions filter and
|
62
|
-
# dynamic user values definition, or null for collection that does not use scopes
|
63
|
-
return false unless are_scopes_valid?(scope_permissions)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
return is_user_allowed(permissions[@collection_name]['collection'][@permission_name])
|
68
|
+
return permissions[@collection_name]['collection'][@permission_name]
|
67
69
|
end
|
68
70
|
else
|
69
71
|
false
|
70
72
|
end
|
71
73
|
end
|
72
74
|
|
73
|
-
def
|
74
|
-
@@
|
75
|
-
|
76
|
-
@@
|
77
|
-
|
78
|
-
|
79
|
-
def scope_cache_expired?
|
80
|
-
return true unless @@scopes_cached[@rendering_id] && @@scopes_cached[@rendering_id]['last_fetch']
|
81
|
-
|
82
|
-
elapsed_seconds = date_difference_in_seconds(Time.now, @@scopes_cached[@rendering_id]['last_fetch'])
|
83
|
-
elapsed_seconds >= @@expiration_in_seconds
|
84
|
-
end
|
85
|
-
|
86
|
-
# This will happen only on rolesACLActivated (as scope cache will always be up to date on disabled)
|
87
|
-
def refresh_scope_cache
|
88
|
-
permissions = ForestLiana::PermissionsGetter::get_permissions_for_rendering(@rendering_id, rendering_specific_only: true)
|
89
|
-
add_scopes_to_cache(permissions)
|
90
|
-
end
|
91
|
-
|
92
|
-
# When acl disabled permissions are stored and retrieved by rendering
|
93
|
-
def get_permissions
|
94
|
-
@@roles_acl_activated ? @@permissions_cached : @@permissions_cached[@rendering_id]
|
95
|
-
end
|
96
|
-
|
97
|
-
def get_permissions_content
|
98
|
-
permissions = get_permissions
|
99
|
-
permissions && permissions['data'] && permissions['data']['collections']
|
100
|
-
end
|
101
|
-
|
102
|
-
def get_last_fetch
|
103
|
-
permissions = get_permissions
|
104
|
-
permissions && permissions['last_fetch']
|
105
|
-
end
|
106
|
-
|
107
|
-
def get_smart_action_permissions(smart_actions_permissions)
|
108
|
-
endpoint = @smart_action_request_info[:endpoint]
|
109
|
-
http_method = @smart_action_request_info[:http_method]
|
110
|
-
|
111
|
-
return nil unless endpoint && http_method
|
112
|
-
|
113
|
-
schema_smart_action = ForestLiana::Utils::BetaSchemaUtils.find_action_from_endpoint(@collection_name, endpoint, http_method)
|
114
|
-
|
115
|
-
schema_smart_action &&
|
116
|
-
schema_smart_action.name &&
|
117
|
-
smart_actions_permissions &&
|
118
|
-
smart_actions_permissions[schema_smart_action.name]
|
119
|
-
end
|
120
|
-
|
121
|
-
def is_user_allowed(permission_value)
|
122
|
-
return false if permission_value.nil?
|
123
|
-
return permission_value if permission_value.in? [true, false]
|
124
|
-
permission_value.include?(@user_id.to_i)
|
125
|
-
end
|
126
|
-
|
127
|
-
def smart_action_allowed?(smart_actions_permissions)
|
128
|
-
smart_action_permissions = get_smart_action_permissions(smart_actions_permissions)
|
129
|
-
|
130
|
-
return false unless smart_action_permissions
|
131
|
-
|
132
|
-
is_user_allowed(smart_action_permissions['triggerEnabled'])
|
133
|
-
end
|
134
|
-
|
135
|
-
def are_scopes_valid?(scope_permissions)
|
136
|
-
return ForestLiana::ScopeValidator.new(
|
137
|
-
scope_permissions['filter'],
|
138
|
-
scope_permissions['dynamicScopesValues']['users']
|
139
|
-
).is_scope_in_request?(@collection_list_parameters)
|
75
|
+
def retrieve_permissions
|
76
|
+
@@permissions_per_rendering[@rendering_id] = Hash.new
|
77
|
+
permissions = ForestLiana::PermissionsGetter.new(@rendering_id).perform()
|
78
|
+
@@permissions_per_rendering[@rendering_id]['data'] = permissions
|
79
|
+
@@permissions_per_rendering[@rendering_id]['last_retrieve'] = Time.now
|
140
80
|
end
|
141
81
|
|
142
82
|
def date_difference_in_seconds(date1, date2)
|
143
83
|
(date1 - date2).to_i
|
144
84
|
end
|
145
85
|
|
146
|
-
def
|
147
|
-
|
148
|
-
|
86
|
+
def is_permission_expired?
|
87
|
+
last_retrieve = get_last_retrieve
|
88
|
+
|
89
|
+
return true if last_retrieve.nil?
|
149
90
|
|
150
|
-
elapsed_seconds = date_difference_in_seconds(Time.now,
|
91
|
+
elapsed_seconds = date_difference_in_seconds(Time.now, last_retrieve)
|
151
92
|
elapsed_seconds >= @@expiration_in_seconds
|
152
93
|
end
|
153
94
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
@@scopes_cached = Hash.new
|
158
|
-
@@roles_acl_activated = false
|
159
|
-
@@expiration_in_seconds = (ENV['FOREST_PERMISSIONS_EXPIRATION_IN_SECONDS'] || 3600).to_i
|
95
|
+
def retrieve_permissions_and_check_allowed
|
96
|
+
retrieve_permissions
|
97
|
+
is_allowed?
|
160
98
|
end
|
161
99
|
end
|
162
100
|
end
|
@@ -1,60 +1,25 @@
|
|
1
1
|
module ForestLiana
|
2
2
|
class PermissionsGetter
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
# Permission format example:
|
9
|
-
# collections => {
|
10
|
-
# {model_name} => {
|
11
|
-
# collection => {
|
12
|
-
# browseEnabled => true,
|
13
|
-
# readEnabled => true,
|
14
|
-
# editEnabled => true,
|
15
|
-
# addEnabled => true,
|
16
|
-
# deleteEnabled => true,
|
17
|
-
# exportEnabled => true,
|
18
|
-
# },
|
19
|
-
# actions => {
|
20
|
-
# {action_name} => {
|
21
|
-
# triggerEnabled => true,
|
22
|
-
# },
|
23
|
-
# },
|
24
|
-
# },
|
25
|
-
# },
|
26
|
-
# rederings => {
|
27
|
-
# {rendering_id} => {
|
28
|
-
# {collection_id} => {
|
29
|
-
# scope => {
|
30
|
-
# dynamicScopesValues => {},
|
31
|
-
# filter => {}
|
32
|
-
# }
|
33
|
-
# }
|
34
|
-
# }
|
35
|
-
# }
|
36
|
-
# }
|
37
|
-
# With `rendering_specific_only` this returns only the permissions related data specific to the provided rendering
|
38
|
-
# For now this only includes scopes
|
39
|
-
def get_permissions_for_rendering(rendering_id, rendering_specific_only: false)
|
40
|
-
begin
|
41
|
-
query_parameters = { 'renderingId' => rendering_id }
|
42
|
-
query_parameters['renderingSpecificOnly'] = rendering_specific_only if rendering_specific_only
|
3
|
+
def initialize(rendering_id)
|
4
|
+
@route = "/liana/v2/permissions"
|
5
|
+
@rendering_id = rendering_id
|
6
|
+
end
|
43
7
|
|
44
|
-
|
45
|
-
|
8
|
+
def perform
|
9
|
+
begin
|
10
|
+
query_parameters = { 'renderingId' => @rendering_id }
|
11
|
+
response = ForestLiana::ForestApiRequester.get(@route, query: query_parameters)
|
46
12
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
52
|
-
rescue => exception
|
53
|
-
FOREST_LOGGER.error 'Cannot retrieve the permissions from the Forest server.'
|
54
|
-
FOREST_LOGGER.error 'Which was caused by:'
|
55
|
-
ForestLiana::Errors::ExceptionHelper.recursively_print(exception, margin: ' ', is_error: true)
|
56
|
-
nil
|
13
|
+
if response.is_a?(Net::HTTPOK)
|
14
|
+
JSON.parse(response.body)
|
15
|
+
else
|
16
|
+
raise "Forest API returned an #{ForestLiana::Errors::HTTPErrorHelper.format(response)}"
|
57
17
|
end
|
18
|
+
rescue => exception
|
19
|
+
FOREST_LOGGER.error 'Cannot retrieve the permissions from the Forest server.'
|
20
|
+
FOREST_LOGGER.error 'Which was caused by:'
|
21
|
+
ForestLiana::Errors::ExceptionHelper.recursively_print(exception, margin: ' ', is_error: true)
|
22
|
+
nil
|
58
23
|
end
|
59
24
|
end
|
60
25
|
end
|
@@ -14,9 +14,9 @@ module ForestLiana
|
|
14
14
|
@record = @resource.find(@params[:id])
|
15
15
|
|
16
16
|
if has_strong_parameter
|
17
|
-
@record.
|
17
|
+
@record.update_attributes(resource_params)
|
18
18
|
else
|
19
|
-
@record.
|
19
|
+
@record.update_attributes(resource_params, without_protection: true)
|
20
20
|
end
|
21
21
|
rescue ActiveRecord::StatementInvalid => exception
|
22
22
|
# NOTICE: SQL request cannot be executed properly
|
@@ -33,7 +33,7 @@ module ForestLiana
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def has_strong_parameter
|
36
|
-
Rails::VERSION::MAJOR > 5 || @resource.instance_method(:
|
36
|
+
Rails::VERSION::MAJOR > 5 || @resource.instance_method(:update_attributes!).arity == 1
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -12,11 +12,11 @@ module ForestLiana
|
|
12
12
|
@collection = get_collection(@collection_name)
|
13
13
|
@fields_to_serialize = get_fields_to_serialize
|
14
14
|
@field_names_requested = field_names_requested
|
15
|
-
get_segment
|
16
|
-
compute_includes
|
15
|
+
get_segment()
|
16
|
+
compute_includes()
|
17
17
|
@search_query_builder = SearchQueryBuilder.new(@params, @includes, @collection)
|
18
18
|
|
19
|
-
prepare_query
|
19
|
+
prepare_query()
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.get_ids_from_request(params)
|
@@ -2,14 +2,9 @@ module ForestLiana
|
|
2
2
|
class SchemaUtils
|
3
3
|
|
4
4
|
def self.associations(active_record_class)
|
5
|
-
active_record_class
|
6
|
-
|
7
|
-
|
8
|
-
rescue
|
9
|
-
FOREST_LOGGER.warn "Unknown association #{association.name} on class #{active_record_class.name}"
|
10
|
-
false
|
11
|
-
end
|
12
|
-
end
|
5
|
+
active_record_class
|
6
|
+
.reflect_on_all_associations
|
7
|
+
.select { |association| !polymorphic?(association) && !is_active_type?(association.klass) }
|
13
8
|
end
|
14
9
|
|
15
10
|
def self.one_associations(active_record_class)
|