Skip to content

Commit 55c0b78

Browse files
committed
Merge branch 'add-tenant-enforcesso-disabled' of github.com:descope/python-sdk into add-tenant-enforcesso-disabled
2 parents 34c2527 + 65d73f8 commit 55c0b78

39 files changed

+357
-59
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
with:
3535
fetch-depth: 0
3636
- name: Setup python for test ${{ matrix.py }}
37-
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
37+
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
3838
with:
3939
python-version: ${{ matrix.py }}
4040
- name: Install tox
@@ -46,7 +46,7 @@ jobs:
4646
env:
4747
COVERAGE_FILE: "coverage.${{ matrix.os }}.${{ matrix.py }}"
4848
- name: Store coverage file
49-
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
49+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
5050
with:
5151
name: coverage.${{ matrix.os }}.${{ matrix.py }}
5252
path: coverage.${{ matrix.os }}.${{ matrix.py }}
@@ -65,7 +65,7 @@ jobs:
6565
steps:
6666
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
6767

68-
- uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9
68+
- uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
6969
id: download
7070
with:
7171
pattern: coverage.*
@@ -81,7 +81,7 @@ jobs:
8181
VERBOSE: true
8282

8383
- name: Store Pull Request comment to be posted
84-
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
84+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
8585
if: steps.coverage_comment.outputs.COMMENT_FILE_WRITTEN == 'true'
8686
with:
8787
name: python-coverage-comment-action

.pre-commit-config.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ repos:
2929
- id: pyupgrade
3030
args: [--py38-plus]
3131
- repo: https://github.com/pycqa/flake8
32-
rev: 7.1.2
32+
rev: 7.2.0
3333
hooks:
3434
- id: flake8
3535
additional_dependencies: [Flake8-pyproject]
3636
- repo: https://github.com/python-poetry/poetry
37-
rev: 2.1.1
37+
rev: 2.1.2
3838
hooks:
3939
- id: poetry-export
4040
files: pyproject.toml
@@ -43,7 +43,7 @@ repos:
4343
- id: poetry-check
4444
files: pyproject.toml
4545
- repo: https://github.com/pre-commit/pre-commit
46-
rev: v4.1.0
46+
rev: v4.2.0
4747
hooks:
4848
- id: validate_manifest
4949
- repo: https://github.com/tox-dev/tox-ini-fmt
@@ -52,7 +52,7 @@ repos:
5252
- id: tox-ini-fmt
5353
args: ["-p", "type"]
5454
- repo: https://github.com/gitleaks/gitleaks
55-
rev: v8.24.0
55+
rev: v8.24.3
5656
hooks:
5757
- id: gitleaks
5858
- repo: local

descope/auth.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ def generate_jwt_response(
560560

561561
def _get_default_headers(self, pswd: str | None = None):
562562
headers = _default_headers.copy()
563+
headers["x-descope-project-id"] = self.project_id
563564
bearer = self.project_id
564565
if pswd:
565566
bearer = f"{self.project_id}:{pswd}"

descope/authmethod/enchantedlink.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ def update_user_email(
107107
add_to_login_ids: bool = False,
108108
on_merge_use_existing: bool = False,
109109
template_options: dict | None = None,
110+
template_id: str | None = None,
111+
provider_id: str | None = None,
110112
) -> dict:
111113
if not login_id:
112114
raise AuthException(
@@ -116,7 +118,8 @@ def update_user_email(
116118
Auth.validate_email(email)
117119

118120
body = EnchantedLink._compose_update_user_email_body(
119-
login_id, email, add_to_login_ids, on_merge_use_existing, template_options
121+
login_id, email, add_to_login_ids, on_merge_use_existing,
122+
template_options, template_id, provider_id
120123
)
121124
uri = EndpointsV1.update_user_email_enchantedlink_path
122125
response = self._auth.do_post(uri, body, None, refresh_token)
@@ -181,6 +184,8 @@ def _compose_update_user_email_body(
181184
add_to_login_ids: bool,
182185
on_merge_use_existing: bool,
183186
template_options: dict | None = None,
187+
template_id: str | None = None,
188+
provider_id: str | None = None,
184189
) -> dict:
185190
body: dict[str, str | bool | dict] = {
186191
"loginId": login_id,
@@ -190,6 +195,10 @@ def _compose_update_user_email_body(
190195
}
191196
if template_options is not None:
192197
body["templateOptions"] = template_options
198+
if template_id is not None:
199+
body["templateId"] = template_id
200+
if provider_id is not None:
201+
body["providerId"] = provider_id
193202

194203
return body
195204

descope/authmethod/magiclink.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ def update_user_email(
106106
add_to_login_ids: bool = False,
107107
on_merge_use_existing: bool = False,
108108
template_options: dict | None = None,
109+
template_id: str | None = None,
110+
provider_id: str | None = None,
109111
) -> str:
110112
if not login_id:
111113
raise AuthException(
@@ -115,7 +117,8 @@ def update_user_email(
115117
Auth.validate_email(email)
116118

117119
body = MagicLink._compose_update_user_email_body(
118-
login_id, email, add_to_login_ids, on_merge_use_existing, template_options
120+
login_id, email, add_to_login_ids, on_merge_use_existing,
121+
template_options, template_id, provider_id
119122
)
120123
uri = EndpointsV1.update_user_email_magiclink_path
121124
response = self._auth.do_post(uri, body, None, refresh_token)
@@ -130,6 +133,8 @@ def update_user_phone(
130133
add_to_login_ids: bool = False,
131134
on_merge_use_existing: bool = False,
132135
template_options: dict | None = None,
136+
template_id: str | None = None,
137+
provider_id: str | None = None,
133138
) -> str:
134139
if not login_id:
135140
raise AuthException(
@@ -139,7 +144,8 @@ def update_user_phone(
139144
Auth.validate_phone(method, phone)
140145

141146
body = MagicLink._compose_update_user_phone_body(
142-
login_id, phone, add_to_login_ids, on_merge_use_existing, template_options
147+
login_id, phone, add_to_login_ids, on_merge_use_existing,
148+
template_options, template_id, provider_id
143149
)
144150
uri = EndpointsV1.update_user_phone_magiclink_path
145151
response = self._auth.do_post(uri, body, None, refresh_token)
@@ -203,6 +209,8 @@ def _compose_update_user_email_body(
203209
add_to_login_ids: bool,
204210
on_merge_use_existing: bool,
205211
template_options: dict | None = None,
212+
template_id: str | None = None,
213+
provider_id: str | None = None,
206214
) -> dict:
207215
body: dict[str, str | bool | dict] = {
208216
"loginId": login_id,
@@ -212,6 +220,10 @@ def _compose_update_user_email_body(
212220
}
213221
if template_options is not None:
214222
body["templateOptions"] = template_options
223+
if template_id is not None:
224+
body["templateId"] = template_id
225+
if provider_id is not None:
226+
body["providerId"] = provider_id
215227

216228
return body
217229

@@ -222,6 +234,8 @@ def _compose_update_user_phone_body(
222234
add_to_login_ids: bool,
223235
on_merge_use_existing: bool,
224236
template_options: dict | None = None,
237+
template_id: str | None = None,
238+
provider_id: str | None = None,
225239
) -> dict:
226240
body: dict[str, str | bool | dict] = {
227241
"loginId": login_id,
@@ -231,5 +245,9 @@ def _compose_update_user_phone_body(
231245
}
232246
if template_options is not None:
233247
body["templateOptions"] = template_options
248+
if template_id is not None:
249+
body["templateId"] = template_id
250+
if provider_id is not None:
251+
body["providerId"] = provider_id
234252

235253
return body

descope/authmethod/otp.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ def update_user_email(
174174
add_to_login_ids: bool = False,
175175
on_merge_use_existing: bool = False,
176176
template_options: dict | None = None,
177+
template_id: str | None = None,
178+
provider_id: str | None = None,
177179
) -> str:
178180
"""
179181
Update the email address of an end user, after verifying the authenticity of the end user using OTP.
@@ -196,7 +198,8 @@ def update_user_email(
196198

197199
uri = EndpointsV1.update_user_email_otp_path
198200
body = OTP._compose_update_user_email_body(
199-
login_id, email, add_to_login_ids, on_merge_use_existing, template_options
201+
login_id, email, add_to_login_ids, on_merge_use_existing,
202+
template_options, template_id, provider_id
200203
)
201204
response = self._auth.do_post(uri, body, None, refresh_token)
202205
return Auth.extract_masked_address(response.json(), DeliveryMethod.EMAIL)
@@ -210,6 +213,8 @@ def update_user_phone(
210213
add_to_login_ids: bool = False,
211214
on_merge_use_existing: bool = False,
212215
template_options: dict | None = None,
216+
template_id: str | None = None,
217+
provider_id: str | None = None,
213218
) -> str:
214219
"""
215220
Update the phone number of an existing end user, after verifying the authenticity of the end user using OTP.
@@ -236,7 +241,8 @@ def update_user_phone(
236241

237242
uri = OTP._compose_update_phone_url(method)
238243
body = OTP._compose_update_user_phone_body(
239-
login_id, phone, add_to_login_ids, on_merge_use_existing, template_options
244+
login_id, phone, add_to_login_ids, on_merge_use_existing,
245+
template_options, template_id, provider_id
240246
)
241247
response = self._auth.do_post(uri, body, None, refresh_token)
242248
return Auth.extract_masked_address(response.json(), method)
@@ -299,6 +305,8 @@ def _compose_update_user_email_body(
299305
add_to_login_ids: bool,
300306
on_merge_use_existing: bool,
301307
template_options: dict | None = None,
308+
template_id: str | None = None,
309+
provider_id: str | None = None,
302310
) -> dict:
303311
body: dict[str, str | bool | dict] = {
304312
"loginId": login_id,
@@ -308,6 +316,10 @@ def _compose_update_user_email_body(
308316
}
309317
if template_options is not None:
310318
body["templateOptions"] = template_options
319+
if template_id is not None:
320+
body["templateId"] = template_id
321+
if provider_id is not None:
322+
body["providerId"] = provider_id
311323

312324
return body
313325

@@ -318,6 +330,8 @@ def _compose_update_user_phone_body(
318330
add_to_login_ids: bool,
319331
on_merge_use_existing: bool,
320332
template_options: dict | None = None,
333+
template_id: str | None = None,
334+
provider_id: str | None = None,
321335
) -> dict:
322336
body: dict[str, str | bool | dict] = {
323337
"loginId": login_id,
@@ -327,5 +341,9 @@ def _compose_update_user_phone_body(
327341
}
328342
if template_options is not None:
329343
body["templateOptions"] = template_options
344+
if template_id is not None:
345+
body["templateId"] = template_id
346+
if provider_id is not None:
347+
body["providerId"] = provider_id
330348

331349
return body

descope/management/common.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,10 @@ class MgmtSignUpOptions:
155155
def __init__(
156156
self,
157157
custom_claims: Optional[dict] = None,
158+
refresh_duration: Optional[int] = None,
158159
):
159160
self.custom_claims = custom_claims
161+
self.refresh_duration = refresh_duration
160162

161163

162164
class MgmtLoginOptions:
@@ -167,12 +169,14 @@ def __init__(
167169
revoke_other_sessions: Optional[bool] = None,
168170
custom_claims: Optional[dict] = None,
169171
jwt: Optional[str] = None,
172+
refresh_duration: Optional[int] = None,
170173
):
171174
self.stepup = stepup
172175
self.custom_claims = custom_claims
173176
self.mfa = mfa
174177
self.revoke_other_sessions = revoke_other_sessions
175178
self.jwt = jwt
179+
self.refresh_duration = refresh_duration
176180

177181

178182
def is_jwt_required(lgo: MgmtLoginOptions) -> bool:

descope/management/jwt.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def impersonate(
4848
validate_consent: bool,
4949
custom_claims: Optional[dict] = None,
5050
tenant_id: Optional[str] = None,
51+
refresh_duration: Optional[int] = None,
5152
) -> str:
5253
"""
5354
Impersonate to another user
@@ -78,8 +79,9 @@ def impersonate(
7879
"loginId": login_id,
7980
"impersonatorId": impersonator_id,
8081
"validateConsent": validate_consent,
81-
"cusotmClaims": custom_claims,
82+
"customClaims": custom_claims,
8283
"selectedTenant": tenant_id,
84+
"refreshDuration": refresh_duration,
8385
},
8486
pswd=self._auth.management_key,
8587
)
@@ -116,6 +118,7 @@ def sign_in(
116118
"revokeOtherSessions": login_options.revoke_other_sessions,
117119
"customClaims": login_options.custom_claims,
118120
"jwt": login_options.jwt,
121+
"refreshDuration": login_options.refresh_duration,
119122
},
120123
pswd=self._auth.management_key,
121124
)
@@ -187,6 +190,7 @@ def _sign_up_internal(
187190
"phoneVerified": user.phone_verified,
188191
"ssoAppId": user.sso_app_id,
189192
"customClaims": signup_options.custom_claims,
193+
"refreshDuration": signup_options.refresh_duration,
190194
},
191195
pswd=self._auth.management_key,
192196
)
@@ -198,6 +202,7 @@ def anonymous(
198202
self,
199203
custom_claims: Optional[dict] = None,
200204
tenant_id: Optional[str] = None,
205+
refresh_duration: Optional[int] = None,
201206
) -> dict:
202207
"""
203208
Generate a JWT for an anonymous user.
@@ -212,6 +217,7 @@ def anonymous(
212217
{
213218
"customClaims": custom_claims,
214219
"selectedTenant": tenant_id,
220+
"refreshDuration": refresh_duration,
215221
},
216222
pswd=self._auth.management_key,
217223
)

descope/management/role.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ def search(
116116
role_names: Optional[List[str]] = None,
117117
role_name_like: Optional[str] = None,
118118
permission_names: Optional[List[str]] = None,
119+
include_project_roles: Optional[bool] = None,
119120
) -> dict:
120121
"""
121122
Search roles based on the given filters.
@@ -134,7 +135,7 @@ def search(
134135
Raise:
135136
AuthException: raised if load operation fails
136137
"""
137-
body: dict[str, str | List[str]] = {}
138+
body: dict[str, str | bool | List[str]] = {}
138139
if tenant_ids is not None:
139140
body["tenantIds"] = tenant_ids
140141
if role_names is not None:
@@ -143,6 +144,8 @@ def search(
143144
body["roleNameLike"] = role_name_like
144145
if permission_names is not None:
145146
body["permissionNames"] = permission_names
147+
if include_project_roles is not None:
148+
body["includeProjectRoles"] = include_project_roles
146149

147150
response = self._auth.do_post(
148151
MgmtV1.role_search_path,

0 commit comments

Comments
 (0)