sfq 0.0.42__py3-none-any.whl → 0.0.43__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.
sfq/__init__.py
CHANGED
@@ -52,7 +52,7 @@ __all__ = [
|
|
52
52
|
"PlatformEventsClient",
|
53
53
|
]
|
54
54
|
|
55
|
-
__version__ = "0.0.
|
55
|
+
__version__ = "0.0.43"
|
56
56
|
"""
|
57
57
|
### `__version__`
|
58
58
|
|
@@ -70,7 +70,7 @@ class _SFTokenAuth:
|
|
70
70
|
access_token: str,
|
71
71
|
api_version: str = "v64.0",
|
72
72
|
token_endpoint: str = "/services/oauth2/token",
|
73
|
-
user_agent: str = "sfq/0.0.
|
73
|
+
user_agent: str = "sfq/0.0.43",
|
74
74
|
sforce_client: str = "_auto",
|
75
75
|
proxy: str = "_auto",
|
76
76
|
) -> None:
|
@@ -114,7 +114,7 @@ class SFAuth:
|
|
114
114
|
access_token: Optional[str] = None,
|
115
115
|
token_expiration_time: Optional[float] = None,
|
116
116
|
token_lifetime: int = 15 * 60,
|
117
|
-
user_agent: str = "sfq/0.0.
|
117
|
+
user_agent: str = "sfq/0.0.43",
|
118
118
|
sforce_client: str = "_auto",
|
119
119
|
proxy: str = "_auto",
|
120
120
|
) -> None:
|
@@ -185,7 +185,7 @@ class SFAuth:
|
|
185
185
|
)
|
186
186
|
|
187
187
|
# Store version information
|
188
|
-
self.__version__ = "0.0.
|
188
|
+
self.__version__ = "0.0.43"
|
189
189
|
"""
|
190
190
|
### `__version__`
|
191
191
|
|
sfq/http_client.py
CHANGED
sfq/utils.py
CHANGED
@@ -6,6 +6,8 @@ used throughout the SFQ library, including the custom TRACE logging level and
|
|
6
6
|
sensitive data redaction functionality.
|
7
7
|
"""
|
8
8
|
|
9
|
+
import base64
|
10
|
+
import hashlib
|
9
11
|
import json
|
10
12
|
import logging
|
11
13
|
import re
|
@@ -374,3 +376,69 @@ def records_to_html_table(
|
|
374
376
|
normalized_data.append(normalized_row)
|
375
377
|
|
376
378
|
return dicts_to_html_table(normalized_data, styled=styled)
|
379
|
+
|
380
|
+
|
381
|
+
def fuzz(text: str, key: str, prefix_len: int = 4, suffix_len: int = 4) -> str:
|
382
|
+
"""Lightweight XOR-based obfuscation with variable hash prefix/suffix (no separators).
|
383
|
+
|
384
|
+
Args:
|
385
|
+
text: The text to obfuscate
|
386
|
+
key: The key for XOR operation
|
387
|
+
prefix_len: Length of the MD5 hash prefix (default: 4)
|
388
|
+
suffix_len: Length of the SHA1 hash suffix (default: 4)
|
389
|
+
|
390
|
+
Returns:
|
391
|
+
Base64 encoded obfuscated string
|
392
|
+
"""
|
393
|
+
|
394
|
+
prefix = hashlib.md5(text.encode()).hexdigest()[:prefix_len]
|
395
|
+
suffix = hashlib.sha1(text.encode()).hexdigest()[-suffix_len:] if suffix_len > 0 else ""
|
396
|
+
|
397
|
+
if not key:
|
398
|
+
combined = prefix + text + suffix
|
399
|
+
else:
|
400
|
+
fuzzed_chars = [
|
401
|
+
chr(ord(char) ^ ord(key[i % len(key)])) for i, char in enumerate(text)
|
402
|
+
]
|
403
|
+
combined = prefix + ''.join(fuzzed_chars) + suffix
|
404
|
+
|
405
|
+
encoded = base64.b64encode(combined.encode("utf-8")).decode("utf-8")
|
406
|
+
return encoded
|
407
|
+
|
408
|
+
|
409
|
+
def defuzz(encoded_text: str, key: str, prefix_len: int = 4, suffix_len: int = 4) -> str:
|
410
|
+
"""Reverse the fuzz transformation (no separators).
|
411
|
+
|
412
|
+
Args:
|
413
|
+
encoded_text: The base64 encoded obfuscated text
|
414
|
+
key: The key used for original XOR operation
|
415
|
+
prefix_len: Length of the MD5 hash prefix (must match encoding)
|
416
|
+
suffix_len: Length of the SHA1 hash suffix (must match encoding)
|
417
|
+
|
418
|
+
Returns:
|
419
|
+
The original decoded text
|
420
|
+
|
421
|
+
Raises:
|
422
|
+
ValueError: If encoded text format is invalid or corrupted
|
423
|
+
"""
|
424
|
+
|
425
|
+
decoded = base64.b64decode(encoded_text.encode("utf-8")).decode("utf-8")
|
426
|
+
|
427
|
+
if len(decoded) < prefix_len + suffix_len:
|
428
|
+
raise ValueError("Invalid encoded text format or corrupted data.")
|
429
|
+
|
430
|
+
prefix = decoded[:prefix_len]
|
431
|
+
suffix = decoded[-suffix_len:] if suffix_len > 0 else ""
|
432
|
+
body = decoded[prefix_len:-suffix_len] if suffix_len > 0 else decoded[prefix_len:]
|
433
|
+
|
434
|
+
if len(prefix) != prefix_len or len(suffix) != suffix_len:
|
435
|
+
raise ValueError("Prefix/suffix length mismatch or corrupted data.")
|
436
|
+
|
437
|
+
if not key:
|
438
|
+
return body
|
439
|
+
|
440
|
+
defuzzed_chars = [
|
441
|
+
chr(ord(char) ^ ord(key[i % len(key)])) for i, char in enumerate(body)
|
442
|
+
]
|
443
|
+
|
444
|
+
return ''.join(defuzzed_chars)
|
@@ -1,16 +1,16 @@
|
|
1
|
-
sfq/__init__.py,sha256=
|
1
|
+
sfq/__init__.py,sha256=G_j9SW-xUvnkKoBlcYyttahIreXvkfGWajCtRFCP468,24675
|
2
2
|
sfq/_cometd.py,sha256=QqdSGsms9uFm7vgmxgau7m2UuLHztK1yjN-BNjeo8xM,10381
|
3
3
|
sfq/auth.py,sha256=MPlaH4lHz9uJDdPGcJ_t4Gsp8pWx9crCfMr7FwPD7U4,14079
|
4
4
|
sfq/crud.py,sha256=fj4wPMt0DcrMKbMWQ9AUMsUNUWicsY93LP_3Q7lhmDU,20300
|
5
5
|
sfq/debug_cleanup.py,sha256=e2_Hpigy3F7XsATOUXo8DZNmuEIL9SDD0tBlZIZeQLc,2638
|
6
6
|
sfq/exceptions.py,sha256=Ys41dV8nAeP8Cl9xr4QuL7itQxjxh5KDCse6hJNl6AY,1028
|
7
|
-
sfq/http_client.py,sha256
|
7
|
+
sfq/http_client.py,sha256=-Wb2SRI8Go0daA82qK-gcr1ZRu-QKnycnP6NcbWPPK8,18642
|
8
8
|
sfq/platform_events.py,sha256=xkYE-FSbvhRYszOc4duBBXkxl7dzy5HhWFUHFSStP4s,14652
|
9
9
|
sfq/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
sfq/query.py,sha256=AoagL8PMKUcpbPPTcHJPKhmUdDDPa0La4JLC0TUN_Yc,14586
|
11
11
|
sfq/soap.py,sha256=FM4msP9ErrgLFaNOQy_kYVde8QFkT4yQu9TfMiZG0VA,7006
|
12
12
|
sfq/timeout_detector.py,sha256=Y8zO0h2dxMchNxhh5ns3GBfRv07EzKzUcr-hqZc_2-s,5503
|
13
|
-
sfq/utils.py,sha256=
|
14
|
-
sfq-0.0.
|
15
|
-
sfq-0.0.
|
16
|
-
sfq-0.0.
|
13
|
+
sfq/utils.py,sha256=K3XBjFrv0Id91jMJoq2besk0UwNkr0v3Dz62g2LzAdw,14652
|
14
|
+
sfq-0.0.43.dist-info/METADATA,sha256=OxTCj9mLNbMxGXrHYiATIzteEfE-IdxIvRjkzr0Wvu4,7813
|
15
|
+
sfq-0.0.43.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
16
|
+
sfq-0.0.43.dist-info/RECORD,,
|
File without changes
|