diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/admin/settings_controller.rb | 73 | ||||
-rw-r--r-- | app/models/form/admin_settings.rb | 131 | ||||
-rw-r--r-- | app/validators/existing_username_validator.rb | 20 | ||||
-rw-r--r-- | app/validators/html_validator.rb | 14 | ||||
-rw-r--r-- | app/views/admin/settings/edit.html.haml | 1 |
5 files changed, 130 insertions, 109 deletions
diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb index a763597f2..dc1c79b7f 100644 --- a/app/controllers/admin/settings_controller.rb +++ b/app/controllers/admin/settings_controller.rb @@ -2,84 +2,29 @@ module Admin class SettingsController < BaseController - ADMIN_SETTINGS = %w( - site_contact_username - site_contact_email - site_title - site_short_description - site_description - site_extended_description - site_terms - registrations_mode - closed_registrations_message - open_deletion - timeline_preview - show_staff_badge - bootstrap_timeline_accounts - theme - thumbnail - hero - mascot - min_invite_role - activity_api_enabled - peers_api_enabled - show_known_fediverse_at_about_page - preview_sensitive_media - custom_css - profile_directory - ).freeze - - BOOLEAN_SETTINGS = %w( - open_deletion - timeline_preview - show_staff_badge - activity_api_enabled - peers_api_enabled - show_known_fediverse_at_about_page - preview_sensitive_media - profile_directory - ).freeze - - UPLOAD_SETTINGS = %w( - thumbnail - hero - mascot - ).freeze - def edit authorize :settings, :show? + @admin_settings = Form::AdminSettings.new end def update authorize :settings, :update? - settings_params.each do |key, value| - if UPLOAD_SETTINGS.include?(key) - upload = SiteUpload.where(var: key).first_or_initialize(var: key) - upload.update(file: value) - else - setting = Setting.where(var: key).first_or_initialize(var: key) - setting.update(value: value_for_update(key, value)) - end - end + @admin_settings = Form::AdminSettings.new(settings_params) - flash[:notice] = I18n.t('generic.changes_saved_msg') - redirect_to edit_admin_settings_path + if @admin_settings.save + flash[:notice] = I18n.t('generic.changes_saved_msg') + redirect_to edit_admin_settings_path + else + render :edit + end end private def settings_params - params.require(:form_admin_settings).permit(ADMIN_SETTINGS) - end - - def value_for_update(key, value) - if BOOLEAN_SETTINGS.include?(key) - value == '1' - else - value - end + params.require(:form_admin_settings).permit(*Form::AdminSettings::KEYS) end end end diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb index a21394a52..2d3aa726d 100644 --- a/app/models/form/admin_settings.rb +++ b/app/models/form/admin_settings.rb @@ -3,49 +3,90 @@ class Form::AdminSettings include ActiveModel::Model - delegate( - :site_contact_username, - :site_contact_username=, - :site_contact_email, - :site_contact_email=, - :site_title, - :site_title=, - :site_short_description, - :site_short_description=, - :site_description, - :site_description=, - :site_extended_description, - :site_extended_description=, - :site_terms, - :site_terms=, - :registrations_mode, - :registrations_mode=, - :closed_registrations_message, - :closed_registrations_message=, - :open_deletion, - :open_deletion=, - :timeline_preview, - :timeline_preview=, - :show_staff_badge, - :show_staff_badge=, - :bootstrap_timeline_accounts, - :bootstrap_timeline_accounts=, - :theme, - :theme=, - :min_invite_role, - :min_invite_role=, - :activity_api_enabled, - :activity_api_enabled=, - :peers_api_enabled, - :peers_api_enabled=, - :show_known_fediverse_at_about_page, - :show_known_fediverse_at_about_page=, - :preview_sensitive_media, - :preview_sensitive_media=, - :custom_css, - :custom_css=, - :profile_directory, - :profile_directory=, - to: Setting - ) + KEYS = %i( + site_contact_username + site_contact_email + site_title + site_short_description + site_description + site_extended_description + site_terms + registrations_mode + closed_registrations_message + open_deletion + timeline_preview + show_staff_badge + bootstrap_timeline_accounts + theme + min_invite_role + activity_api_enabled + peers_api_enabled + show_known_fediverse_at_about_page + preview_sensitive_media + custom_css + profile_directory + ).freeze + + BOOLEAN_KEYS = %i( + open_deletion + timeline_preview + show_staff_badge + activity_api_enabled + peers_api_enabled + show_known_fediverse_at_about_page + preview_sensitive_media + profile_directory + ).freeze + + UPLOAD_KEYS = %i( + thumbnail + hero + mascot + ).freeze + + attr_accessor(*KEYS) + + validates :site_short_description, :site_description, :site_extended_description, :site_terms, :closed_registrations_message, html: true + validates :registrations_mode, inclusion: { in: %w(open approved none) } + validates :min_invite_role, inclusion: { in: %w(disabled user moderator admin) } + validates :site_contact_email, :site_contact_username, presence: true + validates :site_contact_username, existing_username: true + validates :bootstrap_timeline_accounts, existing_username: { multiple: true } + + def initialize(_attributes = {}) + super + initialize_attributes + end + + def save + return false unless valid? + + KEYS.each do |key| + value = instance_variable_get("@#{key}") + + if UPLOAD_KEYS.include?(key) + upload = SiteUpload.where(var: key).first_or_initialize(var: key) + upload.update(file: value) + else + setting = Setting.where(var: key).first_or_initialize(var: key) + setting.update(value: typecast_value(key, value)) + end + end + end + + private + + def initialize_attributes + KEYS.each do |key| + instance_variable_set("@#{key}", Setting.public_send(key)) if instance_variable_get("@#{key}").nil? + end + end + + def typecast_value(key, value) + if BOOLEAN_KEYS.include?(key) + value == '1' + else + value + end + end end diff --git a/app/validators/existing_username_validator.rb b/app/validators/existing_username_validator.rb new file mode 100644 index 000000000..4388a0c98 --- /dev/null +++ b/app/validators/existing_username_validator.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class ExistingUsernameValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + return if value.blank? + + if options[:multiple] + missing_usernames = value.split(',').map { |username| username unless Account.find_local(username) }.compact + record.errors.add(attribute, I18n.t('existing_username_validator.not_found_multiple', usernames: missing_usernames.join(', '))) if missing_usernames.any? + else + record.errors.add(attribute, I18n.t('existing_username_validator.not_found')) unless Account.find_local(value) + end + end + + private + + def valid_html?(str) + Nokogiri::HTML.fragment(str).to_s == str + end +end diff --git a/app/validators/html_validator.rb b/app/validators/html_validator.rb new file mode 100644 index 000000000..882c35d41 --- /dev/null +++ b/app/validators/html_validator.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class HtmlValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + return if value.blank? + record.errors.add(attribute, I18n.t('html_validator.invalid_markup')) unless valid_html?(value) + end + + private + + def valid_html?(str) + Nokogiri::HTML.fragment(str).to_s == str + end +end diff --git a/app/views/admin/settings/edit.html.haml b/app/views/admin/settings/edit.html.haml index d9b4bf01b..1c2c00f10 100644 --- a/app/views/admin/settings/edit.html.haml +++ b/app/views/admin/settings/edit.html.haml @@ -2,6 +2,7 @@ = t('admin.settings.title') = simple_form_for @admin_settings, url: admin_settings_path, html: { method: :patch } do |f| + = render 'shared/error_messages', object: @admin_settings .fields-group = f.input :site_title, wrapper: :with_label, label: t('admin.settings.site_title') |