internetee-registry/app/models/setting_entry.rb
oleghasjanov f2978599b4 feat: add admin contact ident type validation
- Add new setting for allowed admin contact ident types
- Add validation for admin contact ident types on domain create/update
- Add UI controls for managing allowed ident types
- Add tests for new validation rules
- Update domain model to respect new settings

The changes allow configuring which identification types (private person,
organization, birthday) are allowed for administrative contacts. This is
enforced when creating new domains or adding new admin contacts.
2025-02-03 13:59:03 +02:00

103 lines
2.5 KiB
Ruby

class SettingEntry < ApplicationRecord
include Versions
validates :code, presence: true, uniqueness: true, format: { with: /\A([a-z])[a-z|_]+[a-z]\z/ }
validates :format, presence: true
validates :group, presence: true
validate :validate_value_format
validate :validate_code_is_not_using_reserved_name
before_update :replace_boolean_nil_with_false
VALUE_FORMATS = {
string: :string_format,
integer: :integer_format,
float: :float_format,
boolean: :boolean_format,
hash: :hash_format,
array: :array_format,
}.with_indifferent_access.freeze
def retrieve
method = VALUE_FORMATS[format]
return false if self.format == 'boolean' && value.blank?
return if value.blank?
send(method)
end
def self.with_group(group_name)
SettingEntry.order(id: :asc).where(group: group_name)
end
# rubocop:disable Style/MethodMissingSuper
# rubocop:disable Style/MissingRespondToMissing
def self.method_missing(method, *args)
super(method, *args)
rescue NoMethodError
get_or_set(method.to_s, args[0])
end
# rubocop:enable Style/MissingRespondToMissing
# rubocop:enable Style/MethodMissingSuper
def self.get_or_set(method_name, arg)
if method_name[-1] == '='
SettingEntry.find_by!(code: method_name.sub('=', '')).update(value: arg.to_s)
else
stg = SettingEntry.find_by(code: method_name)
stg ? stg.retrieve : nil
end
end
# Hooks
def replace_boolean_nil_with_false
return unless self.format == 'boolean'
return if value == 'true'
self.value = 'false'
end
def validate_code_is_not_using_reserved_name
disallowed = []
ActiveRecord::Base.instance_methods.sort.each { |m| disallowed << m.to_s }
errors.add(:code, :invalid) if disallowed.include? code
end
def validate_value_format
formats = VALUE_FORMATS.with_indifferent_access
errors.add(:format, :invalid) unless formats.keys.any? format
end
def string_format
value
end
def integer_format
value.to_i
end
def float_format
value.to_f
end
def boolean_format
value == 'true'
end
def hash_format
JSON.parse(value)
end
def array_format
begin
if value.is_a?(String)
JSON.parse(value)
elsif value.is_a?(Hash)
value
else
{ 'birthday' => true, 'priv' => true, 'org' => true }
end
rescue JSON::ParserError => e
puts "JSON Parse error: #{e.message}"
{ 'birthday' => true, 'priv' => true, 'org' => true }
end
end
end