admin_settings.rb 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. # frozen_string_literal: true
  2. class Form::AdminSettings
  3. include ActiveModel::Model
  4. include AuthorizedFetchHelper
  5. KEYS = %i(
  6. site_contact_username
  7. site_contact_email
  8. site_title
  9. site_short_description
  10. site_extended_description
  11. site_terms
  12. registrations_mode
  13. closed_registrations_message
  14. timeline_preview
  15. bootstrap_timeline_accounts
  16. theme
  17. activity_api_enabled
  18. peers_api_enabled
  19. preview_sensitive_media
  20. custom_css
  21. profile_directory
  22. thumbnail
  23. mascot
  24. trends
  25. trends_as_landing_page
  26. trendable_by_default
  27. show_domain_blocks
  28. show_domain_blocks_rationale
  29. noindex
  30. require_invite_text
  31. media_cache_retention_period
  32. content_cache_retention_period
  33. backups_retention_period
  34. status_page_url
  35. captcha_enabled
  36. authorized_fetch
  37. ).freeze
  38. INTEGER_KEYS = %i(
  39. media_cache_retention_period
  40. content_cache_retention_period
  41. backups_retention_period
  42. ).freeze
  43. BOOLEAN_KEYS = %i(
  44. timeline_preview
  45. activity_api_enabled
  46. peers_api_enabled
  47. preview_sensitive_media
  48. profile_directory
  49. trends
  50. trends_as_landing_page
  51. trendable_by_default
  52. noindex
  53. require_invite_text
  54. captcha_enabled
  55. authorized_fetch
  56. ).freeze
  57. UPLOAD_KEYS = %i(
  58. thumbnail
  59. mascot
  60. ).freeze
  61. OVERRIDEN_SETTINGS = {
  62. authorized_fetch: :authorized_fetch_mode?,
  63. }.freeze
  64. attr_accessor(*KEYS)
  65. validates :registrations_mode, inclusion: { in: %w(open approved none) }, if: -> { defined?(@registrations_mode) }
  66. validates :site_contact_email, :site_contact_username, presence: true, if: -> { defined?(@site_contact_username) || defined?(@site_contact_email) }
  67. validates :site_contact_username, existing_username: true, if: -> { defined?(@site_contact_username) }
  68. validates :bootstrap_timeline_accounts, existing_username: { multiple: true }, if: -> { defined?(@bootstrap_timeline_accounts) }
  69. validates :show_domain_blocks, inclusion: { in: %w(disabled users all) }, if: -> { defined?(@show_domain_blocks) }
  70. validates :show_domain_blocks_rationale, inclusion: { in: %w(disabled users all) }, if: -> { defined?(@show_domain_blocks_rationale) }
  71. validates :media_cache_retention_period, :content_cache_retention_period, :backups_retention_period, numericality: { only_integer: true }, allow_blank: true, if: -> { defined?(@media_cache_retention_period) || defined?(@content_cache_retention_period) || defined?(@backups_retention_period) }
  72. validates :site_short_description, length: { maximum: 200 }, if: -> { defined?(@site_short_description) }
  73. validates :status_page_url, url: true, allow_blank: true
  74. validate :validate_site_uploads
  75. KEYS.each do |key|
  76. define_method(key) do
  77. return instance_variable_get(:"@#{key}") if instance_variable_defined?(:"@#{key}")
  78. stored_value = if UPLOAD_KEYS.include?(key)
  79. SiteUpload.where(var: key).first_or_initialize(var: key)
  80. elsif OVERRIDEN_SETTINGS.include?(key)
  81. public_send(OVERRIDEN_SETTINGS[key])
  82. else
  83. Setting.public_send(key)
  84. end
  85. instance_variable_set(:"@#{key}", stored_value)
  86. end
  87. end
  88. UPLOAD_KEYS.each do |key|
  89. define_method(:"#{key}=") do |file|
  90. value = public_send(key)
  91. value.file = file
  92. rescue Mastodon::DimensionsValidationError => e
  93. errors.add(key.to_sym, e.message)
  94. end
  95. end
  96. def save
  97. # NOTE: Annoyingly, files are processed and can error out before
  98. # validations are called, and `valid?` clears errors…
  99. # So for now, return early if errors aren't empty.
  100. return false unless errors.empty? && valid?
  101. KEYS.each do |key|
  102. next unless instance_variable_defined?(:"@#{key}")
  103. if UPLOAD_KEYS.include?(key)
  104. public_send(key).save
  105. else
  106. setting = Setting.where(var: key).first_or_initialize(var: key)
  107. setting.update(value: typecast_value(key, instance_variable_get(:"@#{key}")))
  108. end
  109. end
  110. end
  111. private
  112. def typecast_value(key, value)
  113. if BOOLEAN_KEYS.include?(key)
  114. value == '1'
  115. elsif INTEGER_KEYS.include?(key)
  116. value.blank? ? value : Integer(value)
  117. else
  118. value
  119. end
  120. end
  121. def validate_site_uploads
  122. UPLOAD_KEYS.each do |key|
  123. next unless instance_variable_defined?(:"@#{key}")
  124. upload = instance_variable_get(:"@#{key}")
  125. next if upload.valid?
  126. upload.errors.each do |error|
  127. errors.import(error, attribute: key)
  128. end
  129. end
  130. end
  131. end