Skip to content

Commit 7a67fd9

Browse files
authored
fix projectId init by env var + lint fixes (#685)
1 parent 9c145b6 commit 7a67fd9

File tree

9 files changed

+215
-91
lines changed

9 files changed

+215
-91
lines changed

descope/auth.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from typing import Iterable, Optional
1010

1111
import jwt
12-
import requests
1312
from email_validator import EmailNotValidError, validate_email
1413
from jwt import ExpiredSignatureError, ImmatureSignatureError
1514

@@ -53,8 +52,7 @@ def __init__(
5352
http_client: HTTPClient,
5453
):
5554
self.lock_public_keys = Lock()
56-
# validate project id
57-
project_id = project_id or os.getenv("DESCOPE_PROJECT_ID", "")
55+
5856
if not project_id:
5957
raise AuthException(
6058
400,
@@ -451,7 +449,7 @@ def _validate_token(
451449
leeway=self.jwt_validation_leeway,
452450
)
453451
token_audience = unverified_claims.get("aud")
454-
452+
455453
# If token has audience claim and it matches our project ID, use it
456454
if token_audience and self.project_id:
457455
if isinstance(token_audience, list):

descope/descope_client.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,18 @@ def __init__(
3535
auth_management_key: Optional[str] = None,
3636
fga_cache_url: Optional[str] = None,
3737
):
38+
# validate project id
39+
project_id = project_id or os.getenv("DESCOPE_PROJECT_ID", "")
40+
if not project_id:
41+
raise AuthException(
42+
400,
43+
ERROR_TYPE_INVALID_ARGUMENT,
44+
(
45+
"Unable to init DescopeClient because project_id cannot be empty. "
46+
"Set environment variable DESCOPE_PROJECT_ID or pass your Project ID to the init function."
47+
),
48+
)
49+
3850
# Auth Initialization
3951
auth_http_client = HTTPClient(
4052
project_id=project_id,

descope/http_client.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from descope.exceptions import (
2222
API_RATE_LIMIT_RETRY_AFTER_HEADER,
2323
ERROR_TYPE_API_RATE_LIMIT,
24+
ERROR_TYPE_INVALID_ARGUMENT,
2425
ERROR_TYPE_SERVER_ERROR,
2526
AuthException,
2627
RateLimitException,
@@ -55,8 +56,11 @@ def __init__(
5556
if not project_id:
5657
raise AuthException(
5758
400,
58-
ERROR_TYPE_SERVER_ERROR,
59-
"Project ID is required to initialize HTTP client",
59+
ERROR_TYPE_INVALID_ARGUMENT,
60+
(
61+
"Project ID is required to initialize HTTP client"
62+
"Set environment variable DESCOPE_PROJECT_ID or pass your Project ID to the init function."
63+
),
6064
)
6165

6266
# Prefer explicitly provided base_url, then env var, then computed default

descope/management/common.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
from enum import Enum
22
from typing import List, Optional
33

4+
45
class SessionExpirationUnit(Enum):
56
MINUTES = "minutes"
67
HOURS = "hours"
78
DAYS = "days"
89
WEEKS = "weeks"
910

11+
1012
class TenantAuthType(Enum):
1113
NONE = "none"
1214
SAML = "saml"
1315
OIDC = "oidc"
1416

17+
1518
class AccessType(Enum):
1619
OFFLINE = "offline"
1720
ONLINE = "online"
@@ -303,6 +306,7 @@ def associated_tenants_to_dict(associated_tenants: List[AssociatedTenant]) -> li
303306
)
304307
return associated_tenant_list
305308

309+
306310
class SAMLIDPAttributeMappingInfo:
307311
"""
308312
Represents a SAML IDP attribute mapping object. use this class for mapping Descope attribute

descope/management/tenant.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import Any, List, Optional
22

33
from descope._http_base import HTTPBase
4-
from descope.management.common import MgmtV1, TenantAuthType, SessionExpirationUnit
4+
from descope.management.common import MgmtV1, SessionExpirationUnit, TenantAuthType
55

66

77
class Tenant(HTTPBase):
@@ -108,7 +108,7 @@ def update_settings(
108108
enable_inactivity: Optional[bool] = None,
109109
inactivity_time: Optional[int] = None,
110110
inactivity_time_unit: Optional[SessionExpirationUnit] = None,
111-
JITDisabled: Optional[bool] = None
111+
JITDisabled: Optional[bool] = None,
112112
):
113113
"""
114114
Update an existing tenant's session settings.
@@ -150,14 +150,10 @@ def update_settings(
150150
"inactivityTimeUnit": inactivity_time_unit,
151151
"JITDisabled": JITDisabled,
152152
}
153-
153+
154154
body = {k: v for k, v in body.items() if v is not None}
155155

156-
self._http.post(
157-
MgmtV1.tenant_settings_path,
158-
body=body,
159-
params=None
160-
)
156+
self._http.post(MgmtV1.tenant_settings_path, body=body, params=None)
161157

162158
def delete(
163159
self,
@@ -201,7 +197,7 @@ def load(
201197
params={"id": id},
202198
)
203199
return response.json()
204-
200+
205201
def load_settings(
206202
self,
207203
id: str,

tests/management/test_tenant.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,13 @@ def test_update_settings(self):
389389
with patch("requests.post") as mock_post:
390390
mock_post.return_value.ok = True
391391
self.assertIsNone(
392-
client.mgmt.tenant.update_settings("t1", self_provisioning_domains=["domain1.com"], domains=["domain1.com", "domain2.com"], auth_type="oidc", session_settings_enabled=True)
392+
client.mgmt.tenant.update_settings(
393+
"t1",
394+
self_provisioning_domains=["domain1.com"],
395+
domains=["domain1.com", "domain2.com"],
396+
auth_type="oidc",
397+
session_settings_enabled=True,
398+
)
393399
)
394400
mock_post.assert_called_with(
395401
f"{common.DEFAULT_BASE_URL}{MgmtV1.tenant_settings_path}",
@@ -403,7 +409,7 @@ def test_update_settings(self):
403409
"selfProvisioningDomains": ["domain1.com"],
404410
"domains": ["domain1.com", "domain2.com"],
405411
"authType": "oidc",
406-
"enabled": True
412+
"enabled": True,
407413
},
408414
allow_redirects=False,
409415
params=None,

0 commit comments

Comments
 (0)