diff options
author | Jon Velando <28741910+rigzba21@users.noreply.github.com> | 2021-12-13 00:41:35 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-13 11:41:35 +0600 |
commit | 06497bede5934e367a7fbe94fe1b1d0538d417d4 (patch) | |
tree | e99fb037d16725e321c22a93b58c2d95c3bfd815 /tests | |
parent | 6db69014898e2095cf165be0faab4f99178896b6 (diff) | |
download | oauthlib-06497bede5934e367a7fbe94fe1b1d0538d417d4.tar.gz |
PKCE (#786)
* Added pkce on client side for authorization grant flow. Test cases added
* added new args before kwargs
* updating docstrings with clarification on PKCE params
* adding additional clarification on PKCE parameters
* adding initial function to create code_verifier and tests
* using re.compile for code_verifier allowed characters
* adding initial function to create code_challenge with tests
* replacing appropriate chars for base64 URL
Co-authored-by: Aman Singh Solanki <amans330@gmail.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/oauth2/rfc6749/clients/test_base.py | 28 | ||||
-rw-r--r-- | tests/oauth2/rfc6749/clients/test_web_application.py | 18 | ||||
-rw-r--r-- | tests/oauth2/rfc6749/test_parameters.py | 22 |
3 files changed, 68 insertions, 0 deletions
diff --git a/tests/oauth2/rfc6749/clients/test_base.py b/tests/oauth2/rfc6749/clients/test_base.py index 6b4eff0..70a2283 100644 --- a/tests/oauth2/rfc6749/clients/test_base.py +++ b/tests/oauth2/rfc6749/clients/test_base.py @@ -325,3 +325,31 @@ class ClientTest(TestCase): self.assertEqual(client.access_token, response.get("access_token")) self.assertEqual(client.refresh_token, response.get("refresh_token")) self.assertEqual(client.token_type, response.get("token_type")) + + + def test_create_code_verifier_min_length(self): + client = Client(self.client_id) + length = 43 + code_verifier = client.create_code_verifier(length=length) + self.assertEqual(client.code_verifier, code_verifier) + + def test_create_code_verifier_max_length(self): + client = Client(self.client_id) + length = 128 + code_verifier = client.create_code_verifier(length=length) + self.assertEqual(client.code_verifier, code_verifier) + + def test_create_code_challenge_plain(self): + client = Client(self.client_id) + code_verifier = client.create_code_verifier(length=128) + code_challenge_plain = client.create_code_challenge(code_verifier=code_verifier) + + # if no code_challenge_method specified, code_challenge = code_verifier + self.assertEqual(code_challenge_plain, client.code_verifier) + self.assertEqual(client.code_challenge_method, "plain") + + def test_create_code_challenge_s256(self): + client = Client(self.client_id) + code_verifier = client.create_code_verifier(length=128) + code_challenge_s256 = client.create_code_challenge(code_verifier=code_verifier, code_challenge_method='S256') + self.assertEqual(code_challenge_s256, client.code_challenge) diff --git a/tests/oauth2/rfc6749/clients/test_web_application.py b/tests/oauth2/rfc6749/clients/test_web_application.py index 1f711f4..f6b9449 100644 --- a/tests/oauth2/rfc6749/clients/test_web_application.py +++ b/tests/oauth2/rfc6749/clients/test_web_application.py @@ -24,10 +24,15 @@ class WebApplicationClientTest(TestCase): uri_id = uri + "&response_type=code&client_id=" + client_id uri_redirect = uri_id + "&redirect_uri=http%3A%2F%2Fmy.page.com%2Fcallback" redirect_uri = "http://my.page.com/callback" + code_verifier = "code_verifier" scope = ["/profile"] state = "xyz" + code_challenge = "code_challenge" + code_challenge_method = "S256" uri_scope = uri_id + "&scope=%2Fprofile" uri_state = uri_id + "&state=" + state + uri_code_challenge = uri_id + "&code_challenge=" + code_challenge + "&code_challenge_method=" + code_challenge_method + uri_code_challenge_method = uri_id + "&code_challenge=" + code_challenge + "&code_challenge_method=plain" kwargs = { "some": "providers", "require": "extra arguments" @@ -40,6 +45,7 @@ class WebApplicationClientTest(TestCase): body_code = "not=empty&grant_type=authorization_code&code={}&client_id={}".format(code, client_id) body_redirect = body_code + "&redirect_uri=http%3A%2F%2Fmy.page.com%2Fcallback" + bode_code_verifier = body_code + "&code_verifier=code_verifier" body_kwargs = body_code + "&some=providers&require=extra+arguments" response_uri = "https://client.example.com/cb?code=zzzzaaaa&state=xyz" @@ -80,6 +86,14 @@ class WebApplicationClientTest(TestCase): uri = client.prepare_request_uri(self.uri, state=self.state) self.assertURLEqual(uri, self.uri_state) + # with code_challenge and code_challenge_method + uri = client.prepare_request_uri(self.uri, code_challenge=self.code_challenge, code_challenge_method=self.code_challenge_method) + self.assertURLEqual(uri, self.uri_code_challenge) + + # with no code_challenge_method + uri = client.prepare_request_uri(self.uri, code_challenge=self.code_challenge) + self.assertURLEqual(uri, self.uri_code_challenge_method) + # With extra parameters through kwargs uri = client.prepare_request_uri(self.uri, **self.kwargs) self.assertURLEqual(uri, self.uri_kwargs) @@ -99,6 +113,10 @@ class WebApplicationClientTest(TestCase): body = client.prepare_request_body(body=self.body, redirect_uri=self.redirect_uri) self.assertFormBodyEqual(body, self.body_redirect) + # With code verifier + body = client.prepare_request_body(body=self.body, code_verifier=self.code_verifier) + self.assertFormBodyEqual(body, self.bode_code_verifier) + # With extra parameters body = client.prepare_request_body(body=self.body, **self.kwargs) self.assertFormBodyEqual(body, self.body_kwargs) diff --git a/tests/oauth2/rfc6749/test_parameters.py b/tests/oauth2/rfc6749/test_parameters.py index f9245ec..cd8c9e9 100644 --- a/tests/oauth2/rfc6749/test_parameters.py +++ b/tests/oauth2/rfc6749/test_parameters.py @@ -21,12 +21,15 @@ class ParameterTests(TestCase): list_scope = ['list', 'of', 'scopes'] auth_grant = {'response_type': 'code'} + auth_grant_pkce = {'response_type': 'code', 'code_challenge': "code_challenge", + 'code_challenge_method': 'code_challenge_method'} auth_grant_list_scope = {} auth_implicit = {'response_type': 'token', 'extra': 'extra'} auth_implicit_list_scope = {} def setUp(self): self.auth_grant.update(self.auth_base) + self.auth_grant_pkce.update(self.auth_base) self.auth_implicit.update(self.auth_base) self.auth_grant_list_scope.update(self.auth_grant) self.auth_grant_list_scope['scope'] = self.list_scope @@ -37,7 +40,14 @@ class ParameterTests(TestCase): '&client_id=s6BhdRkqt3&redirect_uri=https%3A%2F%2F' 'client.example.com%2Fcb&scope={1}&state={2}{3}') + auth_base_uri_pkce = ('https://server.example.com/authorize?response_type={0}' + '&client_id=s6BhdRkqt3&redirect_uri=https%3A%2F%2F' + 'client.example.com%2Fcb&scope={1}&state={2}{3}&code_challenge={4}' + '&code_challenge_method={5}') + auth_grant_uri = auth_base_uri.format('code', 'photos', state, '') + auth_grant_uri_pkce = auth_base_uri_pkce.format('code', 'photos', state, '', 'code_challenge', + 'code_challenge_method') auth_grant_uri_list_scope = auth_base_uri.format('code', 'list+of+scopes', state, '') auth_implicit_uri = auth_base_uri.format('token', 'photos', state, '&extra=extra') auth_implicit_uri_list_scope = auth_base_uri.format('token', 'list+of+scopes', state, '&extra=extra') @@ -47,11 +57,21 @@ class ParameterTests(TestCase): 'code': 'SplxlOBeZQQYbYS6WxSbIA', 'redirect_uri': 'https://client.example.com/cb' } + grant_body_pkce = { + 'grant_type': 'authorization_code', + 'code': 'SplxlOBeZQQYbYS6WxSbIA', + 'redirect_uri': 'https://client.example.com/cb', + 'code_verifier': 'code_verifier' + } grant_body_scope = {'scope': 'photos'} grant_body_list_scope = {'scope': list_scope} auth_grant_body = ('grant_type=authorization_code&' 'code=SplxlOBeZQQYbYS6WxSbIA&' 'redirect_uri=https%3A%2F%2Fclient.example.com%2Fcb') + auth_grant_body_pkce = ('grant_type=authorization_code&' + 'code=SplxlOBeZQQYbYS6WxSbIA&' + 'redirect_uri=https%3A%2F%2Fclient.example.com%2Fcb' + '&code_verifier=code_verifier') auth_grant_body_scope = auth_grant_body + '&scope=photos' auth_grant_body_list_scope = auth_grant_body + '&scope=list+of+scopes' @@ -179,12 +199,14 @@ class ParameterTests(TestCase): self.assertURLEqual(prepare_grant_uri(**self.auth_grant_list_scope), self.auth_grant_uri_list_scope) self.assertURLEqual(prepare_grant_uri(**self.auth_implicit), self.auth_implicit_uri) self.assertURLEqual(prepare_grant_uri(**self.auth_implicit_list_scope), self.auth_implicit_uri_list_scope) + self.assertURLEqual(prepare_grant_uri(**self.auth_grant_pkce), self.auth_grant_uri_pkce) def test_prepare_token_request(self): """Verify correct access token request body construction.""" self.assertFormBodyEqual(prepare_token_request(**self.grant_body), self.auth_grant_body) self.assertFormBodyEqual(prepare_token_request(**self.pwd_body), self.password_body) self.assertFormBodyEqual(prepare_token_request(**self.cred_grant), self.cred_body) + self.assertFormBodyEqual(prepare_token_request(**self.grant_body_pkce), self.auth_grant_body_pkce) def test_grant_response(self): """Verify correct parameter parsing and validation for auth code responses.""" |