cycode 3.23.1.dev2__py3-none-any.whl → 3.24.1.dev1__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.
cycode/__init__.py CHANGED
@@ -5,4 +5,4 @@ import time as _time
5
5
  # end-to-end scan duration from the moment the user actually triggered it.
6
6
  _BOOT_WALL: float = _time.time()
7
7
 
8
- __version__ = '3.23.1.dev2' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
8
+ __version__ = '3.24.1.dev1' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
@@ -1,3 +1,5 @@
1
+ import secrets
2
+ import time
1
3
  from abc import ABC, abstractmethod
2
4
  from threading import Lock
3
5
  from typing import Any, Optional
@@ -5,6 +7,7 @@ from typing import Any, Optional
5
7
  import arrow
6
8
  from requests import Response
7
9
 
10
+ from cycode.cli.exceptions.custom_exceptions import HttpUnauthorizedError
8
11
  from cycode.cli.user_settings.credentials_manager import CredentialsManager
9
12
  from cycode.cli.user_settings.jwt_creator import JwtCreator
10
13
  from cycode.cyclient.cycode_client import CycodeClient
@@ -15,6 +18,11 @@ _NGINX_PLAIN_ERRORS = [
15
18
  b'JWT Token validation failed',
16
19
  ]
17
20
 
21
+ # Identity provider brute-force protection rejects logins for the same user that land within
22
+ # milliseconds of each other, so when several processes mint at once all but one are refused.
23
+ _MINT_CONFLICT_RETRY_MIN_MS = 50
24
+ _MINT_CONFLICT_RETRY_SPREAD_MS = 100
25
+
18
26
 
19
27
  class BaseTokenAuthClient(CycodeClient, ABC):
20
28
  """Base client for token-based authentication flows with cached JWTs."""
@@ -49,7 +57,20 @@ class BaseTokenAuthClient(CycodeClient, ABC):
49
57
  self._load_token_from_disk()
50
58
  if self._has_valid_token():
51
59
  return
52
- self.refresh_access_token()
60
+
61
+ try:
62
+ self.refresh_access_token()
63
+ except HttpUnauthorizedError:
64
+ # Processes sharing one cached token all expire at the same instant, so a burst of
65
+ # them mints together and the identity provider refuses all but the first as a
66
+ # too-fast login. The winner persists a usable token, so prefer re-reading it over
67
+ # minting again. The wait is randomized to keep the losers from colliding a second
68
+ # time. A genuinely invalid token still raises on the retry.
69
+ time.sleep((_MINT_CONFLICT_RETRY_MIN_MS + secrets.randbelow(_MINT_CONFLICT_RETRY_SPREAD_MS)) / 1000)
70
+ self._load_token_from_disk()
71
+ if self._has_valid_token():
72
+ return
73
+ self.refresh_access_token()
53
74
 
54
75
  def _has_valid_token(self) -> bool:
55
76
  return self._access_token is not None and self._expires_in is not None and arrow.utcnow() < self._expires_in
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cycode
3
- Version: 3.23.1.dev2
3
+ Version: 3.24.1.dev1
4
4
  Summary: Boost security in your dev lifecycle via SAST, SCA, Secrets & IaC scanning.
5
5
  License-Expression: MIT
6
6
  License-File: LICENCE
@@ -1,4 +1,4 @@
1
- cycode/__init__.py,sha256=wL4fy_2l81hPGkz5JbmmSG25aqLYuu9epm6wbFVk8B8,396
1
+ cycode/__init__.py,sha256=I-iQNkQ_J9hG3RTJGySCJrSBiqdRU1jt3DxF46X8qaw,396
2
2
  cycode/__main__.py,sha256=Z3bD5yrA7yPvAChcADQrqCaZd0ChGI1gdiwALwbWJ6U,104
3
3
  cycode/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  cycode/cli/app.py,sha256=AlR2durAEbsa47PDfIj7JtMvJDWA_Dq6wPtVuMJYSCs,10250
@@ -199,7 +199,7 @@ cycode/cyclient/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
199
199
  cycode/cyclient/ai_security_manager_client.py,sha256=90fvqH_h2-dI9YqQ6oo4YBfa777p5mSr8JSM1ZZJJcE,5486
200
200
  cycode/cyclient/ai_security_manager_service_config.py,sha256=83pQzgOb93JW6E-dznJkI4c0NEXmQRlx9YZKMmjVwp8,808
201
201
  cycode/cyclient/auth_client.py,sha256=TwbmZ358Ancf-Q-IZolvfljZ8691_6botsqd0R0PLPk,2105
202
- cycode/cyclient/base_token_auth_client.py,sha256=mn5580d7A8Z2_zcdFKIJk78ADK7mViwTcV-4QCpRCGo,4369
202
+ cycode/cyclient/base_token_auth_client.py,sha256=V907nf_1TvtfzwDal2bAgmXvgqaaX_ERUvSRipujz30,5490
203
203
  cycode/cyclient/cli_activation_client.py,sha256=QaATFVABf0vQ6cTU_dCN9UT6fUkJf5qciaK8W7gQDrc,419
204
204
  cycode/cyclient/client_creator.py,sha256=-bsOT7M28yx-WT1UhSzENY8N9EgoQIv48Smrr9izQTI,2849
205
205
  cycode/cyclient/config.py,sha256=Le3YYp7LyclTwS4vonuFipfRA1qhyC28_muUtxpnImc,1387
@@ -217,8 +217,8 @@ cycode/cyclient/report_client.py,sha256=Scq30NeJPzgXv0hPLO1U05AdE9i_2iu6cIrSKpEJ
217
217
  cycode/cyclient/scan_client.py,sha256=DqAZ7u6Z_cvw9A9RlLkAQUgLRwPCCAsUq5U9umt4F7Y,16955
218
218
  cycode/cyclient/scan_config_base.py,sha256=mXsPZGYCtp85rv5GIige40yQZXuRcEKUW-VQJ0vgFzk,1201
219
219
  cycode/logger.py,sha256=EfZGRK6VC5rE_LAjIcRrHFiQCueylCDXoG6bvGkrIME,2111
220
- cycode-3.23.1.dev2.dist-info/METADATA,sha256=1q-VIDcfL8SgysFOTSE73q1atnb-7ABbYSYLAnnXsp8,93687
221
- cycode-3.23.1.dev2.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
222
- cycode-3.23.1.dev2.dist-info/entry_points.txt,sha256=iDcVJM8ByLElVgvBgtYxDjw1kT7O8Mo0LcWZIT5L3Ig,45
223
- cycode-3.23.1.dev2.dist-info/licenses/LICENCE,sha256=2Wx4N6mD_4xB7-E3hPkZ3MPhpJy__k_I8MaCSO-PDRo,1068
224
- cycode-3.23.1.dev2.dist-info/RECORD,,
220
+ cycode-3.24.1.dev1.dist-info/METADATA,sha256=Q_CfNk0EX1rgA3ndLHucRys9j-AqsPED4kmveNVm5eY,93687
221
+ cycode-3.24.1.dev1.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
222
+ cycode-3.24.1.dev1.dist-info/entry_points.txt,sha256=iDcVJM8ByLElVgvBgtYxDjw1kT7O8Mo0LcWZIT5L3Ig,45
223
+ cycode-3.24.1.dev1.dist-info/licenses/LICENCE,sha256=2Wx4N6mD_4xB7-E3hPkZ3MPhpJy__k_I8MaCSO-PDRo,1068
224
+ cycode-3.24.1.dev1.dist-info/RECORD,,