diff --git a/app/controllers/storage_settings_controller.rb b/app/controllers/storage_settings_controller.rb index 4b3a8390..30e73572 100644 --- a/app/controllers/storage_settings_controller.rb +++ b/app/controllers/storage_settings_controller.rb @@ -1,6 +1,12 @@ # frozen_string_literal: true class StorageSettingsController < ApplicationController + ENV_STORAGE_SERVICES = { + 'S3_ATTACHMENTS_BUCKET' => ['aws_s3', 'AWS S3'], + 'GCS_BUCKET' => ['google', 'GCP'], + 'AZURE_CONTAINER' => ['azure', 'Azure'] + }.freeze + before_action :load_encrypted_config authorize_resource :encrypted_config, only: :index authorize_resource :encrypted_config, parent: false, only: :create @@ -8,6 +14,12 @@ class StorageSettingsController < ApplicationController def index; end def create + if @env_storage_service.present? + redirect_to settings_storage_index_path, alert: I18n.t('storage_settings_are_managed_by_environment_variables') + + return + end + if @encrypted_config.update(storage_configs) LoadActiveStorageConfigs.reload @@ -22,6 +34,13 @@ class StorageSettingsController < ApplicationController def load_encrypted_config @encrypted_config = EncryptedConfig.find_or_initialize_by(account: current_account, key: EncryptedConfig::FILES_STORAGE_KEY) + @env_storage_env_var, @env_storage_service, @env_storage_service_label = env_storage_service + @storage_value = + if @env_storage_service.present? + { 'service' => @env_storage_service } + else + @encrypted_config.value || { 'service' => 'disk' } + end end def storage_configs @@ -31,4 +50,12 @@ class StorageSettingsController < ApplicationController e.dig(:value, :configs)&.compact_blank! end end + + def env_storage_service + ENV_STORAGE_SERVICES.each do |env_var, (service, label)| + return [env_var, service, label] if ENV[env_var].present? + end + + nil + end end diff --git a/app/views/storage_settings/index.html.erb b/app/views/storage_settings/index.html.erb index 9a53e79a..3441b401 100644 --- a/app/views/storage_settings/index.html.erb +++ b/app/views/storage_settings/index.html.erb @@ -4,9 +4,25 @@
+ <%= t('storage_settings_are_managed_by_environment_variables') %> +
+
+ <%= t('storage_provider_is_configured_by_env_var_html', service: @env_storage_service_label, variable: @env_storage_env_var) %>
+
+ <%= t('update_environment_variables_and_restart_the_app_to_change_storage') %>
+
%{variable}.'
+ update_environment_variables_and_restart_the_app_to_change_storage: Update environment variables and restart the app to change storage.
not_suitable_for_heroku_and_other_paas: Not suitable for Heroku and other PaaS
bulk_send_from_excel_xlsx_or_csv: Bulk send from Excel XLSX or CSV
add_new: Add New
diff --git a/spec/requests/storage_settings_controller_spec.rb b/spec/requests/storage_settings_controller_spec.rb
new file mode 100644
index 00000000..3de679de
--- /dev/null
+++ b/spec/requests/storage_settings_controller_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+RSpec.describe 'StorageSettingsController', type: :request do
+ let(:account) { create(:account) }
+ let(:user) { create(:user, account:) }
+
+ def with_env(overrides)
+ previous_values = {}
+ overrides.each_key { |key| previous_values[key] = ENV[key] }
+ overrides.each { |key, value| ENV[key] = value }
+ yield
+ ensure
+ previous_values.each do |key, value|
+ value.nil? ? ENV.delete(key) : ENV[key] = value
+ end
+ end
+
+ before do
+ sign_in(user)
+ end
+
+ describe 'POST /settings/storage' do
+ it 'does not update storage settings when environment variables manage storage' do
+ encrypted_config = create(:encrypted_config, account:, key: EncryptedConfig::FILES_STORAGE_KEY, value: {
+ service: 'aws_s3',
+ configs: {
+ access_key_id: 'db_access_key',
+ secret_access_key: 'db_secret_key',
+ region: 'us-east-1',
+ bucket: 'db-bucket'
+ }
+ })
+
+ with_env('S3_ATTACHMENTS_BUCKET' => 'env-bucket') do
+ expect do
+ post settings_storage_index_path, params: {
+ encrypted_config: {
+ value: {
+ service: 'disk',
+ configs: {}
+ }
+ }
+ }
+ end.not_to(change { encrypted_config.reload.value })
+
+ expect(response).to redirect_to(settings_storage_index_path)
+ end
+ end
+ end
+end
diff --git a/spec/system/storage_settings_spec.rb b/spec/system/storage_settings_spec.rb
index c11d0ea0..97a4f939 100644
--- a/spec/system/storage_settings_spec.rb
+++ b/spec/system/storage_settings_spec.rb
@@ -8,6 +8,17 @@ RSpec.describe 'Storage Settings' do
sign_in(user)
end
+ def with_env(overrides)
+ previous_values = {}
+ overrides.each_key { |key| previous_values[key] = ENV[key] }
+ overrides.each { |key, value| ENV[key] = value }
+ yield
+ ensure
+ previous_values.each do |key, value|
+ value.nil? ? ENV.delete(key) : ENV[key] = value
+ end
+ end
+
context 'when storage settings are not set' do
before do
visit settings_storage_index_path
@@ -93,6 +104,19 @@ RSpec.describe 'Storage Settings' do
end
end
+ context 'when storage is configured via environment variables' do
+ it 'shows the env-managed provider and disables updates' do
+ with_env('S3_ATTACHMENTS_BUCKET' => 'env-bucket') do
+ visit settings_storage_index_path
+
+ expect(page).to have_content('Storage settings are managed by environment variables.')
+ expect(page).to have_content('Current provider: AWS S3 via S3_ATTACHMENTS_BUCKET.')
+ expect(page).to have_checked_field('AWS')
+ expect(page).to have_button('Save', disabled: true)
+ end
+ end
+ end
+
context 'when storage settings are set' do
context 'when updates the same storage settings' do
context 'when AWS S3' do