Encryptors 2.34__tar.gz → 2.36__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.
Files changed (88) hide show
  1. {encryptors-2.34 → encryptors-2.36}/PKG-INFO +1 -1
  2. {encryptors-2.34 → encryptors-2.36}/setup.py +1 -1
  3. {encryptors-2.34 → encryptors-2.36}/src/Encryptors.egg-info/PKG-INFO +1 -1
  4. {encryptors-2.34 → encryptors-2.36}/src/Encryptors.egg-info/SOURCES.txt +1 -0
  5. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Decorators/SecureResolver.py +11 -13
  6. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Encryptor/Aes.py +10 -10
  7. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Exception/ControlledException.py +9 -0
  8. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Graphql/Extensions/AuditExtension.py +29 -11
  9. encryptors-2.36/src/Osdental/Graphql/Models/__init__.py +14 -0
  10. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Graphql/_Exceptions/__init__.py +1 -1
  11. encryptors-2.36/src/Osdental/Graphql/_Helpers/_ExtractAuthToken.py +11 -0
  12. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Graphql/_Helpers/_TenantPolicy.py +10 -7
  13. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Graphql/_Helpers/_TokenService.py +6 -9
  14. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Helpers/AuditDispatcher.py +1 -1
  15. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Http/APIClient.py +4 -2
  16. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Models/Token.py +0 -2
  17. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Enums/Code.py +1 -0
  18. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Enums/Message.py +1 -0
  19. encryptors-2.34/src/Osdental/Graphql/_Helpers/_ExtractAuthToken.py +0 -11
  20. {encryptors-2.34 → encryptors-2.36}/README.md +0 -0
  21. {encryptors-2.34 → encryptors-2.36}/setup.cfg +0 -0
  22. {encryptors-2.34 → encryptors-2.36}/src/Encryptors.egg-info/dependency_links.txt +0 -0
  23. {encryptors-2.34 → encryptors-2.36}/src/Encryptors.egg-info/entry_points.txt +0 -0
  24. {encryptors-2.34 → encryptors-2.36}/src/Encryptors.egg-info/requires.txt +0 -0
  25. {encryptors-2.34 → encryptors-2.36}/src/Encryptors.egg-info/top_level.txt +0 -0
  26. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Cli/__init__.py +0 -0
  27. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Database/BaseRepository.py +0 -0
  28. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Database/Connection.py +0 -0
  29. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Database/__init__.py +0 -0
  30. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Decorators/Grpc.py +0 -0
  31. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Decorators/Retry.py +0 -0
  32. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Decorators/SqlDataNormalizer.py +0 -0
  33. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Decorators/__init__.py +0 -0
  34. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Encryptor/Argon2.py +0 -0
  35. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Encryptor/Bcrypt.py +0 -0
  36. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Encryptor/Jwt.py +0 -0
  37. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Encryptor/Rsa.py +0 -0
  38. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Encryptor/Sha512.py +0 -0
  39. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Encryptor/__init__.py +0 -0
  40. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Exception/__init__.py +0 -0
  41. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Graphql/Extensions/__init__.py +0 -0
  42. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Graphql/_Helpers/_AuditHelper.py +0 -0
  43. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Graphql/_Helpers/__init__.py +0 -0
  44. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Graphql/__init__.py +0 -0
  45. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Helpers/KeyVaultService.py +0 -0
  46. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Helpers/__init__.py +0 -0
  47. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Http/_Exceptions.py +0 -0
  48. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Http/__init__.py +0 -0
  49. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Messaging/AzureServiceBus.py +0 -0
  50. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Messaging/Kafka.py +0 -0
  51. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Messaging/RabbitMQ.py +0 -0
  52. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Messaging/__init__.py +0 -0
  53. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Models/AuditConfig.py +0 -0
  54. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Models/Catalog.py +0 -0
  55. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Models/Legacy.py +0 -0
  56. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Models/Response.py +0 -0
  57. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Models/_Audit.py +0 -0
  58. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Models/__init__.py +0 -0
  59. {encryptors-2.34 → encryptors-2.36}/src/Osdental/RedisCache/Redis.py +0 -0
  60. {encryptors-2.34 → encryptors-2.36}/src/Osdental/RedisCache/__init__.py +0 -0
  61. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Rest/Context/RequestContext.py +0 -0
  62. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Rest/Context/__init__.py +0 -0
  63. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Rest/Middlewares/RequestContextMiddleware.py +0 -0
  64. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Rest/Middlewares/__init__.py +0 -0
  65. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Rest/__init__.py +0 -0
  66. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Enums/Constant.py +0 -0
  67. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Enums/FileType.py +0 -0
  68. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Enums/GrahpqlOperation.py +0 -0
  69. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Enums/Profile.py +0 -0
  70. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Enums/__init__.py +0 -0
  71. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Logger.py +0 -0
  72. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Utils/CaseConverter.py +0 -0
  73. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Utils/CodeGenerator.py +0 -0
  74. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Utils/DataNormalizer.py +0 -0
  75. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Utils/DataUtils.py +0 -0
  76. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Utils/DateUtils.py +0 -0
  77. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Utils/FileMetaData.py +0 -0
  78. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Utils/HashValidator.py +0 -0
  79. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Utils/Mapper.py +0 -0
  80. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Utils/PasswordGenerator.py +0 -0
  81. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Utils/QueryGenerator.py +0 -0
  82. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Utils/TextProcessor.py +0 -0
  83. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/Utils/__init__.py +0 -0
  84. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Shared/__init__.py +0 -0
  85. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Storage/AzureBlobStorage.py +0 -0
  86. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Storage/S3Storage.py +0 -0
  87. {encryptors-2.34 → encryptors-2.36}/src/Osdental/Storage/__init__.py +0 -0
  88. {encryptors-2.34 → encryptors-2.36}/src/Osdental/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Encryptors
3
- Version: 2.34
3
+ Version: 2.36
4
4
  Summary: End-to-end algorithm library
5
5
  Author: OSDental LLC
6
6
  Author-email: support@osdental.ai
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="Encryptors",
5
- version="2.34",
5
+ version="2.36",
6
6
  author="OSDental LLC",
7
7
  author_email="support@osdental.ai",
8
8
  description="End-to-end algorithm library",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Encryptors
3
- Version: 2.34
3
+ Version: 2.36
4
4
  Summary: End-to-end algorithm library
5
5
  Author: OSDental LLC
6
6
  Author-email: support@osdental.ai
@@ -28,6 +28,7 @@ src/Osdental/Exception/__init__.py
28
28
  src/Osdental/Graphql/__init__.py
29
29
  src/Osdental/Graphql/Extensions/AuditExtension.py
30
30
  src/Osdental/Graphql/Extensions/__init__.py
31
+ src/Osdental/Graphql/Models/__init__.py
31
32
  src/Osdental/Graphql/_Exceptions/__init__.py
32
33
  src/Osdental/Graphql/_Helpers/_AuditHelper.py
33
34
  src/Osdental/Graphql/_Helpers/_ExtractAuthToken.py
@@ -2,15 +2,13 @@ import inspect
2
2
  import copy
3
3
  from functools import wraps
4
4
  from typing import Callable, Dict, Any
5
- from graphql import GraphQLResolveInfo
6
5
  from Osdental.Models.Token import AuthToken
7
6
  from Osdental.Models.Response import Response
8
7
  from Osdental.Shared.Enums.Profile import Profile
9
- from Osdental.Exception.ControlledException import OSDException
8
+ from Osdental.Exception.ControlledException import OSDException, AccessDeniedException
10
9
  from Osdental.Encryptor.Aes import AES
10
+ from Osdental.Graphql.Models import BaseGraphQLContext
11
11
 
12
-
13
- aes = AES()
14
12
  def secure_resolver(action = None):
15
13
  def decorator(func: Callable):
16
14
 
@@ -18,25 +16,25 @@ def secure_resolver(action = None):
18
16
  accepts_data = "data" in signature.parameters
19
17
 
20
18
  @wraps(func)
21
- async def wrapper(obj: Any, info: GraphQLResolveInfo, **kwargs: Dict):
19
+ async def wrapper(obj: Any, context: BaseGraphQLContext, **kwargs: Dict[str, Any]):
22
20
  try:
23
- token: AuthToken = info.context.token
24
- payload = getattr(info.context, "decrypted_payload", None)
25
- aes_key = getattr(info.context, "aes_key", None)
21
+ token: AuthToken = context.token
22
+ payload = getattr(context, "decrypted_payload", None)
23
+ aes_auth = getattr(context, "aes_auth", None)
26
24
 
27
25
  if action:
28
26
  if Profile(token.abbreviation) not in action.allowed_roles:
29
- raise OSDException("DB_ERROR_AUTH", "You are not authorized to perform this action.")
27
+ raise AccessDeniedException(error="The user's profile is not allowed to perform this action.")
30
28
 
31
29
  if accepts_data and payload:
32
30
  kwargs["data"] = payload
33
31
 
34
- result: Response = await func(obj, info, **kwargs)
32
+ result: Response = await func(obj, context, **kwargs)
35
33
 
36
- info.context.audit_plain_response = copy.deepcopy(result)
34
+ context.audit_plain_response = copy.deepcopy(result)
37
35
 
38
36
  if result.data is not None:
39
- result.data = aes.encrypt(aes_key, result.data)
37
+ result.data = AES.encrypt(aes_auth, result.data)
40
38
 
41
39
  return result.send()
42
40
 
@@ -46,7 +44,7 @@ def secure_resolver(action = None):
46
44
  message=getattr(e, "message", "Could not process request."),
47
45
  error=f"{type(e).__name__}: {str(e)}"
48
46
  )
49
- info.context.audit_plain_response = result
47
+ context.audit_plain_response = result
50
48
  return result.send()
51
49
 
52
50
  return wrapper
@@ -10,9 +10,8 @@ from Osdental.Shared.Enums.Constant import Constant
10
10
 
11
11
  class AES:
12
12
 
13
- def __init__(self):
14
- self.IV_LENGTH = 32
15
- self.TAG_LENGTH = 16
13
+ IV_LENGTH = 32
14
+ TAG_LENGTH = 16
16
15
 
17
16
  @staticmethod
18
17
  def generate_key() -> str:
@@ -20,7 +19,8 @@ class AES:
20
19
  key = os.urandom(32)
21
20
  return base64.b64encode(key).decode(Constant.DEFAULT_ENCODING)
22
21
 
23
- def encrypt(self, aes_key:str, data:Dict[str,str] | str | List[Dict[str,str]]) -> str:
22
+ @classmethod
23
+ def encrypt(cls, aes_key:str, data:Dict[str,str] | str | List[Dict[str,str]]) -> str:
24
24
  """
25
25
  Encrypts data using AES-GCM.
26
26
  Supports dictionary, string, or list inputs.
@@ -34,7 +34,7 @@ class AES:
34
34
 
35
35
  try:
36
36
  key = base64.b64decode(aes_key)
37
- iv = os.urandom(self.IV_LENGTH)
37
+ iv = os.urandom(cls.IV_LENGTH)
38
38
  if isinstance(data, (dict, list)):
39
39
  json_data = json.dumps(data)
40
40
  else:
@@ -52,8 +52,8 @@ class AES:
52
52
  logger.error(f'Unexpected AES encryption error: {str(e)}')
53
53
  raise AESEncryptException(error=str(e))
54
54
 
55
-
56
- def decrypt(self, aes_key:str, encrypted_data:str, silent:bool = False):
55
+ @classmethod
56
+ def decrypt(cls, aes_key:str, encrypted_data:str, silent:bool = False):
57
57
  """
58
58
  Decrypts data using AES-GCM.
59
59
  Expects encrypted data to represent either a JSON object (dict) or a plain string.
@@ -65,9 +65,9 @@ class AES:
65
65
  try:
66
66
  key = base64.b64decode(aes_key)
67
67
  encrypted_data = base64.b64decode(encrypted_data)
68
- iv = encrypted_data[:self.IV_LENGTH]
69
- tag = encrypted_data[-self.TAG_LENGTH:]
70
- ciphertext = encrypted_data[self.IV_LENGTH:-self.TAG_LENGTH]
68
+ iv = encrypted_data[:cls.IV_LENGTH]
69
+ tag = encrypted_data[-cls.TAG_LENGTH:]
70
+ ciphertext = encrypted_data[cls.IV_LENGTH:-cls.TAG_LENGTH]
71
71
  cipher = Cipher(algorithms.AES(key), modes.GCM(iv, tag))
72
72
  decryptor = cipher.decryptor()
73
73
  plaintext = decryptor.update(ciphertext) + decryptor.finalize()
@@ -24,6 +24,15 @@ class UnauthorizedException(OSDException):
24
24
  ):
25
25
  super().__init__(message=message, error=error, status_code=status_code)
26
26
 
27
+ class AccessDeniedException(OSDException):
28
+ def __init__(
29
+ self,
30
+ message: str = Message.ACCESS_DENIED_MSG,
31
+ error: str = None,
32
+ status_code: str = Code.INVALID_REQUEST_PARAMS_CODE
33
+ ):
34
+ super().__init__(message=message, error=error, status_code=status_code)
35
+
27
36
  class RequestDataException(OSDException):
28
37
  def __init__(
29
38
  self,
@@ -3,36 +3,54 @@ from graphql.pyutils import is_awaitable
3
3
  from ariadne.types import Extension
4
4
  from Osdental.Encryptor.Aes import AES
5
5
  from Osdental.Graphql._Helpers._TenantPolicy import TenantPolicy
6
+ from Osdental.Rest.Context.RequestContext import (
7
+ current_context,
8
+ RequestContext
9
+ )
10
+ from Osdental.Graphql.Models import BaseGraphQLContext
6
11
  from Osdental.Graphql._Exceptions import AESKeyNotFound
7
12
  from Osdental.Shared.Enums.Constant import Constant
8
13
 
9
14
  class AuditExtension(Extension):
10
15
 
11
16
  def request_started(self, context):
17
+ request = context.request
18
+ self._ctx_token = current_context.set(
19
+ RequestContext(
20
+ request=request,
21
+ request_id=request.headers.get("x-request-id"),
22
+ user=None
23
+ )
24
+ )
25
+
12
26
  self.errors = None
13
27
  self.request_payload = None
14
28
  self.result = None
15
- self.aes = AES()
16
29
 
17
30
  async def resolve(self, next_, root, info, **kwargs):
18
31
 
19
32
  if not self.request_payload:
20
- context = info.context
33
+ context: BaseGraphQLContext = info.context
21
34
 
22
- request = info.context.request
35
+ request = context.request
23
36
  self.request = request
24
37
 
25
- body = request.state.graphql_body
38
+ body = await request.json()
39
+ headers = request.headers
26
40
 
27
41
  container = context.container
28
-
29
42
  token_service = container.token_service
30
43
 
31
- aes_key = request.app.state.aes_auth
32
- if not aes_key:
33
- raise AESKeyNotFound("Could not find authorization key Aes.")
44
+ aes_auth = request.app.state.aes_auth
45
+ aes_user = request.app.state.aes_user
46
+
47
+ if not aes_auth:
48
+ raise AESKeyNotFound("AES user key is missing.", "aes_auth")
49
+
50
+ if not aes_user:
51
+ raise AESKeyNotFound("AES authorization key is missing.", "aes_user")
34
52
 
35
- original_token = await token_service.authenticate(request)
53
+ original_token = await token_service.authenticate(headers, aes_user)
36
54
 
37
55
  variables = body.get("variables") or {}
38
56
  encrypted_payload = variables.get("data")
@@ -41,7 +59,7 @@ class AuditExtension(Extension):
41
59
 
42
60
  if encrypted_payload:
43
61
  try:
44
- decrypted_payload = self.aes.decrypt(aes_key, encrypted_payload)
62
+ decrypted_payload = AES.decrypt(aes_auth, encrypted_payload)
45
63
 
46
64
  try:
47
65
  decrypted_payload = json.loads(decrypted_payload)
@@ -68,7 +86,7 @@ class AuditExtension(Extension):
68
86
 
69
87
  context.decrypted_payload = decrypted_payload
70
88
  context.token = token
71
- context.aes_key = aes_key
89
+ context.aes_auth = aes_auth
72
90
 
73
91
  result = next_(root, info, **kwargs)
74
92
 
@@ -0,0 +1,14 @@
1
+ from dataclasses import dataclass
2
+ from typing import Optional, Any
3
+ from fastapi import Request
4
+ from Osdental.Models.Token import AuthToken
5
+
6
+ @dataclass
7
+ class BaseGraphQLContext:
8
+ request: Request
9
+ container: Any
10
+ # valores agregados durante ejecución (AuditExtention)
11
+ token: Optional[AuthToken] = None
12
+ decrypted_payload: Optional[dict] = None
13
+ aes_auth: Optional[str] = None
14
+ audit_plain_response: Optional[Any] = None
@@ -3,6 +3,6 @@ from Osdental.Exception.ControlledException import OSDException
3
3
  class AESKeyNotFound(OSDException):
4
4
  def __init__(
5
5
  self,
6
- error: str = None,
6
+ error: str = None
7
7
  ):
8
8
  super().__init__(error=error)
@@ -0,0 +1,11 @@
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]
@@ -14,13 +14,16 @@ class TenantPolicy:
14
14
  decrypted_payload: Dict[str, Any],
15
15
  operation_type: str
16
16
  ) -> AuthToken:
17
- aes = AES()
18
- # Solo aplicamos cambios si es QUERY
19
- if operation_type != OperationType.QUERY.value:
20
- return token # devolver token tal cual
21
17
 
18
+ # Set original idExternalEnterprise
19
+ token.base_id_external_enterprise = token.id_external_enterprise
22
20
  # SUPER ADMIN / OSDEL ADMIN -> UUID 0
23
- if token.abbreviation.startswith(("SPAU", "OSDA")):
21
+ should_use_zero_uuid = (
22
+ token.abbreviation.startswith(("SPAU", "OSDA"))
23
+ and operation_type == OperationType.QUERY
24
+ )
25
+
26
+ if should_use_zero_uuid:
24
27
  token.id_external_enterprise = str(UUID(int=0))
25
28
  return token
26
29
 
@@ -28,13 +31,13 @@ class TenantPolicy:
28
31
  if token.abbreviation.startswith("OSDMK"):
29
32
  dynamic_client_id = headers.get("dynamicClientId")
30
33
  if dynamic_client_id:
31
- decrypted_mk_id = aes.decrypt(token.aes_key_auth, dynamic_client_id)
34
+ decrypted_mk_id = AES.decrypt(token.aes_key_auth, dynamic_client_id)
32
35
  token.id_external_enterprise = decrypted_mk_id
33
36
  token.mk_id_external_enterprise = decrypted_mk_id
34
37
  return token
35
38
 
36
39
  # If it comes by request, it is taken as priority
37
- external_enterprise_req = decrypted_payload.get('idExternalEnterprise')
40
+ external_enterprise_req = decrypted_payload.get("idExternalEnterprise")
38
41
  if external_enterprise_req and token:
39
42
  token.id_external_enterprise = external_enterprise_req
40
43
 
@@ -1,4 +1,4 @@
1
- from fastapi import Request
1
+ from starlette.datastructures import Headers
2
2
  from Osdental.Encryptor.Aes import AES
3
3
  from Osdental.Encryptor.Jwt import JWT
4
4
  from Osdental.Models.Token import AuthToken
@@ -9,23 +9,20 @@ class TokenService:
9
9
  def __init__(self, jwt_user_key: str, auth_validator):
10
10
  self.jwt_user_key = jwt_user_key
11
11
  self.auth_validator = auth_validator
12
- self.aes = AES()
13
12
 
14
- async def authenticate(self, request: Request) -> AuthToken:
15
- encrypted_token = ExtractAuthToken.get_auth_token(request)
13
+ async def authenticate(self, headers: Headers, aes_user: str) -> AuthToken:
14
+ encrypted_token = ExtractAuthToken.get_auth_token(headers)
16
15
 
17
- aes_user = request.app.state.aes_user
18
-
19
- user_token = self.aes.decrypt(aes_user, encrypted_token)
16
+ user_token = AES.decrypt(aes_user, encrypted_token)
20
17
  payload = JWT.extract_payload(user_token, self.jwt_user_key)
21
18
  token = AuthToken(**payload)
22
19
 
23
20
  # Validate via RPC
24
- request = {
21
+ paylod = {
25
22
  'idToken': token.id_token,
26
23
  'idUser': token.id_user
27
24
  }
28
- is_valid = await self.auth_validator.validate_auth_token(request)
25
+ is_valid = await self.auth_validator.validate_auth_token(paylod)
29
26
  if not is_valid:
30
27
  raise ValueError("You are not authorized to access this portal.")
31
28
 
@@ -87,7 +87,7 @@ class AuditDispatcher:
87
87
  request=request,
88
88
  audit_config=self._audit_config,
89
89
  operation_name=operation_name,
90
- full_name=request_payload.get("user"),
90
+ full_name=request_payload.get("user", "Joe Doe"),
91
91
  payload=request_payload.get("variables")
92
92
  )
93
93
  request_audit_payload = await AuditHelper.build_request_payload(audit=audit)
@@ -37,9 +37,11 @@ class APIClient:
37
37
  **kwargs
38
38
  )
39
39
 
40
- request = current_context.get()
40
+ ctx = current_context.get()
41
+
42
+ if ctx and ctx.request:
43
+ request = ctx.request
41
44
 
42
- if request:
43
45
  dispatcher = request.app.state.audit_dispatcher
44
46
  dispatcher.dispatch(
45
47
  request=request,
@@ -18,8 +18,6 @@ class AuthToken(BaseModel):
18
18
  access_token: Optional[str] = Field(default=None, alias="accessToken")
19
19
  base_id_external_enterprise: Optional[str] = Field(default=None, alias="baseIdExternalEnterprise")
20
20
  mk_id_external_enterprise: Optional[str] = Field(default=None, alias="mkIdExternalEnterprise")
21
- jwt_user_key: Optional[str] = Field(default=None, alias="jwtUserKey")
22
- legacy: Optional[Legacy] = Field(default=None, alias="legacy")
23
21
 
24
22
  class ConfigDict:
25
23
  populate_by_name = True
@@ -8,6 +8,7 @@ class Code(StrEnum):
8
8
  APP_ERROR_CODE = 'DB_ERROR_CONTROLLED'
9
9
  UNEXPECTED_ERROR_CODE = 'DB_ERROR_UNEXPECTED'
10
10
  INVALID_REQUEST_PARAMS_CODE = 'DB_WARNING_INVALID_REQUEST_PARAMS'
11
+ ACCESS_DENIED_CODE = "DB_WARNING_ACCESS_DENIED_CODE"
11
12
  DATABASE_ERROR_CODE = 'DB_WARNING_DATABASE_ERROR'
12
13
  DATABASE_CONNECTION_ERROR_CODE = 'DB_ERROR_DATABASE_CONNECTION'
13
14
  RSA_ERROR_CODE = 'DB_ERROR_RSA'
@@ -1,6 +1,7 @@
1
1
  from enum import StrEnum
2
2
 
3
3
  class Message(StrEnum):
4
+ ACCESS_DENIED_MSG = "You do not have the necessary privileges for this operation."
4
5
  UNEXPECTED_ERROR_MSG = 'Something went wrong while processing your request. Please try again later.'
5
6
  PORTAL_ACCESS_RESTRICTED_MSG = 'You are not authorized to access this portal.'
6
7
  PROCESS_SUCCESS_MSG = 'Process executed successfully.'
@@ -1,11 +0,0 @@
1
- from fastapi import Request
2
-
3
- class ExtractAuthToken:
4
-
5
- @staticmethod
6
- def get_auth_token(request: Request) -> str:
7
- authorization = request.headers.get("authorization")
8
- if not authorization or not authorization.startswith("Bearer "):
9
- raise ValueError("Missing Bearer token")
10
-
11
- return authorization.split(" ")[1]
File without changes
File without changes