Class: Sequent::Core::Helpers::Secret

Inherits:
Object
  • Object
show all
Defined in:
lib/sequent/core/helpers/secret.rb

Overview

You can use this in Commands to handle for instance passwords safely. It uses BCrypt to encrypt the Secret.

Attributes that are of type Secret are encrypted after successful validation in the CommandService automatically. So there is no need to do this yourself, Sequent will take care of this for you. As a result the CommandHandlers will receive the encrypted values.

Since this is meant to be used in Commands based on input you can put in Strings and Secrets.

Example usage:

class CreateUser < Sequent::Command
  attrs email: String, password: Sequent::Secret
end

command = CreateUser.new(
  aggregate_id: Sequent.new_uuid,
  email: '[email protected]',
  password: 'secret',
)

puts command.password
=> secret

command.valid?
=> true

command = command.parse_attrs_to_correct_types
puts command.password
=> SAasdf239as$%^@#%dasfgasasdf (or something similar :-))

When command validation fails attributes of type Sequent::Secret are cleared.

command.valid?
=> false

puts command.password
=> ''

There is no real need to use this type in Events since there we are only interested in the encrypted String at that point.

Besides the Sequent::Secret type there are also some helper methods available to assist in verifying secrets.

See encrypt_secret See re_encrypt_secret See verify_secret

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value) ⇒ Secret

Returns a new instance of Secret.



95
96
97
98
99
100
101
102
# File 'lib/sequent/core/helpers/secret.rb', line 95

def initialize(value)
  fail ArgumentError.new('value can not be blank') if value.blank?
  if value.is_a?(Secret)
    @value = value.value
  else
    @value = value
  end
end

Instance Attribute Details

#valueObject (readonly)

Returns the value of attribute value.



93
94
95
# File 'lib/sequent/core/helpers/secret.rb', line 93

def value
  @value
end

Class Method Details

.deserialize_from_json(value) ⇒ Object



60
61
62
# File 'lib/sequent/core/helpers/secret.rb', line 60

def deserialize_from_json(value)
  new(value)
end

.encrypt_secret(clear_text_secret) ⇒ Object

Creates a hash for the given clear text password.



67
68
69
70
# File 'lib/sequent/core/helpers/secret.rb', line 67

def encrypt_secret(clear_text_secret)
  fail ArgumentError.new('clear_text_secret can not be blank') if clear_text_secret.blank?
  BCrypt::Password.create(clear_text_secret)
end

.re_encrypt_secret(clear_text_secret, hashed_secret) ⇒ Object

Creates a hash for the given clear text secret using the given hashed secret as a salt (essentially re-creating the secret hash).



76
77
78
79
80
81
# File 'lib/sequent/core/helpers/secret.rb', line 76

def re_encrypt_secret(clear_text_secret, hashed_secret)
  fail ArgumentError.new('clear_text_secret can not be blank') if clear_text_secret.blank?
  fail ArgumentError.new('hashed_secret can not be blank') if hashed_secret.blank?

  BCrypt::Engine.hash_secret(clear_text_secret, hashed_secret)
end

.verify_secret(hashed_secret, clear_text_secret) ⇒ Object

Verifies that the hashed and clear text secret are equal.



86
87
88
89
90
# File 'lib/sequent/core/helpers/secret.rb', line 86

def verify_secret(hashed_secret, clear_text_secret)
  return false if (hashed_secret.blank? || clear_text_secret.blank?)

  BCrypt::Password.new(hashed_secret) == clear_text_secret
end

Instance Method Details

#==(other) ⇒ Object



113
114
115
116
117
# File 'lib/sequent/core/helpers/secret.rb', line 113

def ==(other)
  return false unless other&.class == Secret

  other.value == @value
end

#encryptObject



104
105
106
107
# File 'lib/sequent/core/helpers/secret.rb', line 104

def encrypt
  @value = self.class.encrypt_secret(@value)
  self
end

#verify_secret(clear_text_secret) ⇒ Object



109
110
111
# File 'lib/sequent/core/helpers/secret.rb', line 109

def verify_secret(clear_text_secret)
  self.class.verify_secret(@value, clear_text_secret)
end