def test_mapper_with_wrong_cipher_key(self): self.env.name = "App1" self.env[self.factory.CIPHER_TOPIC] = get_topic(AESCipher) cipher_key1 = AESCipher.create_key(16) cipher_key2 = AESCipher.create_key(16) self.env["APP1_" + AESCipher.CIPHER_KEY] = cipher_key1 self.env["APP2_" + AESCipher.CIPHER_KEY] = cipher_key2 mapper1: Mapper = self.factory.mapper(transcoder=self.transcoder, ) domain_event = DomainEvent( originator_id=uuid4(), originator_version=1, timestamp=DomainEvent.create_timestamp(), ) stored_event = mapper1.from_domain_event(domain_event) copy = mapper1.to_domain_event(stored_event) self.assertEqual(domain_event.originator_id, copy.originator_id) self.env.name = "App2" mapper2: Mapper = self.factory.mapper(transcoder=self.transcoder, ) # This should fail because the infrastructure factory # should read different cipher keys from the environment. with self.assertRaises(ValueError): mapper2.to_domain_event(stored_event)
def test_encrypt_and_decrypt(self): environment = Environment() key = AESCipher.create_key(16) environment["CIPHER_KEY"] = key # Check plain text can be encrypted and recovered. plain_text = b"some text" cipher = AESCipher(environment) cipher_text = cipher.encrypt(plain_text) cipher = AESCipher(environment) recovered_text = cipher.decrypt(cipher_text) self.assertEqual(recovered_text, plain_text) # Check raises on invalid nonce. with self.assertRaises(ValueError): cipher.decrypt(cipher_text[:10]) # Check raises on invalid tag. with self.assertRaises(ValueError): cipher.decrypt(cipher_text[:20]) # Check raises on invalid data. with self.assertRaises(ValueError): cipher.decrypt(cipher_text[:30]) # Check raises on invalid key. key = AESCipher.create_key(16) environment["CIPHER_KEY"] = key cipher = AESCipher(environment) with self.assertRaises(ValueError): cipher.decrypt(cipher_text)
def test_createmapper_with_cipher_and_compressor(self, ): # Create mapper with cipher and compressor. self.env[self.factory.COMPRESSOR_TOPIC] = get_topic(ZlibCompressor) self.env[self.factory.CIPHER_TOPIC] = get_topic(AESCipher) cipher_key = AESCipher.create_key(16) self.env[AESCipher.CIPHER_KEY] = cipher_key mapper = self.factory.mapper(transcoder=self.transcoder) self.assertIsInstance(mapper, Mapper) self.assertIsNotNone(mapper.cipher) self.assertIsNotNone(mapper.compressor)
def test_createmapper_with_cipher(self): # Check cipher needs a key. os.environ[self.factory.CIPHER_TOPIC] = get_topic(AESCipher) with self.assertRaises(EnvironmentError): self.factory.mapper(transcoder=self.transcoder) cipher_key = AESCipher.create_key(16) os.environ[self.factory.CIPHER_KEY] = cipher_key # Create mapper with cipher. mapper = self.factory.mapper(transcoder=self.transcoder) self.assertIsInstance(mapper, Mapper) self.assertIsNotNone(mapper.cipher) self.assertIsNone(mapper.compressor)
def test(self): # Construct transcoder. transcoder = JSONTranscoder() transcoder.register(UUIDAsHex()) transcoder.register(DecimalAsStr()) transcoder.register(DatetimeAsISO()) # Construct cipher. cipher = AESCipher(cipher_key=AESCipher.create_key(16)) # Construct compressor. compressor = ZlibCompressor() # Construct mapper with cipher. mapper = Mapper(transcoder=transcoder, cipher=cipher) # Create a domain event. domain_event = BankAccount.TransactionAppended( originator_id=uuid4(), originator_version=123456, timestamp=datetime.now(tz=TZINFO), amount=Decimal("10.00"), ) # Map from domain event. stored_event = mapper.from_domain_event(domain_event) # Map to domain event. copy = mapper.to_domain_event(stored_event) # Check values are not visible. assert "Alice" not in str(stored_event.state) # Check decrypted copy has correct values. assert copy.originator_id == domain_event.originator_id assert copy.originator_version == domain_event.originator_version assert copy.timestamp == domain_event.timestamp, copy.timestamp assert copy.originator_version == domain_event.originator_version assert len(stored_event.state) == 171, len(stored_event.state) # Construct mapper with cipher and compressor. mapper = Mapper( transcoder=transcoder, cipher=cipher, compressor=compressor, ) # Map from domain event. stored_event = mapper.from_domain_event(domain_event) # Map to domain event. copy = mapper.to_domain_event(stored_event) # Check decompressed copy has correct values. assert copy.originator_id == domain_event.originator_id assert copy.originator_version == domain_event.originator_version assert len(stored_event.state) in ( 135, 136, 137, 138, 139, 140, 141, 142, 143, ), len(stored_event.state)
def test_createkey(self): environment = Environment() # Valid key lengths. key = AESCipher.create_key(16) environment["CIPHER_KEY"] = key AESCipher(environment) key = AESCipher.create_key(24) environment["CIPHER_KEY"] = key AESCipher(environment) key = AESCipher.create_key(32) environment["CIPHER_KEY"] = key AESCipher(environment) # Non-valid key lengths (on generate key). with self.assertRaises(ValueError): AESCipher.create_key(12) with self.assertRaises(ValueError): AESCipher.create_key(20) with self.assertRaises(ValueError): AESCipher.create_key(28) with self.assertRaises(ValueError): AESCipher.create_key(36) # Non-valid key lengths (on construction). def create_key(num_bytes): return b64encode(AESCipher.random_bytes(num_bytes)).decode("utf8") key = create_key(12) environment["CIPHER_KEY"] = key with self.assertRaises(ValueError): AESCipher(environment) key = create_key(20) environment["CIPHER_KEY"] = key with self.assertRaises(ValueError): AESCipher(environment) key = create_key(28) environment["CIPHER_KEY"] = key with self.assertRaises(ValueError): AESCipher(environment) key = create_key(36) environment["CIPHER_KEY"] = key with self.assertRaises(ValueError): AESCipher(environment)