forest_liana 6.0.0.pre.beta.2 → 6.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/forest_liana/actions_controller.rb +105 -0
  3. data/app/controllers/forest_liana/authentication_controller.rb +5 -5
  4. data/app/controllers/forest_liana/resources_controller.rb +14 -17
  5. data/app/controllers/forest_liana/smart_actions_controller.rb +10 -5
  6. data/app/helpers/forest_liana/is_same_data_structure_helper.rb +44 -0
  7. data/app/helpers/forest_liana/widgets_helper.rb +59 -0
  8. data/app/models/forest_liana/model/action.rb +2 -1
  9. data/app/serializers/forest_liana/stripe_invoice_serializer.rb +5 -5
  10. data/app/services/forest_liana/apimap_sorter.rb +1 -0
  11. data/app/services/forest_liana/authentication.rb +0 -2
  12. data/app/services/forest_liana/authorization_getter.rb +23 -21
  13. data/app/services/forest_liana/oidc_client_manager.rb +9 -5
  14. data/app/services/forest_liana/permissions_checker.rb +117 -56
  15. data/app/services/forest_liana/permissions_formatter.rb +52 -0
  16. data/app/services/forest_liana/permissions_getter.rb +52 -17
  17. data/app/services/forest_liana/resource_creator.rb +1 -1
  18. data/app/services/forest_liana/resource_updater.rb +3 -3
  19. data/app/services/forest_liana/resources_getter.rb +3 -3
  20. data/app/services/forest_liana/schema_utils.rb +8 -3
  21. data/app/services/forest_liana/scope_validator.rb +8 -7
  22. data/app/services/forest_liana/stripe_invoice_getter.rb +1 -1
  23. data/app/services/forest_liana/stripe_invoices_getter.rb +1 -1
  24. data/app/services/forest_liana/stripe_source_getter.rb +1 -1
  25. data/app/services/forest_liana/stripe_sources_getter.rb +1 -1
  26. data/app/services/forest_liana/utils/beta_schema_utils.rb +13 -0
  27. data/config/initializers/error-messages.rb +3 -0
  28. data/config/initializers/errors.rb +21 -2
  29. data/config/routes.rb +2 -4
  30. data/lib/forest_liana.rb +1 -0
  31. data/lib/forest_liana/bootstrapper.rb +31 -5
  32. data/lib/forest_liana/schema_file_updater.rb +1 -0
  33. data/lib/forest_liana/version.rb +1 -1
  34. data/lib/generators/forest_liana/install_generator.rb +13 -5
  35. data/spec/dummy/app/assets/config/manifest.js +1 -0
  36. data/spec/dummy/config/application.rb +1 -1
  37. data/spec/dummy/db/migrate/20190226172951_create_user.rb +1 -1
  38. data/spec/dummy/db/migrate/20190226173051_create_isle.rb +1 -1
  39. data/spec/dummy/db/migrate/20190226174951_create_tree.rb +1 -1
  40. data/spec/dummy/db/migrate/20190716130830_add_age_to_tree.rb +1 -1
  41. data/spec/dummy/db/migrate/20190716135241_add_type_to_user.rb +1 -1
  42. data/spec/dummy/db/schema.rb +18 -20
  43. data/spec/helpers/forest_liana/is_same_data_structure_helper_spec.rb +87 -0
  44. data/spec/requests/actions_controller_spec.rb +222 -0
  45. data/spec/requests/authentications_spec.rb +12 -13
  46. data/spec/requests/resources_spec.rb +4 -4
  47. data/spec/services/forest_liana/apimap_sorter_spec.rb +6 -4
  48. data/spec/services/forest_liana/permissions_checker_acl_disabled_spec.rb +711 -0
  49. data/spec/services/forest_liana/permissions_checker_acl_enabled_spec.rb +831 -0
  50. data/spec/services/forest_liana/permissions_formatter_spec.rb +222 -0
  51. data/spec/services/forest_liana/permissions_getter_spec.rb +83 -0
  52. data/spec/spec_helper.rb +3 -0
  53. data/test/dummy/app/assets/config/manifest.js +1 -0
  54. data/test/dummy/config/application.rb +1 -1
  55. data/test/dummy/db/migrate/20150608130516_create_date_field.rb +1 -1
  56. data/test/dummy/db/migrate/20150608131430_create_integer_field.rb +1 -1
  57. data/test/dummy/db/migrate/20150608131603_create_decimal_field.rb +1 -1
  58. data/test/dummy/db/migrate/20150608131610_create_float_field.rb +1 -1
  59. data/test/dummy/db/migrate/20150608132159_create_boolean_field.rb +1 -1
  60. data/test/dummy/db/migrate/20150608132621_create_string_field.rb +1 -1
  61. data/test/dummy/db/migrate/20150608133038_create_belongs_to_field.rb +1 -1
  62. data/test/dummy/db/migrate/20150608133044_create_has_one_field.rb +1 -1
  63. data/test/dummy/db/migrate/20150608150016_create_has_many_field.rb +1 -1
  64. data/test/dummy/db/migrate/20150609114636_create_belongs_to_class_name_field.rb +1 -1
  65. data/test/dummy/db/migrate/20150612112520_create_has_and_belongs_to_many_field.rb +1 -1
  66. data/test/dummy/db/migrate/20150616150629_create_polymorphic_field.rb +1 -1
  67. data/test/dummy/db/migrate/20150623115554_create_has_many_class_name_field.rb +1 -1
  68. data/test/dummy/db/migrate/20150814081918_create_has_many_through_field.rb +1 -1
  69. data/test/dummy/db/migrate/20160627172810_create_owner.rb +1 -1
  70. data/test/dummy/db/migrate/20160627172951_create_tree.rb +1 -1
  71. data/test/dummy/db/migrate/20160628173505_add_timestamps.rb +1 -1
  72. data/test/dummy/db/migrate/20170614141921_create_serialize_field.rb +1 -1
  73. data/test/dummy/db/migrate/20181111162121_create_references_table.rb +1 -1
  74. data/test/routing/route_test.rb +0 -12
  75. data/test/services/forest_liana/resources_getter_test.rb +1 -1
  76. metadata +132 -147
  77. data/app/controllers/forest_liana/sessions_controller.rb +0 -95
  78. data/app/serializers/forest_liana/session_serializer.rb +0 -33
  79. data/app/services/forest_liana/login_handler.rb +0 -99
  80. data/app/services/forest_liana/two_factor_registration_confirmer.rb +0 -36
  81. data/app/services/forest_liana/user_secret_creator.rb +0 -26
  82. data/spec/requests/sessions_spec.rb +0 -55
@@ -0,0 +1,222 @@
1
+ module ForestLiana
2
+ describe PermissionsFormatter do
3
+ describe '#convert_to_new_format' do
4
+ let(:rendering_id) { 1 }
5
+ let(:old_format_collection_permissions) {
6
+ {
7
+ 'list'=>true,
8
+ 'show'=>false,
9
+ 'create'=>true,
10
+ 'update'=>false,
11
+ 'delete'=>true,
12
+ 'export'=>false,
13
+ 'searchToEdit'=>false
14
+ }
15
+ }
16
+ let(:old_format_action_permissions) { { 'allowed' => true, 'users' => nil } }
17
+ let(:old_format_scope_permissions) { nil }
18
+ let(:old_format_permissions) {
19
+ {
20
+ 'collection_1' => {
21
+ 'collection' => old_format_collection_permissions,
22
+ 'actions' => {
23
+ 'action_1' => old_format_action_permissions
24
+ },
25
+ 'scope' => old_format_scope_permissions
26
+ }
27
+ }
28
+ }
29
+
30
+ let(:converted_permission) { described_class.convert_to_new_format(old_format_permissions, rendering_id) }
31
+
32
+ describe 'collection permissions' do
33
+ subject { converted_permission['collections']['collection_1']['collection'] }
34
+
35
+ let(:expected_new_collection_permissions_format) {
36
+ {
37
+ 'browseEnabled'=>true,
38
+ 'readEnabled'=>false,
39
+ 'addEnabled'=>true,
40
+ 'editEnabled'=>false,
41
+ 'deleteEnabled'=>true,
42
+ 'exportEnabled'=>false
43
+ }
44
+ }
45
+
46
+ it 'should convert the old format to the new one' do
47
+ expect(subject).to eq expected_new_collection_permissions_format
48
+ end
49
+
50
+ describe 'with searchToEdit true and list false' do
51
+ let(:old_format_collection_permissions) {
52
+ {
53
+ 'list'=>false,
54
+ 'show'=>false,
55
+ 'create'=>false,
56
+ 'update'=>false,
57
+ 'delete'=>false,
58
+ 'export'=>false,
59
+ 'searchToEdit'=>true
60
+ }
61
+ }
62
+
63
+ let(:expected_new_collection_permissions_format) {
64
+ {
65
+ 'browseEnabled'=>true,
66
+ 'readEnabled'=>false,
67
+ 'addEnabled'=>false,
68
+ 'editEnabled'=>false,
69
+ 'deleteEnabled'=>false,
70
+ 'exportEnabled'=>false
71
+ }
72
+ }
73
+
74
+ it 'should convert the old format to the new one with browseEnabled at true' do
75
+ expect(subject).to eq expected_new_collection_permissions_format
76
+ end
77
+ end
78
+
79
+ describe 'with searchToEdit false and list true' do
80
+ let(:old_format_collection_permissions) {
81
+ {
82
+ 'list'=>true,
83
+ 'show'=>false,
84
+ 'create'=>false,
85
+ 'update'=>false,
86
+ 'delete'=>false,
87
+ 'export'=>false,
88
+ 'searchToEdit'=>false
89
+ }
90
+ }
91
+
92
+ let(:expected_new_collection_permissions_format) {
93
+ {
94
+ 'browseEnabled'=>true,
95
+ 'readEnabled'=>false,
96
+ 'addEnabled'=>false,
97
+ 'editEnabled'=>false,
98
+ 'deleteEnabled'=>false,
99
+ 'exportEnabled'=>false
100
+ }
101
+ }
102
+
103
+ it 'should convert the old format to the new one with browseEnabled at true' do
104
+ expect(subject).to eq expected_new_collection_permissions_format
105
+ end
106
+ end
107
+
108
+ describe 'with searchToEdit false and list false' do
109
+ let(:old_format_collection_permissions) {
110
+ {
111
+ 'list'=>false,
112
+ 'show'=>false,
113
+ 'create'=>false,
114
+ 'update'=>false,
115
+ 'delete'=>false,
116
+ 'export'=>false,
117
+ 'searchToEdit'=>false
118
+ }
119
+ }
120
+
121
+ let(:expected_new_collection_permissions_format) {
122
+ {
123
+ 'browseEnabled'=>false,
124
+ 'readEnabled'=>false,
125
+ 'addEnabled'=>false,
126
+ 'editEnabled'=>false,
127
+ 'deleteEnabled'=>false,
128
+ 'exportEnabled'=>false
129
+ }
130
+ }
131
+
132
+ it 'should convert the old format to the new one with browseEnabled at false' do
133
+ expect(subject).to eq expected_new_collection_permissions_format
134
+ end
135
+ end
136
+ end
137
+
138
+ describe 'action permissions' do
139
+ subject { converted_permission['collections']['collection_1']['actions']['action_1'] }
140
+
141
+ context 'when allowed is true' do
142
+ context 'when users is nil' do
143
+ let(:old_format_action_permissions) { { 'allowed' => true, 'users' => nil } }
144
+ let(:expected_new_action_permissions_format) { { 'triggerEnabled' => true } }
145
+
146
+ it 'expected action permission triggerEnabled field should be true' do
147
+ expect(subject).to eq expected_new_action_permissions_format
148
+ end
149
+ end
150
+
151
+ context 'when users is an empty array' do
152
+ let(:old_format_action_permissions) { { 'allowed' => true, 'users' => [] } }
153
+ let(:expected_new_action_permissions_format) { { 'triggerEnabled' => [] } }
154
+
155
+ it 'expected action permission triggerEnabled field should be an empty array' do
156
+ expect(subject).to eq expected_new_action_permissions_format
157
+ end
158
+ end
159
+
160
+ context 'when users is NOT an empty array' do
161
+ let(:old_format_action_permissions) { { 'allowed' => true, 'users' => [2, 3] } }
162
+ let(:expected_new_action_permissions_format) { { 'triggerEnabled' => [2, 3] } }
163
+
164
+ it 'expected action permission triggerEnabled field should be equal to the users array' do
165
+ expect(subject).to eq expected_new_action_permissions_format
166
+ end
167
+ end
168
+ end
169
+
170
+ context 'when allowed is false' do
171
+ context 'when users is nil' do
172
+ let(:old_format_action_permissions) { { 'allowed' => false, 'users' => nil } }
173
+ let(:expected_new_action_permissions_format) { { 'triggerEnabled' => false } }
174
+
175
+ it 'expected action permission triggerEnabled field should be false' do
176
+ expect(subject).to eq expected_new_action_permissions_format
177
+ end
178
+ end
179
+
180
+ context 'when users is an empty array' do
181
+ let(:old_format_action_permissions) { { 'allowed' => false, 'users' => [] } }
182
+ let(:expected_new_action_permissions_format) { { 'triggerEnabled' => false } }
183
+
184
+ it 'expected action permission triggerEnabled field should be false' do
185
+ expect(subject).to eq expected_new_action_permissions_format
186
+ end
187
+ end
188
+
189
+ context 'when users is NOT an empty array' do
190
+ let(:old_format_action_permissions) { { 'allowed' => false, 'users' => [2, 3] } }
191
+ let(:expected_new_action_permissions_format) { { 'triggerEnabled' => false } }
192
+
193
+ it 'expected action permission triggerEnabled field should be false' do
194
+ expect(subject).to eq expected_new_action_permissions_format
195
+ end
196
+ end
197
+ end
198
+ end
199
+
200
+ describe 'scope permissions' do
201
+ subject { converted_permission['renderings'][rendering_id]['collection_1']['scope'] }
202
+ let(:expected_new_format_permissions) { old_format_scope_permissions }
203
+
204
+ context 'when scope permissions are set' do
205
+ let(:old_format_scope_permissions) { { 'dynamicScopesValues' => {}, 'filter' => { 'aggregator' => 'and', 'conditions' => [{ 'field' => 'field_1', 'operator' => 'equal', 'value' => true }] } } }
206
+
207
+ it 'expected scope permissions should be set' do
208
+ expect(subject).to eq expected_new_format_permissions
209
+ end
210
+ end
211
+
212
+ context 'when scope permissions are nil' do
213
+ let(:old_format_scope_permissions) { nil }
214
+
215
+ it 'expected scope permissions should be nil' do
216
+ expect(subject).to eq expected_new_format_permissions
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
222
+ end
@@ -0,0 +1,83 @@
1
+ module ForestLiana
2
+ describe PermissionsGetter do
3
+ describe '#get_permissions_api_route' do
4
+ it 'should respond with the v3 permissions route' do
5
+ expect(described_class.get_permissions_api_route).to eq '/liana/v3/permissions'
6
+ end
7
+ end
8
+
9
+ describe '#get_permissions_for_rendering' do
10
+ let(:rendering_id) { 34 }
11
+ let(:liana_permissions_url) { 'https://api.forestadmin.com/liana/v3/permissions' }
12
+ let(:liana_permissions_api_call_response) { instance_double(HTTParty::Response) }
13
+ let(:expected_request_parameters) {
14
+ {
15
+ :headers => {
16
+ "Content-Type" => "application/json",
17
+ "forest-secret-key" => "env_secret_test"
18
+ },
19
+ :query => expected_query_parameters,
20
+ :verify => false
21
+ }
22
+ }
23
+
24
+ before do
25
+ allow(HTTParty).to receive(:get).and_return(liana_permissions_api_call_response)
26
+ allow(liana_permissions_api_call_response).to receive(:response).and_return(liana_permissions_api_call_response_content)
27
+ allow(liana_permissions_api_call_response_content).to receive(:body).and_return(liana_permissions_api_call_response_content_body)
28
+ end
29
+
30
+ describe 'when the API returns a success' do
31
+ let(:liana_permissions_api_call_response_content) { Net::HTTPOK.new({}, 200, liana_permissions_api_call_response_content_body) }
32
+ let(:liana_permissions_api_call_response_content_body) { '{"test": true}' }
33
+ let(:expected_parsed_result) { { "test" => true } }
34
+
35
+ describe 'when NOT calling for rendering specific only' do
36
+ let(:expected_query_parameters) { { "renderingId" => rendering_id } }
37
+
38
+ it 'should call the API with correct URL' do
39
+ described_class.get_permissions_for_rendering(rendering_id)
40
+ expect(HTTParty).to have_received(:get).with(liana_permissions_url, expected_request_parameters)
41
+ end
42
+
43
+ it 'should return the expected JSON body' do
44
+ expect(described_class.get_permissions_for_rendering(rendering_id)).to eq expected_parsed_result
45
+ end
46
+ end
47
+
48
+ describe 'when calling for rendering specific only' do
49
+ let(:expected_query_parameters) { { "renderingId" => rendering_id, 'renderingSpecificOnly' => true } }
50
+
51
+ it 'should call the API with correct URL and parameters' do
52
+ described_class.get_permissions_for_rendering(rendering_id, rendering_specific_only: true)
53
+ expect(HTTParty).to have_received(:get).with(liana_permissions_url, expected_request_parameters)
54
+ end
55
+
56
+ it 'should return the expected JSON body' do
57
+ expect(described_class.get_permissions_for_rendering(rendering_id, rendering_specific_only: true)).to eq expected_parsed_result
58
+ end
59
+ end
60
+ end
61
+
62
+ describe 'when the API returns a not found error' do
63
+ let(:liana_permissions_api_call_response_content) { Net::HTTPNotFound.new({}, 404, liana_permissions_api_call_response_content_body) }
64
+ let(:liana_permissions_api_call_response_content_body) { 'Not Found' }
65
+
66
+ before do
67
+ allow(FOREST_LOGGER).to receive(:error)
68
+ end
69
+
70
+ it 'should return nil' do
71
+ expect(described_class.get_permissions_for_rendering(rendering_id)).to eq nil
72
+ end
73
+
74
+ it 'should log the not found error' do
75
+ described_class.get_permissions_for_rendering(rendering_id)
76
+ expect(FOREST_LOGGER).to have_received(:error).with('Cannot retrieve the permissions from the Forest server.')
77
+ expect(FOREST_LOGGER).to have_received(:error).with('Which was caused by:')
78
+ expect(FOREST_LOGGER).to have_received(:error).with(' Forest API returned an HTTP error 404')
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require 'simplecov'
2
+ SimpleCov.start 'rails'
3
+
1
4
  # This file was generated by the `rails generate rspec:install` command. Conventionally, all
2
5
  # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
6
  # The generated `.rspec` file contains `--require spec_helper` which will cause
@@ -0,0 +1 @@
1
+ {}
@@ -20,7 +20,7 @@ module Dummy
20
20
  # config.i18n.default_locale = :de
21
21
 
22
22
  # Do not swallow errors in after_commit/after_rollback callbacks.
23
- config.active_record.raise_in_transactional_callbacks = true
23
+ # config.active_record.raise_in_transactional_callbacks = true
24
24
  end
25
25
  end
26
26
 
@@ -1,4 +1,4 @@
1
- class CreateDateField < ActiveRecord::Migration
1
+ class CreateDateField < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :date_fields do |t|
4
4
  t.date :field
@@ -1,4 +1,4 @@
1
- class CreateIntegerField < ActiveRecord::Migration
1
+ class CreateIntegerField < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :integer_fields do |t|
4
4
  t.integer :field
@@ -1,4 +1,4 @@
1
- class CreateDecimalField < ActiveRecord::Migration
1
+ class CreateDecimalField < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :decimal_fields do |t|
4
4
  t.decimal :field
@@ -1,4 +1,4 @@
1
- class CreateFloatField < ActiveRecord::Migration
1
+ class CreateFloatField < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :float_fields do |t|
4
4
  t.float :field
@@ -1,4 +1,4 @@
1
- class CreateBooleanField < ActiveRecord::Migration
1
+ class CreateBooleanField < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :boolean_fields do |t|
4
4
  t.boolean :field
@@ -1,4 +1,4 @@
1
- class CreateStringField < ActiveRecord::Migration
1
+ class CreateStringField < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :string_fields do |t|
4
4
  t.string :field
@@ -1,4 +1,4 @@
1
- class CreateBelongsToField < ActiveRecord::Migration
1
+ class CreateBelongsToField < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :belongs_to_fields do |t|
4
4
  t.references :has_one_field, index: true
@@ -1,4 +1,4 @@
1
- class CreateHasOneField < ActiveRecord::Migration
1
+ class CreateHasOneField < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :has_one_fields do |t|
4
4
  t.boolean :checked
@@ -1,4 +1,4 @@
1
- class CreateHasManyField < ActiveRecord::Migration
1
+ class CreateHasManyField < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :has_many_fields do |t|
4
4
  t.references :has_many_through_field, index: true
@@ -1,4 +1,4 @@
1
- class CreateBelongsToClassNameField < ActiveRecord::Migration
1
+ class CreateBelongsToClassNameField < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :belongs_to_class_name_fields do |t|
4
4
  t.references :foo, index: true
@@ -1,4 +1,4 @@
1
- class CreateHasAndBelongsToManyField < ActiveRecord::Migration
1
+ class CreateHasAndBelongsToManyField < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :has_and_belongs_to_many_fields do |t|
4
4
  end
@@ -1,4 +1,4 @@
1
- class CreatePolymorphicField < ActiveRecord::Migration
1
+ class CreatePolymorphicField < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :polymorphic_fields do |t|
4
4
  t.references :has_one_field, index: true
@@ -1,4 +1,4 @@
1
- class CreateHasManyClassNameField < ActiveRecord::Migration
1
+ class CreateHasManyClassNameField < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :has_many_class_name_fields do |t|
4
4
  end
@@ -1,4 +1,4 @@
1
- class CreateHasManyThroughField < ActiveRecord::Migration
1
+ class CreateHasManyThroughField < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :has_many_through_fields do |t|
4
4
  end
@@ -1,4 +1,4 @@
1
- class CreateOwner < ActiveRecord::Migration
1
+ class CreateOwner < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :owners do |t|
4
4
  t.string :name
@@ -1,4 +1,4 @@
1
- class CreateTree < ActiveRecord::Migration
1
+ class CreateTree < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :trees do |t|
4
4
  t.string :name
@@ -1,4 +1,4 @@
1
- class AddTimestamps < ActiveRecord::Migration
1
+ class AddTimestamps < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  add_column :owners, :created_at, :datetime
4
4
  add_column :owners, :updated_at, :datetime