admin_settings.rb 4.0 KB

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