pangea-sdk 3.8.0b4__py3-none-any.whl → 4.0.0__py3-none-any.whl

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 (43) hide show
  1. pangea/__init__.py +1 -2
  2. pangea/asyncio/request.py +17 -22
  3. pangea/asyncio/services/__init__.py +0 -2
  4. pangea/asyncio/services/audit.py +188 -23
  5. pangea/asyncio/services/authn.py +167 -108
  6. pangea/asyncio/services/authz.py +36 -45
  7. pangea/asyncio/services/embargo.py +2 -2
  8. pangea/asyncio/services/file_scan.py +3 -3
  9. pangea/asyncio/services/intel.py +44 -26
  10. pangea/asyncio/services/redact.py +60 -4
  11. pangea/asyncio/services/vault.py +145 -30
  12. pangea/dump_audit.py +1 -1
  13. pangea/request.py +30 -24
  14. pangea/response.py +34 -42
  15. pangea/services/__init__.py +0 -2
  16. pangea/services/audit/audit.py +202 -34
  17. pangea/services/audit/models.py +56 -8
  18. pangea/services/audit/util.py +3 -3
  19. pangea/services/authn/authn.py +116 -65
  20. pangea/services/authn/models.py +88 -4
  21. pangea/services/authz.py +51 -56
  22. pangea/services/base.py +23 -6
  23. pangea/services/embargo.py +2 -2
  24. pangea/services/file_scan.py +3 -2
  25. pangea/services/intel.py +25 -23
  26. pangea/services/redact.py +124 -4
  27. pangea/services/vault/models/common.py +121 -6
  28. pangea/services/vault/models/symmetric.py +2 -2
  29. pangea/services/vault/vault.py +143 -32
  30. pangea/utils.py +20 -109
  31. pangea/verify_audit.py +267 -83
  32. {pangea_sdk-3.8.0b4.dist-info → pangea_sdk-4.0.0.dist-info}/METADATA +12 -20
  33. pangea_sdk-4.0.0.dist-info/RECORD +46 -0
  34. {pangea_sdk-3.8.0b4.dist-info → pangea_sdk-4.0.0.dist-info}/WHEEL +1 -1
  35. pangea/asyncio/__init__.py +0 -1
  36. pangea/asyncio/file_uploader.py +0 -39
  37. pangea/asyncio/services/sanitize.py +0 -185
  38. pangea/asyncio/services/share.py +0 -573
  39. pangea/file_uploader.py +0 -35
  40. pangea/services/sanitize.py +0 -275
  41. pangea/services/share/file_format.py +0 -170
  42. pangea/services/share/share.py +0 -877
  43. pangea_sdk-3.8.0b4.dist-info/RECORD +0 -54
@@ -1,8 +1,11 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+ from __future__ import annotations
4
+
3
5
  import datetime
4
6
  from typing import Dict, Optional, Union
5
7
 
8
+ from pangea.config import PangeaConfig
6
9
  from pangea.response import PangeaResponse
7
10
  from pangea.services.base import ServiceBase
8
11
  from pangea.services.vault.models.asymmetric import (
@@ -17,6 +20,8 @@ from pangea.services.vault.models.asymmetric import (
17
20
  )
18
21
  from pangea.services.vault.models.common import (
19
22
  AsymmetricAlgorithm,
23
+ DecryptTransformRequest,
24
+ DecryptTransformResult,
20
25
  DeleteRequest,
21
26
  DeleteResult,
22
27
  EncodedPrivateKey,
@@ -24,6 +29,8 @@ from pangea.services.vault.models.common import (
24
29
  EncodedSymmetricKey,
25
30
  EncryptStructuredRequest,
26
31
  EncryptStructuredResult,
32
+ EncryptTransformRequest,
33
+ EncryptTransformResult,
27
34
  FolderCreateRequest,
28
35
  FolderCreateResult,
29
36
  GetRequest,
@@ -50,6 +57,7 @@ from pangea.services.vault.models.common import (
50
57
  SymmetricAlgorithm,
51
58
  Tags,
52
59
  TDict,
60
+ TransformAlphabet,
53
61
  UpdateRequest,
54
62
  UpdateResult,
55
63
  )
@@ -98,10 +106,24 @@ class Vault(ServiceBase):
98
106
 
99
107
  def __init__(
100
108
  self,
101
- token,
102
- config=None,
103
- logger_name="pangea",
104
- ):
109
+ token: str,
110
+ config: PangeaConfig | None = None,
111
+ logger_name: str = "pangea",
112
+ ) -> None:
113
+ """
114
+ Vault client
115
+
116
+ Initializes a new Vault client.
117
+
118
+ Args:
119
+ token: Pangea API token.
120
+ config: Configuration.
121
+ logger_name: Logger name.
122
+
123
+ Examples:
124
+ config = PangeaConfig(domain="pangea_domain")
125
+ vault = Vault(token="pangea_token", config=config)
126
+ """
105
127
  super().__init__(token, config, logger_name)
106
128
 
107
129
  # Delete endpoint
@@ -129,7 +151,7 @@ class Vault(ServiceBase):
129
151
  input = DeleteRequest(
130
152
  id=id,
131
153
  )
132
- return self.request.post("v1/delete", DeleteResult, data=input.dict(exclude_none=True))
154
+ return self.request.post("v1/delete", DeleteResult, data=input.model_dump(exclude_none=True))
133
155
 
134
156
  # Get endpoint
135
157
  def get(
@@ -176,7 +198,7 @@ class Vault(ServiceBase):
176
198
  verbose=verbose,
177
199
  version_state=version_state,
178
200
  )
179
- return self.request.post("v1/get", GetResult, data=input.dict(exclude_none=True))
201
+ return self.request.post("v1/get", GetResult, data=input.model_dump(exclude_none=True))
180
202
 
181
203
  # List endpoint
182
204
  def list(
@@ -232,7 +254,7 @@ class Vault(ServiceBase):
232
254
  )
233
255
  """
234
256
  input = ListRequest(filter=filter, last=last, order=order, order_by=order_by, size=size)
235
- return self.request.post("v1/list", ListResult, data=input.dict(exclude_none=True))
257
+ return self.request.post("v1/list", ListResult, data=input.model_dump(exclude_none=True))
236
258
 
237
259
  # Update endpoint
238
260
  def update(
@@ -313,7 +335,7 @@ class Vault(ServiceBase):
313
335
  expiration=expiration,
314
336
  item_state=item_state,
315
337
  )
316
- return self.request.post("v1/update", UpdateResult, data=input.dict(exclude_none=True))
338
+ return self.request.post("v1/update", UpdateResult, data=input.model_dump(exclude_none=True))
317
339
 
318
340
  def secret_store(
319
341
  self,
@@ -383,7 +405,7 @@ class Vault(ServiceBase):
383
405
  rotation_state=rotation_state,
384
406
  expiration=expiration,
385
407
  )
386
- return self.request.post("v1/secret/store", SecretStoreResult, data=input.dict(exclude_none=True))
408
+ return self.request.post("v1/secret/store", SecretStoreResult, data=input.model_dump(exclude_none=True))
387
409
 
388
410
  def pangea_token_store(
389
411
  self,
@@ -453,7 +475,7 @@ class Vault(ServiceBase):
453
475
  rotation_state=rotation_state,
454
476
  expiration=expiration,
455
477
  )
456
- return self.request.post("v1/secret/store", SecretStoreResult, data=input.dict(exclude_none=True))
478
+ return self.request.post("v1/secret/store", SecretStoreResult, data=input.model_dump(exclude_none=True))
457
479
 
458
480
  # Rotate endpoint
459
481
  def secret_rotate(
@@ -493,7 +515,7 @@ class Vault(ServiceBase):
493
515
  )
494
516
  """
495
517
  input = SecretRotateRequest(id=id, secret=secret, rotation_state=rotation_state)
496
- return self.request.post("v1/secret/rotate", SecretRotateResult, data=input.dict(exclude_none=True))
518
+ return self.request.post("v1/secret/rotate", SecretRotateResult, data=input.model_dump(exclude_none=True))
497
519
 
498
520
  # Rotate endpoint
499
521
  def pangea_token_rotate(self, id: str) -> PangeaResponse[SecretRotateResult]:
@@ -521,7 +543,7 @@ class Vault(ServiceBase):
521
543
  )
522
544
  """
523
545
  input = SecretRotateRequest(id=id) # type: ignore[call-arg]
524
- return self.request.post("v1/secret/rotate", SecretRotateResult, data=input.dict(exclude_none=True))
546
+ return self.request.post("v1/secret/rotate", SecretRotateResult, data=input.model_dump(exclude_none=True))
525
547
 
526
548
  def symmetric_generate(
527
549
  self,
@@ -598,7 +620,7 @@ class Vault(ServiceBase):
598
620
  return self.request.post(
599
621
  "v1/key/generate",
600
622
  SymmetricGenerateResult,
601
- data=input.dict(exclude_none=True),
623
+ data=input.model_dump(exclude_none=True),
602
624
  )
603
625
 
604
626
  def asymmetric_generate(
@@ -676,7 +698,7 @@ class Vault(ServiceBase):
676
698
  return self.request.post(
677
699
  "v1/key/generate",
678
700
  AsymmetricGenerateResult,
679
- data=input.dict(exclude_none=True),
701
+ data=input.model_dump(exclude_none=True),
680
702
  )
681
703
 
682
704
  # Store endpoints
@@ -760,7 +782,7 @@ class Vault(ServiceBase):
760
782
  rotation_state=rotation_state,
761
783
  expiration=expiration,
762
784
  )
763
- return self.request.post("v1/key/store", AsymmetricStoreResult, data=input.dict(exclude_none=True))
785
+ return self.request.post("v1/key/store", AsymmetricStoreResult, data=input.model_dump(exclude_none=True))
764
786
 
765
787
  def symmetric_store(
766
788
  self,
@@ -838,7 +860,7 @@ class Vault(ServiceBase):
838
860
  rotation_state=rotation_state,
839
861
  expiration=expiration,
840
862
  )
841
- return self.request.post("v1/key/store", SymmetricStoreResult, data=input.dict(exclude_none=True))
863
+ return self.request.post("v1/key/store", SymmetricStoreResult, data=input.model_dump(exclude_none=True))
842
864
 
843
865
  # Rotate endpoint
844
866
  def key_rotate(
@@ -891,7 +913,7 @@ class Vault(ServiceBase):
891
913
  key=key,
892
914
  rotation_state=rotation_state,
893
915
  )
894
- return self.request.post("v1/key/rotate", KeyRotateResult, data=input.dict(exclude_none=True))
916
+ return self.request.post("v1/key/rotate", KeyRotateResult, data=input.model_dump(exclude_none=True))
895
917
 
896
918
  # Encrypt
897
919
  def encrypt(self, id: str, plain_text: str, version: Optional[int] = None) -> PangeaResponse[EncryptResult]:
@@ -922,8 +944,8 @@ class Vault(ServiceBase):
922
944
  version=1,
923
945
  )
924
946
  """
925
- input = EncryptRequest(id=id, plain_text=plain_text, version=version) # type: ignore[call-arg]
926
- return self.request.post("v1/key/encrypt", EncryptResult, data=input.dict(exclude_none=True))
947
+ input = EncryptRequest(id=id, plain_text=plain_text, version=version)
948
+ return self.request.post("v1/key/encrypt", EncryptResult, data=input.model_dump(exclude_none=True))
927
949
 
928
950
  # Decrypt
929
951
  def decrypt(self, id: str, cipher_text: str, version: Optional[int] = None) -> PangeaResponse[DecryptResult]:
@@ -954,8 +976,8 @@ class Vault(ServiceBase):
954
976
  version=1,
955
977
  )
956
978
  """
957
- input = DecryptRequest(id=id, cipher_text=cipher_text, version=version) # type: ignore[call-arg]
958
- return self.request.post("v1/key/decrypt", DecryptResult, data=input.dict(exclude_none=True))
979
+ input = DecryptRequest(id=id, cipher_text=cipher_text, version=version)
980
+ return self.request.post("v1/key/decrypt", DecryptResult, data=input.model_dump(exclude_none=True))
959
981
 
960
982
  # Sign
961
983
  def sign(self, id: str, message: str, version: Optional[int] = None) -> PangeaResponse[SignResult]:
@@ -987,7 +1009,7 @@ class Vault(ServiceBase):
987
1009
  )
988
1010
  """
989
1011
  input = SignRequest(id=id, message=message, version=version)
990
- return self.request.post("v1/key/sign", SignResult, data=input.dict(exclude_none=True))
1012
+ return self.request.post("v1/key/sign", SignResult, data=input.model_dump(exclude_none=True))
991
1013
 
992
1014
  # Verify
993
1015
  def verify(
@@ -1028,7 +1050,7 @@ class Vault(ServiceBase):
1028
1050
  signature=signature,
1029
1051
  version=version,
1030
1052
  )
1031
- return self.request.post("v1/key/verify", VerifyResult, data=input.dict(exclude_none=True))
1053
+ return self.request.post("v1/key/verify", VerifyResult, data=input.model_dump(exclude_none=True))
1032
1054
 
1033
1055
  def jwt_verify(self, jws: str) -> PangeaResponse[JWTVerifyResult]:
1034
1056
  """
@@ -1055,7 +1077,7 @@ class Vault(ServiceBase):
1055
1077
  )
1056
1078
  """
1057
1079
  input = JWTVerifyRequest(jws=jws)
1058
- return self.request.post("v1/key/verify/jwt", JWTVerifyResult, data=input.dict(exclude_none=True))
1080
+ return self.request.post("v1/key/verify/jwt", JWTVerifyResult, data=input.model_dump(exclude_none=True))
1059
1081
 
1060
1082
  def jwt_sign(self, id: str, payload: str) -> PangeaResponse[JWTSignResult]:
1061
1083
  """
@@ -1084,7 +1106,7 @@ class Vault(ServiceBase):
1084
1106
  )
1085
1107
  """
1086
1108
  input = JWTSignRequest(id=id, payload=payload)
1087
- return self.request.post("v1/key/sign/jwt", JWTSignResult, data=input.dict(exclude_none=True))
1109
+ return self.request.post("v1/key/sign/jwt", JWTSignResult, data=input.model_dump(exclude_none=True))
1088
1110
 
1089
1111
  # Get endpoint
1090
1112
  def jwk_get(self, id: str, version: Optional[str] = None) -> PangeaResponse[JWKGetResult]:
@@ -1115,7 +1137,7 @@ class Vault(ServiceBase):
1115
1137
  )
1116
1138
  """
1117
1139
  input = JWKGetRequest(id=id, version=version)
1118
- return self.request.post("v1/get/jwk", JWKGetResult, data=input.dict(exclude_none=True))
1140
+ return self.request.post("v1/get/jwk", JWKGetResult, data=input.model_dump(exclude_none=True))
1119
1141
 
1120
1142
  # State change
1121
1143
  def state_change(
@@ -1158,7 +1180,7 @@ class Vault(ServiceBase):
1158
1180
  )
1159
1181
  """
1160
1182
  input = StateChangeRequest(id=id, state=state, version=version, destroy_period=destroy_period)
1161
- return self.request.post("v1/state/change", StateChangeResult, data=input.dict(exclude_none=True))
1183
+ return self.request.post("v1/state/change", StateChangeResult, data=input.model_dump(exclude_none=True))
1162
1184
 
1163
1185
  # Folder create
1164
1186
  def folder_create(
@@ -1195,7 +1217,7 @@ class Vault(ServiceBase):
1195
1217
  )
1196
1218
  """
1197
1219
  input = FolderCreateRequest(name=name, folder=folder, metadata=metadata, tags=tags)
1198
- return self.request.post("v1/folder/create", FolderCreateResult, data=input.dict(exclude_none=True))
1220
+ return self.request.post("v1/folder/create", FolderCreateResult, data=input.model_dump(exclude_none=True))
1199
1221
 
1200
1222
  # Encrypt structured
1201
1223
  def encrypt_structured(
@@ -1216,7 +1238,7 @@ class Vault(ServiceBase):
1216
1238
  Args:
1217
1239
  id (str): The item ID.
1218
1240
  structured_data (dict): Structured data for applying bulk operations.
1219
- filter (str, optional): A filter expression for applying bulk operations to the data field.
1241
+ filter (str): A filter expression for applying bulk operations to the data field.
1220
1242
  version (int, optional): The item version. Defaults to the current version.
1221
1243
  additional_data (str, optional): User provided authentication data.
1222
1244
 
@@ -1243,7 +1265,7 @@ class Vault(ServiceBase):
1243
1265
  return self.request.post(
1244
1266
  "v1/key/encrypt/structured",
1245
1267
  EncryptStructuredResult,
1246
- data=input.dict(exclude_none=True),
1268
+ data=input.model_dump(exclude_none=True),
1247
1269
  )
1248
1270
 
1249
1271
  # Decrypt structured
@@ -1265,7 +1287,7 @@ class Vault(ServiceBase):
1265
1287
  Args:
1266
1288
  id (str): The item ID.
1267
1289
  structured_data (dict): Structured data to decrypt.
1268
- filter (str, optional): A filter expression for applying bulk operations to the data field.
1290
+ filter (str): A filter expression for applying bulk operations to the data field.
1269
1291
  version (int, optional): The item version. Defaults to the current version.
1270
1292
  additional_data (str, optional): User provided authentication data.
1271
1293
 
@@ -1292,5 +1314,94 @@ class Vault(ServiceBase):
1292
1314
  return self.request.post(
1293
1315
  "v1/key/decrypt/structured",
1294
1316
  EncryptStructuredResult,
1295
- data=input.dict(exclude_none=True),
1317
+ data=input.model_dump(exclude_none=True),
1318
+ )
1319
+
1320
+ def encrypt_transform(
1321
+ self,
1322
+ id: str,
1323
+ plain_text: str,
1324
+ alphabet: TransformAlphabet,
1325
+ tweak: str | None = None,
1326
+ version: int | None = None,
1327
+ ) -> PangeaResponse[EncryptTransformResult]:
1328
+ """
1329
+ Encrypt transform
1330
+
1331
+ Encrypt using a format-preserving algorithm (FPE).
1332
+
1333
+ OperationId: vault_post_v1_key_encrypt_transform
1334
+
1335
+ Args:
1336
+ id: The item ID.
1337
+ plain_text: A message to be encrypted.
1338
+ alphabet: Set of characters to use for format-preserving encryption (FPE).
1339
+ tweak: User provided tweak string. If not provided, a random string will be generated and returned.
1340
+ version: The item version. Defaults to the current version.
1341
+
1342
+ Raises:
1343
+ PangeaAPIException: If an API error happens.
1344
+
1345
+ Returns:
1346
+ A `PangeaResponse` containing the encrypted message.
1347
+
1348
+ Examples:
1349
+ vault.encrypt_transform(
1350
+ id="pvi_[...]",
1351
+ plain_text="message to encrypt",
1352
+ alphabet=TransformAlphabet.ALPHANUMERIC,
1353
+ tweak="MTIzMTIzMT==",
1354
+ )
1355
+ """
1356
+
1357
+ input = EncryptTransformRequest(
1358
+ id=id,
1359
+ plain_text=plain_text,
1360
+ tweak=tweak,
1361
+ alphabet=alphabet,
1362
+ version=version,
1363
+ )
1364
+ return self.request.post(
1365
+ "v1/key/encrypt/transform",
1366
+ EncryptTransformResult,
1367
+ data=input.model_dump(exclude_none=True),
1368
+ )
1369
+
1370
+ def decrypt_transform(
1371
+ self, id: str, cipher_text: str, tweak: str, alphabet: TransformAlphabet, version: int | None = None
1372
+ ) -> PangeaResponse[DecryptTransformResult]:
1373
+ """
1374
+ Decrypt transform
1375
+
1376
+ Decrypt using a format-preserving algorithm (FPE).
1377
+
1378
+ OperationId: vault_post_v1_key_decrypt_transform
1379
+
1380
+ Args:
1381
+ id: The item ID.
1382
+ cipher_text: A message encrypted by Vault.
1383
+ tweak: User provided tweak string.
1384
+ alphabet: Set of characters to use for format-preserving encryption (FPE).
1385
+ version: The item version. Defaults to the current version.
1386
+
1387
+ Raises:
1388
+ PangeaAPIException: If an API error happens.
1389
+
1390
+ Returns:
1391
+ A `PangeaResponse` containing the decrypted message.
1392
+
1393
+ Examples:
1394
+ vault.decrypt_transform(
1395
+ id="pvi_[...]",
1396
+ cipher_text="encrypted message",
1397
+ tweak="MTIzMTIzMT==",
1398
+ alphabet=TransformAlphabet.ALPHANUMERIC,
1399
+ )
1400
+ """
1401
+
1402
+ input = DecryptTransformRequest(id=id, cipher_text=cipher_text, tweak=tweak, alphabet=alphabet, version=version)
1403
+ return self.request.post(
1404
+ "v1/key/decrypt/transform",
1405
+ DecryptTransformResult,
1406
+ data=input.model_dump(exclude_none=True),
1296
1407
  )
pangea/utils.py CHANGED
@@ -3,11 +3,9 @@ import copy
3
3
  import datetime
4
4
  import io
5
5
  import json
6
- from collections import OrderedDict
7
- from hashlib import md5, new, sha1, sha256, sha512
8
- from typing import Union
6
+ from hashlib import new, sha1, sha256, sha512
9
7
 
10
- from google_crc32c import Checksum as CRC32C # type: ignore[import]
8
+ from google_crc32c import Checksum as CRC32C # type: ignore[import-untyped]
11
9
  from pydantic import BaseModel
12
10
 
13
11
 
@@ -31,24 +29,8 @@ def default_encoder(obj) -> str:
31
29
  return str(obj)
32
30
 
33
31
 
34
- def str2str_b64(data: str):
35
- return base64.b64encode(data.encode("ascii")).decode("ascii")
36
-
37
-
38
- def dict_order_keys(data: dict) -> OrderedDict:
39
- if isinstance(data, dict):
40
- return OrderedDict(sorted(data.items()))
41
- else:
42
- return data
43
-
44
-
45
- def dict_order_keys_recursive(data: dict) -> OrderedDict:
46
- if isinstance(data, dict):
47
- for k, v in data.items():
48
- if type(v) is dict:
49
- data[k] = dict_order_keys_recursive(v)
50
-
51
- return data # type: ignore[return-value]
32
+ def str2str_b64(data: str, encoding: str = "utf-8") -> str:
33
+ return base64.b64encode(data.encode(encoding)).decode("ascii")
52
34
 
53
35
 
54
36
  def canonicalize_nested_json(data: dict) -> dict:
@@ -77,97 +59,33 @@ def canonicalize(data: dict) -> str:
77
59
  return str(data)
78
60
 
79
61
 
80
- def hash_sha256(input: Union[str, io.BufferedReader]) -> str:
81
- # Return SHA256 hash in hex format
82
- hash = sha256()
83
- if isinstance(input, io.BufferedReader):
84
- input.seek(0) # restart reading
85
- while True:
86
- chunk = input.read(1024 * 1024)
87
- if not chunk:
88
- break
89
- hash.update(chunk)
90
-
91
- input.seek(0) # restart reading
92
- else:
93
- hash.update(input) # type: ignore
94
-
95
- return hash.hexdigest()
96
-
62
+ def hash_sha256(data: str) -> str:
63
+ # Return sha256 hash in hex format
64
+ return sha256(data.encode("ascii")).hexdigest()
97
65
 
98
- def hash_sha1(input: Union[str, io.BufferedReader]) -> str:
99
- # Return SHA1 hash in hex format
100
- hash = sha1()
101
- if isinstance(input, io.BufferedReader):
102
- input.seek(0) # restart reading
103
- while True:
104
- chunk = input.read(1024 * 1024)
105
- if not chunk:
106
- break
107
- hash.update(chunk)
108
-
109
- input.seek(0) # restart reading
110
- else:
111
- hash.update(input) # type: ignore
112
66
 
113
- return hash.hexdigest()
67
+ def hash_256_filepath(filepath: str) -> str:
68
+ data = open(filepath, "rb")
69
+ hash = sha256(data.read()).hexdigest()
70
+ data.close()
71
+ return hash
114
72
 
115
73
 
116
- def hash_sha512(input: Union[str, io.BufferedReader]) -> str:
117
- # Return SHA512 hash in hex format
118
- hash = sha512()
119
- if isinstance(input, io.BufferedReader):
120
- input.seek(0) # restart reading
121
- while True:
122
- chunk = input.read(1024 * 1024)
123
- if not chunk:
124
- break
125
- hash.update(chunk)
74
+ def hash_sha1(data: str) -> str:
75
+ # Return sha1 hash in hex format
76
+ return sha1(data.encode("ascii")).hexdigest()
126
77
 
127
- input.seek(0) # restart reading
128
- else:
129
- hash.update(input) # type: ignore
130
78
 
131
- return hash.hexdigest()
79
+ def hash_sha512(data: str) -> str:
80
+ # Return sha512 hash in hex format
81
+ return sha512(data.encode("ascii")).hexdigest()
132
82
 
133
83
 
134
- def hash_ntlm(data: str) -> str:
135
- # Return NTLM hash in hex format
84
+ def hash_ntlm(data: str):
85
+ # Calculate the NTLM hash
136
86
  return new("md4", data.encode("utf-16le")).hexdigest()
137
87
 
138
88
 
139
- def hash_md5(input: Union[str, io.BufferedReader]) -> str:
140
- # Return MD5 hash in hex format
141
- hash = md5()
142
- if isinstance(input, io.BufferedReader):
143
- input.seek(0) # restart reading
144
-
145
- while True:
146
- chunk = input.read(1024 * 1024)
147
- if not chunk:
148
- break
149
- hash.update(chunk)
150
-
151
- input.seek(0) # restart reading
152
- else:
153
- hash.update(input) # type: ignore
154
-
155
- return hash.hexdigest()
156
-
157
-
158
- def get_crc32c(data: str) -> str:
159
- crc = CRC32C()
160
- crc.update(data)
161
- return crc.hexdigest().decode("utf-8")
162
-
163
-
164
- def hash_256_filepath(filepath: str) -> str:
165
- data = open(filepath, "rb")
166
- hash = sha256(data.read()).hexdigest()
167
- data.close()
168
- return hash
169
-
170
-
171
89
  def get_prefix(hash: str, len: int = 5):
172
90
  return hash[0:len]
173
91
 
@@ -197,10 +115,3 @@ def get_file_upload_params(file: io.BufferedReader) -> FileUploadParams:
197
115
 
198
116
  file.seek(0) # restart reading
199
117
  return FileUploadParams(crc_hex=crc.hexdigest().decode("utf-8"), sha256_hex=sha.hexdigest(), size=size)
200
-
201
-
202
- def get_file_size(file: io.BufferedReader) -> int:
203
- file.seek(0, io.SEEK_END)
204
- size = file.tell()
205
- file.seek(0) # restart reading
206
- return size