maleo-foundation 0.2.7__tar.gz → 0.2.8__tar.gz
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-0.2.7 → maleo_foundation-0.2.8}/PKG-INFO +1 -1
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/authentication.py +5 -4
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/managers/service.py +2 -4
- maleo_foundation-0.2.8/maleo_foundation/middlewares/authentication.py +99 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/middlewares/base.py +29 -6
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation.egg-info/PKG-INFO +1 -1
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/pyproject.toml +1 -1
- maleo_foundation-0.2.7/maleo_foundation/middlewares/authentication.py +0 -80
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/README.md +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/manager.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/encryption/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/encryption/aes.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/encryption/rsa.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/hash/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/hash/bcrypt.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/hash/hmac.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/hash/sha256.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/key.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/signature.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/token.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/constants.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/enums.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/client.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/encryption/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/encryption/aes.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/encryption/rsa.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/general.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/hash.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/key.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/query.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/service.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/signature.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/token.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/extended_types.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/managers/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/managers/client/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/managers/client/base.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/managers/client/google/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/managers/client/google/base.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/managers/client/google/secret.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/managers/client/google/storage.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/managers/client/maleo.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/managers/db.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/managers/middleware.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/middlewares/cors.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/responses.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/schemas/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/schemas/encryption.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/schemas/general.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/schemas/hash.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/schemas/key.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/schemas/parameter.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/schemas/result.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/schemas/signature.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/schemas/token.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/table.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/general/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/general/key.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/general/signature.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/general/token.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/parameters/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/parameters/client.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/parameters/encryption/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/parameters/encryption/aes.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/parameters/encryption/rsa.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/parameters/general.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/parameters/hash/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/parameters/hash/bcrypt.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/parameters/hash/hmac.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/parameters/hash/sha256.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/parameters/key.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/parameters/service.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/parameters/signature.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/parameters/token.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/client/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/client/controllers/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/client/controllers/http.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/client/service.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/encryption/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/encryption/aes.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/encryption/rsa.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/hash.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/key.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/service/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/service/controllers/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/service/controllers/rest.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/service/general.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/service/query.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/signature.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/token.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/types.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/controller.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/exceptions.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/extractor.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/formatter/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/formatter/case.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/loaders/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/loaders/credential/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/loaders/credential/google.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/loaders/json.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/loaders/key/__init__.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/loaders/key/rsa.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/loaders/yaml.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/logging.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/mergers.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/query.py +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation.egg-info/SOURCES.txt +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation.egg-info/dependency_links.txt +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation.egg-info/requires.txt +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation.egg-info/top_level.txt +0 -0
- {maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/setup.cfg +0 -0
@@ -1,25 +1,26 @@
|
|
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.enums import BaseEnums
|
4
5
|
from maleo_foundation.models.transfers.general.token import MaleoFoundationTokenGeneralTransfers
|
5
6
|
from maleo_foundation.types import BaseTypes
|
6
7
|
|
7
8
|
class Credentials(AuthCredentials):
|
8
9
|
def __init__(
|
9
10
|
self,
|
10
|
-
|
11
|
+
token_type:Optional[BaseEnums.TokenType] = None,
|
11
12
|
token:BaseTypes.OptionalString = None,
|
12
13
|
payload:Optional[MaleoFoundationTokenGeneralTransfers.DecodePayload] = None,
|
13
14
|
scopes:Optional[Sequence[str]] = None
|
14
15
|
) -> None:
|
15
|
-
self.
|
16
|
+
self._token_type = token_type
|
16
17
|
self._token = token
|
17
18
|
self._payload = payload
|
18
19
|
super().__init__(scopes)
|
19
20
|
|
20
21
|
@property
|
21
|
-
def
|
22
|
-
return self.
|
22
|
+
def token_type(self) -> Optional[BaseEnums.TokenType]:
|
23
|
+
return self._token_type
|
23
24
|
|
24
25
|
@property
|
25
26
|
def token(self) -> BaseTypes.OptionalString:
|
@@ -261,7 +261,7 @@ class ServiceManager:
|
|
261
261
|
raise NotImplementedError()
|
262
262
|
|
263
263
|
@property
|
264
|
-
def token(self) ->
|
264
|
+
def token(self) -> BaseTypes.OptionalString:
|
265
265
|
payload = MaleoFoundationTokenGeneralTransfers.BaseEncodePayload(
|
266
266
|
iss=None,
|
267
267
|
sub=str(self._maleo_credentials.id),
|
@@ -272,9 +272,7 @@ class ServiceManager:
|
|
272
272
|
)
|
273
273
|
parameters = MaleoFoundationTokenParametersTransfers.Encode(key=self._keys.private, password=self._keys.password, payload=payload)
|
274
274
|
result = self._foundation.services.token.encode(parameters=parameters)
|
275
|
-
if
|
276
|
-
raise RuntimeError("Failed encoding payload into token")
|
277
|
-
return result.data.token
|
275
|
+
return result.data.token if result.success else None
|
278
276
|
|
279
277
|
def create_app(self, router:APIRouter, lifespan:Optional[Lifespan[AppType]] = None) -> FastAPI:
|
280
278
|
self._loggers.application.info("Creating FastAPI application")
|
@@ -0,0 +1,99 @@
|
|
1
|
+
from fastapi import FastAPI
|
2
|
+
from starlette.authentication import AuthenticationBackend, AuthenticationError
|
3
|
+
from starlette.middleware.authentication import AuthenticationMiddleware
|
4
|
+
from starlette.requests import HTTPConnection
|
5
|
+
from typing import Tuple
|
6
|
+
from maleo_foundation.authentication import Credentials, User
|
7
|
+
from maleo_foundation.enums import BaseEnums
|
8
|
+
from maleo_foundation.client.manager import MaleoFoundationClientManager
|
9
|
+
from maleo_foundation.models.schemas import BaseGeneralSchemas
|
10
|
+
from maleo_foundation.models.transfers.parameters.token import MaleoFoundationTokenParametersTransfers
|
11
|
+
from maleo_foundation.utils.exceptions import BaseExceptions
|
12
|
+
from maleo_foundation.utils.logging import MiddlewareLogger
|
13
|
+
|
14
|
+
class Backend(AuthenticationBackend):
|
15
|
+
def __init__(self, keys:BaseGeneralSchemas.RSAKeys, logger:MiddlewareLogger, maleo_foundation:MaleoFoundationClientManager):
|
16
|
+
super().__init__()
|
17
|
+
self._keys = keys
|
18
|
+
self._logger = logger
|
19
|
+
self._maleo_foundation = maleo_foundation
|
20
|
+
|
21
|
+
async def authenticate(self, conn:HTTPConnection) -> Tuple[Credentials, User]:
|
22
|
+
if "Authorization" in conn.headers:
|
23
|
+
auth = conn.headers["Authorization"]
|
24
|
+
parts = auth.split()
|
25
|
+
if len(parts) != 2 or parts[0] != "Bearer":
|
26
|
+
raise AuthenticationError("Invalid Authorization header format")
|
27
|
+
scheme, token = parts
|
28
|
+
if scheme != 'Bearer':
|
29
|
+
raise AuthenticationError("Authorization scheme must be Bearer token")
|
30
|
+
|
31
|
+
#* Decode token
|
32
|
+
decode_token_parameters = MaleoFoundationTokenParametersTransfers.Decode(key=self._keys.public, token=token)
|
33
|
+
decode_token_result = self._maleo_foundation.services.token.decode(parameters=decode_token_parameters)
|
34
|
+
if decode_token_result.success:
|
35
|
+
payload = decode_token_result.data
|
36
|
+
return (
|
37
|
+
Credentials(
|
38
|
+
token_type=BaseEnums.TokenType.ACCESS,
|
39
|
+
token=token,
|
40
|
+
payload=payload,
|
41
|
+
scopes=["authenticated", payload.sr]
|
42
|
+
),
|
43
|
+
User(
|
44
|
+
authenticated=True,
|
45
|
+
username=payload.u_u,
|
46
|
+
email=payload.u_e
|
47
|
+
)
|
48
|
+
)
|
49
|
+
|
50
|
+
if "token" in conn.cookies:
|
51
|
+
token = conn.cookies["token"]
|
52
|
+
#* Decode token
|
53
|
+
decode_token_parameters = MaleoFoundationTokenParametersTransfers.Decode(key=self._keys.public, token=token)
|
54
|
+
decode_token_result = self._maleo_foundation.services.token.decode(parameters=decode_token_parameters)
|
55
|
+
if decode_token_result.success:
|
56
|
+
payload = decode_token_result.data
|
57
|
+
return (
|
58
|
+
Credentials(
|
59
|
+
token_type=BaseEnums.TokenType.REFRESH,
|
60
|
+
token=token,
|
61
|
+
payload=payload,
|
62
|
+
scopes=["authenticated", payload.sr]
|
63
|
+
),
|
64
|
+
User(
|
65
|
+
authenticated=True,
|
66
|
+
username=payload.u_u,
|
67
|
+
email=payload.u_e
|
68
|
+
)
|
69
|
+
)
|
70
|
+
|
71
|
+
return Credentials(), User(authenticated=False)
|
72
|
+
|
73
|
+
def add_authentication_middleware(app:FastAPI, keys:BaseGeneralSchemas.RSAKeys, logger:MiddlewareLogger, maleo_foundation:MaleoFoundationClientManager) -> None:
|
74
|
+
"""
|
75
|
+
Adds Authentication middleware to the FastAPI application.
|
76
|
+
|
77
|
+
Args:
|
78
|
+
app: FastAPI
|
79
|
+
The FastAPI application instance to which the middleware will be added.
|
80
|
+
|
81
|
+
logger: MiddlewareLogger
|
82
|
+
Authentication middleware logger to be used.
|
83
|
+
|
84
|
+
key: str
|
85
|
+
Public key to be used for token decoding.
|
86
|
+
|
87
|
+
Returns:
|
88
|
+
None: The function modifies the FastAPI app by adding Base middleware.
|
89
|
+
|
90
|
+
Note:
|
91
|
+
FastAPI applies middleware in reverse order of registration, so this middleware
|
92
|
+
will execute after any middleware added subsequently.
|
93
|
+
|
94
|
+
Example:
|
95
|
+
```python
|
96
|
+
add_authentication_middleware(app=app, limit=10, window=1, cleanup_interval=60, ip_timeout=300)
|
97
|
+
```
|
98
|
+
"""
|
99
|
+
app.add_middleware(AuthenticationMiddleware, backend=Backend(keys, logger, maleo_foundation), on_error=BaseExceptions.authentication_error_handler)
|
@@ -8,10 +8,13 @@ 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.authentication import
|
11
|
+
from maleo_foundation.authentication import Authentication
|
12
|
+
from maleo_foundation.enums import BaseEnums
|
12
13
|
from maleo_foundation.client.manager import MaleoFoundationClientManager
|
13
14
|
from maleo_foundation.models.schemas import BaseGeneralSchemas
|
14
15
|
from maleo_foundation.models.responses import BaseResponses
|
16
|
+
from maleo_foundation.models.transfers.general.token import MaleoFoundationTokenGeneralTransfers
|
17
|
+
from maleo_foundation.models.transfers.parameters.token import MaleoFoundationTokenParametersTransfers
|
15
18
|
from maleo_foundation.models.transfers.parameters.signature import MaleoFoundationSignatureParametersTransfers
|
16
19
|
from maleo_foundation.utils.extractor import BaseExtractors
|
17
20
|
from maleo_foundation.utils.logging import MiddlewareLogger
|
@@ -117,6 +120,7 @@ class BaseMiddleware(BaseHTTPMiddleware):
|
|
117
120
|
def _add_response_headers(
|
118
121
|
self,
|
119
122
|
request:Request,
|
123
|
+
authentication:Authentication,
|
120
124
|
response:Response,
|
121
125
|
request_timestamp:datetime,
|
122
126
|
response_timestamp:datetime,
|
@@ -132,11 +136,22 @@ class BaseMiddleware(BaseHTTPMiddleware):
|
|
132
136
|
if sign_result.success:
|
133
137
|
response.headers["X-Signature"] = sign_result.data.signature
|
134
138
|
response = self._append_cors_headers(request=request, response=response) #* Re-append CORS headers
|
139
|
+
if authentication.user.is_authenticated \
|
140
|
+
and authentication.credentials.token_type == BaseEnums.TokenType.REFRESH \
|
141
|
+
and authentication.credentials.payload is not None \
|
142
|
+
and (response.status_code >= 200 and response.status_code < 300):
|
143
|
+
#* Regenerate new authorization
|
144
|
+
payload = MaleoFoundationTokenGeneralTransfers.BaseEncodePayload.model_validate(authentication.credentials.payload.model_dump())
|
145
|
+
parameters = MaleoFoundationTokenParametersTransfers.Encode(key=self._keys.private, password=self._keys.password, payload=payload)
|
146
|
+
result = self._maleo_foundation.services.token.encode(parameters=parameters)
|
147
|
+
if result.success:
|
148
|
+
response.headers["X-New-Authorization"] = result.data.token
|
135
149
|
return response
|
136
150
|
|
137
151
|
def _build_response(
|
138
152
|
self,
|
139
153
|
request:Request,
|
154
|
+
authentication:Authentication,
|
140
155
|
authentication_info:str,
|
141
156
|
response:Response,
|
142
157
|
request_timestamp:datetime,
|
@@ -145,7 +160,7 @@ class BaseMiddleware(BaseHTTPMiddleware):
|
|
145
160
|
log_level:str = "info",
|
146
161
|
client_ip:str = "unknown"
|
147
162
|
) -> Response:
|
148
|
-
response = self._add_response_headers(request, response, request_timestamp, response_timestamp, process_time)
|
163
|
+
response = self._add_response_headers(request, authentication, response, request_timestamp, response_timestamp, process_time)
|
149
164
|
log_func = getattr(self._logger, log_level)
|
150
165
|
log_func(
|
151
166
|
f"Request {authentication_info} | IP: {client_ip} | Host: {request.client.host} | Port: {request.client.port} | Method: {request.method} | URL: {request.url.path} | "
|
@@ -156,6 +171,7 @@ class BaseMiddleware(BaseHTTPMiddleware):
|
|
156
171
|
def _handle_exception(
|
157
172
|
self,
|
158
173
|
request:Request,
|
174
|
+
authentication:Authentication,
|
159
175
|
authentication_info:str,
|
160
176
|
error,
|
161
177
|
request_timestamp:datetime,
|
@@ -183,7 +199,7 @@ class BaseMiddleware(BaseHTTPMiddleware):
|
|
183
199
|
f"Headers: {dict(request.headers)} - Response | Status: 500 | Exception:\n{json.dumps(error_details, indent=4)}"
|
184
200
|
)
|
185
201
|
|
186
|
-
return self._add_response_headers(request, response, request_timestamp, response_timestamp, process_time)
|
202
|
+
return self._add_response_headers(request, authentication, response, request_timestamp, response_timestamp, process_time)
|
187
203
|
|
188
204
|
async def _request_processor(self, request:Request) -> Optional[Response]:
|
189
205
|
return None
|
@@ -193,17 +209,21 @@ class BaseMiddleware(BaseHTTPMiddleware):
|
|
193
209
|
request_timestamp = datetime.now(tz=timezone.utc) #* Record the request timestamp
|
194
210
|
start_time = time.perf_counter() #* Record the start time
|
195
211
|
client_ip = BaseExtractors.extract_client_ip(request) #* Get request IP with improved extraction
|
196
|
-
|
197
|
-
|
212
|
+
authentication = Authentication(
|
213
|
+
credentials=request.auth,
|
214
|
+
user=request.user
|
215
|
+
)
|
216
|
+
if not authentication.user.is_authenticated:
|
198
217
|
authentication_info = "| Unauthenticated"
|
199
218
|
else:
|
200
|
-
authentication_info = f"| Username: {user.display_name} | Email:{user.identity}"
|
219
|
+
authentication_info = f"| Username: {authentication.user.display_name} | Email:{authentication.user.identity}"
|
201
220
|
|
202
221
|
try:
|
203
222
|
#* 1. Rate limit check
|
204
223
|
if self._check_rate_limit(client_ip):
|
205
224
|
return self._build_response(
|
206
225
|
request=request,
|
226
|
+
authentication=authentication,
|
207
227
|
authentication_info=authentication_info,
|
208
228
|
response=JSONResponse(
|
209
229
|
content=BaseResponses.RateLimitExceeded().model_dump(),
|
@@ -221,6 +241,7 @@ class BaseMiddleware(BaseHTTPMiddleware):
|
|
221
241
|
if pre_response is not None:
|
222
242
|
return self._build_response(
|
223
243
|
request=request,
|
244
|
+
authentication=authentication,
|
224
245
|
authentication_info=authentication_info,
|
225
246
|
response=pre_response,
|
226
247
|
request_timestamp=request_timestamp,
|
@@ -234,6 +255,7 @@ class BaseMiddleware(BaseHTTPMiddleware):
|
|
234
255
|
response = await call_next(request)
|
235
256
|
response = self._build_response(
|
236
257
|
request=request,
|
258
|
+
authentication=authentication,
|
237
259
|
authentication_info=authentication_info,
|
238
260
|
response=response,
|
239
261
|
request_timestamp=request_timestamp,
|
@@ -248,6 +270,7 @@ class BaseMiddleware(BaseHTTPMiddleware):
|
|
248
270
|
except Exception as e:
|
249
271
|
return self._handle_exception(
|
250
272
|
request=request,
|
273
|
+
authentication=authentication,
|
251
274
|
authentication_info=authentication_info,
|
252
275
|
error=e,
|
253
276
|
request_timestamp=request_timestamp,
|
@@ -1,80 +0,0 @@
|
|
1
|
-
from datetime import datetime, timezone
|
2
|
-
from fastapi import FastAPI
|
3
|
-
from starlette.authentication import AuthenticationBackend, AuthenticationError
|
4
|
-
from starlette.middleware.authentication import AuthenticationMiddleware
|
5
|
-
from starlette.requests import HTTPConnection
|
6
|
-
from typing import Tuple
|
7
|
-
from maleo_foundation.authentication import Credentials, User
|
8
|
-
from maleo_foundation.client.manager import MaleoFoundationClientManager
|
9
|
-
from maleo_foundation.models.schemas import BaseGeneralSchemas
|
10
|
-
from maleo_foundation.models.transfers.parameters.token import MaleoFoundationTokenParametersTransfers
|
11
|
-
from maleo_foundation.utils.exceptions import BaseExceptions
|
12
|
-
from maleo_foundation.utils.logging import MiddlewareLogger
|
13
|
-
|
14
|
-
class Backend(AuthenticationBackend):
|
15
|
-
def __init__(self, keys:BaseGeneralSchemas.RSAKeys, logger:MiddlewareLogger, maleo_foundation:MaleoFoundationClientManager):
|
16
|
-
super().__init__()
|
17
|
-
self._keys = keys
|
18
|
-
self._logger = logger
|
19
|
-
self._maleo_foundation = maleo_foundation
|
20
|
-
|
21
|
-
async def authenticate(self, conn:HTTPConnection) -> Tuple[Credentials, User]:
|
22
|
-
if "Authorization" not in conn.headers:
|
23
|
-
return Credentials(), User(authenticated=False)
|
24
|
-
|
25
|
-
auth = conn.headers["Authorization"]
|
26
|
-
scheme, token = auth.split()
|
27
|
-
if scheme != 'Bearer':
|
28
|
-
# raise AuthenticationError("Authorization scheme must be Bearer token")
|
29
|
-
return Credentials(), User(authenticated=False)
|
30
|
-
|
31
|
-
decode_token_parameters = MaleoFoundationTokenParametersTransfers.Decode(key=self._keys.public, token=token)
|
32
|
-
decode_token_result = self._maleo_foundation.services.token.decode(parameters=decode_token_parameters)
|
33
|
-
if not decode_token_result.success:
|
34
|
-
# raise AuthenticationError("Invalid Bearer token, unable to decode token")
|
35
|
-
return Credentials(), User(authenticated=False)
|
36
|
-
if decode_token_result.data.exp_dt <= datetime.now(tz=timezone.utc):
|
37
|
-
# raise AuthenticationError("Expired Bearer token, request new or refresh token")
|
38
|
-
return Credentials(), User(authenticated=False)
|
39
|
-
|
40
|
-
payload = decode_token_result.data
|
41
|
-
return (
|
42
|
-
Credentials(
|
43
|
-
token=token,
|
44
|
-
payload=payload,
|
45
|
-
scopes=["authenticated", payload.sr]
|
46
|
-
),
|
47
|
-
User(
|
48
|
-
authenticated=True,
|
49
|
-
username=payload.u_u,
|
50
|
-
email=payload.u_e
|
51
|
-
)
|
52
|
-
)
|
53
|
-
|
54
|
-
def add_authentication_middleware(app:FastAPI, keys:BaseGeneralSchemas.RSAKeys, logger:MiddlewareLogger, maleo_foundation:MaleoFoundationClientManager) -> None:
|
55
|
-
"""
|
56
|
-
Adds Authentication middleware to the FastAPI application.
|
57
|
-
|
58
|
-
Args:
|
59
|
-
app: FastAPI
|
60
|
-
The FastAPI application instance to which the middleware will be added.
|
61
|
-
|
62
|
-
logger: MiddlewareLogger
|
63
|
-
Authentication middleware logger to be used.
|
64
|
-
|
65
|
-
key: str
|
66
|
-
Public key to be used for token decoding.
|
67
|
-
|
68
|
-
Returns:
|
69
|
-
None: The function modifies the FastAPI app by adding Base middleware.
|
70
|
-
|
71
|
-
Note:
|
72
|
-
FastAPI applies middleware in reverse order of registration, so this middleware
|
73
|
-
will execute after any middleware added subsequently.
|
74
|
-
|
75
|
-
Example:
|
76
|
-
```python
|
77
|
-
add_authentication_middleware(app=app, limit=10, window=1, cleanup_interval=60, ip_timeout=300)
|
78
|
-
```
|
79
|
-
"""
|
80
|
-
app.add_middleware(AuthenticationMiddleware, backend=Backend(keys, logger, maleo_foundation), on_error=BaseExceptions.authentication_error_handler)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/__init__.py
RENAMED
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/encryption/aes.py
RENAMED
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/encryption/rsa.py
RENAMED
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/hash/__init__.py
RENAMED
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/hash/bcrypt.py
RENAMED
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/hash/hmac.py
RENAMED
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/hash/sha256.py
RENAMED
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/client/services/signature.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/encryption/aes.py
RENAMED
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/encryption/rsa.py
RENAMED
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/general.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/service.py
RENAMED
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/expanded_types/signature.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/managers/client/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/managers/client/google/base.py
RENAMED
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/managers/client/google/secret.py
RENAMED
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/managers/client/google/storage.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/schemas/__init__.py
RENAMED
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/schemas/encryption.py
RENAMED
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/schemas/general.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/schemas/parameter.py
RENAMED
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/schemas/signature.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/__init__.py
RENAMED
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/general/key.py
RENAMED
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/general/token.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/hash.py
RENAMED
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/key.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/models/transfers/results/token.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/formatter/__init__.py
RENAMED
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/loaders/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation/utils/loaders/key/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{maleo_foundation-0.2.7 → maleo_foundation-0.2.8}/maleo_foundation.egg-info/dependency_links.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|