forked from fedi/mastodon
30 lines
811 B
Ruby
30 lines
811 B
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
class Ed25519SignatureValidator < ActiveModel::EachValidator
|
||
|
def validate_each(record, attribute, value)
|
||
|
return if value.blank?
|
||
|
|
||
|
verify_key = Ed25519::VerifyKey.new(Base64.decode64(option_to_value(record, :verify_key)))
|
||
|
signature = Base64.decode64(value)
|
||
|
message = option_to_value(record, :message)
|
||
|
|
||
|
record.errors[attribute] << I18n.t('crypto.errors.invalid_signature') unless verified?(verify_key, signature, message)
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def verified?(verify_key, signature, message)
|
||
|
verify_key.verify(signature, message)
|
||
|
rescue Ed25519::VerifyError, ArgumentError
|
||
|
false
|
||
|
end
|
||
|
|
||
|
def option_to_value(record, key)
|
||
|
if options[key].is_a?(Proc)
|
||
|
options[key].call(record)
|
||
|
else
|
||
|
record.public_send(options[key])
|
||
|
end
|
||
|
end
|
||
|
end
|