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.
- {encryptors-2.42 → encryptors-2.43}/PKG-INFO +1 -1
- {encryptors-2.42 → encryptors-2.43}/setup.py +1 -1
- {encryptors-2.42 → encryptors-2.43}/src/Encryptors.egg-info/PKG-INFO +1 -1
- encryptors-2.43/src/Osdental/Decorators/SecureResolver.py +61 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/Extensions/AuditExtension.py +17 -18
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Helpers/AuditDispatcher.py +6 -5
- encryptors-2.42/src/Osdental/Decorators/SecureResolver.py +0 -56
- {encryptors-2.42 → encryptors-2.43}/README.md +0 -0
- {encryptors-2.42 → encryptors-2.43}/setup.cfg +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Encryptors.egg-info/SOURCES.txt +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Encryptors.egg-info/dependency_links.txt +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Encryptors.egg-info/entry_points.txt +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Encryptors.egg-info/requires.txt +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Encryptors.egg-info/top_level.txt +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Cli/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Database/BaseRepository.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Database/Connection.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Database/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Decorators/Grpc.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Decorators/PublicResolver.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Decorators/Retry.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Decorators/SqlDataNormalizer.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Decorators/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Encryptor/Aes.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Encryptor/Argon2.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Encryptor/Bcrypt.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Encryptor/Jwt.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Encryptor/Rsa.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Encryptor/Sha512.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Encryptor/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Exception/ControlledException.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Exception/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/Extensions/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/Models/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/_Exceptions/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/_Helpers/_AuditHelper.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/_Helpers/_ExtractAuthToken.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/_Helpers/_TenantPolicy.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/_Helpers/_TokenService.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/_Helpers/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Graphql/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Helpers/KeyVaultService.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Helpers/ResponseDecryptor.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Helpers/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Http/APIClient.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Http/_Exceptions.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Http/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Messaging/AzureServiceBus.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Messaging/Kafka.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Messaging/RabbitMQ.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Messaging/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Models/AuditConfig.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Models/Response.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Models/Token.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Models/_Audit.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Models/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/RedisCache/Redis.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/RedisCache/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Rest/Context/RequestContext.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Rest/Context/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Rest/Middlewares/RequestContextMiddleware.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Rest/Middlewares/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Rest/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Enums/Code.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Enums/Constant.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Enums/FileType.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Enums/GrahpqlOperation.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Enums/Message.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Enums/Profile.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Enums/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Logger.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/CaseConverter.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/CodeGenerator.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/DataNormalizer.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/DataUtils.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/DateUtils.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/FileMetaData.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/HashValidator.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/Mapper.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/PasswordGenerator.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/QueryGenerator.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/RsaUtils.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/TextProcessor.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/Utils/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Shared/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Storage/AzureBlobStorage.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Storage/S3Storage.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/Storage/__init__.py +0 -0
- {encryptors-2.42 → encryptors-2.43}/src/Osdental/__init__.py +0 -0
|
@@ -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.
|
|
5
|
+
version="2.43",
|
|
6
6
|
author="OSDental LLC",
|
|
7
7
|
author_email="support@osdental.ai",
|
|
8
8
|
description="End-to-end algorithm library",
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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 "
|
|
168
|
+
if self._should_skip({"query": query}):
|
|
169
|
+
return
|
|
170
|
+
|
|
171
|
+
if self.result is None:
|
|
178
172
|
return
|
|
179
173
|
|
|
180
|
-
|
|
174
|
+
decrypted_key = None
|
|
181
175
|
|
|
182
|
-
if
|
|
183
|
-
|
|
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=
|
|
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
|
-
|
|
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
|
|
131
|
-
data = decryptor_data(encryption_type,
|
|
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
|
|
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
|
{encryptors-2.42 → encryptors-2.43}/src/Osdental/Rest/Middlewares/RequestContextMiddleware.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
|