Encryptors 2.39__tar.gz → 2.40__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.39 → encryptors-2.40}/PKG-INFO +1 -20
  2. {encryptors-2.39 → encryptors-2.40}/setup.py +1 -1
  3. {encryptors-2.39 → encryptors-2.40}/src/Encryptors.egg-info/PKG-INFO +1 -20
  4. {encryptors-2.39 → encryptors-2.40}/src/Encryptors.egg-info/SOURCES.txt +1 -0
  5. encryptors-2.40/src/Osdental/Decorators/PublicResolver.py +3 -0
  6. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Decorators/SecureResolver.py +8 -3
  7. encryptors-2.40/src/Osdental/Graphql/Extensions/AuditExtension.py +190 -0
  8. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Storage/AzureBlobStorage.py +5 -1
  9. encryptors-2.40/src/Osdental/__init__.py +0 -0
  10. encryptors-2.39/README.md +0 -17
  11. encryptors-2.39/src/Osdental/Graphql/Extensions/AuditExtension.py +0 -120
  12. /encryptors-2.39/src/Osdental/Database/__init__.py → /encryptors-2.40/README.md +0 -0
  13. {encryptors-2.39 → encryptors-2.40}/setup.cfg +0 -0
  14. {encryptors-2.39 → encryptors-2.40}/src/Encryptors.egg-info/dependency_links.txt +0 -0
  15. {encryptors-2.39 → encryptors-2.40}/src/Encryptors.egg-info/entry_points.txt +0 -0
  16. {encryptors-2.39 → encryptors-2.40}/src/Encryptors.egg-info/requires.txt +0 -0
  17. {encryptors-2.39 → encryptors-2.40}/src/Encryptors.egg-info/top_level.txt +0 -0
  18. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Cli/__init__.py +0 -0
  19. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Database/BaseRepository.py +0 -0
  20. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Database/Connection.py +0 -0
  21. {encryptors-2.39/src/Osdental/Decorators → encryptors-2.40/src/Osdental/Database}/__init__.py +0 -0
  22. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Decorators/Grpc.py +0 -0
  23. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Decorators/Retry.py +0 -0
  24. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Decorators/SqlDataNormalizer.py +0 -0
  25. {encryptors-2.39/src/Osdental/Encryptor → encryptors-2.40/src/Osdental/Decorators}/__init__.py +0 -0
  26. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Encryptor/Aes.py +0 -0
  27. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Encryptor/Argon2.py +0 -0
  28. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Encryptor/Bcrypt.py +0 -0
  29. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Encryptor/Jwt.py +0 -0
  30. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Encryptor/Rsa.py +0 -0
  31. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Encryptor/Sha512.py +0 -0
  32. {encryptors-2.39/src/Osdental/Exception → encryptors-2.40/src/Osdental/Encryptor}/__init__.py +0 -0
  33. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Exception/ControlledException.py +0 -0
  34. {encryptors-2.39/src/Osdental/Graphql/Extensions → encryptors-2.40/src/Osdental/Exception}/__init__.py +0 -0
  35. {encryptors-2.39/src/Osdental/Graphql/_Helpers → encryptors-2.40/src/Osdental/Graphql/Extensions}/__init__.py +0 -0
  36. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Graphql/Models/__init__.py +0 -0
  37. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Graphql/_Exceptions/__init__.py +0 -0
  38. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Graphql/_Helpers/_AuditHelper.py +0 -0
  39. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Graphql/_Helpers/_ExtractAuthToken.py +0 -0
  40. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Graphql/_Helpers/_TenantPolicy.py +0 -0
  41. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Graphql/_Helpers/_TokenService.py +0 -0
  42. {encryptors-2.39/src/Osdental/Graphql → encryptors-2.40/src/Osdental/Graphql/_Helpers}/__init__.py +0 -0
  43. {encryptors-2.39/src/Osdental/Helpers → encryptors-2.40/src/Osdental/Graphql}/__init__.py +0 -0
  44. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Helpers/AuditDispatcher.py +0 -0
  45. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Helpers/KeyVaultService.py +0 -0
  46. {encryptors-2.39/src/Osdental/Http → encryptors-2.40/src/Osdental/Helpers}/__init__.py +0 -0
  47. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Http/APIClient.py +0 -0
  48. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Http/_Exceptions.py +0 -0
  49. {encryptors-2.39/src/Osdental/Models → encryptors-2.40/src/Osdental/Http}/__init__.py +0 -0
  50. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Messaging/AzureServiceBus.py +0 -0
  51. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Messaging/Kafka.py +0 -0
  52. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Messaging/RabbitMQ.py +0 -0
  53. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Messaging/__init__.py +0 -0
  54. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Models/AuditConfig.py +0 -0
  55. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Models/Response.py +0 -0
  56. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Models/Token.py +0 -0
  57. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Models/_Audit.py +0 -0
  58. {encryptors-2.39/src/Osdental/RedisCache → encryptors-2.40/src/Osdental/Models}/__init__.py +0 -0
  59. {encryptors-2.39 → encryptors-2.40}/src/Osdental/RedisCache/Redis.py +0 -0
  60. {encryptors-2.39/src/Osdental/Rest/Context → encryptors-2.40/src/Osdental/RedisCache}/__init__.py +0 -0
  61. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Rest/Context/RequestContext.py +0 -0
  62. {encryptors-2.39/src/Osdental/Rest/Middlewares → encryptors-2.40/src/Osdental/Rest/Context}/__init__.py +0 -0
  63. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Rest/Middlewares/RequestContextMiddleware.py +0 -0
  64. {encryptors-2.39/src/Osdental/Rest → encryptors-2.40/src/Osdental/Rest/Middlewares}/__init__.py +0 -0
  65. {encryptors-2.39/src/Osdental/Shared/Enums → encryptors-2.40/src/Osdental/Rest}/__init__.py +0 -0
  66. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Enums/Code.py +0 -0
  67. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Enums/Constant.py +0 -0
  68. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Enums/FileType.py +0 -0
  69. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Enums/GrahpqlOperation.py +0 -0
  70. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Enums/Message.py +0 -0
  71. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Enums/Profile.py +0 -0
  72. {encryptors-2.39/src/Osdental/Shared/Utils → encryptors-2.40/src/Osdental/Shared/Enums}/__init__.py +0 -0
  73. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Logger.py +0 -0
  74. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Utils/CaseConverter.py +0 -0
  75. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Utils/CodeGenerator.py +0 -0
  76. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Utils/DataNormalizer.py +0 -0
  77. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Utils/DataUtils.py +0 -0
  78. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Utils/DateUtils.py +0 -0
  79. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Utils/FileMetaData.py +0 -0
  80. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Utils/HashValidator.py +0 -0
  81. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Utils/Mapper.py +0 -0
  82. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Utils/PasswordGenerator.py +0 -0
  83. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Utils/QueryGenerator.py +0 -0
  84. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Shared/Utils/TextProcessor.py +0 -0
  85. {encryptors-2.39/src/Osdental/Shared → encryptors-2.40/src/Osdental/Shared/Utils}/__init__.py +0 -0
  86. {encryptors-2.39/src/Osdental → encryptors-2.40/src/Osdental/Shared}/__init__.py +0 -0
  87. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Storage/S3Storage.py +0 -0
  88. {encryptors-2.39 → encryptors-2.40}/src/Osdental/Storage/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Encryptors
3
- Version: 2.39
3
+ Version: 2.40
4
4
  Summary: End-to-end algorithm library
5
5
  Author: OSDental LLC
6
6
  Author-email: support@osdental.ai
@@ -59,26 +59,7 @@ Requires-Dist: gunicorn==23.0.0
59
59
  Dynamic: author
60
60
  Dynamic: author-email
61
61
  Dynamic: classifier
62
- Dynamic: description
63
62
  Dynamic: description-content-type
64
63
  Dynamic: requires-dist
65
64
  Dynamic: requires-python
66
65
  Dynamic: summary
67
-
68
- # osdental-library
69
-
70
- `osdental-library` is a versatile and easy-to-use library for handling common tasks related to **encryption**, **hashing**, and **JWT token management**. Ideal for projects that require a secure and efficient approach to handling sensitive data.
71
-
72
- ## Features
73
-
74
- - Generation and validation of **hashes** using modern algorithms.
75
- - Encryption and decryption of data using secure keys.
76
- - Creation and verification of **JWT tokens** for authentication and authorization.
77
- - Implementations that are easy to integrate into any Python project.
78
-
79
- ## Installation
80
-
81
- You can easily install `osdental-library` using `pip`:
82
-
83
- ```bash
84
- pip install osdental-library
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="Encryptors",
5
- version="2.39",
5
+ version="2.40",
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.39
3
+ Version: 2.40
4
4
  Summary: End-to-end algorithm library
5
5
  Author: OSDental LLC
6
6
  Author-email: support@osdental.ai
@@ -59,26 +59,7 @@ Requires-Dist: gunicorn==23.0.0
59
59
  Dynamic: author
60
60
  Dynamic: author-email
61
61
  Dynamic: classifier
62
- Dynamic: description
63
62
  Dynamic: description-content-type
64
63
  Dynamic: requires-dist
65
64
  Dynamic: requires-python
66
65
  Dynamic: summary
67
-
68
- # osdental-library
69
-
70
- `osdental-library` is a versatile and easy-to-use library for handling common tasks related to **encryption**, **hashing**, and **JWT token management**. Ideal for projects that require a secure and efficient approach to handling sensitive data.
71
-
72
- ## Features
73
-
74
- - Generation and validation of **hashes** using modern algorithms.
75
- - Encryption and decryption of data using secure keys.
76
- - Creation and verification of **JWT tokens** for authentication and authorization.
77
- - Implementations that are easy to integrate into any Python project.
78
-
79
- ## Installation
80
-
81
- You can easily install `osdental-library` using `pip`:
82
-
83
- ```bash
84
- pip install osdental-library
@@ -12,6 +12,7 @@ src/Osdental/Database/BaseRepository.py
12
12
  src/Osdental/Database/Connection.py
13
13
  src/Osdental/Database/__init__.py
14
14
  src/Osdental/Decorators/Grpc.py
15
+ src/Osdental/Decorators/PublicResolver.py
15
16
  src/Osdental/Decorators/Retry.py
16
17
  src/Osdental/Decorators/SecureResolver.py
17
18
  src/Osdental/Decorators/SqlDataNormalizer.py
@@ -0,0 +1,3 @@
1
+ def public_resolver(resolver):
2
+ setattr(resolver, "_is_public", True)
3
+ return resolver
@@ -8,12 +8,13 @@ from Osdental.Shared.Enums.Profile import Profile
8
8
  from Osdental.Exception.ControlledException import OSDException, AccessDeniedException
9
9
  from Osdental.Encryptor.Aes import AES
10
10
  from Osdental.Graphql.Models import BaseGraphQLContext
11
+ from Osdental.Shared.Logger import logger
11
12
 
12
13
  def secure_resolver(action = None):
13
14
  def decorator(func: Callable):
14
15
 
15
16
  signature = inspect.signature(func)
16
- accepts_data = "data" in signature.parameters
17
+ params = signature.parameters
17
18
 
18
19
  @wraps(func)
19
20
  async def wrapper(obj: Any, context: BaseGraphQLContext, **kwargs: Dict[str, Any]):
@@ -26,10 +27,13 @@ def secure_resolver(action = None):
26
27
  if Profile(token.abbreviation) not in action.allowed_roles:
27
28
  raise AccessDeniedException(error="The user's profile is not allowed to perform this action.")
28
29
 
29
- if accepts_data and payload:
30
+ if "token" in params:
31
+ kwargs["token"] = token
32
+
33
+ if "data" in params:
30
34
  kwargs["data"] = payload
31
35
 
32
- result: Response = await func(obj, context, **kwargs)
36
+ result: Response = await func(obj, **kwargs)
33
37
 
34
38
  context.audit_plain_response = copy.deepcopy(result)
35
39
 
@@ -39,6 +43,7 @@ def secure_resolver(action = None):
39
43
  return result.send()
40
44
 
41
45
  except (Exception, OSDException) as e:
46
+ logger.exception(f"An error has occurred: {str(e)}")
42
47
  result = Response(
43
48
  status=getattr(e, "status_code", "DB_ERROR_UNEXPECTED"),
44
49
  message=getattr(e, "message", "Could not process request."),
@@ -0,0 +1,190 @@
1
+ import json
2
+ from graphql.pyutils import is_awaitable
3
+ from ariadne.types import Extension
4
+ from Osdental.Shared.Logger import logger
5
+ from Osdental.Encryptor.Aes import AES
6
+ from Osdental.Graphql._Helpers._TenantPolicy import TenantPolicy
7
+ from Osdental.Rest.Context.RequestContext import (
8
+ current_context,
9
+ RequestContext
10
+ )
11
+ from Osdental.Graphql.Models import BaseGraphQLContext
12
+ from Osdental.Shared.Enums.Constant import Constant
13
+
14
+ class AuditExtension(Extension):
15
+
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
+
26
+ self.errors = None
27
+ self.request_payload = None
28
+ self.result = None
29
+
30
+ def _should_skip(self, body) -> bool:
31
+ query = body.get("query", "") or ""
32
+ return "__schema" in query or "__type" in query
33
+
34
+ async def resolve(self, next_, root, info, **kwargs):
35
+
36
+ context: BaseGraphQLContext = info.context
37
+ request = context.request
38
+
39
+ # 🔹 cache body
40
+ if not hasattr(context, "_cached_body"):
41
+ context._cached_body = await request.json()
42
+
43
+ body = context._cached_body
44
+
45
+ # 🔹 skip introspection
46
+ if self._should_skip(body):
47
+ result = next_(root, info, **kwargs)
48
+ if is_awaitable(result):
49
+ result = await result
50
+ return result
51
+
52
+ # 🔥 CLAVE
53
+ is_root = root is None
54
+
55
+ # 🔥 SOLO ROOT → TODO TU SISTEMA
56
+ if is_root:
57
+
58
+ # 🔹 identificar resolver público
59
+ resolver_fn = getattr(next_, "__wrapped__", next_)
60
+ is_public = getattr(resolver_fn, "_is_public", False)
61
+
62
+ # 🔹 inicializar auth UNA SOLA VEZ
63
+ if not hasattr(context, "_auth_initialized"):
64
+ context._auth_initialized = True
65
+
66
+ headers = request.headers
67
+ container = context.container
68
+ token_service = container.token_service
69
+
70
+ aes_auth = request.app.state.aes_auth
71
+ aes_user = request.app.state.aes_user
72
+
73
+ if not aes_auth or not aes_user:
74
+ aes_auth = None
75
+ aes_user = None
76
+
77
+ original_token = None
78
+ if not is_public and headers.get("authorization"):
79
+ try:
80
+ original_token = await token_service.authenticate(headers, aes_user)
81
+ except Exception:
82
+ original_token = None
83
+
84
+ context._original_token = original_token
85
+ context.token = original_token
86
+ context.aes_auth = aes_auth
87
+
88
+ # 🔐 VALIDACIÓN SOLO ROOT
89
+ original_token = getattr(context, "_original_token", None)
90
+
91
+ if not is_public and not original_token:
92
+ raise ValueError("Authorization required")
93
+
94
+ # 🔹 payload
95
+ variables = body.get("variables") or {}
96
+
97
+ encrypted_payload = (
98
+ kwargs.get("data")
99
+ or variables.get("data")
100
+ )
101
+
102
+ decrypted_payload = None
103
+
104
+ if encrypted_payload is not None:
105
+ if isinstance(encrypted_payload, dict):
106
+ decrypted_payload = encrypted_payload
107
+
108
+ elif isinstance(encrypted_payload, str):
109
+ try:
110
+ decrypted_payload = json.loads(encrypted_payload)
111
+ except Exception:
112
+ if context.aes_auth:
113
+ try:
114
+ decrypted_payload = AES.decrypt(context.aes_auth, encrypted_payload)
115
+ try:
116
+ decrypted_payload = json.loads(decrypted_payload)
117
+ except Exception:
118
+ pass
119
+ except Exception:
120
+ decrypted_payload = None
121
+
122
+ if decrypted_payload is not None:
123
+ context.decrypted_payload = decrypted_payload
124
+
125
+ if not is_public:
126
+ token = TenantPolicy.resolve(
127
+ token=context._original_token,
128
+ headers=request.headers,
129
+ decrypted_payload=decrypted_payload,
130
+ operation_type=info.operation.operation.value
131
+ )
132
+ context.token = token
133
+
134
+ # 🔹 auditoría request
135
+ if not self.request_payload:
136
+ token = context.token
137
+
138
+ self.request = request
139
+ self.request_payload = {
140
+ "operation_type": info.operation.operation.value,
141
+ "operation_name": body.get("operationName", "UnknownOperation"),
142
+ "query": body.get("query"),
143
+ "variables": decrypted_payload,
144
+ "user": token.user_full_name if token else "Public"
145
+ }
146
+
147
+ # 🔥 SIEMPRE ejecutar resolver (root + fields)
148
+ result = next_(root, info, **kwargs)
149
+
150
+ if is_awaitable(result):
151
+ result = await result
152
+
153
+ # 🔹 SOLO ROOT captura resultado final
154
+ if is_root and self.result is None:
155
+ self.result = result
156
+
157
+ if not getattr(context, "audit_plain_response", None):
158
+ context.audit_plain_response = result
159
+
160
+ return result
161
+
162
+ def has_errors(self, errors, context):
163
+ self.errors = errors
164
+
165
+ def request_finished(self, context):
166
+
167
+ if not self.request_payload:
168
+ return
169
+
170
+ query = self.request_payload.get("query", "")
171
+
172
+ if "__schema" in query or "__type" in query:
173
+ return
174
+
175
+ final_result = context.audit_plain_response or self.result
176
+
177
+ if final_result is None:
178
+ return
179
+
180
+ dispatcher = context.request.app.state.audit_dispatcher
181
+
182
+ try:
183
+ dispatcher.dispatch(
184
+ request=self.request,
185
+ request_payload=self.request_payload,
186
+ result=final_result,
187
+ audit_type=Constant.MESSAGE_LOG_INTERNAL
188
+ )
189
+ except Exception as e:
190
+ logger(f"[AUDIT ERROR]: {str(e)}")
@@ -80,4 +80,8 @@ class AzureBlobStorage(IStorageService):
80
80
  return {
81
81
  "uploadUrl": url,
82
82
  "blobName": filename
83
- }
83
+ }
84
+
85
+ async def close(self):
86
+ await self._client.close()
87
+ await self._credential.close()
File without changes
encryptors-2.39/README.md DELETED
@@ -1,17 +0,0 @@
1
- # osdental-library
2
-
3
- `osdental-library` is a versatile and easy-to-use library for handling common tasks related to **encryption**, **hashing**, and **JWT token management**. Ideal for projects that require a secure and efficient approach to handling sensitive data.
4
-
5
- ## Features
6
-
7
- - Generation and validation of **hashes** using modern algorithms.
8
- - Encryption and decryption of data using secure keys.
9
- - Creation and verification of **JWT tokens** for authentication and authorization.
10
- - Implementations that are easy to integrate into any Python project.
11
-
12
- ## Installation
13
-
14
- You can easily install `osdental-library` using `pip`:
15
-
16
- ```bash
17
- pip install osdental-library
@@ -1,120 +0,0 @@
1
- import json
2
- from graphql.pyutils import is_awaitable
3
- from ariadne.types import Extension
4
- from Osdental.Encryptor.Aes import AES
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
11
- from Osdental.Graphql._Exceptions import AESKeyNotFound
12
- from Osdental.Shared.Enums.Constant import Constant
13
-
14
- class AuditExtension(Extension):
15
-
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
-
26
- self.errors = None
27
- self.request_payload = None
28
- self.result = None
29
-
30
- async def resolve(self, next_, root, info, **kwargs):
31
-
32
- if not self.request_payload:
33
- context: BaseGraphQLContext = info.context
34
-
35
- request = context.request
36
- self.request = request
37
-
38
- body = await request.json()
39
- headers = request.headers
40
-
41
- container = context.container
42
- token_service = container.token_service
43
-
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")
52
-
53
- original_token = await token_service.authenticate(headers, aes_user)
54
-
55
- variables = body.get("variables") or {}
56
- encrypted_payload = variables.get("data")
57
-
58
- decrypted_payload = None
59
-
60
- if encrypted_payload:
61
- try:
62
- decrypted_payload = AES.decrypt(aes_auth, encrypted_payload)
63
-
64
- try:
65
- decrypted_payload = json.loads(decrypted_payload)
66
- except Exception:
67
- pass
68
-
69
- except Exception:
70
- decrypted_payload = None
71
-
72
- token = TenantPolicy.resolve(
73
- token=original_token,
74
- headers=request.headers,
75
- decrypted_payload=decrypted_payload,
76
- operation_type=info.operation.operation.value
77
- )
78
-
79
- self.request_payload = {
80
- "operation_type": info.operation.operation.value,
81
- "operation_name": body.get("operationName", "UnknownOperation"),
82
- "query": body.get("query"),
83
- "variables": decrypted_payload,
84
- "user": token.user_full_name
85
- }
86
-
87
- context.decrypted_payload = decrypted_payload
88
- context.token = token
89
- context.aes_auth = aes_auth
90
-
91
- result = next_(root, info, **kwargs)
92
-
93
- if is_awaitable(result):
94
- result = await result
95
-
96
- if root is None:
97
- self.result = result
98
-
99
- return result
100
-
101
- def has_errors(self, errors, context):
102
- self.errors = errors
103
-
104
- def request_finished(self, context):
105
- if not self.request_payload: return
106
-
107
- query = self.request_payload.get("query", "")
108
-
109
- if "__schema" in query or "__type" in query: return
110
-
111
- if not hasattr(context, "audit_plain_response"): return
112
-
113
- dispatcher = context.request.app.state.audit_dispatcher
114
-
115
- dispatcher.dispatch(
116
- request=self.request,
117
- request_payload=self.request_payload,
118
- result=context.audit_plain_response,
119
- audit_type=Constant.MESSAGE_LOG_INTERNAL
120
- )
File without changes