You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

29 lines
811 B

  1. # frozen_string_literal: true
  2. class Ed25519SignatureValidator < ActiveModel::EachValidator
  3. def validate_each(record, attribute, value)
  4. return if value.blank?
  5. verify_key = Ed25519::VerifyKey.new(Base64.decode64(option_to_value(record, :verify_key)))
  6. signature = Base64.decode64(value)
  7. message = option_to_value(record, :message)
  8. record.errors[attribute] << I18n.t('crypto.errors.invalid_signature') unless verified?(verify_key, signature, message)
  9. end
  10. private
  11. def verified?(verify_key, signature, message)
  12. verify_key.verify(signature, message)
  13. rescue Ed25519::VerifyError, ArgumentError
  14. false
  15. end
  16. def option_to_value(record, key)
  17. if options[key].is_a?(Proc)
  18. options[key].call(record)
  19. else
  20. record.public_send(options[key])
  21. end
  22. end
  23. end