maleo-foundation 0.1.58__py3-none-any.whl → 0.1.60__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/client/services/__init__.py +2 -0
- maleo_foundation/client/services/signature.py +74 -0
- maleo_foundation/expanded_types/signature.py +13 -0
- maleo_foundation/managers/client/maleo.py +5 -0
- maleo_foundation/middlewares/authentication.py +9 -7
- maleo_foundation/middlewares/base.py +52 -39
- maleo_foundation/models/schemas/signature.py +4 -0
- maleo_foundation/models/transfers/general/signature.py +8 -0
- maleo_foundation/models/transfers/parameters/signature.py +14 -0
- maleo_foundation/models/transfers/results/signature.py +12 -0
- {maleo_foundation-0.1.58.dist-info → maleo_foundation-0.1.60.dist-info}/METADATA +1 -1
- {maleo_foundation-0.1.58.dist-info → maleo_foundation-0.1.60.dist-info}/RECORD +14 -11
- maleo_foundation/services/__init__.py +0 -5
- maleo_foundation/services/token.py +0 -20
- {maleo_foundation-0.1.58.dist-info → maleo_foundation-0.1.60.dist-info}/WHEEL +0 -0
- {maleo_foundation-0.1.58.dist-info → maleo_foundation-0.1.60.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,9 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
from pydantic import Field
|
3
3
|
from maleo_foundation.managers.client.base import ClientServices
|
4
|
+
from maleo_foundation.client.services.signature import MaleoFoundationSignatureClientService
|
4
5
|
from maleo_foundation.client.services.token import MaleoFoundationTokenClientService
|
5
6
|
|
6
7
|
class MaleoFoundationServices(ClientServices):
|
8
|
+
signature:MaleoFoundationSignatureClientService = Field(..., description="Signature's service")
|
7
9
|
token:MaleoFoundationTokenClientService = Field(..., description="Token's service")
|
@@ -0,0 +1,74 @@
|
|
1
|
+
from base64 import b64decode, b64encode
|
2
|
+
from Crypto.PublicKey import RSA
|
3
|
+
from Crypto.Hash import SHA256
|
4
|
+
from Crypto.Signature import pkcs1_15
|
5
|
+
from maleo_foundation.models.schemas.signature import BaseSignatureSchemas
|
6
|
+
from maleo_foundation.models.transfers.parameters.signature import BaseSignatureParametersTransfers
|
7
|
+
from maleo_foundation.models.transfers.results.signature import BaseSignatureResultsTransfers
|
8
|
+
from maleo_foundation.expanded_types.signature import BaseSignatureResultsTypes
|
9
|
+
from maleo_foundation.managers.client.base import ClientService
|
10
|
+
from maleo_foundation.utils.exceptions import BaseExceptions
|
11
|
+
|
12
|
+
class MaleoFoundationSignatureClientService(ClientService):
|
13
|
+
def sign(self, parameters:BaseSignatureParametersTransfers.Sign) -> BaseSignatureResultsTypes.Sign:
|
14
|
+
@BaseExceptions.service_exception_handler(
|
15
|
+
operation="signing single message",
|
16
|
+
logger=self._logger,
|
17
|
+
fail_result_class=BaseSignatureResultsTransfers.Fail
|
18
|
+
)
|
19
|
+
def _impl():
|
20
|
+
try:
|
21
|
+
#* Load RSA key using PyCryptodome's RSA.import_key
|
22
|
+
private_key = RSA.import_key(extern_key=parameters.key, passphrase=parameters.password)
|
23
|
+
#* Validate the key type
|
24
|
+
if not private_key.has_private():
|
25
|
+
message = "Invalid key type"
|
26
|
+
description = "A private key must be used for RSA Verify"
|
27
|
+
other = "Ensure the given key is of type private key"
|
28
|
+
return BaseSignatureResultsTransfers.Fail(message=message, description=description, other=other)
|
29
|
+
except Exception as e:
|
30
|
+
self._logger.error("Unexpected error occured while trying to import key:\n'%s'", str(e), exc_info=True)
|
31
|
+
message = "Invalid key"
|
32
|
+
description = "Unexpected error occured while trying to import key"
|
33
|
+
other = "Ensure given key is valid"
|
34
|
+
return BaseSignatureResultsTransfers.Fail(message=message, description=description, other=other)
|
35
|
+
hash = SHA256.new(parameters.message.encode()) #* Generate message hash
|
36
|
+
signature = b64encode(pkcs1_15.new(private_key).sign(hash)).decode() #* Sign the hashed message
|
37
|
+
data = BaseSignatureSchemas.Signature(signature=signature)
|
38
|
+
self._logger.info("Message successfully signed")
|
39
|
+
return BaseSignatureResultsTransfers.Sign(data=data)
|
40
|
+
return _impl()
|
41
|
+
|
42
|
+
def verify(self, parameters:BaseSignatureParametersTransfers.Verify) -> BaseSignatureResultsTypes.Verify:
|
43
|
+
@BaseExceptions.service_exception_handler(
|
44
|
+
operation="verify single signature",
|
45
|
+
logger=self._logger,
|
46
|
+
fail_result_class=BaseSignatureResultsTransfers.Fail
|
47
|
+
)
|
48
|
+
def _impl():
|
49
|
+
try:
|
50
|
+
#* Load RSA key using PyCryptodome's RSA.import_key
|
51
|
+
public_key = RSA.import_key(parameters.key)
|
52
|
+
#* Validate the key type
|
53
|
+
if public_key.has_private():
|
54
|
+
message = "Invalid key type"
|
55
|
+
description = "A public key must be used for RSA Sign"
|
56
|
+
other = "Ensure the given key is of type public key"
|
57
|
+
return BaseSignatureResultsTransfers.Fail(message=message, description=description, other=other)
|
58
|
+
except Exception as e:
|
59
|
+
self._logger.error("Unexpected error occured while trying to import key:\n'%s'", str(e), exc_info=True)
|
60
|
+
message = "Invalid key"
|
61
|
+
description = "Unexpected error occured while trying to import key"
|
62
|
+
other = "Ensure given key is valid"
|
63
|
+
return BaseSignatureResultsTransfers.Fail(message=message, description=description, other=other)
|
64
|
+
hash = SHA256.new(parameters.message.encode()) #* Generate message hash
|
65
|
+
#* Verify the hashed message and decoded signature
|
66
|
+
try:
|
67
|
+
pkcs1_15.new(public_key).verify(hash, b64decode(parameters.signature))
|
68
|
+
is_valid = True
|
69
|
+
except (TypeError, ValueError):
|
70
|
+
is_valid = False
|
71
|
+
data = BaseSignatureSchemas.IsValid(is_valid=is_valid)
|
72
|
+
self._logger.info("Signature successfully verified")
|
73
|
+
return BaseSignatureResultsTransfers.Verify(data=data)
|
74
|
+
return _impl()
|
@@ -0,0 +1,13 @@
|
|
1
|
+
from typing import Union
|
2
|
+
from maleo_foundation.models.transfers.results.signature import BaseSignatureResultsTransfers
|
3
|
+
|
4
|
+
class BaseSignatureResultsTypes:
|
5
|
+
Sign = Union[
|
6
|
+
BaseSignatureResultsTransfers.Fail,
|
7
|
+
BaseSignatureResultsTransfers.Sign
|
8
|
+
]
|
9
|
+
|
10
|
+
Verify = Union[
|
11
|
+
BaseSignatureResultsTransfers.Fail,
|
12
|
+
BaseSignatureResultsTransfers.Verify
|
13
|
+
]
|
@@ -26,8 +26,13 @@ class MaleoClientManager(ClientManager):
|
|
26
26
|
service_manager:ServiceManager
|
27
27
|
):
|
28
28
|
self._url = url
|
29
|
+
self._service_manager = service_manager
|
29
30
|
super().__init__(key, name, service_manager.log_config, service_manager.configs.service.key)
|
30
31
|
|
32
|
+
@property
|
33
|
+
def service_manager(self) -> ServiceManager:
|
34
|
+
return self._service_manager
|
35
|
+
|
31
36
|
def _initialize_controllers(self) -> None:
|
32
37
|
#* Initialize managers
|
33
38
|
http_controller_manager = ClientHTTPControllerManager(url=self._url)
|
@@ -4,16 +4,18 @@ from starlette.middleware.authentication import AuthenticationMiddleware
|
|
4
4
|
from starlette.requests import HTTPConnection
|
5
5
|
from typing import Tuple
|
6
6
|
from maleo_foundation.authentication import Credentials, User
|
7
|
+
from maleo_foundation.client.manager import MaleoFoundationClientManager
|
8
|
+
from maleo_foundation.managers.service import Keys
|
7
9
|
from maleo_foundation.models.transfers.parameters.token import BaseTokenParametersTransfers
|
8
|
-
from maleo_foundation.services.token import BaseTokenService
|
9
10
|
from maleo_foundation.utils.extractor import BaseExtractors
|
10
11
|
from maleo_foundation.utils.logging import MiddlewareLogger
|
11
12
|
|
12
13
|
class Backend(AuthenticationBackend):
|
13
|
-
def __init__(self, logger:MiddlewareLogger,
|
14
|
+
def __init__(self, logger:MiddlewareLogger, keys:Keys, maleo_foundation:MaleoFoundationClientManager):
|
14
15
|
super().__init__()
|
15
16
|
self._logger = logger
|
16
|
-
self.
|
17
|
+
self._keys = keys
|
18
|
+
self._maleo_foundation = maleo_foundation
|
17
19
|
|
18
20
|
async def authenticate(self, conn:HTTPConnection) -> Tuple[Credentials, User]:
|
19
21
|
client_ip = BaseExtractors.extract_client_ip(conn)
|
@@ -27,8 +29,8 @@ class Backend(AuthenticationBackend):
|
|
27
29
|
self._logger.info(f"Request | IP: {client_ip} | URL: {conn.url.path} - Result | General: Authorization scheme is not Bearer")
|
28
30
|
return Credentials(), User(authenticated=False)
|
29
31
|
|
30
|
-
decode_token_parameters = BaseTokenParametersTransfers.Decode(key=self.
|
31
|
-
decode_token_result =
|
32
|
+
decode_token_parameters = BaseTokenParametersTransfers.Decode(key=self._keys.public, token=token)
|
33
|
+
decode_token_result = self._maleo_foundation.services.token.decode(parameters=decode_token_parameters)
|
32
34
|
if not decode_token_result.success:
|
33
35
|
self._logger.error(f"Request | IP: {client_ip} | URL: {conn.url.path} - Result | General: Failed decoding authorization token")
|
34
36
|
return Credentials(token=token), User(authenticated=False)
|
@@ -36,7 +38,7 @@ class Backend(AuthenticationBackend):
|
|
36
38
|
self._logger.info(f"Request | IP: {client_ip} | URL: {conn.url.path} - Result | Username: {decode_token_result.data.u_u} | Email: {decode_token_result.data.u_e}")
|
37
39
|
return Credentials(token=token), User(authenticated=True, username=decode_token_result.data.u_u, email=decode_token_result.data.u_e)
|
38
40
|
|
39
|
-
def add_authentication_middleware(app:FastAPI, logger:MiddlewareLogger,
|
41
|
+
def add_authentication_middleware(app:FastAPI, logger:MiddlewareLogger, keys:Keys) -> None:
|
40
42
|
"""
|
41
43
|
Adds Authentication middleware to the FastAPI application.
|
42
44
|
|
@@ -62,4 +64,4 @@ def add_authentication_middleware(app:FastAPI, logger:MiddlewareLogger, key:str)
|
|
62
64
|
add_authentication_middleware(app=app, limit=10, window=1, cleanup_interval=60, ip_timeout=300)
|
63
65
|
```
|
64
66
|
"""
|
65
|
-
app.add_middleware(AuthenticationMiddleware, backend=Backend(logger=logger,
|
67
|
+
app.add_middleware(AuthenticationMiddleware, backend=Backend(logger=logger, keys=keys))
|
@@ -8,7 +8,10 @@ from fastapi import FastAPI, Request, Response, status
|
|
8
8
|
from fastapi.responses import JSONResponse
|
9
9
|
from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
|
10
10
|
from typing import Awaitable, Callable, Optional, Sequence
|
11
|
+
from maleo_foundation.client.manager import MaleoFoundationClientManager
|
12
|
+
from maleo_foundation.managers.service import Keys
|
11
13
|
from maleo_foundation.models.responses import BaseResponses
|
14
|
+
from maleo_foundation.models.transfers.parameters.signature import BaseSignatureParametersTransfers
|
12
15
|
from maleo_foundation.utils.extractor import BaseExtractors
|
13
16
|
from maleo_foundation.utils.logging import MiddlewareLogger
|
14
17
|
|
@@ -18,8 +21,10 @@ ResponseProcessor = Callable[[Response], Awaitable[Response]]
|
|
18
21
|
class BaseMiddleware(BaseHTTPMiddleware):
|
19
22
|
def __init__(
|
20
23
|
self,
|
21
|
-
app,
|
24
|
+
app:FastAPI,
|
22
25
|
logger:MiddlewareLogger,
|
26
|
+
keys:Keys,
|
27
|
+
maleo_foundation:MaleoFoundationClientManager,
|
23
28
|
allow_origins:Sequence[str] = (),
|
24
29
|
allow_methods:Sequence[str] = ("GET",),
|
25
30
|
allow_headers:Sequence[str] = (),
|
@@ -27,23 +32,23 @@ class BaseMiddleware(BaseHTTPMiddleware):
|
|
27
32
|
limit:int = 10,
|
28
33
|
window:int = 1,
|
29
34
|
cleanup_interval:int = 60,
|
30
|
-
ip_timeout:int = 300
|
31
|
-
request_processor:Optional[RequestProcessor] = None
|
35
|
+
ip_timeout:int = 300
|
32
36
|
):
|
33
37
|
super().__init__(app)
|
34
|
-
self.
|
35
|
-
self.
|
36
|
-
self.
|
37
|
-
self.
|
38
|
-
self.
|
39
|
-
self.
|
40
|
-
self.
|
41
|
-
self.
|
42
|
-
self.
|
43
|
-
self.
|
44
|
-
self.
|
45
|
-
self.
|
46
|
-
self.
|
38
|
+
self._logger = logger
|
39
|
+
self._keys = keys
|
40
|
+
self._maleo_foundation = maleo_foundation
|
41
|
+
self._allow_origins = allow_origins
|
42
|
+
self._allow_methods = allow_methods
|
43
|
+
self._allow_headers = allow_headers
|
44
|
+
self._allow_credentials = allow_credentials
|
45
|
+
self._limit = limit
|
46
|
+
self._window = timedelta(seconds=window)
|
47
|
+
self._cleanup_interval = timedelta(seconds=cleanup_interval)
|
48
|
+
self._ip_timeout = timedelta(seconds=ip_timeout)
|
49
|
+
self._requests:dict[str, list[datetime]] = defaultdict(list)
|
50
|
+
self._last_seen: dict[str, datetime] = {}
|
51
|
+
self._last_cleanup = datetime.now()
|
47
52
|
self._lock = threading.RLock() #* Use RLock for thread safety
|
48
53
|
|
49
54
|
def _cleanup_old_data(self) -> None:
|
@@ -54,64 +59,72 @@ class BaseMiddleware(BaseHTTPMiddleware):
|
|
54
59
|
2. IPs that haven't been seen in ip_timeout period
|
55
60
|
"""
|
56
61
|
now = datetime.now()
|
57
|
-
if now - self.
|
62
|
+
if now - self._last_cleanup > self._cleanup_interval:
|
58
63
|
with self._lock:
|
59
64
|
#* Remove inactive IPs (not seen recently) and empty lists
|
60
65
|
inactive_ips = []
|
61
|
-
for ip in list(self.
|
66
|
+
for ip in list(self._requests.keys()):
|
62
67
|
#* Remove IPs with empty timestamp lists
|
63
|
-
if not self.
|
68
|
+
if not self._requests[ip]:
|
64
69
|
inactive_ips.append(ip)
|
65
70
|
continue
|
66
71
|
|
67
72
|
#* Remove IPs that haven't been active recently
|
68
|
-
last_active = self.
|
69
|
-
if now - last_active > self.
|
73
|
+
last_active = self._last_seen.get(ip, datetime.min)
|
74
|
+
if now - last_active > self._ip_timeout:
|
70
75
|
inactive_ips.append(ip)
|
71
76
|
|
72
77
|
#* Remove the inactive IPs
|
73
78
|
for ip in inactive_ips:
|
74
|
-
if ip in self.
|
75
|
-
del self.
|
76
|
-
if ip in self.
|
77
|
-
del self.
|
79
|
+
if ip in self._requests:
|
80
|
+
del self._requests[ip]
|
81
|
+
if ip in self._last_seen:
|
82
|
+
del self._last_seen[ip]
|
78
83
|
|
79
84
|
# Update last cleanup time
|
80
|
-
self.
|
81
|
-
self.
|
85
|
+
self._last_cleanup = now
|
86
|
+
self._logger.debug(f"Cleaned up request cache. Removed {len(inactive_ips)} inactive IPs. Current tracked IPs: {len(self._requests)}")
|
82
87
|
|
83
88
|
def _check_rate_limit(self, client_ip:str) -> bool:
|
84
89
|
"""Check if the client has exceeded their rate limit"""
|
85
90
|
with self._lock:
|
86
91
|
now = datetime.now() #* Define current timestamp
|
87
|
-
self.
|
92
|
+
self._last_seen[client_ip] = now #* Update last seen timestamp for this IP
|
88
93
|
|
89
94
|
#* Filter requests within the window
|
90
|
-
self.
|
95
|
+
self._requests[client_ip] = [timestamp for timestamp in self._requests[client_ip] if now - timestamp <= self._window]
|
91
96
|
|
92
97
|
#* Check if the request count exceeds the limit
|
93
|
-
if len(self.
|
98
|
+
if len(self._requests[client_ip]) >= self._limit:
|
94
99
|
return True
|
95
100
|
|
96
101
|
#* Add the current request timestamp
|
97
|
-
self.
|
102
|
+
self._requests[client_ip].append(now)
|
98
103
|
return False
|
99
104
|
|
100
105
|
def _append_cors_headers(self, request:Request, response:Response) -> Response:
|
101
106
|
origin = request.headers.get("Origin")
|
102
107
|
|
103
|
-
if origin in self.
|
108
|
+
if origin in self._allow_origins:
|
104
109
|
response.headers["Access-Control-Allow-Origin"] = origin
|
105
|
-
response.headers["Access-Control-Allow-Methods"] = ", ".join(self.
|
106
|
-
response.headers["Access-Control-Allow-Headers"] = ", ".join(self.
|
107
|
-
response.headers["Access-Control-Allow-Credentials"] = "true" if self.
|
110
|
+
response.headers["Access-Control-Allow-Methods"] = ", ".join(self._allow_methods)
|
111
|
+
response.headers["Access-Control-Allow-Headers"] = ", ".join(self._allow_headers)
|
112
|
+
response.headers["Access-Control-Allow-Credentials"] = "true" if self._allow_credentials else "false"
|
108
113
|
|
109
114
|
return response
|
110
115
|
|
111
116
|
def _add_response_headers(self, request:Request, response:Response, request_timestamp:datetime, process_time:int) -> Response:
|
112
117
|
response.headers["X-Process-Time"] = str(process_time) #* Add Process Time Header
|
113
118
|
response.headers["X-Request-Timestamp"] = request_timestamp.isoformat() #* Add request timestamp header
|
114
|
-
|
119
|
+
#* Define and add response timestamp header
|
120
|
+
response_timestamp = datetime.now(tz=timezone.utc)
|
121
|
+
response.headers["X-Response-Timestamp"] = response_timestamp.isoformat()
|
122
|
+
#* Generate signature header
|
123
|
+
message = f"{request.method}|{request.url.path}|{request_timestamp.isoformat()}|{response_timestamp.isoformat()}|{str(process_time)}"
|
124
|
+
sign_parameters = BaseSignatureParametersTransfers.Sign(key=self._keys.private, password=self._keys.password, message=message)
|
125
|
+
sign_result = self._maleo_foundation.services.signature.sign(parameters=sign_parameters)
|
126
|
+
if sign_result.success:
|
127
|
+
response.headers["X-Signature"] = sign_result.data.signature
|
115
128
|
response = self._append_cors_headers(request=request, response=response) #* Re-append CORS headers
|
116
129
|
return response
|
117
130
|
|
@@ -125,7 +138,7 @@ class BaseMiddleware(BaseHTTPMiddleware):
|
|
125
138
|
client_ip:str = "unknown"
|
126
139
|
) -> Response:
|
127
140
|
response = self._add_response_headers(request, response, request_timestamp, process_time)
|
128
|
-
log_func = getattr(self.
|
141
|
+
log_func = getattr(self._logger, log_level)
|
129
142
|
log_func(
|
130
143
|
f"Request | IP: {client_ip} | Method: {request.method} | URL: {request.url.path} | "
|
131
144
|
f"Headers: {dict(request.headers)} - Response | Status: {response.status_code} | "
|
@@ -148,7 +161,7 @@ class BaseMiddleware(BaseHTTPMiddleware):
|
|
148
161
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
149
162
|
)
|
150
163
|
|
151
|
-
self.
|
164
|
+
self._logger.error(
|
152
165
|
f"Request | IP: {client_ip} | Method: {request.method} | URL: {request.url.path} | "
|
153
166
|
f"Headers: {dict(request.headers)} - Response | Status: 500 | Exception:\n{json.dumps(error_details, indent=4)}"
|
154
167
|
)
|
@@ -180,7 +193,7 @@ class BaseMiddleware(BaseHTTPMiddleware):
|
|
180
193
|
)
|
181
194
|
|
182
195
|
#* 2. Optional preprocessing
|
183
|
-
pre_response = await self.
|
196
|
+
pre_response = await self._request_processor(request)
|
184
197
|
if pre_response is not None:
|
185
198
|
return self._build_response(
|
186
199
|
request=request,
|
@@ -1,9 +1,13 @@
|
|
1
1
|
from pydantic import BaseModel, Field
|
2
|
+
from maleo_foundation.types import BaseTypes
|
2
3
|
|
3
4
|
class BaseSignatureSchemas:
|
4
5
|
class Key(BaseModel):
|
5
6
|
key:str = Field(..., description="Key")
|
6
7
|
|
8
|
+
class Password(BaseModel):
|
9
|
+
password:BaseTypes.OptionalString = Field(None, min_length=32, max_length=1024, description="password")
|
10
|
+
|
7
11
|
class Message(BaseModel):
|
8
12
|
message:str = Field(..., description="Message")
|
9
13
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
from maleo_foundation.models.schemas.signature import BaseSignatureSchemas
|
2
|
+
|
3
|
+
class BaseSignatureParametersTransfers:
|
4
|
+
class Sign(
|
5
|
+
BaseSignatureSchemas.Message,
|
6
|
+
BaseSignatureSchemas.Password,
|
7
|
+
BaseSignatureSchemas.Key
|
8
|
+
): pass
|
9
|
+
|
10
|
+
class Verify(
|
11
|
+
BaseSignatureSchemas.Signature,
|
12
|
+
BaseSignatureSchemas.Message,
|
13
|
+
BaseSignatureSchemas.Key
|
14
|
+
): pass
|
@@ -0,0 +1,12 @@
|
|
1
|
+
from pydantic import Field
|
2
|
+
from maleo_foundation.models.transfers.results.service.general import BaseServiceGeneralResultsTransfers
|
3
|
+
from maleo_foundation.models.schemas.signature import BaseSignatureSchemas
|
4
|
+
|
5
|
+
class BaseSignatureResultsTransfers:
|
6
|
+
class Fail(BaseServiceGeneralResultsTransfers.Fail): pass
|
7
|
+
|
8
|
+
class Sign(BaseServiceGeneralResultsTransfers.SingleData):
|
9
|
+
data:BaseSignatureSchemas.Signature = Field(..., description="Single signature data")
|
10
|
+
|
11
|
+
class Verify(BaseServiceGeneralResultsTransfers.SingleData):
|
12
|
+
data:BaseSignatureSchemas.IsValid = Field(..., description="Single verify data")
|
@@ -6,13 +6,15 @@ maleo_foundation/extended_types.py,sha256=pIKt-_9tby4rmune3fmWcCW_mohaNRh_1lywBm
|
|
6
6
|
maleo_foundation/types.py,sha256=aKXnIgEhYGSfFqNMGLc4qIKGkINBRpkOo9R9cb2CbwI,2414
|
7
7
|
maleo_foundation/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
8
|
maleo_foundation/client/manager.py,sha256=hF5Uiv93yHmno8ec4ukCDrpTh2apUabMeYZNVgSbxZM,1035
|
9
|
-
maleo_foundation/client/services/__init__.py,sha256=
|
9
|
+
maleo_foundation/client/services/__init__.py,sha256=SUGBVhs_Zu9rNUxWIxcjGmi54W6RRlwSTqW4h8E0vW0,540
|
10
|
+
maleo_foundation/client/services/signature.py,sha256=W9ZF_FGGOMXw03jaRlZJPkakCw0grZk52P8IAkOxYLs,4373
|
10
11
|
maleo_foundation/client/services/token.py,sha256=KJcA6aTW12JovrbBf0KoKMDgOopz-mZ_SmCRHhWLS_k,1894
|
11
12
|
maleo_foundation/expanded_types/__init__.py,sha256=lm_r7rxlLA0sgSTGQBMR9ZbZbVDpD7Te-UYb3oRVi1g,364
|
12
13
|
maleo_foundation/expanded_types/client.py,sha256=To0kRXp3QTmuSu5rWKaCiTsMK9qkYiyYKYbHfw-y1fY,2396
|
13
14
|
maleo_foundation/expanded_types/general.py,sha256=bjIBREYTS73tvS-Key7P7db82a2HHlSJ1XBAvKuYmT0,826
|
14
15
|
maleo_foundation/expanded_types/query.py,sha256=0yUG-JIVsanzB7KAkrRz_OsrhP6J0bRqD9Q3l3atQnk,2384
|
15
16
|
maleo_foundation/expanded_types/service.py,sha256=q8jpKdbCbLWwH1UPQavKpVE14rC5rveduk2cFWzuhGw,2416
|
17
|
+
maleo_foundation/expanded_types/signature.py,sha256=zNgXRrxVCfEIGXsRANIa1Ljj-ebHjC2pWOTtw_ABJlQ,379
|
16
18
|
maleo_foundation/expanded_types/token.py,sha256=4fRTJw6W5MYq71NksNrWNi7qYHQ4_lQwfu9WxwrMipc,355
|
17
19
|
maleo_foundation/managers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
20
|
maleo_foundation/managers/db.py,sha256=Pn5EZ-c1Hy6-BihN7KokHJWmBIt3Ty96fZ0zF-srtF4,5208
|
@@ -20,14 +22,14 @@ maleo_foundation/managers/middleware.py,sha256=7CDXPMb28AR7J72TWOeKFxOlMypKezEtO
|
|
20
22
|
maleo_foundation/managers/service.py,sha256=UI5aXIgVqTud4PtI5QCSFApOALdSvMhR9O3cMW1NqIE,16960
|
21
23
|
maleo_foundation/managers/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
24
|
maleo_foundation/managers/client/base.py,sha256=qfWu_wxoPSSzgZwuTEwRiXERg60diAkz65Qk3fnQej4,3972
|
23
|
-
maleo_foundation/managers/client/maleo.py,sha256=
|
25
|
+
maleo_foundation/managers/client/maleo.py,sha256=iCM47TLL-RSQ2FkTmHVPdsb2JCd1LebMx6OJvIr4vCQ,2035
|
24
26
|
maleo_foundation/managers/client/google/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
27
|
maleo_foundation/managers/client/google/base.py,sha256=j3W18Pmcu9jJ5wK12bbWBI6r8cVt5f7QmGU9uIJgKrU,1249
|
26
28
|
maleo_foundation/managers/client/google/secret.py,sha256=Uh01RoOp8QOIvu8X4AGJzOJRlrfAeXHO8ZFvmKo7A-E,3114
|
27
29
|
maleo_foundation/managers/client/google/storage.py,sha256=MPuVpLTl0QJhlBOqpxv5UtD3ANO1WCCE1sRrfHnlCZM,2355
|
28
30
|
maleo_foundation/middlewares/__init__.py,sha256=bqE2EIFC3rWcR2AwFPR0fk2kSFfeTRzgA24GbnuT5RA,3697
|
29
|
-
maleo_foundation/middlewares/authentication.py,sha256=
|
30
|
-
maleo_foundation/middlewares/base.py,sha256
|
31
|
+
maleo_foundation/middlewares/authentication.py,sha256=SC9p_7lCcGYbO9GedOKiPDF12KaGFbv1OypJsnRzLww,3329
|
32
|
+
maleo_foundation/middlewares/base.py,sha256=-tpnutxov5UxrKjWMxktpsZ0JqXYLQCkD3x2B3F3OCI,11821
|
31
33
|
maleo_foundation/middlewares/cors.py,sha256=9uvBvY2N6Vxa9RP_YtESxcWo6Doi6uS0lzAG9iLY7Uc,2288
|
32
34
|
maleo_foundation/models/__init__.py,sha256=AaKehO7c1HyKhoTGRmNHDddSeBXkW-_YNrpOGBu8Ms8,246
|
33
35
|
maleo_foundation/models/responses.py,sha256=Ka9Peb1fVuQKaxyy11FVkUPtGtzyEm_9Xfe8Vla3ml0,4764
|
@@ -36,17 +38,20 @@ maleo_foundation/models/schemas/__init__.py,sha256=Xj8Ahsqyra-fmEaVcGPok5GOOsPQl
|
|
36
38
|
maleo_foundation/models/schemas/general.py,sha256=hEQQPcddxMsJXMb36nqItIAfp3pqUyJOlaD7nXkNM2I,3609
|
37
39
|
maleo_foundation/models/schemas/parameter.py,sha256=K47z2NzmTEhUiOfRiRLyRPXoQurbWsKBL7ObXAxIWRY,2100
|
38
40
|
maleo_foundation/models/schemas/result.py,sha256=V3dljS2AdtWW4Pf8YsnQuiCylN1bZtEY1AtYC7okWuI,1747
|
39
|
-
maleo_foundation/models/schemas/signature.py,sha256=
|
41
|
+
maleo_foundation/models/schemas/signature.py,sha256=4DVcsBR9TnxD2R28oWk51jMtF1j5ylmorVM3jDNVlrU,609
|
40
42
|
maleo_foundation/models/schemas/token.py,sha256=u71kPXJyCxqn_INK05MSNFhQr9MaLfQM-icYc536xik,551
|
41
43
|
maleo_foundation/models/transfers/__init__.py,sha256=oJLJ3Geeme6vBw7R2Dhvdvg4ziVvzEYAGJaP-tm_90w,299
|
42
44
|
maleo_foundation/models/transfers/general/__init__.py,sha256=0yW67vJvKgJmZ9htteOVatG7mb-YEpHF62dpwH2g_Bk,146
|
45
|
+
maleo_foundation/models/transfers/general/signature.py,sha256=EFcr-QC3QcDLZivkmL89ERVc5ZDGe_SYH5dMItll5Bs,264
|
43
46
|
maleo_foundation/models/transfers/general/token.py,sha256=QZNGG5DdmQDTYIqNFMqBQDJoeahIHgzBzyXiMoTS-JA,2414
|
44
47
|
maleo_foundation/models/transfers/parameters/__init__.py,sha256=oKW4RPIEISISRjsJzD8lsCGY1HhZRTzshPpWHcJu86k,353
|
45
48
|
maleo_foundation/models/transfers/parameters/client.py,sha256=tn_Hwa-k-Utp5rODe7GylqZB8djIKKupgkUFscYCyLc,4059
|
46
49
|
maleo_foundation/models/transfers/parameters/general.py,sha256=WoekZJCIoAllhXdRIJkNRdNq0QEIn0bteiHJLtzkCxU,579
|
47
50
|
maleo_foundation/models/transfers/parameters/service.py,sha256=d7Xy_R-DtLBRozyD6r8YnTiuKlE3sb9HMDCCq9WmUbY,6757
|
51
|
+
maleo_foundation/models/transfers/parameters/signature.py,sha256=Kn6gJrQUHyn2uG6LyYnhbUEMfXJVTLgMG6n3CXZ4hu8,395
|
48
52
|
maleo_foundation/models/transfers/parameters/token.py,sha256=WTmCKoP-KJLqZjdwr__BeVnBrnRrsxzHSQ0IBaOKvqw,535
|
49
53
|
maleo_foundation/models/transfers/results/__init__.py,sha256=0_8uJ1IQW87RZ4nIxzWkQVi3Fxb7B8myZTngXfoxgNc,241
|
54
|
+
maleo_foundation/models/transfers/results/signature.py,sha256=md3tBOfjJlg-35ICSt8h_EZZett_x7obdlx_GQ3lB00,619
|
50
55
|
maleo_foundation/models/transfers/results/token.py,sha256=4zDgj8FWGK6Rcz_pprwnLcpRyyXKRBPbrCl3IOrRvVg,574
|
51
56
|
maleo_foundation/models/transfers/results/client/__init__.py,sha256=xBRuY0NUIPpQEGQ2qoBnqLZGX4W1YSrQ0VnDf5OYJBo,290
|
52
57
|
maleo_foundation/models/transfers/results/client/service.py,sha256=TO_U53vmUEnFWiiyuu33ao3BUidt6KFxvk3GC9uo8JE,1108
|
@@ -57,8 +62,6 @@ maleo_foundation/models/transfers/results/service/general.py,sha256=G4x-MhQI7Km9
|
|
57
62
|
maleo_foundation/models/transfers/results/service/query.py,sha256=G5A4FRkHyRRlpuGWrPV5-vqgyyBjMqu8f-Ka9BjD0lA,1828
|
58
63
|
maleo_foundation/models/transfers/results/service/controllers/__init__.py,sha256=HZJWMy2dskzOCzLmp_UaL9rjbQ-sDMI7sd2bXb-4QOU,175
|
59
64
|
maleo_foundation/models/transfers/results/service/controllers/rest.py,sha256=wCuFyOTQkuBs2cqjPsWnPy0XIsCfMqGByhrSy57qp7Y,1107
|
60
|
-
maleo_foundation/services/__init__.py,sha256=Ho5zJSA89xdGFKIwOdzjmd8sm23cIuwrqYAxCEBBTIU,120
|
61
|
-
maleo_foundation/services/token.py,sha256=QkiMBTe4aol2uDBfFP2MFa58j-yevr8HtBjenifElR0,1230
|
62
65
|
maleo_foundation/utils/__init__.py,sha256=SRPEVoqjZoO6W8rtF_Ti8VIangg6Auwm6eHbZMdOthY,520
|
63
66
|
maleo_foundation/utils/controller.py,sha256=ECzPzpw36zBAjKcWcDbUAhIJGbc6UpeypdUUX6ipXBg,6396
|
64
67
|
maleo_foundation/utils/exceptions.py,sha256=LPPcU-6_3NbRIBZg2Nr2Ac5HF1qZJbHbMVnwfIfZg6g,3702
|
@@ -72,7 +75,7 @@ maleo_foundation/utils/loaders/__init__.py,sha256=Dnuv7BWyglSddnbsFb96s-b3KaW7UK
|
|
72
75
|
maleo_foundation/utils/loaders/json.py,sha256=NsXLq3VZSgzmEf99tV1VtrmiudWdQ8Pzh_hI4Rm0cM8,397
|
73
76
|
maleo_foundation/utils/loaders/key.py,sha256=GZ4h1ONfp6Xx8-E8AWoGP4ajAZrwPhZRtidjn_u82Qg,2562
|
74
77
|
maleo_foundation/utils/loaders/yaml.py,sha256=jr8v3BlgmRCMTzdNgKhIYt1tnubaJXcDSSGkKVR8pbw,362
|
75
|
-
maleo_foundation-0.1.
|
76
|
-
maleo_foundation-0.1.
|
77
|
-
maleo_foundation-0.1.
|
78
|
-
maleo_foundation-0.1.
|
78
|
+
maleo_foundation-0.1.60.dist-info/METADATA,sha256=zM8enB2P4VlpCcXAFlZKc_OEsXFLaTDN_duopiUhNfQ,3354
|
79
|
+
maleo_foundation-0.1.60.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
80
|
+
maleo_foundation-0.1.60.dist-info/top_level.txt,sha256=_iBos3F_bhEOdjOnzeiEYSrCucasc810xXtLBXI8cQc,17
|
81
|
+
maleo_foundation-0.1.60.dist-info/RECORD,,
|
@@ -1,20 +0,0 @@
|
|
1
|
-
import jwt
|
2
|
-
from maleo_foundation.models.transfers.general.token import BaseTokenGeneralTransfers
|
3
|
-
from maleo_foundation.models.schemas.token import BaseTokenSchemas
|
4
|
-
from maleo_foundation.models.transfers.parameters.token import BaseTokenParametersTransfers
|
5
|
-
from maleo_foundation.models.transfers.results.token import BaseTokenResultsTransfers
|
6
|
-
from maleo_foundation.expanded_types.token import BaseTokenResultsTypes
|
7
|
-
|
8
|
-
class BaseTokenService:
|
9
|
-
@staticmethod
|
10
|
-
def encode(parameters:BaseTokenParametersTransfers.Encode) -> BaseTokenResultsTypes.Encode:
|
11
|
-
payload = BaseTokenGeneralTransfers.EncodePayload.model_validate(parameters.payload.model_dump()).model_dump(mode="json")
|
12
|
-
token = jwt.encode(payload=payload, key=parameters.key.encode(), algorithm="RS256")
|
13
|
-
data = BaseTokenSchemas.Token(token=token)
|
14
|
-
return BaseTokenResultsTransfers.Encode(data=data)
|
15
|
-
|
16
|
-
@staticmethod
|
17
|
-
def decode(parameters:BaseTokenParametersTransfers.Decode) -> BaseTokenResultsTypes.Decode:
|
18
|
-
payload = jwt.decode(jwt=parameters.token, key=parameters.key, algorithms=["RS256"])
|
19
|
-
data = BaseTokenGeneralTransfers.DecodePayload.model_validate(payload)
|
20
|
-
return BaseTokenResultsTransfers.Decode(data=data)
|
File without changes
|
File without changes
|