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:
parent
42872ab107
commit
24155bc009
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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(/,/) %>
|
||||||
|
@ -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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user