Skip to content

Commit d41bfb0

Browse files
authored
Merge pull request #45 from kinde-oss/rai/add-state-login
Added ability to pass state to the login and register urls
2 parents ce2513f + 42590c5 commit d41bfb0

File tree

3 files changed

+59
-14
lines changed

3 files changed

+59
-14
lines changed

kinde_sdk/kinde_api_client.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,14 @@ def __init__(
7373
"scope": self.scope,
7474
"token_endpoint": self.token_endpoint,
7575
}
76-
create_authorization_url_params = {}
76+
self.create_authorization_url_params = {}
7777
if self.grant_type == GrantType.AUTHORIZATION_CODE_WITH_PKCE:
7878
if self.code_verifier is None:
7979
raise KindeConfigurationException(
8080
'"code_verifier" parameter is required when a grant_type is AUTHORIZATION_CODE_WITH_PKCE.'
8181
)
8282
auth_session_params["code_challenge_method"] = "S256"
83-
create_authorization_url_params["code_verifier"] = self.code_verifier
83+
self.create_authorization_url_params["code_verifier"] = self.code_verifier
8484

8585
self.client = OAuth2Session(
8686
self.client_id,
@@ -89,29 +89,35 @@ def __init__(
8989
**auth_session_params,
9090
)
9191

92+
self.login_url = ""
93+
self.registration_url = ""
94+
95+
self.jwks_client = PyJWKClient(
96+
uri=f"{self.domain}/.well-known/jwks.json",
97+
cache_keys=True,
98+
)
99+
100+
def _get_auth_url(self, state: str = None):
92101
self.login_url, self.state = self.client.create_authorization_url(
93-
self.authorization_endpoint, **create_authorization_url_params
102+
self.authorization_endpoint, **self.create_authorization_url_params, state=state
94103
)
95104

96105
if self.audience:
97106
self.login_url = f"{self.login_url}&audience={self.audience}"
98107
if self.org_code:
99108
self.login_url = f"{self.login_url}&org_code={self.org_code}"
100109

101-
self.registration_url = f"{self.login_url}&start_page=registration"
102-
self.create_org_url = f"{self.registration_url}&is_create_org=true"
103-
self.jwks_client = PyJWKClient(
104-
uri=f"{self.domain}/.well-known/jwks.json",
105-
cache_keys=True,
106-
)
107-
110+
def get_login_url(self, additional_params: Optional[Dict[str, str]] = None, state: str = None) -> str:
111+
self._get_auth_url(state=state)
108112

109-
def get_login_url(self, additional_params: Optional[Dict[str, str]] = None) -> str:
110113
if additional_params:
111114
return self._add_additional_params(self.login_url, additional_params=additional_params)
112115
return self.login_url
113116

114-
def get_register_url(self, additional_params: Optional[Dict[str, str]] = None) -> str:
117+
def get_register_url(self, additional_params: Optional[Dict[str, str]] = None, state: str = None) -> str:
118+
self._get_auth_url(state=state)
119+
self.registration_url = f"{self.login_url}&start_page=registration"
120+
115121
if additional_params:
116122
return self._add_additional_params(self.registration_url, additional_params=additional_params)
117123
return self.registration_url
@@ -129,7 +135,7 @@ def is_authenticated(self) -> bool:
129135
return False
130136

131137
def create_org(self) -> str:
132-
return self.create_org_url
138+
return f"{self.registration_url}&is_create_org=true"
133139

134140
def get_claim(self, key: str, token_name: str = "access_token") -> Any:
135141
if token_name not in self.TOKEN_NAMES:

kinde_sdk/test/test_kinde_api_client.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from unittest.mock import patch, MagicMock
33
from kinde_sdk.kinde_api_client import KindeApiClient, GrantType
44
from kinde_sdk import __version__
5+
from urllib.parse import urlparse, parse_qs
56

67
class TestKindeApiClient(unittest.TestCase):
78

@@ -164,5 +165,43 @@ def test_fetch_token_headers_with_PKCE(self):
164165
self.assertIn('code_verifier', call_kwargs)
165166
self.assertEqual(call_kwargs['code_verifier'], '1234')
166167

168+
169+
170+
class TestKindeApiClientAdditional(unittest.TestCase):
171+
def setUp(self):
172+
self.domain = "https://example.kinde.com"
173+
self.callback_url = "https://example.com/callback"
174+
self.client_id = "test_client_id"
175+
self.client_secret = "test_client_secret"
176+
177+
def _create_kinde_client(self, grant_type, code_verifier=None):
178+
return KindeApiClient(
179+
domain=self.domain,
180+
callback_url=self.callback_url,
181+
client_id=self.client_id,
182+
client_secret=self.client_secret,
183+
grant_type=grant_type,
184+
code_verifier = code_verifier
185+
)
186+
187+
def test_get_login_url_state(self):
188+
client = self._create_kinde_client(GrantType.AUTHORIZATION_CODE)
189+
login_url = client.get_login_url(state="hello")
190+
191+
url_parts = urlparse(login_url)
192+
query = parse_qs(url_parts.query)
193+
194+
self.assertEqual(query['state'][0], "hello")
195+
196+
def test_get_register_url_state(self):
197+
client = self._create_kinde_client(GrantType.AUTHORIZATION_CODE)
198+
register_url = client.get_register_url(state="regis")
199+
200+
url_parts = urlparse(register_url)
201+
query = parse_qs(url_parts.query)
202+
203+
self.assertEqual(query['state'][0], "regis")
204+
self.assertEqual(query['start_page'][0], "registration")
205+
167206
if __name__ == '__main__':
168207
unittest.main()

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "kinde-python-sdk"
3-
version = "1.2.5"
3+
version = "1.2.6"
44
authors = [
55
{ name = "Kinde Engineering", email = "engineering@kinde.com" },
66
]

0 commit comments

Comments
 (0)