Example #1
0
async def _validate_edit_authority(
    item_id: int, user: Person, loader: Loader
) -> Result[Person, Union[ItemNotFoundError, Unauthorized]]:
    unauthorized = Unauthorized("No authority to edit this")
    row = await loader.load(item_id)

    if row is None:
        return Result(error=ItemNotFoundError(id=item_id))

    author_id = getattr(row, loader.model.author_key, None)

    if author_id is None:
        return Result(error=unauthorized)

    return Result(value=user) if (author_id == user.id) else Result(error=unauthorized)
Example #2
0
async def test_send_login_code_calls_authenticator(
        email: str, info: Info, authenticator: MockAuthenticator):
    """Check that send_login_code resolver uses authenticator."""
    authenticator.send_login_code.return_value = Result(value=None)

    result = await send_login_code(email, info)
    assert isinstance(result, SendLoginCodeResponse)
Example #3
0
async def test_login_with_code_calls_authenticator(
        info: Info, authenticator: MockAuthenticator, result: Result):
    """Check that send_login_code resolver uses authenticator and passes the result through."""
    authenticator.login_with_code.return_value = result

    assert (await login_with_code("InR5cCI6", "*****@*****.**",
                                  info)) == result.collapse()
Example #4
0
async def test_send_login_code_returns_auth_error_on_authenticator_auth_error(
        email: str, info: Info, authenticator: MockAuthenticator,
        error: AuthError):
    """Check that send_login_code returns auth error from authenticator."""
    authenticator.send_login_code.return_value = Result(error=error)

    result = await send_login_code(email, info)
    assert result == error
Example #5
0
def test_login_with_code(
    client: GraphQLClient,
    email: str,
    code: str,
    authentication: Authentication,
    mocker: MockerFixture,
):
    """
    Check that loginWithCode() endpoint returns Authentication from
    configured authenticator.
    """
    mocker.patch("blog_app.adapters.auth0.Auth0Authenticator.login_with_code"
                 ).return_value = Result(value=authentication)

    result = client.execute(
        """
        mutation loginWithCode($email: String!, $code: String!) {
            loginWithCode(emailAddress: $email, code: $code) {
                ... on Authentication {
                    accessToken
                    refreshToken
                    user {
                        id
                        name
                    }
                    tokenType
                }
            }
        }
        """,
        variables={
            "email": email,
            "code": code
        },
    )
    assert result.get("errors") is None
    assert result["data"] == {
        "loginWithCode": {
            "accessToken": authentication.access_token,
            "refreshToken": authentication.refresh_token,
            "user": {
                "id": authentication.user.id,
                "name": authentication.user.name
            },
            "tokenType": "Bearer",
        }
    }
Example #6
0
def test_send_login_code(client: GraphQLClient, email: str,
                         mocker: MockerFixture):
    mocker.patch("blog_app.adapters.auth0.Auth0Authenticator.send_login_code"
                 ).return_value = Result(value=None)

    result = client.execute(
        """
        mutation sendLoginCode($email: String!) {
            sendLoginCode(emailAddress: $email) {
                ... on SendLoginCodeResponse {
                    emailAddress
                }
            }
        }
        """,
        variables={"email": email},
    )
    assert result.get("errors") is None
    assert result["data"] == {"sendLoginCode": {"emailAddress": email}}
Example #7
0
def test_auth_mutations_auth_errors(
    client: GraphQLClient,
    query: str,
    patch_target: str,
    autherror: AuthError,
    mocker: MockerFixture,
):
    """
    Check that sendLoginCode/loginWithCode endpoint returns AuthError from
    configured authenticator as typed response.
    """
    mocker.patch(patch_target).return_value = Result(error=autherror)

    result = client.execute(query)
    assert result.get("errors") is None
    assert result["data"] == {
        "errorOperation": {
            "reason": autherror.reason.value.upper(),
            "message": autherror.originalMessage,
        }
    }
Example #8
0
@pytest.mark.parametrize("email", ["*****@*****.**"])
@pytest.mark.asyncio
async def test_send_login_code_returns_auth_error_on_authenticator_exception(
        email: str, info: Info, authenticator: MockAuthenticator):
    """Check that send_login_code returns AuthError if authenticator throws an exception."""
    authenticator.send_login_code.side_effect = Exception()

    result = await send_login_code(email, info)
    assert isinstance(result, AuthError)
    assert result.reason == AuthErrorReason.INTERNAL_ERROR


@pytest.mark.parametrize(
    "result",
    [
        Result(error=AuthError.internal_error("Something happened")),
        Result(error=AuthError.temporary_failure("Something happened")),
        Result(error=AuthError.invalid_request("Something happened")),
        Result(error=AuthError.invalid_token("Something happened")),
        Result(value=Authentication(
            user=User(id=strawberry.ID("foo"), name="Someone's Name"),
            access_token="foo",
            refresh_token="bar",
            expires_in=0,
        )),
    ],
)
@pytest.mark.asyncio
async def test_login_with_code_calls_authenticator(
        info: Info, authenticator: MockAuthenticator, result: Result):
    """Check that send_login_code resolver uses authenticator and passes the result through."""
Example #9
0
 async def get_verified_user_stub(token: str):
     matching_user = next(
         (user for user in FakeUser.registry if user.access_token == token),
         None)
     return (Result(value=matching_user) if matching_user else Result(
         error=AuthError.invalid_token("invalid access token")))
Example #10
0
def test_err_marks_failure(err):
    """Ensure that `Result(error=e)` produces 'failed' Results."""
    assert Result(error=err).is_failed
Example #11
0
def test_ok_marks_success(value):
    """Ensure that `Result(value=v)` produces 'ok' Results."""
    assert Result(value=value).is_ok
Example #12
0
def test_construct_result_without_args_is_invalid():
    """Ensure Result() will raise an error."""
    with pytest.raises(InvalidResult):
        Result()  # type: ignore
Example #13
0
def test_wrap_on_sunny_day():
    """Ensure that `Result.wrap` wraps the return value when there are no errors."""
    value, _ = Result.wrap(ValueError, int, "100").as_tuple()
    assert value == 100
Example #14
0
def test_wrap_raises_unexpected_errors():
    """Ensure that `Result.wrap` does not catch errors it does not expect."""
    with pytest.raises(ValueError):
        result = Result.wrap(TypeError, int, "foo")
Example #15
0
def test_wrap_catches_expected_errors():
    """Ensure that `Result.wrap` catches the error type it's supposed to."""
    assert Result.wrap(ValueError, int, "foo").is_failed
Example #16
0
def test_construct_result_with_value_and_error_is_invalid():
    """Ensure Result(value=v, error=e) will raise an error."""
    with pytest.raises(InvalidResult):
        Result(value=10, error=ValueError("an error"))  # type: ignore