1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-20 09:52:19 +01:00

ability to lock settings from the env vars

This commit is contained in:
Sylvain 2020-06-15 13:20:48 +02:00
parent 42872ab107
commit 24155bc009
12 changed files with 52 additions and 0 deletions

View File

@ -66,6 +66,11 @@ Application.Directives.directive('booleanSetting', ['Setting', 'growl', '_t',
function (error) { function (error) {
if (error.status === 304) return; if (error.status === 304) return;
if (error.status === 423) {
growl.error(_t('app.admin.settings.error_SETTING_locked', { SETTING: _t(`app.admin.settings.${setting.name}`) }));
return;
}
growl.error(_t('app.admin.settings.an_error_occurred_saving_the_setting')); growl.error(_t('app.admin.settings.an_error_occurred_saving_the_setting'));
console.log(error); console.log(error);
} }

View File

@ -42,6 +42,11 @@ Application.Directives.directive('numberSetting', ['Setting', 'growl', '_t',
function (error) { function (error) {
if (error.status === 304) return; if (error.status === 304) return;
if (error.status === 423) {
growl.error(_t('app.admin.settings.error_SETTING_locked', { SETTING: _t(`app.admin.settings.${setting.name}`) }));
return;
}
growl.error(_t('app.admin.settings.an_error_occurred_saving_the_setting')); growl.error(_t('app.admin.settings.an_error_occurred_saving_the_setting'));
console.log(error); console.log(error);
} }

View File

@ -87,6 +87,11 @@ Application.Directives.directive('selectMultipleSetting', ['Setting', 'growl', '
function (error) { function (error) {
if (error.status === 304) return; if (error.status === 304) return;
if (error.status === 423) {
growl.error(_t('app.admin.settings.error_SETTING_locked', { SETTING: _t(`app.admin.settings.${setting.name}`) }));
return;
}
growl.error(_t('app.admin.settings.an_error_occurred_saving_the_setting')); growl.error(_t('app.admin.settings.an_error_occurred_saving_the_setting'));
console.log(error); console.log(error);
} }

View File

@ -39,6 +39,11 @@ Application.Directives.directive('selectSetting', ['Setting', 'growl', '_t',
function (error) { function (error) {
if (error.status === 304) return; if (error.status === 304) return;
if (error.status === 423) {
growl.error(_t('app.admin.settings.error_SETTING_locked', { SETTING: _t(`app.admin.settings.${setting.name}`) }));
return;
}
growl.error(_t('app.admin.settings.an_error_occurred_saving_the_setting')); growl.error(_t('app.admin.settings.an_error_occurred_saving_the_setting'));
console.log(error); console.log(error);
} }

View File

@ -50,6 +50,11 @@ Application.Directives.directive('textSetting', ['Setting', 'growl', '_t',
function (error) { function (error) {
if (error.status === 304) return; if (error.status === 304) return;
if (error.status === 423) {
growl.error(_t('app.admin.settings.error_SETTING_locked', { SETTING: _t(`app.admin.settings.${setting.name}`) }));
return;
}
growl.error(_t('app.admin.settings.an_error_occurred_saving_the_setting')); growl.error(_t('app.admin.settings.an_error_occurred_saving_the_setting'));
console.log(error); console.log(error);
} }

View File

@ -12,6 +12,7 @@ class API::SettingsController < API::ApiController
authorize Setting authorize Setting
@setting = Setting.find_or_initialize_by(name: params[:name]) @setting = Setting.find_or_initialize_by(name: params[:name])
render status: :not_modified and return if setting_params[:value] == @setting.value render status: :not_modified and return if setting_params[:value] == @setting.value
render status: :locked, json: { error: 'locked setting' } and return unless SettingService.before_update(@setting)
if @setting.save && @setting.history_values.create(value: setting_params[:value], invoicing_profile: current_user.invoicing_profile) if @setting.save && @setting.history_values.create(value: setting_params[:value], invoicing_profile: current_user.invoicing_profile)
SettingService.after_update(@setting) SettingService.after_update(@setting)
@ -29,6 +30,8 @@ class API::SettingsController < API::ApiController
next if !setting[:name] || !setting[:value] next if !setting[:name] || !setting[:value]
db_setting = Setting.find_or_initialize_by(name: setting[:name]) db_setting = Setting.find_or_initialize_by(name: setting[:name])
next unless SettingService.before_update(db_setting)
db_setting.save && db_setting.history_values.create(value: setting[:value], invoicing_profile: current_user.invoicing_profile) db_setting.save && db_setting.history_values.create(value: setting[:value], invoicing_profile: current_user.invoicing_profile)
SettingService.after_update(db_setting) SettingService.after_update(db_setting)
@settings.push db_setting @settings.push db_setting
@ -52,12 +55,15 @@ class API::SettingsController < API::ApiController
authorize Setting authorize Setting
setting = Setting.find_or_create_by(name: params[:name]) setting = Setting.find_or_create_by(name: params[:name])
render status: :locked, json: { error: 'locked setting' } and return unless SettingService.before_update(setting)
first_val = setting.history_values.order(created_at: :asc).limit(1).first first_val = setting.history_values.order(created_at: :asc).limit(1).first
new_val = HistoryValue.create!( new_val = HistoryValue.create!(
setting_id: setting.id, setting_id: setting.id,
value: first_val.value, value: first_val.value,
invoicing_profile_id: current_user.invoicing_profile.id invoicing_profile_id: current_user.invoicing_profile.id
) )
SettingService.after_update(setting)
render json: new_val, status: :ok render json: new_val, status: :ok
end end

View File

@ -6,6 +6,8 @@
# after_update callback is handled by SettingService # after_update callback is handled by SettingService
class Setting < ApplicationRecord class Setting < ApplicationRecord
has_many :history_values has_many :history_values
# The following list contains all the settings that can be customized from the Fab-manager's UI.
# A few of them that are system settings, that should not be updated manually (uuid, origin).
validates :name, inclusion: validates :name, inclusion:
{ in: %w[about_title { in: %w[about_title
about_body about_body

View File

@ -4,6 +4,12 @@
# Due to the way the controller updates the settings, we cannot safely use ActiveRecord's callbacks (eg. after_update, after_commit...) # Due to the way the controller updates the settings, we cannot safely use ActiveRecord's callbacks (eg. after_update, after_commit...)
# so this service provides a wrapper around these operations. # so this service provides a wrapper around these operations.
class SettingService class SettingService
def self.before_update(setting)
return false if Rails.application.secrets.locked_settings.include? setting.name
true
end
def self.after_update(setting) def self.after_update(setting)
# update the stylesheet # update the stylesheet
Stylesheet.theme&.rebuild! if %w[main_color secondary_color].include? setting.name Stylesheet.theme&.rebuild! if %w[main_color secondary_color].include? setting.name

View File

@ -1067,6 +1067,7 @@ en:
advanced: "Advanced settings" advanced: "Advanced settings"
customize_home_page_css: "Customise the stylesheet of the home page" customize_home_page_css: "Customise the stylesheet of the home page"
home_css_notice_html: "You can customize the stylesheet which will apply to the home page, using the <a href=\"https://sass-lang.com/documentation\" target=\"_blank\">SASS</a> syntax. These styles will be automatically subordinated to the <code>.home-page</code> selector to prevent any risk of breaking the application. Meanwhile please be careful, any changes in the home page editor at the top of the page may broke your styles, always refer to the HTML code." home_css_notice_html: "You can customize the stylesheet which will apply to the home page, using the <a href=\"https://sass-lang.com/documentation\" target=\"_blank\">SASS</a> syntax. These styles will be automatically subordinated to the <code>.home-page</code> selector to prevent any risk of breaking the application. Meanwhile please be careful, any changes in the home page editor at the top of the page may broke your styles, always refer to the HTML code."
error_SETTING_locked: "Unable to update the setting: {SETTING} is locked. Please contact your system administrator."
an_error_occurred_saving_the_setting: "An error occurred while saving the setting. Please try again later." an_error_occurred_saving_the_setting: "An error occurred while saving the setting. Please try again later."
book_overlapping_slots_info: "Allow / prevent the reservation of overlapping slots" book_overlapping_slots_info: "Allow / prevent the reservation of overlapping slots"
allow_booking: "Allow booking" allow_booking: "Allow booking"

View File

@ -1067,6 +1067,7 @@ fr:
advanced: "Paramètres avancés" advanced: "Paramètres avancés"
customize_home_page_css: "Personnaliser la feuille de style de la page d'accueil" customize_home_page_css: "Personnaliser la feuille de style de la page d'accueil"
home_css_notice_html: "Vous pouvez personnaliser la feuille de style qui s'appliquera à la page d'accueil en utilisant la syntaxe <a href=\"https://sass-lang.com/documentation\" target=\"_blank\">SASS</a>. Ces styles seront automatiquement subordonnées au sélecteur <code>.home-page</code> pour prévenir tout risque de casse de l'application. Attention toutefois, les modifications de la page d'accueil dans l'éditeur en haut de page peuvent rendre caduque vos styles, référez vous toujours au code HTML." home_css_notice_html: "Vous pouvez personnaliser la feuille de style qui s'appliquera à la page d'accueil en utilisant la syntaxe <a href=\"https://sass-lang.com/documentation\" target=\"_blank\">SASS</a>. Ces styles seront automatiquement subordonnées au sélecteur <code>.home-page</code> pour prévenir tout risque de casse de l'application. Attention toutefois, les modifications de la page d'accueil dans l'éditeur en haut de page peuvent rendre caduque vos styles, référez vous toujours au code HTML."
error_SETTING_locked: "Impossible de mettre à jour le paramètre : {SETTING} est verrouillé. Veuillez contacter votre administrateur système."
an_error_occurred_saving_the_setting: "Une erreur est survenue pendant l'enregistrement du paramètre. Veuillez réessayer plus tard." an_error_occurred_saving_the_setting: "Une erreur est survenue pendant l'enregistrement du paramètre. Veuillez réessayer plus tard."
book_overlapping_slots_info: "Autoriser / empêcher la réservation de créneaux qui se chevauchent" book_overlapping_slots_info: "Autoriser / empêcher la réservation de créneaux qui se chevauchent"
allow_booking: "Autoriser la réservation" allow_booking: "Autoriser la réservation"

View File

@ -36,6 +36,7 @@ development:
disk_space_mb_alert: <%= ENV["DISK_SPACE_MB_ALERT"] %> disk_space_mb_alert: <%= ENV["DISK_SPACE_MB_ALERT"] %>
superadmin_email: <%= ENV["SUPERADMIN_EMAIL"] %> superadmin_email: <%= ENV["SUPERADMIN_EMAIL"] %>
allow_insecure_http: <%= ENV.fetch("ALLOW_INSECURE_HTTP", false) %> allow_insecure_http: <%= ENV.fetch("ALLOW_INSECURE_HTTP", false) %>
locked_settings: <%= ENV.fetch("LOCKED_SETTINGS", 'uuid,origin').split(/,/) %>
test: test:
secret_key_base: 83daf5e7b80d990f037407bab78dff9904aaf3c195a50f84fa8695a22287e707dfbd9524b403b1dcf116ae1d8c06844c3d7ed942564e5b46be6ae3ead93a9d30 secret_key_base: 83daf5e7b80d990f037407bab78dff9904aaf3c195a50f84fa8695a22287e707dfbd9524b403b1dcf116ae1d8c06844c3d7ed942564e5b46be6ae3ead93a9d30
@ -63,6 +64,7 @@ test:
disk_space_mb_alert: <%= ENV["DISK_SPACE_MB_ALERT"] %> disk_space_mb_alert: <%= ENV["DISK_SPACE_MB_ALERT"] %>
superadmin_email: <%= ENV["SUPERADMIN_EMAIL"] %> superadmin_email: <%= ENV["SUPERADMIN_EMAIL"] %>
allow_insecure_http: <%= ENV.fetch("ALLOW_INSECURE_HTTP", false) %> allow_insecure_http: <%= ENV.fetch("ALLOW_INSECURE_HTTP", false) %>
locked_settings: <%= ENV.fetch("LOCKED_SETTINGS", 'uuid,origin').split(/,/) %>
staging: staging:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
@ -99,6 +101,7 @@ staging:
superadmin_email: <%= ENV["SUPERADMIN_EMAIL"] %> superadmin_email: <%= ENV["SUPERADMIN_EMAIL"] %>
enable_in_context_translation: <%= ENV["ENABLE_IN_CONTEXT_TRANSLATION"] %> enable_in_context_translation: <%= ENV["ENABLE_IN_CONTEXT_TRANSLATION"] %>
allow_insecure_http: <%= ENV.fetch("ALLOW_INSECURE_HTTP", false) %> allow_insecure_http: <%= ENV.fetch("ALLOW_INSECURE_HTTP", false) %>
locked_settings: <%= ENV.fetch("LOCKED_SETTINGS", 'uuid,origin').split(/,/) %>
# Do not keep production secrets in the repository, # Do not keep production secrets in the repository,
# instead read values from the environment. # instead read values from the environment.
@ -136,3 +139,4 @@ production:
disk_space_mb_alert: <%= ENV["DISK_SPACE_MB_ALERT"] %> disk_space_mb_alert: <%= ENV["DISK_SPACE_MB_ALERT"] %>
superadmin_email: <%= ENV["SUPERADMIN_EMAIL"] %> superadmin_email: <%= ENV["SUPERADMIN_EMAIL"] %>
allow_insecure_http: <%= ENV.fetch("ALLOW_INSECURE_HTTP", false) %> allow_insecure_http: <%= ENV.fetch("ALLOW_INSECURE_HTTP", false) %>
locked_settings: <%= ENV.fetch("LOCKED_SETTINGS", 'uuid,origin').split(/,/) %>

View File

@ -128,6 +128,13 @@ In test and development environments, the version won't be check automatically,
In production and staging environments, the session cookie won't be sent to the server unless through the HTTPS protocol. In production and staging environments, the session cookie won't be sent to the server unless through the HTTPS protocol.
If you're using Fab-manager on a non-public network or for testing purposes, you can disable this behavior by setting this variable to `true`. If you're using Fab-manager on a non-public network or for testing purposes, you can disable this behavior by setting this variable to `true`.
Please, ensure you know what you're doing, as this can lead to serious security issues. Please, ensure you know what you're doing, as this can lead to serious security issues.
<a name="LOCKED_SETTINGS"></a>
LOCKED_SETTINGS
A comma separated list of settings that cannot be changed from the UI.
Please refer to https://github.com/sleede/fab-manager/blob/master/app/models/setting.rb for a list of possible values.
Only the system administrator can change them, with the command: `ENV=value rails fablab:setup:env_to_db`
<a name="internationalization-settings"></a> <a name="internationalization-settings"></a>
## Internationalization setting. ## Internationalization setting.