Encryptors 2.81.2__tar.gz → 2.81.3__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.
- {encryptors-2.81.2 → encryptors-2.81.3}/PKG-INFO +1 -1
- {encryptors-2.81.2 → encryptors-2.81.3}/setup.py +1 -1
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Encryptors.egg-info/PKG-INFO +1 -1
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Encryptors.egg-info/SOURCES.txt +2 -2
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Decorators/SecureResolver.py +19 -53
- encryptors-2.81.3/src/Osdental/Helpers/authorization_helpers.py +53 -0
- encryptors-2.81.3/src/Osdental/Helpers/request_decryption.py +32 -0
- encryptors-2.81.3/src/Osdental/Helpers/token_validation_service.py +51 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Models/Token.py +4 -5
- encryptors-2.81.2/src/Osdental/Helpers/extract_auth_token.py +0 -11
- encryptors-2.81.2/src/Osdental/Helpers/tenant_policy.py +0 -46
- encryptors-2.81.2/src/Osdental/Helpers/token_validation_service.py +0 -49
- {encryptors-2.81.2 → encryptors-2.81.3}/README.md +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/setup.cfg +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Encryptors.egg-info/dependency_links.txt +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Encryptors.egg-info/entry_points.txt +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Encryptors.egg-info/requires.txt +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Encryptors.egg-info/top_level.txt +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Cache/Redis.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Cache/__init__.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Cli/__init__.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Database/BaseRepository.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Database/Connection.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Database/SqlExceptionTranslator.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Database/SqlTransientDetector.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Database/StoredProcedureResultValidator.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Database/__init__.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Decorators/Grpc.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Decorators/PublicResolver.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Decorators/Retry.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Decorators/__init__.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Encryptor/Aes.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Encryptor/Argon2.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Encryptor/Bcrypt.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Encryptor/Jwt.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Encryptor/Rsa.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Encryptor/Sha512.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Encryptor/__init__.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Exception/ControlledException.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Exception/__init__.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Helpers/AzureClassifier.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Helpers/GrpcConnection.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Helpers/Resilience.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Helpers/ResponseDecryptor.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Helpers/__init__.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Http/Constants.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Http/Exceptions.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Http/HttpxClient.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Http/Messages.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Http/Types.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Http/__init__.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Messaging/AzureServiceBus.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Messaging/Kafka.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Messaging/RabbitMQ.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Messaging/__init__.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Models/Response.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Models/__init__.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Models/base_graphql_context.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Secrets/KeyVaultService.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Secrets/__init__.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Enums/Code.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Enums/Constant.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Enums/FileType.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Enums/GrahpqlOperation.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Enums/Message.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Enums/Profile.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Enums/__init__.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Logger.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Utils/CaseConverter.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Utils/CodeGenerator.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Utils/DataNormalizer.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Utils/DataUtils.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Utils/DateUtils.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Utils/FileMetaData.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Utils/HashValidator.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Utils/Mapper.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Utils/PasswordGenerator.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Utils/QueryGenerator.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Utils/RsaUtils.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Utils/TextProcessor.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/Utils/__init__.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Shared/__init__.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Storage/AzureBlobStorage.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Storage/S3Storage.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Storage/__init__.py +0 -0
- {encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/__init__.py +0 -0
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
# ANDERSON REVISAR EL CACHE LOCAL DEL KEYVAULT PARA VALIDAR SI FUNCIONA
|
|
3
3
|
setup(
|
|
4
4
|
name="Encryptors",
|
|
5
|
-
version="2.81.
|
|
5
|
+
version="2.81.3",
|
|
6
6
|
author="OSDental LLC",
|
|
7
7
|
author_email="support@osdental.ai",
|
|
8
8
|
description="End-to-end algorithm library",
|
|
@@ -35,8 +35,8 @@ src/Osdental/Helpers/GrpcConnection.py
|
|
|
35
35
|
src/Osdental/Helpers/Resilience.py
|
|
36
36
|
src/Osdental/Helpers/ResponseDecryptor.py
|
|
37
37
|
src/Osdental/Helpers/__init__.py
|
|
38
|
-
src/Osdental/Helpers/
|
|
39
|
-
src/Osdental/Helpers/
|
|
38
|
+
src/Osdental/Helpers/authorization_helpers.py
|
|
39
|
+
src/Osdental/Helpers/request_decryption.py
|
|
40
40
|
src/Osdental/Helpers/token_validation_service.py
|
|
41
41
|
src/Osdental/Http/Constants.py
|
|
42
42
|
src/Osdental/Http/Exceptions.py
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import json
|
|
2
1
|
from functools import wraps
|
|
3
2
|
from typing import Callable
|
|
4
3
|
from Osdental.Models.Response import Response
|
|
5
4
|
from Osdental.Shared.Enums.Profile import Profile
|
|
6
5
|
from Osdental.Exception.ControlledException import (
|
|
7
|
-
OSDException, AccessDeniedException
|
|
6
|
+
OSDException, AccessDeniedException
|
|
8
7
|
)
|
|
9
|
-
from Osdental.Encryptor.Aes import AES
|
|
10
8
|
from Osdental.Models.base_graphql_context import BaseGraphQLContext
|
|
11
|
-
from Osdental.Helpers.
|
|
9
|
+
from Osdental.Helpers.authorization_helpers import tenant_context_resolver
|
|
10
|
+
from Osdental.Helpers.request_decryption import decrypt_payload
|
|
12
11
|
from Osdental.Secrets import ISecretProvider
|
|
13
12
|
from Osdental.Shared.Logger import logger
|
|
14
13
|
|
|
@@ -29,67 +28,34 @@ def resolver(action=None):
|
|
|
29
28
|
error="User not allowed to perform this action"
|
|
30
29
|
)
|
|
31
30
|
|
|
32
|
-
# Get secrets
|
|
33
31
|
secret_service: ISecretProvider = context.container.secret_service
|
|
34
|
-
|
|
32
|
+
secrets = await secret_service.get_many(
|
|
35
33
|
["AES-KEY-AUTH", "AES-KEY-USER", "AUTH-JWT-USER-KEY"]
|
|
36
34
|
)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if encrypted_payload is not None:
|
|
44
|
-
|
|
45
|
-
if not isinstance(encrypted_payload, str):
|
|
46
|
-
raise ValueError("Encrypted payload must be a string")
|
|
47
|
-
|
|
48
|
-
if not context.aes_auth:
|
|
49
|
-
raise ValueError("Missing AES configuration")
|
|
50
|
-
|
|
51
|
-
try:
|
|
52
|
-
decrypted = AES.decrypt(context.aes_auth, encrypted_payload)
|
|
53
|
-
except Exception:
|
|
54
|
-
raise ValueError("Invalid encrypted payload")
|
|
55
|
-
|
|
56
|
-
if isinstance(decrypted, dict):
|
|
57
|
-
decrypted_payload = decrypted
|
|
58
|
-
|
|
59
|
-
elif isinstance(decrypted, str):
|
|
60
|
-
try:
|
|
61
|
-
decrypted_payload = json.loads(decrypted)
|
|
62
|
-
except Exception:
|
|
63
|
-
raise ValueError("Decrypted payload is not valid JSON")
|
|
64
|
-
|
|
65
|
-
else:
|
|
66
|
-
raise ValueError("Unsupported decrypted payload type")
|
|
35
|
+
|
|
36
|
+
decrypted_payload = decrypt_payload(
|
|
37
|
+
encrypted_payload=kwargs.get("data"),
|
|
38
|
+
aes_auth_aes_key=secrets["AES-KEY-AUTH"]
|
|
39
|
+
)
|
|
67
40
|
|
|
68
41
|
if decrypted_payload is not None:
|
|
69
42
|
kwargs["data"] = decrypted_payload
|
|
70
43
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
original_token = None
|
|
80
|
-
|
|
81
|
-
token = TenantPolicy.resolve(
|
|
44
|
+
|
|
45
|
+
original_token = await token_service.authenticate(
|
|
46
|
+
request.headers,
|
|
47
|
+
secrets["AUTH-JWT-USER-KEY"],
|
|
48
|
+
secrets["AES-KEY-USER"],
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
token = tenant_context_resolver(
|
|
82
52
|
token=original_token,
|
|
83
53
|
headers=request.headers,
|
|
84
54
|
decrypted_payload=decrypted_payload,
|
|
85
55
|
operation_type=info.operation.operation.value
|
|
86
56
|
)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
raise UnauthorizedException(
|
|
90
|
-
error="Authorization required"
|
|
91
|
-
)
|
|
92
|
-
# token
|
|
57
|
+
|
|
58
|
+
context.token = token
|
|
93
59
|
|
|
94
60
|
result = await func(obj, info, **kwargs)
|
|
95
61
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from typing import Dict, Any
|
|
2
|
+
from uuid import UUID
|
|
3
|
+
from starlette.datastructures import Headers
|
|
4
|
+
from graphql import OperationType
|
|
5
|
+
from starlette.datastructures import Headers
|
|
6
|
+
from Osdental.Encryptor.Aes import AES
|
|
7
|
+
from Osdental.Models.Token import AuthToken
|
|
8
|
+
from Osdental.Shared.Enums.Profile import Profile
|
|
9
|
+
|
|
10
|
+
def get_auth_token(headers: Headers) -> str:
|
|
11
|
+
|
|
12
|
+
authorization = headers.get("authorization")
|
|
13
|
+
if not authorization or not authorization.startswith("Bearer "):
|
|
14
|
+
raise ValueError("Missing Bearer token")
|
|
15
|
+
|
|
16
|
+
return authorization.split(" ")[1]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def tenant_context_resolver(
|
|
20
|
+
token: AuthToken,
|
|
21
|
+
headers: Headers,
|
|
22
|
+
decrypted_payload: Dict[str, Any],
|
|
23
|
+
operation_type: str
|
|
24
|
+
) -> AuthToken:
|
|
25
|
+
|
|
26
|
+
final_id = None
|
|
27
|
+
dynamic_client_id = headers.get("dynamicClientId", None)
|
|
28
|
+
external_enterprise_req = (
|
|
29
|
+
decrypted_payload.get("idExternalEnterprise")
|
|
30
|
+
if decrypted_payload else None
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
if external_enterprise_req:
|
|
34
|
+
final_id = external_enterprise_req
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
elif token.abbreviation.startswith(
|
|
38
|
+
(Profile.MARKETING, Profile.SUPER_ADMIN, Profile.ADMIN_OSD)
|
|
39
|
+
) and dynamic_client_id:
|
|
40
|
+
decrypted_mk_id = AES.decrypt(token.aes_key_auth, dynamic_client_id)
|
|
41
|
+
final_id = decrypted_mk_id
|
|
42
|
+
token.mk_id_external_enterprise = decrypted_mk_id
|
|
43
|
+
|
|
44
|
+
elif (
|
|
45
|
+
token.abbreviation.startswith((Profile.SUPER_ADMIN, Profile.ADMIN_OSD))
|
|
46
|
+
and operation_type == OperationType.QUERY.value and not dynamic_client_id
|
|
47
|
+
):
|
|
48
|
+
final_id = str(UUID(int=0))
|
|
49
|
+
|
|
50
|
+
if final_id:
|
|
51
|
+
token.id_external_enterprise = final_id
|
|
52
|
+
|
|
53
|
+
return token
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from Osdental.Encryptor.Aes import AES
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def decrypt_payload(encrypted_payload: str, aes_auth_aes_key: str):
|
|
6
|
+
decrypted_payload = None
|
|
7
|
+
|
|
8
|
+
if encrypted_payload is not None:
|
|
9
|
+
|
|
10
|
+
if not isinstance(encrypted_payload, str):
|
|
11
|
+
raise ValueError("Encrypted payload must be a string")
|
|
12
|
+
|
|
13
|
+
if not aes_auth_aes_key:
|
|
14
|
+
raise ValueError("Missing AES configuration")
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
decrypted = AES.decrypt(aes_auth_aes_key, encrypted_payload)
|
|
18
|
+
except Exception:
|
|
19
|
+
raise ValueError("Invalid encrypted payload")
|
|
20
|
+
|
|
21
|
+
if isinstance(decrypted, dict):
|
|
22
|
+
decrypted_payload = decrypted
|
|
23
|
+
|
|
24
|
+
elif isinstance(decrypted, str):
|
|
25
|
+
try:
|
|
26
|
+
decrypted_payload = json.loads(decrypted)
|
|
27
|
+
except Exception:
|
|
28
|
+
raise ValueError("Decrypted payload is not valid JSON")
|
|
29
|
+
else:
|
|
30
|
+
raise ValueError("Unsupported decrypted payload type")
|
|
31
|
+
|
|
32
|
+
return decrypted_payload
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from starlette.datastructures import Headers
|
|
2
|
+
from Osdental.Encryptor.Aes import AES
|
|
3
|
+
from Osdental.Encryptor.Jwt import JWT
|
|
4
|
+
from Osdental.Models.Token import AuthToken
|
|
5
|
+
from Osdental.Helpers.authorization_helpers import get_auth_token
|
|
6
|
+
from Osdental.Exception.ControlledException import UnauthorizedException
|
|
7
|
+
|
|
8
|
+
class TokenValidationService:
|
|
9
|
+
|
|
10
|
+
def __init__(self, auth_validator):
|
|
11
|
+
self.auth_validator = auth_validator
|
|
12
|
+
|
|
13
|
+
async def authenticate(
|
|
14
|
+
self,
|
|
15
|
+
headers: Headers,
|
|
16
|
+
jwt_user_key: str,
|
|
17
|
+
aes_user: str
|
|
18
|
+
) -> AuthToken:
|
|
19
|
+
|
|
20
|
+
encrypted_token = get_auth_token(headers)
|
|
21
|
+
|
|
22
|
+
user_token = AES.decrypt(aes_user, encrypted_token)
|
|
23
|
+
claims = JWT.extract_payload(user_token, jwt_user_key)
|
|
24
|
+
|
|
25
|
+
token = AuthToken(
|
|
26
|
+
id_token=claims.get("idToken"),
|
|
27
|
+
id_user=claims.get("idUser"),
|
|
28
|
+
id_external_enterprise=claims.get("idExternalEnterprise"),
|
|
29
|
+
id_profile=claims.get("idProfile"),
|
|
30
|
+
id_legacy=claims.get("idLegacy"),
|
|
31
|
+
id_authorization=claims.get("idAuthorization"),
|
|
32
|
+
id_item_report=claims.get("idItemReport"),
|
|
33
|
+
id_enterprise=claims.get("idEnterprise"),
|
|
34
|
+
user_full_name=claims.get("userFullName"),
|
|
35
|
+
abbreviation=claims.get("abbreviation"),
|
|
36
|
+
aes_key_auth=claims.get("aesKeyAuth"),
|
|
37
|
+
aes_key_user=claims.get("aesKeyUser"),
|
|
38
|
+
base_id_external_enterprise=claims.get("idExternalEnterprise")
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# Validate via RPC
|
|
42
|
+
payload = {
|
|
43
|
+
"idToken": token.id_token,
|
|
44
|
+
"idUser": token.id_user
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
is_valid = await self.auth_validator.validate_auth_token(payload)
|
|
48
|
+
if not int(is_valid):
|
|
49
|
+
raise UnauthorizedException(error="The session token has expired or is invalid.")
|
|
50
|
+
|
|
51
|
+
return token
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
1
|
from dataclasses import dataclass
|
|
3
2
|
|
|
4
3
|
@dataclass
|
|
@@ -14,7 +13,7 @@ class AuthToken:
|
|
|
14
13
|
user_full_name: str
|
|
15
14
|
abbreviation: str
|
|
16
15
|
aes_key_auth: str
|
|
17
|
-
aes_key_user:
|
|
18
|
-
access_token:
|
|
19
|
-
base_id_external_enterprise:
|
|
20
|
-
mk_id_external_enterprise:
|
|
16
|
+
aes_key_user: str | None = None
|
|
17
|
+
access_token: str | None = None
|
|
18
|
+
base_id_external_enterprise: str | None = None
|
|
19
|
+
mk_id_external_enterprise: str | None = None
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
from starlette.datastructures import Headers
|
|
2
|
-
|
|
3
|
-
class ExtractAuthToken:
|
|
4
|
-
|
|
5
|
-
@staticmethod
|
|
6
|
-
def get_auth_token(headers: Headers) -> str:
|
|
7
|
-
authorization = headers.get("authorization")
|
|
8
|
-
if not authorization or not authorization.startswith("Bearer "):
|
|
9
|
-
raise ValueError("Missing Bearer token")
|
|
10
|
-
|
|
11
|
-
return authorization.split(" ")[1]
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
from typing import Dict, Any
|
|
2
|
-
from uuid import UUID
|
|
3
|
-
from graphql import OperationType
|
|
4
|
-
from starlette.datastructures import Headers
|
|
5
|
-
from Osdental.Encryptor.Aes import AES
|
|
6
|
-
from Osdental.Models.Token import AuthToken
|
|
7
|
-
from Osdental.Shared.Enums.Profile import Profile
|
|
8
|
-
|
|
9
|
-
class TenantPolicy:
|
|
10
|
-
|
|
11
|
-
@staticmethod
|
|
12
|
-
def resolve(
|
|
13
|
-
token: AuthToken,
|
|
14
|
-
headers: Headers,
|
|
15
|
-
decrypted_payload: Dict[str, Any],
|
|
16
|
-
operation_type: str
|
|
17
|
-
) -> AuthToken:
|
|
18
|
-
|
|
19
|
-
final_id = None
|
|
20
|
-
dynamic_client_id = headers.get("dynamicClientId", None)
|
|
21
|
-
external_enterprise_req = (
|
|
22
|
-
decrypted_payload.get("idExternalEnterprise")
|
|
23
|
-
if decrypted_payload else None
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
if external_enterprise_req:
|
|
27
|
-
final_id = external_enterprise_req
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
elif token.abbreviation.startswith(
|
|
31
|
-
(Profile.MARKETING, Profile.SUPER_ADMIN, Profile.ADMIN_OSD)
|
|
32
|
-
) and dynamic_client_id:
|
|
33
|
-
decrypted_mk_id = AES.decrypt(token.aes_key_auth, dynamic_client_id)
|
|
34
|
-
final_id = decrypted_mk_id
|
|
35
|
-
token.mk_id_external_enterprise = decrypted_mk_id
|
|
36
|
-
|
|
37
|
-
elif (
|
|
38
|
-
token.abbreviation.startswith((Profile.SUPER_ADMIN, Profile.ADMIN_OSD))
|
|
39
|
-
and operation_type == OperationType.QUERY.value and not dynamic_client_id
|
|
40
|
-
):
|
|
41
|
-
final_id = str(UUID(int=0))
|
|
42
|
-
|
|
43
|
-
if final_id:
|
|
44
|
-
token.id_external_enterprise = final_id
|
|
45
|
-
|
|
46
|
-
return token
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
from starlette.datastructures import Headers
|
|
2
|
-
from Osdental.Encryptor.Aes import AES
|
|
3
|
-
from Osdental.Encryptor.Jwt import JWT
|
|
4
|
-
from Osdental.Models.Token import AuthToken
|
|
5
|
-
from Osdental.Helpers.extract_auth_token import ExtractAuthToken
|
|
6
|
-
|
|
7
|
-
class TokenValidationService:
|
|
8
|
-
|
|
9
|
-
def __init__(self, auth_validator):
|
|
10
|
-
self.auth_validator = auth_validator
|
|
11
|
-
|
|
12
|
-
async def authenticate(
|
|
13
|
-
self,
|
|
14
|
-
headers: Headers,
|
|
15
|
-
jwt_user_key: str,
|
|
16
|
-
aes_user: str
|
|
17
|
-
) -> AuthToken:
|
|
18
|
-
|
|
19
|
-
encrypted_token = ExtractAuthToken.get_auth_token(headers)
|
|
20
|
-
|
|
21
|
-
user_token = AES.decrypt(aes_user, encrypted_token)
|
|
22
|
-
payload = JWT.extract_payload(user_token, jwt_user_key)
|
|
23
|
-
|
|
24
|
-
token = AuthToken(
|
|
25
|
-
id_token=payload.get("idToken"),
|
|
26
|
-
id_user=payload.get("idUser"),
|
|
27
|
-
id_external_enterprise=payload.get("idExternalEnterprise"),
|
|
28
|
-
id_profile=payload.get("idProfile"),
|
|
29
|
-
id_legacy=payload.get("idLegacy"),
|
|
30
|
-
id_authorization=payload.get("idAuthorization"),
|
|
31
|
-
id_item_report=payload.get("idItemReport"),
|
|
32
|
-
id_enterprise=payload.get("idEnterprise"),
|
|
33
|
-
user_full_name=payload.get("userFullName"),
|
|
34
|
-
abbreviation=payload.get("abbreviation"),
|
|
35
|
-
aes_key_auth=payload.get("aesKeyAuth"),
|
|
36
|
-
aes_key_user=payload.get("aesKeyUser"),
|
|
37
|
-
base_id_external_enterprise=payload.get("idExternalEnterprise")
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
# Validate via RPC
|
|
41
|
-
payload = {
|
|
42
|
-
"idToken": token.id_token,
|
|
43
|
-
"idUser": token.id_user
|
|
44
|
-
}
|
|
45
|
-
is_valid = await self.auth_validator.validate_auth_token(payload)
|
|
46
|
-
if not int(is_valid):
|
|
47
|
-
raise ValueError("You are not authorized to access this portal.")
|
|
48
|
-
|
|
49
|
-
return token
|
|
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
|
{encryptors-2.81.2 → encryptors-2.81.3}/src/Osdental/Database/StoredProcedureResultValidator.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
|
|
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
|
|
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
|