kinde-python-sdk 1.2.7__py3-none-any.whl → 1.2.9__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.
- {kinde_python_sdk-1.2.7.dist-info → kinde_python_sdk-1.2.9.dist-info}/METADATA +1 -1
- {kinde_python_sdk-1.2.7.dist-info → kinde_python_sdk-1.2.9.dist-info}/RECORD +7 -7
- {kinde_python_sdk-1.2.7.dist-info → kinde_python_sdk-1.2.9.dist-info}/WHEEL +1 -1
- kinde_sdk/kinde_api_client.py +154 -0
- kinde_sdk/test/test_kinde_api_client.py +86 -0
- {kinde_python_sdk-1.2.7.dist-info → kinde_python_sdk-1.2.9.dist-info}/LICENSE +0 -0
- {kinde_python_sdk-1.2.7.dist-info → kinde_python_sdk-1.2.9.dist-info}/top_level.txt +0 -0
|
@@ -2,7 +2,7 @@ kinde_sdk/__init__.py,sha256=cBbmyFIDIH3kIYStgbhPnRJgsfe1EGa9_kLnimT4m7k,726
|
|
|
2
2
|
kinde_sdk/api_client.py,sha256=ofpdNwrQxXPFlv5KRisoPOXDta9K_Eg_IbD2hwLjAE8,58495
|
|
3
3
|
kinde_sdk/configuration.py,sha256=oqZGvKEf4kNNURbI1pip2ZVVcDyRTSmmnjXWziH4s80,15765
|
|
4
4
|
kinde_sdk/exceptions.py,sha256=1rFuvc5vj6ZjnT_m1yd_vCyFROfV_4ytcmFrj3rg1jw,4736
|
|
5
|
-
kinde_sdk/kinde_api_client.py,sha256=
|
|
5
|
+
kinde_sdk/kinde_api_client.py,sha256=FgFYIx46tjwFn4XmwqfDHzzM6Xt1dz_Y0rypsIumZGI,18818
|
|
6
6
|
kinde_sdk/rest.py,sha256=HKfSGwlWNMRgB8wrT0u__2K-ZNFSSmAyBBFLH-dCilM,10552
|
|
7
7
|
kinde_sdk/schemas.py,sha256=PC7NB7JscfXesOxq2TyddRb_3N2gqSZGUjsCKP3_7RU,97655
|
|
8
8
|
kinde_sdk/apis/__init__.py,sha256=RTosXhMn41tMsKPUjIy-VK-_efOWzhkKiuGggJ3A6E0,214
|
|
@@ -509,7 +509,7 @@ kinde_sdk/paths/oauth2_v2_user_profile/__init__.py,sha256=O-78h6bM2O__SxkzxirG-q
|
|
|
509
509
|
kinde_sdk/paths/oauth2_v2_user_profile/get.py,sha256=XDLPbzx2q_CkZ4Da5LJXGZBAySPxRrAoIYyilwedplA,8381
|
|
510
510
|
kinde_sdk/paths/oauth2_v2_user_profile/get.pyi,sha256=aFY0cUUoAko2Gai-WIj4awMxCrHSjCMepztWdxwpdIA,8205
|
|
511
511
|
kinde_sdk/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
512
|
-
kinde_sdk/test/test_kinde_api_client.py,sha256=
|
|
512
|
+
kinde_sdk/test/test_kinde_api_client.py,sha256=Tp-akbRcKcMMoCWWiSrXIwafC-aM-HdM-OhOFWjRuto,12764
|
|
513
513
|
kinde_sdk/test/test_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
514
514
|
kinde_sdk/test/test_models/test_add_organization_users_response.py,sha256=OxtCMFQ7WirbzdeBL0VXXcIBkrv_RXdr2jrbuhivzxU,1017
|
|
515
515
|
kinde_sdk/test/test_models/test_api.py,sha256=5w0EcvDwo1tWfZ00TVNnyV79tW7z22H0DNfq6Rbswg8,517
|
|
@@ -582,8 +582,8 @@ kinde_sdk/test/test_models/test_user_profile_v2.py,sha256=QltYLnrMdUUM_rw6Fg5Nyw
|
|
|
582
582
|
kinde_sdk/test/test_models/test_users.py,sha256=IGWziLNMAJbamUqoQxvcQKKd5G1D5Gp1sns9fdhxLt4,526
|
|
583
583
|
kinde_sdk/test/test_models/test_users_response.py,sha256=ZHgkFH98bHU1JLIGh7R7MU4XfEqPY3QnkRiHZ2eLqmg,858
|
|
584
584
|
kinde_sdk/test/test_models/test_webhook.py,sha256=9iZ6FjNBEA-rPbO1Deq0qonOkVp-ANoxFt0__O8COqg,533
|
|
585
|
-
kinde_python_sdk-1.2.
|
|
586
|
-
kinde_python_sdk-1.2.
|
|
587
|
-
kinde_python_sdk-1.2.
|
|
588
|
-
kinde_python_sdk-1.2.
|
|
589
|
-
kinde_python_sdk-1.2.
|
|
585
|
+
kinde_python_sdk-1.2.9.dist-info/LICENSE,sha256=iT6AIO6NJn_mo0kDD5mpz2zp9GpzH6YdhqOmkCBg-kQ,1385
|
|
586
|
+
kinde_python_sdk-1.2.9.dist-info/METADATA,sha256=hrkr9mMfiDDmQ_HfQAi80Y2qg3PyPPQ7m7Zb7xiWiI8,1961
|
|
587
|
+
kinde_python_sdk-1.2.9.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
|
588
|
+
kinde_python_sdk-1.2.9.dist-info/top_level.txt,sha256=Tx4AaXvRSme43PIec8zPL_lCo02AWIRBG8JADU0GedQ,10
|
|
589
|
+
kinde_python_sdk-1.2.9.dist-info/RECORD,,
|
kinde_sdk/kinde_api_client.py
CHANGED
|
@@ -133,6 +133,13 @@ class KindeApiClient(ApiClient):
|
|
|
133
133
|
self._refresh_token()
|
|
134
134
|
return True
|
|
135
135
|
return False
|
|
136
|
+
|
|
137
|
+
def is_authenticated_token(self, token_value: dict) -> dict:
|
|
138
|
+
if token_value:
|
|
139
|
+
if token_value.is_expired():
|
|
140
|
+
self._refresh_token_value(token_value)
|
|
141
|
+
return True
|
|
142
|
+
return None
|
|
136
143
|
|
|
137
144
|
def create_org(self) -> str:
|
|
138
145
|
return f"{self.registration_url}&is_create_org=true"
|
|
@@ -145,23 +152,50 @@ class KindeApiClient(ApiClient):
|
|
|
145
152
|
self._decode_token_if_needed(token_name)
|
|
146
153
|
value = self.__decoded_tokens[token_name].get(key)
|
|
147
154
|
return {"name": key, "value": value}
|
|
155
|
+
|
|
156
|
+
def get_claim_token(self, token_value: dict, key: str, token_name: str = "access_token") -> Any:
|
|
157
|
+
if token_name not in self.TOKEN_NAMES:
|
|
158
|
+
raise KindeTokenException(
|
|
159
|
+
f"Please use only tokens from the list: {self.TOKEN_NAMES}"
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
decoded_tokens = self._decode_token_if_needed_value(token_name,token_value)
|
|
163
|
+
value = decoded_tokens[token_name].get(key)
|
|
164
|
+
return {"name": key, "value": value}
|
|
148
165
|
|
|
149
166
|
def get_permission(self, permission: str) -> Dict[str, Any]:
|
|
150
167
|
return {
|
|
151
168
|
"org_code": self.get_claim("org_code")["value"],
|
|
152
169
|
"is_granted": permission in self.get_claim("permissions")["value"],
|
|
153
170
|
}
|
|
171
|
+
|
|
172
|
+
def get_permission_token(self, token_value: dict, permission: str) -> Dict[str, Any]:
|
|
173
|
+
return {
|
|
174
|
+
"org_code": self.get_claim_token(token_value, "org_code")["value"],
|
|
175
|
+
"is_granted": permission in self.get_claim_token(token_value, "permissions")["value"],
|
|
176
|
+
}
|
|
154
177
|
|
|
155
178
|
def get_permissions(self) -> Dict[str, Any]:
|
|
156
179
|
return {
|
|
157
180
|
"org_code": self.get_claim("org_code")["value"],
|
|
158
181
|
"permissions": self.get_claim("permissions")["value"],
|
|
159
182
|
}
|
|
183
|
+
|
|
184
|
+
def get_permissions_token(self, token_value: dict) -> Dict[str, Any]:
|
|
185
|
+
return {
|
|
186
|
+
"org_code": self.get_claim_token(token_value, "org_code")["value"],
|
|
187
|
+
"permissions": self.get_claim_token(token_value, "permissions")["value"],
|
|
188
|
+
}
|
|
160
189
|
|
|
161
190
|
def get_organization(self) -> Dict[str, str]:
|
|
162
191
|
return {
|
|
163
192
|
"org_code": self.get_claim("org_code")["value"],
|
|
164
193
|
}
|
|
194
|
+
|
|
195
|
+
def get_organization_token(self, token_value: dict) -> Dict[str, str]:
|
|
196
|
+
return {
|
|
197
|
+
"org_code": self.get_claim_token(token_value, "org_code")["value"],
|
|
198
|
+
}
|
|
165
199
|
|
|
166
200
|
def get_user_details(self) -> Dict[str, str]:
|
|
167
201
|
return {
|
|
@@ -171,11 +205,25 @@ class KindeApiClient(ApiClient):
|
|
|
171
205
|
"email": self.get_claim("email", "id_token")["value"],
|
|
172
206
|
"picture": self.get_claim("picture", "id_token")["value"],
|
|
173
207
|
}
|
|
208
|
+
|
|
209
|
+
def get_user_details_token(self,token_value: dict) -> Dict[str, str]:
|
|
210
|
+
return {
|
|
211
|
+
"id": self.get_claim_token(token_value, "sub","id_token")["value"],
|
|
212
|
+
"given_name": self.get_claim_token(token_value, "given_name", "id_token")["value"],
|
|
213
|
+
"family_name": self.get_claim_token(token_value, "family_name", "id_token")["value"],
|
|
214
|
+
"email": self.get_claim_token(token_value, "email", "id_token")["value"],
|
|
215
|
+
"picture": self.get_claim_token(token_value, "picture", "id_token")["value"],
|
|
216
|
+
}
|
|
174
217
|
|
|
175
218
|
def get_user_organizations(self) -> Dict[str, List[str]]:
|
|
176
219
|
return {
|
|
177
220
|
"org_codes": self.get_claim("org_codes", "id_token")["value"],
|
|
178
221
|
}
|
|
222
|
+
|
|
223
|
+
def get_user_organizations_token(self, token_value: dict) -> Dict[str, List[str]]:
|
|
224
|
+
return {
|
|
225
|
+
"org_codes": self.get_claim_token(token_value, "org_codes", "id_token")["value"],
|
|
226
|
+
}
|
|
179
227
|
|
|
180
228
|
def get_flag(
|
|
181
229
|
self, code: str, default_value: Any = None, flag_type: str = ""
|
|
@@ -205,15 +253,53 @@ class KindeApiClient(ApiClient):
|
|
|
205
253
|
result_flag["type"] = FlagType[flag_type].value
|
|
206
254
|
|
|
207
255
|
return result_flag
|
|
256
|
+
|
|
257
|
+
def get_flag_token(
|
|
258
|
+
self, token_value: dict, code: str, default_value: Any = None, flag_type: str = ""
|
|
259
|
+
) -> Any:
|
|
260
|
+
flags = self.get_claim_token(token_value, "feature_flags")["value"] or {}
|
|
261
|
+
flag = {}
|
|
262
|
+
|
|
263
|
+
if code not in list(flags.keys()):
|
|
264
|
+
if default_value is None:
|
|
265
|
+
raise KindeRetrieveException(
|
|
266
|
+
f"Flag {code} was not found, and no default value has been provided"
|
|
267
|
+
)
|
|
268
|
+
else:
|
|
269
|
+
flag = flags[code]
|
|
270
|
+
if flag_type and flag.get("t") and flag_type != flag.get("t"):
|
|
271
|
+
raise KindeRetrieveException(
|
|
272
|
+
f"Flag {code} is of type {FlagType[flag.get('t')].value} - requested type {FlagType[flag_type].value}"
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
result_flag = {
|
|
276
|
+
"code": code,
|
|
277
|
+
"value": flag.get("v") if flag else default_value,
|
|
278
|
+
"is_default": not bool(flag),
|
|
279
|
+
}
|
|
280
|
+
flag_type = flag["t"] if flag else flag_type
|
|
281
|
+
if flag_type:
|
|
282
|
+
result_flag["type"] = FlagType[flag_type].value
|
|
283
|
+
|
|
284
|
+
return result_flag
|
|
208
285
|
|
|
209
286
|
def get_boolean_flag(self, code: str, default_value: Any = None) -> bool:
|
|
210
287
|
return self.get_flag(code, default_value, "b")["value"]
|
|
288
|
+
|
|
289
|
+
def get_boolean_flag_token(self, token_value: dict, code: str, default_value: Any = None) -> bool:
|
|
290
|
+
return self.get_flag_token(token_value, code, default_value, "b")["value"]
|
|
211
291
|
|
|
212
292
|
def get_string_flag(self, code: str, default_value: Any = None) -> str:
|
|
213
293
|
return self.get_flag(code, default_value, "s")["value"]
|
|
294
|
+
|
|
295
|
+
def get_string_flag_token(self, token_value: dict, code: str, default_value: Any = None) -> str:
|
|
296
|
+
return self.get_flag_token(token_value, code, default_value, "s")["value"]
|
|
214
297
|
|
|
215
298
|
def get_integer_flag(self, code: str, default_value: Any = None) -> int:
|
|
216
299
|
return self.get_flag(code, default_value, "i")["value"]
|
|
300
|
+
|
|
301
|
+
def get_integer_flag_token(self, token_value: dict, code: str, default_value: Any = None) -> int:
|
|
302
|
+
return self.get_flag_token(token_value, code, default_value, "i")["value"]
|
|
217
303
|
|
|
218
304
|
def call_api(self, *args, **kwargs) -> Any:
|
|
219
305
|
self._get_or_refresh_access_token()
|
|
@@ -248,6 +334,28 @@ class KindeApiClient(ApiClient):
|
|
|
248
334
|
self.__decoded_tokens[token_name] = jwt.decode(**decode_token_params)
|
|
249
335
|
else:
|
|
250
336
|
raise KindeTokenException(f"Token {token_name} doesn't exist.")
|
|
337
|
+
|
|
338
|
+
def _decode_token_if_needed_value(self, token_name: str, token_value: dict) -> dict:
|
|
339
|
+
token = token_value.get(token_name)
|
|
340
|
+
|
|
341
|
+
if not isinstance(token, str):
|
|
342
|
+
return token_value
|
|
343
|
+
|
|
344
|
+
signing_key = self.jwks_client.get_signing_key_from_jwt(token)
|
|
345
|
+
if signing_key:
|
|
346
|
+
decode_token_params = {
|
|
347
|
+
"jwt":token,
|
|
348
|
+
"key": signing_key.key,
|
|
349
|
+
"algorithms":["RS256"],
|
|
350
|
+
"options":{
|
|
351
|
+
"verify_signature": True,
|
|
352
|
+
"verify_exp": True,
|
|
353
|
+
"verify_aud": False
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return {token_name: jwt.decode(**decode_token_params)}
|
|
357
|
+
else:
|
|
358
|
+
raise KindeTokenException(f"Token {token_name} doesn't exist.")
|
|
251
359
|
|
|
252
360
|
def fetch_token(self, authorization_response: Optional[str] = None) -> None:
|
|
253
361
|
if self.grant_type == GrantType.CLIENT_CREDENTIALS:
|
|
@@ -274,6 +382,31 @@ class KindeApiClient(ApiClient):
|
|
|
274
382
|
self.configuration.access_token = self.__access_token_obj.get("access_token")
|
|
275
383
|
self._clear_decoded_tokens()
|
|
276
384
|
|
|
385
|
+
def fetch_token_value(self, authorization_response: Optional[str] = None) -> dict:
|
|
386
|
+
if self.grant_type == GrantType.CLIENT_CREDENTIALS:
|
|
387
|
+
params = {"grant_type": "client_credentials"}
|
|
388
|
+
if self.audience:
|
|
389
|
+
params["audience"] = self.audience
|
|
390
|
+
else:
|
|
391
|
+
if authorization_response is None:
|
|
392
|
+
raise KindeConfigurationException(
|
|
393
|
+
'"authorization_response" parameter is required when grant_type is different than CLIENT_CREDENTIALS.'
|
|
394
|
+
)
|
|
395
|
+
params = {"authorization_response": authorization_response}
|
|
396
|
+
if self.grant_type == GrantType.AUTHORIZATION_CODE_WITH_PKCE:
|
|
397
|
+
params["code_verifier"] = self.code_verifier
|
|
398
|
+
|
|
399
|
+
access_token_obj = self.client.fetch_token(
|
|
400
|
+
self.token_endpoint,
|
|
401
|
+
headers={
|
|
402
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
403
|
+
"Kinde-SDK": "/".join(("Python", kinde_sdk_version)),
|
|
404
|
+
},
|
|
405
|
+
**params,
|
|
406
|
+
)
|
|
407
|
+
return access_token_obj
|
|
408
|
+
|
|
409
|
+
|
|
277
410
|
def _get_or_refresh_access_token(self) -> None:
|
|
278
411
|
if self.grant_type == GrantType.CLIENT_CREDENTIALS:
|
|
279
412
|
if not self.__access_token_obj or self.__access_token_obj.is_expired():
|
|
@@ -309,6 +442,27 @@ class KindeApiClient(ApiClient):
|
|
|
309
442
|
self._clear_decoded_tokens()
|
|
310
443
|
else:
|
|
311
444
|
raise KindeTokenException('"Access token" and "Refresh token" are invalid.')
|
|
445
|
+
|
|
446
|
+
def _refresh_token_value(self, token_value: dict) -> dict:
|
|
447
|
+
refresh_token = token_value.get("refresh_token")
|
|
448
|
+
|
|
449
|
+
if refresh_token:
|
|
450
|
+
token_value = self.client.refresh_token(
|
|
451
|
+
self.token_endpoint,
|
|
452
|
+
headers={
|
|
453
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
454
|
+
"Kinde-SDK": "/".join(("Python", kinde_sdk_version)),
|
|
455
|
+
},
|
|
456
|
+
refresh_token=refresh_token,
|
|
457
|
+
)
|
|
458
|
+
if not token_value:
|
|
459
|
+
raise KindeTokenException(
|
|
460
|
+
'"Access token" and "Refresh token" are invalid.'
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
return token_value
|
|
464
|
+
else:
|
|
465
|
+
raise KindeTokenException('"Access token" and "Refresh token" are invalid.')
|
|
312
466
|
|
|
313
467
|
def _add_additional_params(self, url: str, additional_params: Optional[Dict[str, str]] = None) -> str:
|
|
314
468
|
|
|
@@ -98,6 +98,12 @@ class TestKindeApiClient(unittest.TestCase):
|
|
|
98
98
|
client.fetch_token(authorization_response="https://example.com/callback?code=test_code")
|
|
99
99
|
self.mock_oauth2_session.return_value.fetch_token.assert_called_once()
|
|
100
100
|
|
|
101
|
+
def test_fetch_token_authorization_code_token(self):
|
|
102
|
+
client = self._create_kinde_client(GrantType.AUTHORIZATION_CODE)
|
|
103
|
+
self.mock_oauth2_session.return_value.fetch_token.return_value = {"access_token": "test_token"}
|
|
104
|
+
token_value = client.fetch_token_value(authorization_response="https://example.com/callback?code=test_code")
|
|
105
|
+
self.mock_oauth2_session.return_value.fetch_token.assert_called_once()
|
|
106
|
+
|
|
101
107
|
@patch('kinde_sdk.kinde_api_client.ApiClient.call_api')
|
|
102
108
|
def test_super_call_api_with_correct_args(self, mock_super_call_api):
|
|
103
109
|
client = self._create_kinde_client(GrantType.CLIENT_CREDENTIALS)
|
|
@@ -142,6 +148,86 @@ class TestKindeApiClient(unittest.TestCase):
|
|
|
142
148
|
mock_get_claim.assert_any_call("permissions")
|
|
143
149
|
self.assertEqual(mock_get_claim.call_count, 2)
|
|
144
150
|
|
|
151
|
+
def test_get_permissions_token(self):
|
|
152
|
+
client = self._create_kinde_client(GrantType.AUTHORIZATION_CODE)
|
|
153
|
+
|
|
154
|
+
result = client.get_permissions_token({"access_token":{"org_code":"org123","permissions": ["read", "write", "delete"]}})
|
|
155
|
+
|
|
156
|
+
expected_result = {
|
|
157
|
+
"org_code": "org123",
|
|
158
|
+
"permissions": ["read", "write", "delete"]
|
|
159
|
+
}
|
|
160
|
+
self.assertEqual(result, expected_result)
|
|
161
|
+
|
|
162
|
+
def test_get_permission_token(self):
|
|
163
|
+
client = self._create_kinde_client(GrantType.AUTHORIZATION_CODE)
|
|
164
|
+
|
|
165
|
+
result = client.get_permission_token({"access_token":{"org_code":"org123","permissions": ["read", "write", "delete"]}},"read")
|
|
166
|
+
|
|
167
|
+
expected_result = {
|
|
168
|
+
"org_code": "org123",
|
|
169
|
+
"is_granted": True
|
|
170
|
+
}
|
|
171
|
+
self.assertEqual(result, expected_result)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def test_get_claim_token(self):
|
|
175
|
+
client = self._create_kinde_client(GrantType.AUTHORIZATION_CODE)
|
|
176
|
+
|
|
177
|
+
result = client.get_claim_token({"access_token":{"org_code":"org123","permissions": ["read", "write", "delete"]}},"org_code")
|
|
178
|
+
|
|
179
|
+
expected_result = {
|
|
180
|
+
"name": "org_code",
|
|
181
|
+
"value": "org123"
|
|
182
|
+
}
|
|
183
|
+
self.assertEqual(result, expected_result)
|
|
184
|
+
|
|
185
|
+
def test_get_user_details_token(self):
|
|
186
|
+
client = self._create_kinde_client(GrantType.AUTHORIZATION_CODE)
|
|
187
|
+
|
|
188
|
+
result = client.get_user_details_token({
|
|
189
|
+
"access_token":{"org_code":"org123","permissions": ["read", "write", "delete"]}
|
|
190
|
+
,"id_token":{"sub":"123","given_name":"John","family_name":"Doe","email":"john@example.com","picture":"https://example.com/pic.jpg"}
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
expected_result = {
|
|
194
|
+
"id":"123","given_name":"John","family_name":"Doe","email":"john@example.com","picture":"https://example.com/pic.jpg"
|
|
195
|
+
}
|
|
196
|
+
self.assertEqual(result, expected_result)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def test_get_flag_token(self):
|
|
200
|
+
client = self._create_kinde_client(GrantType.AUTHORIZATION_CODE)
|
|
201
|
+
|
|
202
|
+
result = client.get_flag_token({
|
|
203
|
+
"access_token":{"org_code":"org123","permissions": ["read", "write", "delete"],"feature_flags":{"test_flag":{"v":True,"t":"b"}}}
|
|
204
|
+
,"id_token":{"sub":"123","given_name":"John","family_name":"Doe","email":"john@example.com","picture":"https://example.com/pic.jpg"}
|
|
205
|
+
},
|
|
206
|
+
"test_flag"
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
expected_result = {
|
|
210
|
+
"code":"test_flag",
|
|
211
|
+
"value":True,
|
|
212
|
+
"is_default":False,
|
|
213
|
+
"type":"boolean"
|
|
214
|
+
}
|
|
215
|
+
self.assertEqual(result, expected_result)
|
|
216
|
+
|
|
217
|
+
def test_get_boolean_flag_token(self):
|
|
218
|
+
client = self._create_kinde_client(GrantType.AUTHORIZATION_CODE)
|
|
219
|
+
|
|
220
|
+
result = client.get_boolean_flag_token({
|
|
221
|
+
"access_token":{"org_code":"org123","permissions": ["read", "write", "delete"],"feature_flags":{"test_flag":{"v":True,"t":"b"}}}
|
|
222
|
+
,"id_token":{"sub":"123","given_name":"John","family_name":"Doe","email":"john@example.com","picture":"https://example.com/pic.jpg"}
|
|
223
|
+
},
|
|
224
|
+
"test_flag"
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
expected_result = True
|
|
228
|
+
self.assertEqual(result, expected_result)
|
|
229
|
+
|
|
230
|
+
|
|
145
231
|
def test_fetch_token_headers_with_authorization_code(self):
|
|
146
232
|
client = self._create_kinde_client(GrantType.AUTHORIZATION_CODE)
|
|
147
233
|
self.mock_oauth2_session.return_value.fetch_token.return_value = {"access_token": "test_token"}
|
|
File without changes
|
|
File without changes
|