maleo-foundation 0.1.76__py3-none-any.whl → 0.1.78__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- maleo_foundation/authentication.py +3 -3
- maleo_foundation/client/manager.py +3 -0
- maleo_foundation/client/services/__init__.py +2 -0
- maleo_foundation/client/services/encryption/aes.py +11 -11
- maleo_foundation/client/services/encryption/rsa.py +16 -16
- maleo_foundation/client/services/hash/bcrypt.py +12 -12
- maleo_foundation/client/services/hash/hmac.py +12 -12
- maleo_foundation/client/services/hash/sha256.py +12 -12
- maleo_foundation/client/services/key.py +113 -0
- maleo_foundation/client/services/signature.py +16 -16
- maleo_foundation/client/services/token.py +18 -18
- maleo_foundation/expanded_types/encryption/__init__.py +4 -4
- maleo_foundation/expanded_types/encryption/aes.py +6 -6
- maleo_foundation/expanded_types/encryption/rsa.py +6 -6
- maleo_foundation/expanded_types/hash.py +6 -6
- maleo_foundation/expanded_types/key.py +18 -0
- maleo_foundation/expanded_types/signature.py +6 -6
- maleo_foundation/expanded_types/token.py +6 -6
- maleo_foundation/managers/service.py +4 -4
- maleo_foundation/middlewares/authentication.py +2 -2
- maleo_foundation/middlewares/base.py +2 -2
- maleo_foundation/models/schemas/encryption.py +1 -1
- maleo_foundation/models/schemas/hash.py +1 -1
- maleo_foundation/models/schemas/key.py +15 -0
- maleo_foundation/models/schemas/signature.py +1 -1
- maleo_foundation/models/schemas/token.py +1 -1
- maleo_foundation/models/transfers/general/__init__.py +2 -2
- maleo_foundation/models/transfers/general/key.py +15 -0
- maleo_foundation/models/transfers/general/signature.py +3 -3
- maleo_foundation/models/transfers/general/token.py +3 -3
- maleo_foundation/models/transfers/parameters/encryption/__init__.py +4 -4
- maleo_foundation/models/transfers/parameters/encryption/aes.py +7 -7
- maleo_foundation/models/transfers/parameters/encryption/rsa.py +6 -6
- maleo_foundation/models/transfers/parameters/hash/__init__.py +6 -6
- maleo_foundation/models/transfers/parameters/hash/bcrypt.py +5 -5
- maleo_foundation/models/transfers/parameters/hash/hmac.py +7 -7
- maleo_foundation/models/transfers/parameters/hash/sha256.py +5 -5
- maleo_foundation/models/transfers/parameters/key.py +13 -0
- maleo_foundation/models/transfers/parameters/signature.py +8 -8
- maleo_foundation/models/transfers/parameters/token.py +8 -8
- maleo_foundation/models/transfers/results/encryption/__init__.py +4 -4
- maleo_foundation/models/transfers/results/encryption/aes.py +6 -6
- maleo_foundation/models/transfers/results/encryption/rsa.py +4 -4
- maleo_foundation/models/transfers/results/hash.py +4 -4
- maleo_foundation/models/transfers/results/key.py +16 -0
- maleo_foundation/models/transfers/results/signature.py +4 -4
- maleo_foundation/models/transfers/results/token.py +5 -5
- {maleo_foundation-0.1.76.dist-info → maleo_foundation-0.1.78.dist-info}/METADATA +1 -1
- {maleo_foundation-0.1.76.dist-info → maleo_foundation-0.1.78.dist-info}/RECORD +51 -45
- {maleo_foundation-0.1.76.dist-info → maleo_foundation-0.1.78.dist-info}/WHEEL +0 -0
- {maleo_foundation-0.1.76.dist-info → maleo_foundation-0.1.78.dist-info}/top_level.txt +0 -0
@@ -1,14 +1,14 @@
|
|
1
1
|
from pydantic import BaseModel, Field
|
2
2
|
from starlette.authentication import AuthCredentials, BaseUser
|
3
3
|
from typing import Optional, Sequence
|
4
|
-
from maleo_foundation.models.transfers.general.token import
|
4
|
+
from maleo_foundation.models.transfers.general.token import MaleoFoundationTokenGeneralTransfers
|
5
5
|
from maleo_foundation.types import BaseTypes
|
6
6
|
|
7
7
|
class Credentials(AuthCredentials):
|
8
8
|
def __init__(
|
9
9
|
self,
|
10
10
|
token:BaseTypes.OptionalString = None,
|
11
|
-
payload:Optional[
|
11
|
+
payload:Optional[MaleoFoundationTokenGeneralTransfers.DecodePayload] = None,
|
12
12
|
scopes:Optional[Sequence[str]] = None
|
13
13
|
) -> None:
|
14
14
|
self._token = token
|
@@ -20,7 +20,7 @@ class Credentials(AuthCredentials):
|
|
20
20
|
return self._token
|
21
21
|
|
22
22
|
@property
|
23
|
-
def payload(self) -> Optional[
|
23
|
+
def payload(self) -> Optional[MaleoFoundationTokenGeneralTransfers.DecodePayload]:
|
24
24
|
return self._payload
|
25
25
|
|
26
26
|
class User(BaseUser):
|
@@ -14,6 +14,7 @@ from maleo_foundation.client.services.hash import (
|
|
14
14
|
from maleo_foundation.client.services import (
|
15
15
|
MaleoFoundationEncryptionServices,
|
16
16
|
MaleoFoundationHashServices,
|
17
|
+
MaleoFoundationKeyClientService,
|
17
18
|
MaleoFoundationSignatureClientService,
|
18
19
|
MaleoFoundationTokenClientService,
|
19
20
|
MaleoFoundationServices
|
@@ -35,6 +36,7 @@ class MaleoFoundationClientManager(ClientManager):
|
|
35
36
|
aes=aes_encryption_service,
|
36
37
|
rsa=rsa_encryption_service
|
37
38
|
)
|
39
|
+
key_service = MaleoFoundationKeyClientService(logger=self._logger)
|
38
40
|
bcrypt_hash_service = MaleoFoundationBcryptHashClientService(logger=self._logger)
|
39
41
|
hmac_hash_service = MaleoFoundationHMACHashClientService(logger=self._logger)
|
40
42
|
sha256_hash_service = MaleoFoundationSHA256HashClientService(logger=self._logger)
|
@@ -48,6 +50,7 @@ class MaleoFoundationClientManager(ClientManager):
|
|
48
50
|
self._services = MaleoFoundationServices(
|
49
51
|
encryption=encryption_services,
|
50
52
|
hash=hash_services,
|
53
|
+
key=key_service,
|
51
54
|
signature=signature_service,
|
52
55
|
token=token_service
|
53
56
|
)
|
@@ -3,11 +3,13 @@ from pydantic import Field
|
|
3
3
|
from maleo_foundation.managers.client.base import ClientServices
|
4
4
|
from maleo_foundation.client.services.encryption import MaleoFoundationEncryptionServices
|
5
5
|
from maleo_foundation.client.services.hash import MaleoFoundationHashServices
|
6
|
+
from maleo_foundation.client.services.key import MaleoFoundationKeyClientService
|
6
7
|
from maleo_foundation.client.services.signature import MaleoFoundationSignatureClientService
|
7
8
|
from maleo_foundation.client.services.token import MaleoFoundationTokenClientService
|
8
9
|
|
9
10
|
class MaleoFoundationServices(ClientServices):
|
10
11
|
encryption:MaleoFoundationEncryptionServices = Field(..., description="Encryption's services")
|
11
12
|
hash:MaleoFoundationHashServices = Field(..., description="Hash's services")
|
13
|
+
key:MaleoFoundationKeyClientService = Field(..., description="Key's service")
|
12
14
|
signature:MaleoFoundationSignatureClientService = Field(..., description="Signature's service")
|
13
15
|
token:MaleoFoundationTokenClientService = Field(..., description="Token's service")
|
@@ -2,20 +2,20 @@ import os
|
|
2
2
|
from base64 import b64decode, b64encode
|
3
3
|
from cryptography.hazmat.backends import default_backend
|
4
4
|
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
5
|
-
from maleo_foundation.expanded_types.encryption.aes import
|
5
|
+
from maleo_foundation.expanded_types.encryption.aes import MaleoFoundationAESEncryptionResultsTypes
|
6
6
|
from maleo_foundation.managers.client.base import ClientService
|
7
|
-
from maleo_foundation.models.schemas.encryption import
|
8
|
-
from maleo_foundation.models.transfers.parameters.encryption.aes import
|
9
|
-
from maleo_foundation.models.transfers.results.encryption.aes import EncryptData,
|
7
|
+
from maleo_foundation.models.schemas.encryption import MaleoFoundationEncryptionSchemas
|
8
|
+
from maleo_foundation.models.transfers.parameters.encryption.aes import MaleoFoundationAESEncryptionParametersTransfers
|
9
|
+
from maleo_foundation.models.transfers.results.encryption.aes import EncryptData, MaleoFoundationAESEncryptionResultsTransfers
|
10
10
|
from maleo_foundation.utils.exceptions import BaseExceptions
|
11
11
|
|
12
12
|
class MaleoFoundationAESEncryptionClientService(ClientService):
|
13
|
-
def encrypt(self, parameters:
|
13
|
+
def encrypt(self, parameters:MaleoFoundationAESEncryptionParametersTransfers.Encrypt) -> MaleoFoundationAESEncryptionResultsTypes.Hash:
|
14
14
|
"""Encrypt a plaintext using AES algorithm."""
|
15
15
|
@BaseExceptions.service_exception_handler(
|
16
16
|
operation="encrypting plaintext",
|
17
17
|
logger=self._logger,
|
18
|
-
fail_result_class=
|
18
|
+
fail_result_class=MaleoFoundationAESEncryptionResultsTransfers.Fail
|
19
19
|
)
|
20
20
|
def _impl():
|
21
21
|
#* Define random key and initialization vector bytes
|
@@ -30,15 +30,15 @@ class MaleoFoundationAESEncryptionClientService(ClientService):
|
|
30
30
|
initialization_vector = b64encode(initialization_vector_bytes).decode('utf-8')
|
31
31
|
data = EncryptData(key=key, initialization_vector=initialization_vector, ciphertext=ciphertext)
|
32
32
|
self._logger.info("Plaintext successfully encrypted")
|
33
|
-
return
|
33
|
+
return MaleoFoundationAESEncryptionResultsTransfers.Encrypt(data=data)
|
34
34
|
return _impl()
|
35
35
|
|
36
|
-
def decrypt(self, parameters:
|
36
|
+
def decrypt(self, parameters:MaleoFoundationAESEncryptionParametersTransfers.Decrypt) -> MaleoFoundationAESEncryptionResultsTypes.Decrypt:
|
37
37
|
"""Decrypt a ciphertext using AES algorithm."""
|
38
38
|
@BaseExceptions.service_exception_handler(
|
39
39
|
operation="verify single encryption",
|
40
40
|
logger=self._logger,
|
41
|
-
fail_result_class=
|
41
|
+
fail_result_class=MaleoFoundationAESEncryptionResultsTransfers.Fail
|
42
42
|
)
|
43
43
|
def _impl():
|
44
44
|
#* Decode base64-encoded AES key, IV, and encrypted message
|
@@ -48,7 +48,7 @@ class MaleoFoundationAESEncryptionClientService(ClientService):
|
|
48
48
|
cipher = Cipher(algorithms.AES(key_bytes), modes.CFB(initialization_vector_bytes), backend=default_backend())
|
49
49
|
decryptor = cipher.decryptor()
|
50
50
|
plaintext = decryptor.update(b64decode(parameters.ciphertext)) + decryptor.finalize()
|
51
|
-
data =
|
51
|
+
data = MaleoFoundationEncryptionSchemas.Plaintext(plaintext=plaintext)
|
52
52
|
self._logger.info("Ciphertext successfully decrypted")
|
53
|
-
return
|
53
|
+
return MaleoFoundationAESEncryptionResultsTransfers.Decrypt(data=data)
|
54
54
|
return _impl()
|
@@ -2,21 +2,21 @@ from base64 import b64decode, b64encode
|
|
2
2
|
from Crypto.Cipher import PKCS1_OAEP
|
3
3
|
from Crypto.Hash import SHA256
|
4
4
|
from maleo_foundation.enums import BaseEnums
|
5
|
-
from maleo_foundation.expanded_types.encryption.rsa import
|
5
|
+
from maleo_foundation.expanded_types.encryption.rsa import MaleoFoundationRSAEncryptionResultsTypes
|
6
6
|
from maleo_foundation.managers.client.base import ClientService
|
7
|
-
from maleo_foundation.models.schemas.encryption import
|
8
|
-
from maleo_foundation.models.transfers.parameters.encryption.rsa import
|
9
|
-
from maleo_foundation.models.transfers.results.encryption.rsa import
|
7
|
+
from maleo_foundation.models.schemas.encryption import MaleoFoundationEncryptionSchemas
|
8
|
+
from maleo_foundation.models.transfers.parameters.encryption.rsa import MaleoFoundationRSAEncryptionParametersTransfers
|
9
|
+
from maleo_foundation.models.transfers.results.encryption.rsa import MaleoFoundationRSAEncryptionResultsTransfers
|
10
10
|
from maleo_foundation.utils.exceptions import BaseExceptions
|
11
11
|
from maleo_foundation.utils.loaders.key.rsa import RSAKeyLoader
|
12
12
|
|
13
13
|
class MaleoFoundationRSAEncryptionClientService(ClientService):
|
14
|
-
def encrypt(self, parameters:
|
14
|
+
def encrypt(self, parameters:MaleoFoundationRSAEncryptionParametersTransfers.Encrypt) -> MaleoFoundationRSAEncryptionResultsTypes.Hash:
|
15
15
|
"""Encrypt a plaintext using RSA algorithm."""
|
16
16
|
@BaseExceptions.service_exception_handler(
|
17
17
|
operation="encrypting plaintext",
|
18
18
|
logger=self._logger,
|
19
|
-
fail_result_class=
|
19
|
+
fail_result_class=MaleoFoundationRSAEncryptionResultsTransfers.Fail
|
20
20
|
)
|
21
21
|
def _impl():
|
22
22
|
try:
|
@@ -25,26 +25,26 @@ class MaleoFoundationRSAEncryptionClientService(ClientService):
|
|
25
25
|
message = "Invalid key type"
|
26
26
|
description = "A public key must be used for encrypting a plaintext"
|
27
27
|
other = "Ensure the given key is of type public key"
|
28
|
-
return
|
28
|
+
return MaleoFoundationRSAEncryptionResultsTransfers.Fail(message=message, description=description, other=other)
|
29
29
|
except Exception as e:
|
30
30
|
self._logger.error("Unexpected error occured while trying to import key:\n'%s'", str(e), exc_info=True)
|
31
31
|
message = "Invalid key"
|
32
32
|
description = "Unexpected error occured while trying to import key"
|
33
33
|
other = "Ensure given key is valid"
|
34
|
-
return
|
34
|
+
return MaleoFoundationRSAEncryptionResultsTransfers.Fail(message=message, description=description, other=other)
|
35
35
|
cipher = PKCS1_OAEP.new(public_key, hashAlgo=SHA256) #* Initialize cipher with OAEP padding and SHA-256
|
36
36
|
ciphertext = b64encode(cipher.encrypt(parameters.plaintext.encode('utf-8'))).decode('utf-8') #* Encrypt the plaintext and return as base64-encoded string
|
37
|
-
data =
|
37
|
+
data = MaleoFoundationEncryptionSchemas.Ciphertext(ciphertext=ciphertext)
|
38
38
|
self._logger.info("Plaintext successfully encrypted")
|
39
|
-
return
|
39
|
+
return MaleoFoundationRSAEncryptionResultsTransfers.Encrypt(data=data)
|
40
40
|
return _impl()
|
41
41
|
|
42
|
-
def decrypt(self, parameters:
|
42
|
+
def decrypt(self, parameters:MaleoFoundationRSAEncryptionParametersTransfers.Decrypt) -> MaleoFoundationRSAEncryptionResultsTypes.Decrypt:
|
43
43
|
"""Decrypt a ciphertext using RSA algorithm."""
|
44
44
|
@BaseExceptions.service_exception_handler(
|
45
45
|
operation="verify single encryption",
|
46
46
|
logger=self._logger,
|
47
|
-
fail_result_class=
|
47
|
+
fail_result_class=MaleoFoundationRSAEncryptionResultsTransfers.Fail
|
48
48
|
)
|
49
49
|
def _impl():
|
50
50
|
try:
|
@@ -53,16 +53,16 @@ class MaleoFoundationRSAEncryptionClientService(ClientService):
|
|
53
53
|
message = "Invalid key type"
|
54
54
|
description = "A private key must be used for decrypting a ciphertext"
|
55
55
|
other = "Ensure the given key is of type private key"
|
56
|
-
return
|
56
|
+
return MaleoFoundationRSAEncryptionResultsTransfers.Fail(message=message, description=description, other=other)
|
57
57
|
except Exception as e:
|
58
58
|
self._logger.error("Unexpected error occured while trying to import key:\n'%s'", str(e), exc_info=True)
|
59
59
|
message = "Invalid key"
|
60
60
|
description = "Unexpected error occured while trying to import key"
|
61
61
|
other = "Ensure given key is valid"
|
62
|
-
return
|
62
|
+
return MaleoFoundationRSAEncryptionResultsTransfers.Fail(message=message, description=description, other=other)
|
63
63
|
cipher = PKCS1_OAEP.new(private_key, hashAlgo=SHA256) #* Initialize cipher with OAEP padding and SHA-256
|
64
64
|
plaintext = cipher.decrypt(b64decode(parameters.ciphertext)) #* Decode the base64-encoded ciphertext and then decrypt
|
65
|
-
data =
|
65
|
+
data = MaleoFoundationEncryptionSchemas.Plaintext(plaintext=plaintext)
|
66
66
|
self._logger.info("Ciphertext successfully decrypted")
|
67
|
-
return
|
67
|
+
return MaleoFoundationRSAEncryptionResultsTransfers.Decrypt(data=data)
|
68
68
|
return _impl()
|
@@ -1,37 +1,37 @@
|
|
1
1
|
import bcrypt
|
2
|
-
from maleo_foundation.expanded_types.hash import
|
2
|
+
from maleo_foundation.expanded_types.hash import MaleoFoundationHashResultsTypes
|
3
3
|
from maleo_foundation.managers.client.base import ClientService
|
4
|
-
from maleo_foundation.models.schemas.hash import
|
5
|
-
from maleo_foundation.models.transfers.parameters.hash.bcrypt import
|
6
|
-
from maleo_foundation.models.transfers.results.hash import
|
4
|
+
from maleo_foundation.models.schemas.hash import MaleoFoundationHashSchemas
|
5
|
+
from maleo_foundation.models.transfers.parameters.hash.bcrypt import MaleoFoundationBcryptHashParametersTransfers
|
6
|
+
from maleo_foundation.models.transfers.results.hash import MaleoFoundationHashResultsTransfers
|
7
7
|
from maleo_foundation.utils.exceptions import BaseExceptions
|
8
8
|
|
9
9
|
class MaleoFoundationBcryptHashClientService(ClientService):
|
10
|
-
def hash(self, parameters:
|
10
|
+
def hash(self, parameters:MaleoFoundationBcryptHashParametersTransfers.Hash) -> MaleoFoundationHashResultsTypes.Hash:
|
11
11
|
"""Generate a bcrypt hash for the given message."""
|
12
12
|
@BaseExceptions.service_exception_handler(
|
13
13
|
operation="hashing single message",
|
14
14
|
logger=self._logger,
|
15
|
-
fail_result_class=
|
15
|
+
fail_result_class=MaleoFoundationHashResultsTransfers.Fail
|
16
16
|
)
|
17
17
|
def _impl():
|
18
18
|
salt = bcrypt.gensalt()
|
19
19
|
hash = bcrypt.hashpw(parameters.message.encode(), salt).decode()
|
20
|
-
data =
|
20
|
+
data = MaleoFoundationHashSchemas.Hash(hash=hash)
|
21
21
|
self._logger.info("Message successfully hashed")
|
22
|
-
return
|
22
|
+
return MaleoFoundationHashResultsTransfers.Hash(data=data)
|
23
23
|
return _impl()
|
24
24
|
|
25
|
-
def verify(self, parameters:
|
25
|
+
def verify(self, parameters:MaleoFoundationBcryptHashParametersTransfers.Verify) -> MaleoFoundationHashResultsTypes.Verify:
|
26
26
|
"""Verify a message against the given message hash."""
|
27
27
|
@BaseExceptions.service_exception_handler(
|
28
28
|
operation="verify single hash",
|
29
29
|
logger=self._logger,
|
30
|
-
fail_result_class=
|
30
|
+
fail_result_class=MaleoFoundationHashResultsTransfers.Fail
|
31
31
|
)
|
32
32
|
def _impl():
|
33
33
|
is_valid = bcrypt.checkpw(parameters.message.encode(), parameters.hash.encode())
|
34
|
-
data =
|
34
|
+
data = MaleoFoundationHashSchemas.IsValid(is_valid=is_valid)
|
35
35
|
self._logger.info("Hash successfully verified")
|
36
|
-
return
|
36
|
+
return MaleoFoundationHashResultsTransfers.Verify(data=data)
|
37
37
|
return _impl()
|
@@ -1,37 +1,37 @@
|
|
1
1
|
from Crypto.Hash import HMAC, SHA256
|
2
|
-
from maleo_foundation.expanded_types.hash import
|
2
|
+
from maleo_foundation.expanded_types.hash import MaleoFoundationHashResultsTypes
|
3
3
|
from maleo_foundation.managers.client.base import ClientService
|
4
|
-
from maleo_foundation.models.schemas.hash import
|
5
|
-
from maleo_foundation.models.transfers.parameters.hash.hmac import
|
6
|
-
from maleo_foundation.models.transfers.results.hash import
|
4
|
+
from maleo_foundation.models.schemas.hash import MaleoFoundationHashSchemas
|
5
|
+
from maleo_foundation.models.transfers.parameters.hash.hmac import MaleoFoundationHMACHashParametersTransfers
|
6
|
+
from maleo_foundation.models.transfers.results.hash import MaleoFoundationHashResultsTransfers
|
7
7
|
from maleo_foundation.utils.exceptions import BaseExceptions
|
8
8
|
|
9
9
|
class MaleoFoundationHMACHashClientService(ClientService):
|
10
|
-
def hash(self, parameters:
|
10
|
+
def hash(self, parameters:MaleoFoundationHMACHashParametersTransfers.Hash) -> MaleoFoundationHashResultsTypes.Hash:
|
11
11
|
"""Generate a hmac hash for the given message."""
|
12
12
|
@BaseExceptions.service_exception_handler(
|
13
13
|
operation="hashing single message",
|
14
14
|
logger=self._logger,
|
15
|
-
fail_result_class=
|
15
|
+
fail_result_class=MaleoFoundationHashResultsTransfers.Fail
|
16
16
|
)
|
17
17
|
def _impl():
|
18
18
|
hash = HMAC.new(parameters.key.encode(), parameters.message.encode(), SHA256).hexdigest()
|
19
|
-
data =
|
19
|
+
data = MaleoFoundationHashSchemas.Hash(hash=hash)
|
20
20
|
self._logger.info("Message successfully hashed")
|
21
|
-
return
|
21
|
+
return MaleoFoundationHashResultsTransfers.Hash(data=data)
|
22
22
|
return _impl()
|
23
23
|
|
24
|
-
def verify(self, parameters:
|
24
|
+
def verify(self, parameters:MaleoFoundationHMACHashParametersTransfers.Verify) -> MaleoFoundationHashResultsTypes.Verify:
|
25
25
|
"""Verify a message against the given message hash."""
|
26
26
|
@BaseExceptions.service_exception_handler(
|
27
27
|
operation="verify single hash",
|
28
28
|
logger=self._logger,
|
29
|
-
fail_result_class=
|
29
|
+
fail_result_class=MaleoFoundationHashResultsTransfers.Fail
|
30
30
|
)
|
31
31
|
def _impl():
|
32
32
|
computed_hash = HMAC.new(parameters.key.encode(), parameters.message.encode(), SHA256).hexdigest()
|
33
33
|
is_valid = computed_hash == parameters.hash
|
34
|
-
data =
|
34
|
+
data = MaleoFoundationHashSchemas.IsValid(is_valid=is_valid)
|
35
35
|
self._logger.info("Hash successfully verified")
|
36
|
-
return
|
36
|
+
return MaleoFoundationHashResultsTransfers.Verify(data=data)
|
37
37
|
return _impl()
|
@@ -1,37 +1,37 @@
|
|
1
1
|
from Crypto.Hash import SHA256
|
2
|
-
from maleo_foundation.expanded_types.hash import
|
2
|
+
from maleo_foundation.expanded_types.hash import MaleoFoundationHashResultsTypes
|
3
3
|
from maleo_foundation.managers.client.base import ClientService
|
4
|
-
from maleo_foundation.models.schemas.hash import
|
5
|
-
from maleo_foundation.models.transfers.parameters.hash.sha256 import
|
6
|
-
from maleo_foundation.models.transfers.results.hash import
|
4
|
+
from maleo_foundation.models.schemas.hash import MaleoFoundationHashSchemas
|
5
|
+
from maleo_foundation.models.transfers.parameters.hash.sha256 import MaleoFoundationSHA256HashParametersTransfers
|
6
|
+
from maleo_foundation.models.transfers.results.hash import MaleoFoundationHashResultsTransfers
|
7
7
|
from maleo_foundation.utils.exceptions import BaseExceptions
|
8
8
|
|
9
9
|
class MaleoFoundationSHA256HashClientService(ClientService):
|
10
|
-
def hash(self, parameters:
|
10
|
+
def hash(self, parameters:MaleoFoundationSHA256HashParametersTransfers.Hash) -> MaleoFoundationHashResultsTypes.Hash:
|
11
11
|
"""Generate a sha256 hash for the given message."""
|
12
12
|
@BaseExceptions.service_exception_handler(
|
13
13
|
operation="hashing single message",
|
14
14
|
logger=self._logger,
|
15
|
-
fail_result_class=
|
15
|
+
fail_result_class=MaleoFoundationHashResultsTransfers.Fail
|
16
16
|
)
|
17
17
|
def _impl():
|
18
18
|
hash = SHA256.new(parameters.message.encode()).hexdigest()
|
19
|
-
data =
|
19
|
+
data = MaleoFoundationHashSchemas.Hash(hash=hash)
|
20
20
|
self._logger.info("Message successfully hashed")
|
21
|
-
return
|
21
|
+
return MaleoFoundationHashResultsTransfers.Hash(data=data)
|
22
22
|
return _impl()
|
23
23
|
|
24
|
-
def verify(self, parameters:
|
24
|
+
def verify(self, parameters:MaleoFoundationSHA256HashParametersTransfers.Verify) -> MaleoFoundationHashResultsTypes.Verify:
|
25
25
|
"""Verify a message against the given message hash."""
|
26
26
|
@BaseExceptions.service_exception_handler(
|
27
27
|
operation="verify single hash",
|
28
28
|
logger=self._logger,
|
29
|
-
fail_result_class=
|
29
|
+
fail_result_class=MaleoFoundationHashResultsTransfers.Fail
|
30
30
|
)
|
31
31
|
def _impl():
|
32
32
|
computed_hash = SHA256.new(parameters.message.encode()).hexdigest()
|
33
33
|
is_valid = computed_hash == parameters.hash
|
34
|
-
data =
|
34
|
+
data = MaleoFoundationHashSchemas.IsValid(is_valid=is_valid)
|
35
35
|
self._logger.info("Hash successfully verified")
|
36
|
-
return
|
36
|
+
return MaleoFoundationHashResultsTransfers.Verify(data=data)
|
37
37
|
return _impl()
|
@@ -0,0 +1,113 @@
|
|
1
|
+
from cryptography.hazmat.backends import default_backend
|
2
|
+
from cryptography.hazmat.primitives.asymmetric import rsa
|
3
|
+
from cryptography.hazmat.primitives import serialization
|
4
|
+
from maleo_foundation.expanded_types.key import MaleoFoundationKeyResultsTypes
|
5
|
+
from maleo_foundation.managers.client.base import ClientService
|
6
|
+
from maleo_foundation.models.transfers.general.key import MaleoFoundationKeyGeneralTransfers
|
7
|
+
from maleo_foundation.models.transfers.parameters.key import MaleoFoundationKeyParametersTransfers
|
8
|
+
from maleo_foundation.models.transfers.results.key import MaleoFoundationKeyResultsTransfers
|
9
|
+
from maleo_foundation.utils.exceptions import BaseExceptions
|
10
|
+
|
11
|
+
class MaleoFoundationKeyClientService(ClientService):
|
12
|
+
def create_private(self, parameters:MaleoFoundationKeyParametersTransfers.CreatePrivateOrPair) -> MaleoFoundationKeyResultsTypes.CreatePrivate:
|
13
|
+
"""Create an RSA private key with X.509 encoding in .pem format."""
|
14
|
+
@BaseExceptions.service_exception_handler(
|
15
|
+
operation="creating private key",
|
16
|
+
logger=self._logger,
|
17
|
+
fail_result_class=MaleoFoundationKeyResultsTransfers.Fail
|
18
|
+
)
|
19
|
+
def _impl():
|
20
|
+
#* Create private key
|
21
|
+
private_key = rsa.generate_private_key(
|
22
|
+
public_exponent=65537,
|
23
|
+
key_size=parameters.key_size,
|
24
|
+
backend=default_backend()
|
25
|
+
)
|
26
|
+
|
27
|
+
if parameters.password is None:
|
28
|
+
encryption_algorithm = serialization.NoEncryption()
|
29
|
+
else:
|
30
|
+
encryption_algorithm = serialization.BestAvailableEncryption(parameters.password.encode())
|
31
|
+
|
32
|
+
#* Serialize private key to PEM format
|
33
|
+
private_key_bytes = private_key.private_bytes(
|
34
|
+
encoding=serialization.Encoding.PEM,
|
35
|
+
format=serialization.PrivateFormat.PKCS8,
|
36
|
+
encryption_algorithm=encryption_algorithm
|
37
|
+
)
|
38
|
+
|
39
|
+
self._logger.info("Successfully created private key")
|
40
|
+
data = MaleoFoundationKeyGeneralTransfers.PrivateKey(value=private_key_bytes.decode())
|
41
|
+
return MaleoFoundationKeyResultsTransfers.CreatePrivate(data=data)
|
42
|
+
return _impl()
|
43
|
+
|
44
|
+
def create_public(self, parameters:MaleoFoundationKeyParametersTransfers.CreatePublic) -> MaleoFoundationKeyResultsTypes.CreatePublic:
|
45
|
+
"""Create an RSA public key with X.509 encoding in .pem format."""
|
46
|
+
@BaseExceptions.service_exception_handler(
|
47
|
+
operation="creating public key",
|
48
|
+
logger=self._logger,
|
49
|
+
fail_result_class=MaleoFoundationKeyResultsTransfers.Fail
|
50
|
+
)
|
51
|
+
def _impl():
|
52
|
+
#* Serialize private key
|
53
|
+
private_key_bytes = parameters.value.encode()
|
54
|
+
private_key = serialization.load_pem_private_key(
|
55
|
+
private_key_bytes,
|
56
|
+
password=parameters.password.encode() if parameters.password else None,
|
57
|
+
backend=default_backend()
|
58
|
+
)
|
59
|
+
|
60
|
+
public_key = private_key.public_key() #* Create public key
|
61
|
+
|
62
|
+
#* Serialize public key to PEM format
|
63
|
+
public_key_bytes = public_key.public_bytes(
|
64
|
+
encoding=serialization.Encoding.PEM,
|
65
|
+
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
66
|
+
)
|
67
|
+
|
68
|
+
self._logger.info("Successfully created public key")
|
69
|
+
data = MaleoFoundationKeyGeneralTransfers.PublicKey(value=public_key_bytes.decode())
|
70
|
+
return MaleoFoundationKeyResultsTransfers.CreatePublic(data=data)
|
71
|
+
return _impl()
|
72
|
+
|
73
|
+
def create_pair(self, parameters:MaleoFoundationKeyParametersTransfers.CreatePrivateOrPair) -> MaleoFoundationKeyResultsTypes.CreatePair:
|
74
|
+
"""Create an RSA key pair with X.509 encoding in .pem format."""
|
75
|
+
@BaseExceptions.service_exception_handler(
|
76
|
+
operation="creating key pair",
|
77
|
+
logger=self._logger,
|
78
|
+
fail_result_class=MaleoFoundationKeyResultsTransfers.Fail
|
79
|
+
)
|
80
|
+
def _impl():
|
81
|
+
#* Create private key
|
82
|
+
private_key = rsa.generate_private_key(
|
83
|
+
public_exponent=65537,
|
84
|
+
key_size=parameters.key_size,
|
85
|
+
backend=default_backend()
|
86
|
+
)
|
87
|
+
|
88
|
+
if parameters.password is None:
|
89
|
+
encryption_algorithm = serialization.NoEncryption()
|
90
|
+
else:
|
91
|
+
encryption_algorithm = serialization.BestAvailableEncryption(parameters.password.encode())
|
92
|
+
|
93
|
+
#* Serialize private key to PEM format
|
94
|
+
private_key_bytes = private_key.private_bytes(
|
95
|
+
encoding=serialization.Encoding.PEM,
|
96
|
+
format=serialization.PrivateFormat.PKCS8,
|
97
|
+
encryption_algorithm=encryption_algorithm
|
98
|
+
)
|
99
|
+
private = MaleoFoundationKeyGeneralTransfers.PrivateKey(value=private_key_bytes.decode())
|
100
|
+
|
101
|
+
public_key = private_key.public_key() #* Create public key
|
102
|
+
|
103
|
+
#* Serialize public key to PEM format
|
104
|
+
public_key_bytes = public_key.public_bytes(
|
105
|
+
encoding=serialization.Encoding.PEM,
|
106
|
+
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
107
|
+
)
|
108
|
+
public = MaleoFoundationKeyGeneralTransfers.PublicKey(value=public_key_bytes.decode())
|
109
|
+
|
110
|
+
self._logger.info("Successfully created key pair")
|
111
|
+
data = MaleoFoundationKeyGeneralTransfers.KeyPair(private=private, public=public)
|
112
|
+
return MaleoFoundationKeyResultsTransfers.CreatePair(data=data)
|
113
|
+
return _impl()
|
@@ -2,20 +2,20 @@ from base64 import b64decode, b64encode
|
|
2
2
|
from Crypto.Hash import SHA256
|
3
3
|
from Crypto.Signature import pkcs1_15
|
4
4
|
from maleo_foundation.enums import BaseEnums
|
5
|
-
from maleo_foundation.expanded_types.signature import
|
5
|
+
from maleo_foundation.expanded_types.signature import MaleoFoundationSignatureResultsTypes
|
6
6
|
from maleo_foundation.managers.client.base import ClientService
|
7
|
-
from maleo_foundation.models.schemas.signature import
|
8
|
-
from maleo_foundation.models.transfers.parameters.signature import
|
9
|
-
from maleo_foundation.models.transfers.results.signature import
|
7
|
+
from maleo_foundation.models.schemas.signature import MaleoFoundationSignatureSchemas
|
8
|
+
from maleo_foundation.models.transfers.parameters.signature import MaleoFoundationSignatureParametersTransfers
|
9
|
+
from maleo_foundation.models.transfers.results.signature import MaleoFoundationSignatureResultsTransfers
|
10
10
|
from maleo_foundation.utils.exceptions import BaseExceptions
|
11
11
|
from maleo_foundation.utils.loaders.key.rsa import RSAKeyLoader
|
12
12
|
|
13
13
|
class MaleoFoundationSignatureClientService(ClientService):
|
14
|
-
def sign(self, parameters:
|
14
|
+
def sign(self, parameters:MaleoFoundationSignatureParametersTransfers.Sign) -> MaleoFoundationSignatureResultsTypes.Sign:
|
15
15
|
@BaseExceptions.service_exception_handler(
|
16
16
|
operation="signing single message",
|
17
17
|
logger=self._logger,
|
18
|
-
fail_result_class=
|
18
|
+
fail_result_class=MaleoFoundationSignatureResultsTransfers.Fail
|
19
19
|
)
|
20
20
|
def _impl():
|
21
21
|
try:
|
@@ -24,25 +24,25 @@ class MaleoFoundationSignatureClientService(ClientService):
|
|
24
24
|
message = "Invalid key type"
|
25
25
|
description = "A private key must be used for signing a message"
|
26
26
|
other = "Ensure the given key is of type private key"
|
27
|
-
return
|
27
|
+
return MaleoFoundationSignatureResultsTransfers.Fail(message=message, description=description, other=other)
|
28
28
|
except Exception as e:
|
29
29
|
self._logger.error("Unexpected error occured while trying to import key:\n'%s'", str(e), exc_info=True)
|
30
30
|
message = "Invalid key"
|
31
31
|
description = "Unexpected error occured while trying to import key"
|
32
32
|
other = "Ensure given key is valid"
|
33
|
-
return
|
33
|
+
return MaleoFoundationSignatureResultsTransfers.Fail(message=message, description=description, other=other)
|
34
34
|
hash = SHA256.new(parameters.message.encode()) #* Generate message hash
|
35
35
|
signature = b64encode(pkcs1_15.new(private_key).sign(hash)).decode() #* Sign the hashed message
|
36
|
-
data =
|
36
|
+
data = MaleoFoundationSignatureSchemas.Signature(signature=signature)
|
37
37
|
self._logger.info("Message successfully signed")
|
38
|
-
return
|
38
|
+
return MaleoFoundationSignatureResultsTransfers.Sign(data=data)
|
39
39
|
return _impl()
|
40
40
|
|
41
|
-
def verify(self, parameters:
|
41
|
+
def verify(self, parameters:MaleoFoundationSignatureParametersTransfers.Verify) -> MaleoFoundationSignatureResultsTypes.Verify:
|
42
42
|
@BaseExceptions.service_exception_handler(
|
43
43
|
operation="verify single signature",
|
44
44
|
logger=self._logger,
|
45
|
-
fail_result_class=
|
45
|
+
fail_result_class=MaleoFoundationSignatureResultsTransfers.Fail
|
46
46
|
)
|
47
47
|
def _impl():
|
48
48
|
try:
|
@@ -51,13 +51,13 @@ class MaleoFoundationSignatureClientService(ClientService):
|
|
51
51
|
message = "Invalid key type"
|
52
52
|
description = "A public key must be used for verifying a signature"
|
53
53
|
other = "Ensure the given key is of type public key"
|
54
|
-
return
|
54
|
+
return MaleoFoundationSignatureResultsTransfers.Fail(message=message, description=description, other=other)
|
55
55
|
except Exception as e:
|
56
56
|
self._logger.error("Unexpected error occured while trying to import key:\n'%s'", str(e), exc_info=True)
|
57
57
|
message = "Invalid key"
|
58
58
|
description = "Unexpected error occured while trying to import key"
|
59
59
|
other = "Ensure given key is valid"
|
60
|
-
return
|
60
|
+
return MaleoFoundationSignatureResultsTransfers.Fail(message=message, description=description, other=other)
|
61
61
|
hash = SHA256.new(parameters.message.encode()) #* Generate message hash
|
62
62
|
#* Verify the hashed message and decoded signature
|
63
63
|
try:
|
@@ -65,7 +65,7 @@ class MaleoFoundationSignatureClientService(ClientService):
|
|
65
65
|
is_valid = True
|
66
66
|
except (TypeError, ValueError):
|
67
67
|
is_valid = False
|
68
|
-
data =
|
68
|
+
data = MaleoFoundationSignatureSchemas.IsValid(is_valid=is_valid)
|
69
69
|
self._logger.info("Signature successfully verified")
|
70
|
-
return
|
70
|
+
return MaleoFoundationSignatureResultsTransfers.Verify(data=data)
|
71
71
|
return _impl()
|
@@ -1,20 +1,20 @@
|
|
1
1
|
import jwt
|
2
2
|
from maleo_foundation.enums import BaseEnums
|
3
|
-
from maleo_foundation.expanded_types.token import
|
3
|
+
from maleo_foundation.expanded_types.token import MaleoFoundationTokenResultsTypes
|
4
4
|
from maleo_foundation.managers.client.base import ClientService
|
5
|
-
from maleo_foundation.models.schemas.token import
|
6
|
-
from maleo_foundation.models.transfers.general.token import
|
7
|
-
from maleo_foundation.models.transfers.parameters.token import
|
8
|
-
from maleo_foundation.models.transfers.results.token import
|
5
|
+
from maleo_foundation.models.schemas.token import MaleoFoundationTokenSchemas
|
6
|
+
from maleo_foundation.models.transfers.general.token import MaleoFoundationTokenGeneralTransfers
|
7
|
+
from maleo_foundation.models.transfers.parameters.token import MaleoFoundationTokenParametersTransfers
|
8
|
+
from maleo_foundation.models.transfers.results.token import MaleoFoundationTokenResultsTransfers
|
9
9
|
from maleo_foundation.utils.exceptions import BaseExceptions
|
10
10
|
from maleo_foundation.utils.loaders.key.rsa import RSAKeyLoader
|
11
11
|
|
12
12
|
class MaleoFoundationTokenClientService(ClientService):
|
13
|
-
def encode(self, parameters:
|
13
|
+
def encode(self, parameters:MaleoFoundationTokenParametersTransfers.Encode) -> MaleoFoundationTokenResultsTypes.Encode:
|
14
14
|
@BaseExceptions.service_exception_handler(
|
15
15
|
operation="encoding a payload into a token",
|
16
16
|
logger=self._logger,
|
17
|
-
fail_result_class=
|
17
|
+
fail_result_class=MaleoFoundationTokenResultsTransfers.Fail
|
18
18
|
)
|
19
19
|
def _impl():
|
20
20
|
try:
|
@@ -23,24 +23,24 @@ class MaleoFoundationTokenClientService(ClientService):
|
|
23
23
|
message = "Invalid key type"
|
24
24
|
description = "A private key must be used for payload encoding"
|
25
25
|
other = "Ensure the given key is of type private key"
|
26
|
-
return
|
26
|
+
return MaleoFoundationTokenResultsTransfers.Fail(message=message, description=description, other=other)
|
27
27
|
except Exception as e:
|
28
28
|
self._logger.error("Unexpected error occured while trying to import key:\n'%s'", str(e), exc_info=True)
|
29
29
|
message = "Invalid key"
|
30
30
|
description = "Unexpected error occured while trying to import key"
|
31
31
|
other = "Ensure given key is valid"
|
32
|
-
return
|
33
|
-
payload =
|
32
|
+
return MaleoFoundationTokenResultsTransfers.Fail(message=message, description=description, other=other)
|
33
|
+
payload = MaleoFoundationTokenGeneralTransfers.EncodePayload.model_validate(parameters.payload.model_dump()).model_dump(mode="json")
|
34
34
|
token = jwt.encode(payload=payload, key=private_key.export_key(), algorithm="RS256")
|
35
|
-
data =
|
36
|
-
return
|
35
|
+
data = MaleoFoundationTokenSchemas.Token(token=token)
|
36
|
+
return MaleoFoundationTokenResultsTransfers.Encode(data=data)
|
37
37
|
return _impl()
|
38
38
|
|
39
|
-
def decode(self, parameters:
|
39
|
+
def decode(self, parameters:MaleoFoundationTokenParametersTransfers.Decode) -> MaleoFoundationTokenResultsTypes.Decode:
|
40
40
|
@BaseExceptions.service_exception_handler(
|
41
41
|
operation="decoding a token into a payload",
|
42
42
|
logger=self._logger,
|
43
|
-
fail_result_class=
|
43
|
+
fail_result_class=MaleoFoundationTokenResultsTransfers.Fail
|
44
44
|
)
|
45
45
|
def _impl():
|
46
46
|
try:
|
@@ -49,14 +49,14 @@ class MaleoFoundationTokenClientService(ClientService):
|
|
49
49
|
message = "Invalid key type"
|
50
50
|
description = "A public key must be used for token decoding"
|
51
51
|
other = "Ensure the given key is of type public key"
|
52
|
-
return
|
52
|
+
return MaleoFoundationTokenResultsTransfers.Fail(message=message, description=description, other=other)
|
53
53
|
except Exception as e:
|
54
54
|
self._logger.error("Unexpected error occured while trying to import key:\n'%s'", str(e), exc_info=True)
|
55
55
|
message = "Invalid key"
|
56
56
|
description = "Unexpected error occured while trying to import key"
|
57
57
|
other = "Ensure given key is valid"
|
58
|
-
return
|
58
|
+
return MaleoFoundationTokenResultsTransfers.Fail(message=message, description=description, other=other)
|
59
59
|
payload = jwt.decode(jwt=parameters.token, key=public_key.export_key(), algorithms=["RS256"])
|
60
|
-
data =
|
61
|
-
return
|
60
|
+
data = MaleoFoundationTokenGeneralTransfers.DecodePayload.model_validate(payload)
|
61
|
+
return MaleoFoundationTokenResultsTransfers.Decode(data=data)
|
62
62
|
return _impl()
|