Class: Yes::Core::Middlewares::Encryptor

Inherits:
Object
  • Object
show all
Includes:
PgEventstore::Middleware
Defined in:
lib/yes/core/middlewares/encryptor.rb

Overview

PgEventstore middleware for encrypting/decrypting event data.

Register it through register_encryptor rather than by hand, so its write-only counterpart (WriteEncryptor) is always registered alongside it.

Examples:

PgEventstore.configure do |config|
  Yes::Core::Middlewares.register_encryptor(key_repository, config:)
end

Direct Known Subclasses

WriteEncryptor

Instance Method Summary collapse

Constructor Details

#initialize(key_repository) ⇒ Encryptor

Returns a new instance of Encryptor.

Parameters:

  • key_repository (#find, #create, #encrypt, #decrypt)


22
23
24
# File 'lib/yes/core/middlewares/encryptor.rb', line 22

def initialize(key_repository)
  @key_repository = key_repository
end

Instance Method Details

#deserialize(event) ⇒ PgEventstore::Event

Parameters:

  • event (PgEventstore::Event)

Returns:

  • (PgEventstore::Event)


47
48
49
50
51
52
# File 'lib/yes/core/middlewares/encryptor.rb', line 47

def deserialize(event)
  decrypted_data =
    DataDecryptor.new(data: event.data, schema: event.['encryption'], repository: key_repository).call
  event.data = decrypted_data
  event
end

#serialize(event) ⇒ PgEventstore::Event

Parameters:

  • event (PgEventstore::Event)

Returns:

  • (PgEventstore::Event)


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/yes/core/middlewares/encryptor.rb', line 28

def serialize(event)
  return event unless event.class.respond_to?(:encryption_schema)
  # Idempotence guard. With {WriteEncryptor} registered, the DEFAULT middleware list holds two
  # serialize-capable encryptors, so an append that omits `middlewares:` would encrypt twice. The
  # second pass would encrypt the sentinels written by the first and overwrite the real ciphertext,
  # which cannot be recovered. It also guards re-appending an event that was read at rest.
  return event if event.data[DataEncryptor::CIPHERTEXT_KEY].present?

  encryptor = DataEncryptor.new(
    data: event.data, schema: event.class.encryption_schema, repository: key_repository
  )
  encryptor.call
  event.data = encryptor.encrypted_data
  event.['encryption'] = encryptor.
  event
end