def test_with_invalid_grant_request_invalid_scope_error( token_cache, responses: RequestsMock, monkeypatch, browser_mock: BrowserMock ): monkeypatch.setattr(requests_auth.authentication.os, "urandom", lambda x: b"1" * 63) auth = requests_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) tab = browser_mock.add_response( opened_url="https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url="http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b", ) responses.add( responses.POST, "https://testserver.okta-emea.com/oauth2/default/v1/token", json={"error": "invalid_scope"}, status=400, ) with pytest.raises(requests_auth.InvalidGrantRequest) as exception_info: requests.get("http://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_scope: The requested scope is invalid, unknown, malformed, or " "exceeds the scope granted by the resource owner." ) tab.assert_success( "You are now authenticated on 5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b. You may close this tab." )
def test_oauth2_pkce_flow_get_code_is_sent_in_authorization_header_by_default( token_cache, responses: RequestsMock, monkeypatch, browser_mock: BrowserMock ): monkeypatch.setattr(requests_auth.authentication.os, "urandom", lambda x: b"1" * 63) auth = requests_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) tab = browser_mock.add_response( opened_url="https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url="http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b", ) responses.add( responses.POST, "https://testserver.okta-emea.com/oauth2/default/v1/token", json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", "expires_in": 3600, "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter": "example_value", }, ) assert ( get_header(responses, auth).get("Authorization") == "Bearer 2YotnFZFEjr1zCsicMWpAA" ) assert ( get_request( responses, "https://testserver.okta-emea.com/oauth2/default/v1/token" ).body == "code_verifier=MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEx&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA" ) tab.assert_success( "You are now authenticated on 5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b. You may close this tab." )
def test_with_invalid_grant_request_invalid_client_error( token_cache, responses: RequestsMock, monkeypatch, browser_mock: BrowserMock ): monkeypatch.setattr(requests_auth.authentication.os, "urandom", lambda x: b"1" * 63) auth = requests_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) tab = browser_mock.add_response( opened_url="https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url="http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b", ) responses.add( responses.POST, "https://testserver.okta-emea.com/oauth2/default/v1/token", json={"error": "invalid_client"}, status=400, ) with pytest.raises(requests_auth.InvalidGrantRequest) as exception_info: requests.get("http://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_client: Client authentication failed (e.g., unknown client, no " "client authentication included, or unsupported authentication method). The " "authorization server MAY return an HTTP 401 (Unauthorized) status code to " "indicate which HTTP authentication schemes are supported. If the client " 'attempted to authenticate via the "Authorization" request header field, the ' "authorization server MUST respond with an HTTP 401 (Unauthorized) status " 'code and include the "WWW-Authenticate" response header field matching the ' "authentication scheme used by the client." ) tab.assert_success( "You are now authenticated on 5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b. You may close this tab." )
def test_okta_authorization_code_pkce_flow(token_cache_mock, responses: RequestsMock): auth = requests_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd") assert (get_header( responses, auth).get("Authorization") == "Bearer 2YotnFZFEjr1zCsicMWpAA")
def test_corresponding_oauth2_authorization_code_flow_instance(monkeypatch): monkeypatch.setattr(requests_auth.authentication.os, "urandom", lambda x: b"1" * 63) okta = requests_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd") assert ( okta.code_grant_details.url == "https://testserver.okta-emea.com/oauth2/default/v1/authorize?" "client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd" "&scope=openid" "&response_type=code" "&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b" "&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F" "&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc" "&code_challenge_method=S256") assert (okta.authorization_url == "https://testserver.okta-emea.com/oauth2/default/v1/authorize") assert okta.token_url == "https://testserver.okta-emea.com/oauth2/default/v1/token" assert okta.token_data == { "client_id": "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", "code_verifier": b"MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEx" b"MTExMTExMTExMTExMTExMTExMTEx", "grant_type": "authorization_code", "redirect_uri": "http://localhost:5000/", "response_type": "code", "scope": "openid", } assert okta.code_grant_details.name == "code"
def test_header_value_must_contains_token(): with pytest.raises(Exception) as exception_info: requests_auth.OktaAuthorizationCodePKCE( "test_url", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", header_value="Bearer token", ) assert str(exception_info.value) == "header_value parameter must contains {token}."
def test_with_invalid_token_request_invalid_request_error_and_error_description( token_cache, responses: RequestsMock, monkeypatch, browser_mock: BrowserMock ): monkeypatch.setattr(requests_auth.authentication.os, "urandom", lambda x: b"1" * 63) auth = requests_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) tab = browser_mock.add_response( opened_url="https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url="http://localhost:5000#error=invalid_request&error_description=desc", ) with pytest.raises(requests_auth.InvalidGrantRequest) as exception_info: requests.get("http://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc" tab.assert_failure( "Unable to properly perform authentication: invalid_request: desc" )
def test_with_invalid_token_request_temporarily_unavailable_error( token_cache, responses: RequestsMock, monkeypatch, browser_mock: BrowserMock ): monkeypatch.setattr(requests_auth.authentication.os, "urandom", lambda x: b"1" * 63) auth = requests_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) tab = browser_mock.add_response( opened_url="https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url="http://localhost:5000#error=temporarily_unavailable", ) with pytest.raises(requests_auth.InvalidGrantRequest) as exception_info: requests.get("http://authorized_only", auth=auth) assert ( str(exception_info.value) == "temporarily_unavailable: The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server. (This error code is needed because a 503 Service Unavailable HTTP status code cannot be returned to the client via an HTTP redirect.)" ) tab.assert_failure( "Unable to properly perform authentication: temporarily_unavailable: The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server. (This error code is needed because a 503 Service Unavailable HTTP status code cannot be returned to the client via an HTTP redirect.)" )
def test_okta_pkce_flow_token_custom_expiry(token_cache, responses: RequestsMock, monkeypatch, browser_mock: BrowserMock): monkeypatch.setattr(requests_auth.authentication.os, "urandom", lambda x: b"1" * 63) auth = requests_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", early_expiry=28, ) # Add a token that expires in 29 seconds, so should be considered as not expired when issuing the request token_cache._add_token( key= "5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b", token="2YotnFZFEjr1zCsicMWpAA", expiry=requests_auth.oauth2_tokens._to_expiry(expires_in=29), ) assert (get_header( responses, auth).get("Authorization") == "Bearer 2YotnFZFEjr1zCsicMWpAA")