Encryptors 2.42__tar.gz → 2.43__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 (89) hide show
  1. {encryptors-2.42 → encryptors-2.43}/PKG-INFO +1 -1
  2. {encryptors-2.42 → encryptors-2.43}/setup.py +1 -1
  3. {encryptors-2.42 → encryptors-2.43}/src/Encryptors.egg-info/PKG-INFO +1 -1
  4. encryptors-2.43/src/Osdental/Decorators/SecureResolver.py +61 -0
  5. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/Extensions/AuditExtension.py +17 -18
  6. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Helpers/AuditDispatcher.py +6 -5
  7. encryptors-2.42/src/Osdental/Decorators/SecureResolver.py +0 -56
  8. {encryptors-2.42 → encryptors-2.43}/README.md +0 -0
  9. {encryptors-2.42 → encryptors-2.43}/setup.cfg +0 -0
  10. {encryptors-2.42 → encryptors-2.43}/src/Encryptors.egg-info/SOURCES.txt +0 -0
  11. {encryptors-2.42 → encryptors-2.43}/src/Encryptors.egg-info/dependency_links.txt +0 -0
  12. {encryptors-2.42 → encryptors-2.43}/src/Encryptors.egg-info/entry_points.txt +0 -0
  13. {encryptors-2.42 → encryptors-2.43}/src/Encryptors.egg-info/requires.txt +0 -0
  14. {encryptors-2.42 → encryptors-2.43}/src/Encryptors.egg-info/top_level.txt +0 -0
  15. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Cli/__init__.py +0 -0
  16. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Database/BaseRepository.py +0 -0
  17. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Database/Connection.py +0 -0
  18. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Database/__init__.py +0 -0
  19. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Decorators/Grpc.py +0 -0
  20. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Decorators/PublicResolver.py +0 -0
  21. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Decorators/Retry.py +0 -0
  22. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Decorators/SqlDataNormalizer.py +0 -0
  23. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Decorators/__init__.py +0 -0
  24. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Encryptor/Aes.py +0 -0
  25. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Encryptor/Argon2.py +0 -0
  26. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Encryptor/Bcrypt.py +0 -0
  27. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Encryptor/Jwt.py +0 -0
  28. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Encryptor/Rsa.py +0 -0
  29. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Encryptor/Sha512.py +0 -0
  30. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Encryptor/__init__.py +0 -0
  31. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Exception/ControlledException.py +0 -0
  32. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Exception/__init__.py +0 -0
  33. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/Extensions/__init__.py +0 -0
  34. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/Models/__init__.py +0 -0
  35. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/_Exceptions/__init__.py +0 -0
  36. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/_Helpers/_AuditHelper.py +0 -0
  37. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/_Helpers/_ExtractAuthToken.py +0 -0
  38. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/_Helpers/_TenantPolicy.py +0 -0
  39. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/_Helpers/_TokenService.py +0 -0
  40. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/_Helpers/__init__.py +0 -0
  41. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/__init__.py +0 -0
  42. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Helpers/KeyVaultService.py +0 -0
  43. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Helpers/ResponseDecryptor.py +0 -0
  44. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Helpers/__init__.py +0 -0
  45. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Http/APIClient.py +0 -0
  46. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Http/_Exceptions.py +0 -0
  47. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Http/__init__.py +0 -0
  48. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Messaging/AzureServiceBus.py +0 -0
  49. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Messaging/Kafka.py +0 -0
  50. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Messaging/RabbitMQ.py +0 -0
  51. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Messaging/__init__.py +0 -0
  52. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Models/AuditConfig.py +0 -0
  53. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Models/Response.py +0 -0
  54. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Models/Token.py +0 -0
  55. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Models/_Audit.py +0 -0
  56. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Models/__init__.py +0 -0
  57. {encryptors-2.42 → encryptors-2.43}/src/Osdental/RedisCache/Redis.py +0 -0
  58. {encryptors-2.42 → encryptors-2.43}/src/Osdental/RedisCache/__init__.py +0 -0
  59. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Rest/Context/RequestContext.py +0 -0
  60. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Rest/Context/__init__.py +0 -0
  61. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Rest/Middlewares/RequestContextMiddleware.py +0 -0
  62. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Rest/Middlewares/__init__.py +0 -0
  63. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Rest/__init__.py +0 -0
  64. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Enums/Code.py +0 -0
  65. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Enums/Constant.py +0 -0
  66. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Enums/FileType.py +0 -0
  67. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Enums/GrahpqlOperation.py +0 -0
  68. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Enums/Message.py +0 -0
  69. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Enums/Profile.py +0 -0
  70. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Enums/__init__.py +0 -0
  71. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Logger.py +0 -0
  72. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/CaseConverter.py +0 -0
  73. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/CodeGenerator.py +0 -0
  74. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/DataNormalizer.py +0 -0
  75. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/DataUtils.py +0 -0
  76. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/DateUtils.py +0 -0
  77. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/FileMetaData.py +0 -0
  78. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/HashValidator.py +0 -0
  79. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/Mapper.py +0 -0
  80. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/PasswordGenerator.py +0 -0
  81. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/QueryGenerator.py +0 -0
  82. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/RsaUtils.py +0 -0
  83. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/TextProcessor.py +0 -0
  84. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/__init__.py +0 -0
  85. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/__init__.py +0 -0
  86. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Storage/AzureBlobStorage.py +0 -0
  87. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Storage/S3Storage.py +0 -0
  88. {encryptors-2.42 → encryptors-2.43}/src/Osdental/Storage/__init__.py +0 -0
  89. {encryptors-2.42 → encryptors-2.43}/src/Osdental/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Encryptors
3
- Version: 2.42
3
+ Version: 2.43
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
  # ANDERSON ESTO YA SE SUBIO Y ESTA ESTABLE, AUN TE QUEDA PENDIENTE LA AUDITORIA CON RSA Y AES DE ACCESSTOKEN
3
3
  setup(
4
4
  name="Encryptors",
5
- version="2.42",
5
+ version="2.43",
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.42
3
+ Version: 2.43
4
4
  Summary: End-to-end algorithm library
5
5
  Author: OSDental LLC
6
6
  Author-email: support@osdental.ai
@@ -0,0 +1,61 @@
1
+ from functools import wraps
2
+ from typing import Callable
3
+ from Osdental.Models.Response import Response
4
+ from Osdental.Shared.Enums.Profile import Profile
5
+ from Osdental.Exception.ControlledException import OSDException, AccessDeniedException
6
+ from Osdental.Shared.Logger import logger
7
+
8
+ def resolver(public: bool = False, action=None):
9
+
10
+ def decorator(func: Callable):
11
+
12
+ @wraps(func)
13
+ async def wrapper(obj, info, **kwargs):
14
+ try:
15
+ context = info.context
16
+ token = getattr(context, "token", None)
17
+
18
+ # 🔐 AUTH
19
+ if not public:
20
+ if not token:
21
+ raise AccessDeniedException(
22
+ error="Authorization required"
23
+ )
24
+
25
+ # 🎯 AUTHORIZATION (roles)
26
+ if action:
27
+ if Profile(token.abbreviation) not in action.allowed_roles:
28
+ raise AccessDeniedException(
29
+ error="User not allowed to perform this action"
30
+ )
31
+
32
+ result = await func(obj, info, **kwargs)
33
+
34
+ if not isinstance(result, Response):
35
+ raise TypeError("Resolver must return a Response instance")
36
+
37
+ return result
38
+
39
+ except OSDException as e:
40
+ logger.warning(f"Business error: {str(e)}")
41
+
42
+ return Response(
43
+ status=e.status_code,
44
+ message=e.message,
45
+ error=None
46
+ ).send()
47
+
48
+ except Exception as e:
49
+ logger.exception(f"Unexpected error: {str(e)}")
50
+
51
+ return Response(
52
+ status="DB_ERROR_UNEXPECTED",
53
+ message="Could not process request.",
54
+ error=str(e)
55
+ ).send()
56
+
57
+ wrapper._is_public = public
58
+
59
+ return wrapper
60
+
61
+ return decorator
@@ -1,5 +1,4 @@
1
1
  import json
2
- import copy
3
2
  from graphql.pyutils import is_awaitable
4
3
  from ariadne.types import Extension
5
4
  from Osdental.Shared.Logger import logger
@@ -9,8 +8,8 @@ from Osdental.Rest.Context.RequestContext import (
9
8
  current_context,
10
9
  RequestContext
11
10
  )
11
+ from Osdental.Models.Response import Response
12
12
  from Osdental.Graphql.Models import BaseGraphQLContext
13
- from Osdental.Helpers.ResponseDecryptor import encryptor_data, VALID_TYPES
14
13
  from Osdental.Shared.Enums.Constant import Constant
15
14
 
16
15
  class AuditExtension(Extension):
@@ -39,8 +38,7 @@ class AuditExtension(Extension):
39
38
  request = context.request
40
39
 
41
40
  # cache body
42
- if not hasattr(context, "_cached_body"):
43
- context._cached_body = await request.json()
41
+ context._cached_body = getattr(context, "_cached_body", None) or await request.json()
44
42
 
45
43
  body = context._cached_body
46
44
 
@@ -121,7 +119,7 @@ class AuditExtension(Extension):
121
119
  decrypted_payload = None
122
120
 
123
121
  if decrypted_payload is not None:
124
- context.decrypted_payload = decrypted_payload
122
+ kwargs["data"] = decrypted_payload
125
123
 
126
124
  if not is_public:
127
125
  token = TenantPolicy.resolve(
@@ -155,13 +153,6 @@ class AuditExtension(Extension):
155
153
  if is_root and self.result is None:
156
154
  self.result = result
157
155
 
158
- if not getattr(context, "audit_plain_response", None):
159
- if result.encryption_type in VALID_TYPES and result.key:
160
- result_copy = copy.deepcopy(result)
161
- result = encryptor_data(result.encryption_type, result.key, result.data)
162
-
163
- context.audit_plain_response = result_copy
164
-
165
156
  return result
166
157
 
167
158
  def has_errors(self, errors, context):
@@ -174,13 +165,18 @@ class AuditExtension(Extension):
174
165
 
175
166
  query = self.request_payload.get("query", "")
176
167
 
177
- if "__schema" in query or "__type" in query:
168
+ if self._should_skip({"query": query}):
169
+ return
170
+
171
+ if self.result is None:
178
172
  return
179
173
 
180
- final_result = context.audit_plain_response or self.result
174
+ decrypted_key = None
181
175
 
182
- if final_result is None:
183
- return
176
+ if isinstance(self.result, Response):
177
+ decrypted_key = self.result.key or context.aes_auth
178
+ else:
179
+ decrypted_key = context.aes_auth
184
180
 
185
181
  dispatcher = context.request.app.state.audit_dispatcher
186
182
 
@@ -188,8 +184,11 @@ class AuditExtension(Extension):
188
184
  dispatcher.dispatch(
189
185
  request=self.request,
190
186
  request_payload=self.request_payload,
191
- result=final_result,
187
+ result=self.result,
188
+ metadata={
189
+ "decrypted_key": decrypted_key
190
+ },
192
191
  audit_type=Constant.MESSAGE_LOG_INTERNAL
193
192
  )
194
193
  except Exception as e:
195
- logger(f"[AUDIT ERROR]: {str(e)}")
194
+ logger.warning(f"[AUDIT ERROR]: {str(e)}")
@@ -40,6 +40,7 @@ class AuditDispatcher:
40
40
  request: Request,
41
41
  request_payload: Dict[str, Any],
42
42
  result: Response,
43
+ metadata: Dict[str, Any],
43
44
  audit_type: str = None
44
45
  ):
45
46
  try:
@@ -47,6 +48,7 @@ class AuditDispatcher:
47
48
  "request": request,
48
49
  "request_payload": request_payload,
49
50
  "result": result,
51
+ "metadata": metadata,
50
52
  "audit_type": audit_type
51
53
  }
52
54
 
@@ -77,6 +79,7 @@ class AuditDispatcher:
77
79
  request_payload = payload["request_payload"]
78
80
  result: Response = payload["result"]
79
81
  audit_type = payload["audit_type"]
82
+ metadata = payload["metadata"]
80
83
 
81
84
  operation_name = request_payload.get("operation_name")
82
85
  if operation_name == 'UnknownOperation':
@@ -100,9 +103,8 @@ class AuditDispatcher:
100
103
 
101
104
  # Obtencion de campos adicionales cuando es otro tipo de encriptacion o clave
102
105
  encryption_type = result.encryption_type
103
- key = result.key
106
+ decrypted_key = metadata["decrypted_key"]
104
107
 
105
-
106
108
  if audit_type == Constant.MESSAGE_LOG_INTERNAL:
107
109
 
108
110
  ERROR_PREFIXES = ("DB_ERROR", "DB_WARNING")
@@ -116,7 +118,6 @@ class AuditDispatcher:
116
118
  except ValueError:
117
119
  is_error = True
118
120
 
119
-
120
121
  if is_error:
121
122
  payload = AuditHelper.build_final_payload(
122
123
  _type="ERROR",
@@ -127,8 +128,8 @@ class AuditDispatcher:
127
128
  audit_message = request_audit_payload | payload
128
129
 
129
130
  else:
130
- if encryption_type in VALID_TYPES and key:
131
- data = decryptor_data(encryption_type, key, data)
131
+ if encryption_type in VALID_TYPES and decrypted_key:
132
+ data = decryptor_data(encryption_type, decrypted_key, data)
132
133
 
133
134
  payload = AuditHelper.build_final_payload(
134
135
  _type="RESPONSE",
@@ -1,56 +0,0 @@
1
- import inspect
2
- import copy
3
- from functools import wraps
4
- from typing import Callable, Dict, Any
5
- from Osdental.Models.Token import AuthToken
6
- from Osdental.Models.Response import Response
7
- from Osdental.Shared.Enums.Profile import Profile
8
- from Osdental.Exception.ControlledException import OSDException, AccessDeniedException
9
- from Osdental.Encryptor.Aes import AES
10
- from Osdental.Graphql.Models import BaseGraphQLContext
11
- from Osdental.Shared.Logger import logger
12
-
13
- def secure_resolver(action = None):
14
- def decorator(func: Callable):
15
-
16
- signature = inspect.signature(func)
17
- params = signature.parameters
18
-
19
- @wraps(func)
20
- async def wrapper(obj: Any, context: BaseGraphQLContext, **kwargs: Dict[str, Any]):
21
- try:
22
- token: AuthToken = context.token
23
- payload = getattr(context, "decrypted_payload", None)
24
- aes_auth = getattr(context, "aes_auth", None)
25
-
26
- if action:
27
- if Profile(token.abbreviation) not in action.allowed_roles:
28
- raise AccessDeniedException(error="The user's profile is not allowed to perform this action.")
29
-
30
- if "token" in params:
31
- kwargs["token"] = token
32
-
33
- if "data" in params:
34
- kwargs["data"] = payload
35
-
36
- result: Response = await func(obj, **kwargs)
37
-
38
- context.audit_plain_response = copy.deepcopy(result)
39
-
40
- if result.data is not None and result.encryption_type == "AES" and result.key is None:
41
- result.data = AES.encrypt(aes_auth, result.data)
42
-
43
- return result.send()
44
-
45
- except (Exception, OSDException) as e:
46
- logger.exception(f"An error has occurred: {str(e)}")
47
- result = Response(
48
- status=getattr(e, "status_code", "DB_ERROR_UNEXPECTED"),
49
- message=getattr(e, "message", "Could not process request."),
50
- error=f"{type(e).__name__}: {str(e)}"
51
- )
52
- context.audit_plain_response = result
53
- return result.send()
54
-
55
- return wrapper
56
- return decorator
File without changes
File without changes