Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix static settings issues and code refactor (#297) #317

Merged
merged 1 commit into from
Dec 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions app/controllers/settings/static_settings_controller.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
# frozen_string_literal: true

class Settings::StaticSettingsController < Settings::BaseController
before_action :set_settings

def index
authorize :static_settings, :index?
end

def show
@static_setting = StaticSetting.last || StaticSetting.new
authorize :static_settings, :show?
end

def update
authorize :static_settings, :update?
if update_or_create
if updated
redirect_to settings_static_settings_path, notice: I18n.t('generic.changes_saved_msg')
else
render :show
Expand All @@ -18,9 +22,8 @@ def update

private

def update_or_create
@static_setting = StaticSetting.last || StaticSetting.new(resource_params)
resource_params[:id].empty? ? @static_setting.save : @static_setting.update(resource_params)
def updated
@static_setting.update(resource_params)
rescue Mastodon::DimensionsValidationError
false
end
Expand All @@ -29,4 +32,7 @@ def resource_params
params.require(:static_setting).permit(:id, :max_post_character, :max_poll_options, :max_poll_option_character, :user_fields, :min_profile_description_character)
end

end
def set_settings
@static_setting = StaticSetting.registry
end
end
11 changes: 6 additions & 5 deletions app/models/account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ class Account < ApplicationRecord
# Local user validations
validates :username, format: { with: /\A[a-z0-9_]+\z/i }, length: { maximum: 30 }, if: -> { local? && will_save_change_to_username? && actor_type != 'Application' }
validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? }
validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? }
validates :display_name, length: { maximum: 30 }, if: -> { local? && will_save_change_to_display_name? }
validates :note, note_length: { maximum: 500 }, length: { minimum: ((ActiveRecord::Base.connection.data_source_exists? 'static_settings') ? StaticSetting.last&.min_profile_description_character : nil) || 0}, if: -> { local? && will_save_change_to_note? }
validates :note, note_length: { maximum: 500 }, length: { minimum: lambda { |_obj| StaticSetting.registry.min_profile_description_character } }, if: -> { local? && will_save_change_to_note? }
validates :fields, length: { maximum: 4 }, if: -> { local? && will_save_change_to_fields? }

scope :remote, -> { where.not(domain: nil) }
Expand Down Expand Up @@ -325,15 +326,15 @@ def fields_attributes=(attributes)
self[:fields] = fields
end

DEFAULT_FIELDS_SIZE = ((ActiveRecord::Base.connection.data_source_exists? 'static_settings') ? StaticSetting.last&.user_fields : nil) || 4

def build_fields
return if fields.size >= DEFAULT_FIELDS_SIZE
field_size = StaticSetting.registry.user_fields

return if fields.size >= field_size

tmp = self[:fields] || []
tmp = [] if tmp.is_a?(Hash)

(DEFAULT_FIELDS_SIZE - tmp.size).times do
(field_size - tmp.size).times do
tmp << { name: '', value: '' }
end

Expand Down
14 changes: 14 additions & 0 deletions app/models/static_setting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,18 @@ class StaticSetting < ApplicationRecord
validates :max_poll_option_character, numericality: { greater_than: 0, less_than_or_equal_to: 1000}, unless: -> { max_poll_option_character.blank? }
validates :user_fields, numericality: { greater_than: 0, less_than_or_equal_to: 10}, unless: -> { user_fields.blank? }
validates :min_profile_description_character, numericality: { greater_than: 0, less_than_or_equal_to: 1000}, unless: -> { min_profile_description_character.blank? }

def self.registry
StaticSetting.last || StaticSetting.create(StaticSetting.default_settings)
end

def self.default_settings
{
max_post_character: ENV['MAX_TOOT_CHARS'] || 500,
max_poll_options: ENV['MAX_POLL_OPTIONS'] || 4,
max_poll_option_character: ENV['MAX_POLL_OPTION_CHARS'] || 50,
user_fields: 4,
min_profile_description_character: 0
}
end
end
5 changes: 4 additions & 1 deletion app/policies/static_settings_policy.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
# frozen_string_literal: true

class StaticSettingsPolicy < ApplicationPolicy
def index?
admin?
end

def update?
admin?
end

def show?
admin?
end

end
10 changes: 7 additions & 3 deletions app/serializers/initial_state_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ class InitialStateSerializer < ActiveModel::Serializer
has_one :push_subscription, serializer: REST::WebPushSubscriptionSerializer

def max_toot_chars
StatusLengthValidator::MAX_CHARS
static_settings.max_post_character
end

def max_poll_options
PollValidator::MAX_OPTIONS
static_settings.max_poll_options
end

def max_poll_option_chars
PollValidator::MAX_OPTION_CHARS
static_settings.max_poll_option_character
end

def meta
Expand Down Expand Up @@ -93,6 +93,10 @@ def media_attachments

private

def static_settings
@static_settings ||= StaticSetting.registry
end

def instance_presenter
@instance_presenter ||= InstancePresenter.new
end
Expand Down
12 changes: 8 additions & 4 deletions app/serializers/rest/instance_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def thumbnail
end

def max_toot_chars
StatusLengthValidator::MAX_CHARS
static_settings.max_post_character
end

def stats
Expand All @@ -61,7 +61,7 @@ def urls
def configuration
{
statuses: {
max_characters: StatusLengthValidator::MAX_CHARS,
max_characters: static_settings.max_post_character,
max_media_attachments: 4,
characters_reserved_per_url: StatusLengthValidator::URL_PLACEHOLDER_CHARS,
},
Expand All @@ -76,8 +76,8 @@ def configuration
},

polls: {
max_options: PollValidator::MAX_OPTIONS,
max_characters_per_option: PollValidator::MAX_OPTION_CHARS,
max_options: static_settings.max_poll_options,
max_characters_per_option: static_settings.max_poll_option_character,
min_expiration: PollValidator::MIN_EXPIRATION,
max_expiration: PollValidator::MAX_EXPIRATION,
},
Expand All @@ -102,6 +102,10 @@ def invites_enabled

private

def static_settings
@static_settings ||= StaticSetting.registry
end

def instance_presenter
@instance_presenter ||= InstancePresenter.new
end
Expand Down
7 changes: 3 additions & 4 deletions app/validators/poll_validator.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
# frozen_string_literal: true

class PollValidator < ActiveModel::Validator
MAX_OPTIONS = (((ActiveRecord::Base.connection.data_source_exists? 'static_settings') ? StaticSetting.last&.max_poll_options : nil) || ENV['MAX_POLL_OPTIONS'] || 4).to_i
MAX_OPTION_CHARS = (((ActiveRecord::Base.connection.data_source_exists? 'static_settings') ? StaticSetting.last&.max_poll_option_character : nil) || ENV['MAX_POLL_OPTION_CHARS'] || 50).to_i
MAX_EXPIRATION = 1.month.freeze
MIN_EXPIRATION = 5.minutes.freeze

def validate(poll)
current_time = Time.now.utc

setting_registry = StaticSetting.registry
poll.errors.add(:options, I18n.t('polls.errors.too_few_options')) unless poll.options.size > 1
poll.errors.add(:options, I18n.t('polls.errors.too_many_options', max: MAX_OPTIONS)) if poll.options.size > MAX_OPTIONS
poll.errors.add(:options, I18n.t('polls.errors.over_character_limit', max: MAX_OPTION_CHARS)) if poll.options.any? { |option| option.mb_chars.grapheme_length > MAX_OPTION_CHARS }
poll.errors.add(:options, I18n.t('polls.errors.too_many_options', max: setting_registry.max_poll_options)) if poll.options.size > setting_registry.max_poll_options
poll.errors.add(:options, I18n.t('polls.errors.over_character_limit', max: setting_registry.max_poll_option_character)) if poll.options.any? { |option| option.mb_chars.grapheme_length > setting_registry.max_poll_option_character }
poll.errors.add(:options, I18n.t('polls.errors.duplicate_options')) unless poll.options.uniq.size == poll.options.size
poll.errors.add(:expires_at, I18n.t('polls.errors.duration_too_long')) if poll.expires_at.nil? || poll.expires_at - current_time > MAX_EXPIRATION
poll.errors.add(:expires_at, I18n.t('polls.errors.duration_too_short')) if poll.expires_at.present? && (poll.expires_at - current_time).ceil < MIN_EXPIRATION
Expand Down
8 changes: 4 additions & 4 deletions app/validators/status_length_validator.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
# frozen_string_literal: true

class StatusLengthValidator < ActiveModel::Validator
MAX_CHARS = (((ActiveRecord::Base.connection.data_source_exists? 'static_settings') ? StaticSetting.last&.max_post_character : nil) || ENV['MAX_TOOT_CHARS'] || 500).to_i
URL_PLACEHOLDER_CHARS = 23
URL_PLACEHOLDER = "\1#{'x' * URL_PLACEHOLDER_CHARS}"

def validate(status)
return unless status.local? && !status.reblog?

max_characters = StaticSetting.registry.max_post_character
@status = status
status.errors.add(:text, I18n.t('statuses.over_character_limit', max: MAX_CHARS)) if too_long?
status.errors.add(:text, I18n.t('statuses.over_character_limit', max: max_characters)) if too_long?(max_characters)
end

private

def too_long?
countable_length > MAX_CHARS
def too_long?(max_characters)
countable_length > max_characters
end

def countable_length
Expand Down
26 changes: 26 additions & 0 deletions app/views/settings/static_settings/index.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
- content_for :page_title do
= 'Static Settings'

- content_for :heading_actions do
= button_tag t('generic.save_changes'), class: 'button', form: 'edit_static_setting'

= simple_form_for @static_setting, url: settings_static_settings_path(@staic_setting), html: { method: :put, id: 'edit_static_setting' } do |f|
= render 'shared/error_messages', object: @static_setting
= f.hidden_field :id, value: @static_setting.id

.fields-row
.fields-row__column.fields-group.fields-row__column-6
= f.input :max_poll_options, wrapper: :with_label, input_html: { maxlength: 2 }, required: false, hint: false
.fields-row__column.fields-group.fields-row__column-6
= f.input :max_poll_option_character, wrapper: :with_label, input_html: { maxlength: 3 }, required: false , hint: false
.fields-row
.fields-row__column.fields-group.fields-row__column-6
= f.input :user_fields, wrapper: :with_label, input_html: { maxlength: 2 }, required: false, hint: false
.fields-row__column.fields-group.fields-row__column-6
= f.input :max_post_character, wrapper: :with_label, input_html: { maxlength: 4 }, required: false , hint: false
.fields-row
.fields-row__column.fields-group.fields-row__column-12
= f.input :min_profile_description_character, wrapper: :with_label, input_html: { maxlength: 3 }, required: false, hint: true

.actions
= f.button :button, t('generic.save_changes'), type: :submit
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@
resources :sessions, only: [:destroy]
resources :featured_tags, only: [:index, :create, :destroy]
resources :login_activities, only: [:index]
resource :static_settings, only: [:show, :update]
resource :static_settings, only: [:index, :show, :update]
end

resources :media, only: [:show] do
Expand Down