def test_refresh_access_token__success(make_token, respx_mock, dummy_context): """ Validate that the ``refreshed_access_token()`` function uses a refresh token to retrieve a new access token from the ``oauth/token`` endpoint of the ``settings.AUTH0_DOMAIN``. """ access_token = "expired-access-token" refresh_token = "dummy-refresh-token" token_set = TokenSet(access_token=access_token, refresh_token=refresh_token) refreshed_access_token = make_token( identity_data=dict( user_email="*****@*****.**", org_name="good_org", ), expires="2022-02-17 22:30:00", ) respx_mock.post(f"{LOGIN_DOMAIN}/oauth/token").mock( return_value=httpx.Response( httpx.codes.OK, json=dict(access_token=refreshed_access_token), ), ) refresh_access_token(dummy_context, token_set) assert token_set.access_token == refreshed_access_token
def test_save_tokens_to_cache__only_saves_access_token_if_refresh_token_is_not_defined( make_token, tmp_path, mocker): """ Validate that the ``save_tokens_to_cache()`` function will only write an access token to the cache if the ``TokenSet`` instance does not carry a refresh token. """ access_token = make_token( identity_data=dict( user_email="*****@*****.**", org_name="good_org", ), expires="2022-02-16 22:30:00", ) access_token_path = tmp_path / "access.jwt" refresh_token_path = tmp_path / "refresh.jwt" token_set = TokenSet(access_token=access_token, ) mocker.patch.object(settings, "JOBBERGATE_API_ACCESS_TOKEN_PATH", new=access_token_path) mocker.patch.object(settings, "JOBBERGATE_API_REFRESH_TOKEN_PATH", new=refresh_token_path) save_tokens_to_cache(token_set) assert access_token_path.exists() assert access_token_path.read_text() == access_token assert not refresh_token_path.exists()
def test_save_tokens_to_cache__success(make_token, tmp_path, mocker): """ Validate that the ``save_tokens_to_cache()`` function will write a access and refresh token from a ``TokenSet`` instance to the locations described by ``JOBBERGATE_API_ACCESS_TOKEN_PATH`` and ``JOBBERGATE_API_REFRESH_TOKEN_PATH``. """ access_token = make_token( identity_data=dict( user_email="*****@*****.**", org_name="good_org", ), expires="2022-02-16 22:30:00", ) access_token_path = tmp_path / "access.jwt" refresh_token = "dummy-refresh-token" refresh_token_path = tmp_path / "refresh.jwt" token_set = TokenSet( access_token=access_token, refresh_token=refresh_token, ) mocker.patch.object(settings, "JOBBERGATE_API_ACCESS_TOKEN_PATH", new=access_token_path) mocker.patch.object(settings, "JOBBERGATE_API_REFRESH_TOKEN_PATH", new=refresh_token_path) save_tokens_to_cache(token_set) assert access_token_path.exists() assert access_token_path.read_text() == access_token assert refresh_token_path.exists() assert refresh_token_path.read_text() == refresh_token
def test_validate_token_and_extract_identity__raises_abort_on_empty_token(): """ Validate that the ``validate_token_and_extract_identity()`` function will raise an ``Abort`` when the access_token exists but is an empty string/file. """ test_token_set = TokenSet(access_token="") with pytest.raises(Abort, match="Access token file exists but it is empty"): validate_token_and_extract_identity(test_token_set)
def test_validate_token_and_extract_identity__raises_abort_if_token_has_no_identity_data( make_token): """ Validate that the ``validate_token_and_extract_identity()`` function will raise an Abort if the access_token doesn't carry identity_data in it. """ access_token = make_token(expires="2022-02-16 22:30:00") with plummet.frozen_time("2022-02-16 21:30:00"): with pytest.raises(Abort, match="No identity data found"): validate_token_and_extract_identity( TokenSet(access_token=access_token))
def test_validate_token_and_extract_identity__raises_abort_on_unknown_error( mocker): """ Validate that the ``validate_token_and_extract_identity()`` function will raise an ``Abort`` when the ``jwt.decode()`` function raises an exception type besides ``ExpiredSignatureError``. """ test_token_set = TokenSet(access_token="BOGUS-TOKEN") mocker.patch("jose.jwt.decode", side_effect=Exception("BOOM!")) with pytest.raises(Abort, match="There was an unknown error while validating"): validate_token_and_extract_identity(test_token_set)
def test_validate_token_and_extract_identity__raises_abort_if_identity_data_is_malformed( make_token): """ Validate that the ``validate_token_and_extract_identity()`` function will raise an Abort if the access token's identity data does not match the ``IdentityData`` class spec. """ access_token = make_token( expires="2022-02-16 22:30:00", identity_data=dict(bad="data", ), ) with plummet.frozen_time("2022-02-16 21:30:00"): with pytest.raises(Abort, match="malformed or incomplete"): validate_token_and_extract_identity( TokenSet(access_token=access_token))
def test_validate_token_and_extract_identity__re_raises_ExpiredSignatureError( make_token): """ Validate that the ``validate_token_and_extract_identity()`` function will catch and then re-raise a ``ExpiredSignatureError`` thrown by the ``jwt.decode()`` function. """ access_token = make_token( identity_data=dict( user_email="*****@*****.**", org_name="good_org", ), expires="2022-02-16 20:30:00", ) with plummet.frozen_time("2022-02-16 21:30:00"): with pytest.raises(ExpiredSignatureError): validate_token_and_extract_identity( TokenSet(access_token=access_token))
def test_validate_token_and_extract_identity__success(make_token): """ Validate that the ``validate_token_and_extract_identity()`` function can successfully validate a good access token and extract identity_data from it. """ access_token = make_token( identity_data=dict( user_email="*****@*****.**", org_name="good_org", ), expires="2022-02-16 22:30:00", ) with plummet.frozen_time("2022-02-16 21:30:00"): identity_data = validate_token_and_extract_identity( TokenSet(access_token=access_token)) assert identity_data.user_email == "*****@*****.**" assert identity_data.org_name == "good_org"
def test_refresh_access_token__raises_abort_on_non_200_response( respx_mock, dummy_context): """ Validate that the ``refreshed_access_token()`` function raises an abort if the response from the ``oauth/token`` endpoint of the ``settings.AUTH0_DOMAIN`` is not a 200. """ access_token = "expired-access-token" refresh_token = "dummy-refresh-token" token_set = TokenSet(access_token=access_token, refresh_token=refresh_token) respx_mock.post(f"{LOGIN_DOMAIN}/oauth/token").mock( return_value=httpx.Response( httpx.codes.BAD_REQUEST, json=dict(error_description="BOOM!"), ), ) with pytest.raises(Abort, match="auth token could not be refreshed"): refresh_access_token(dummy_context, token_set)
def test_init_persona__uses_passed_token_set(make_token, tmp_path, dummy_context, mocker): """ Validate that the ``init_persona()`` function will used the passed ``TokenSet`` instance instead of loading it from the cache and will write the tokens to the cache after validating them. """ access_token = make_token( identity_data=dict( user_email="*****@*****.**", org_name="good_org", ), expires="2022-02-16 22:30:00", ) access_token_path = tmp_path / "access.jwt" refresh_token = "dummy-refresh-token" refresh_token_path = tmp_path / "refresh.jwt" token_set = TokenSet( access_token=access_token, refresh_token=refresh_token, ) assert not access_token_path.exists() assert not refresh_token_path.exists() mocker.patch.object(settings, "JOBBERGATE_API_ACCESS_TOKEN_PATH", new=access_token_path) mocker.patch.object(settings, "JOBBERGATE_API_REFRESH_TOKEN_PATH", new=refresh_token_path) with plummet.frozen_time("2022-02-16 21:30:00"): persona = init_persona(dummy_context, token_set) assert persona.token_set.access_token == access_token assert persona.token_set.refresh_token == refresh_token assert persona.identity_data.user_email == "*****@*****.**" assert persona.identity_data.org_name == "good_org" assert access_token_path.exists() assert access_token_path.read_text() == access_token assert refresh_token_path.exists()