Пример #1
0
def test_basic_login(db):
    # Create our test user using signup
    _quick_signup()

    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.Login(auth_pb2.LoginReq(user="******"))
    assert reply.next_step == auth_pb2.LoginRes.LoginStep.NEED_PASSWORD

    with auth_api_session() as (auth_api, metadata_interceptor):
        auth_api.Authenticate(
            auth_pb2.AuthReq(user="******",
                             password="******"))

    reply_token = get_session_cookie_token(metadata_interceptor)

    with session_scope() as session:
        token = (session.execute(
            select(UserSession).join(User, UserSession.user_id == User.id).
            where(User.username == "frodo").where(
                UserSession.token == reply_token)).scalar_one_or_none()).token
        assert token

    # log out
    with auth_api_session() as (auth_api, metadata_interceptor):
        auth_api.Deauthenticate(empty_pb2.Empty(),
                                metadata=(("cookie",
                                           f"couchers-sesh={reply_token}"), ))
Пример #2
0
def test_unsuccessful_login(db):
    # Invalid email, user doesn't exist
    with auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError) as e:
            reply = auth_api.Login(
                auth_pb2.LoginReq(
                    user=f"{random_hex(12)}@couchers.org.invalid"))
        assert e.value.code() == grpc.StatusCode.NOT_FOUND
        assert e.value.details() == errors.USER_NOT_FOUND

    # Invalid id
    with auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError) as e:
            reply = auth_api.Login(auth_pb2.LoginReq(user="******"))
        assert e.value.code() == grpc.StatusCode.NOT_FOUND
        assert e.value.details() == errors.USER_NOT_FOUND

    # Invalid username
    with auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError) as e:
            reply = auth_api.Login(auth_pb2.LoginReq(user="******"))
        assert e.value.code() == grpc.StatusCode.NOT_FOUND
        assert e.value.details() == errors.USER_NOT_FOUND

    testing_email = f"{random_hex(12)}@couchers.org.invalid"
    # No Password
    user_without_pass, _ = generate_user(hashed_password=None)

    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.Login(
            auth_pb2.LoginReq(user=user_without_pass.username))
    assert reply.next_step == auth_pb2.LoginRes.LoginStep.SENT_LOGIN_EMAIL
Пример #3
0
def test_basic_login(db):
    # Create our test user using signup
    test_basic_signup(db)

    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.Login(auth_pb2.LoginReq(user="******"))
    assert reply.next_step == auth_pb2.LoginRes.LoginStep.SENT_LOGIN_EMAIL

    # backdoor to find login token
    with session_scope() as session:
        entry = session.query(LoginToken).one()
        login_token = entry.token

    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.CompleteTokenLogin(
            auth_pb2.CompleteTokenLoginReq(login_token=login_token))

    reply_token = get_session_cookie_token(metadata_interceptor)

    with session_scope() as session:
        token = (session.query(UserSession).filter(
            User.username == "frodo").filter(
                UserSession.token == reply_token).one_or_none())
        assert token

    # log out
    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.Deauthenticate(
            empty_pb2.Empty(),
            metadata=(("cookie", f"couchers-sesh={reply_token}"), ))
Пример #4
0
def test_logout_invalid_token(db):
    # Create our test user using signup
    test_basic_signup(db)

    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.Login(auth_pb2.LoginReq(user="******"))
    assert reply.next_step == auth_pb2.LoginRes.LoginStep.SENT_LOGIN_EMAIL

    # backdoor to find login token
    with session_scope() as session:
        entry = session.query(LoginToken).one()
        login_token = entry.token

    with auth_api_session() as (auth_api, metadata_interceptor):
        auth_api.CompleteTokenLogin(
            auth_pb2.CompleteTokenLoginReq(login_token=login_token))

    reply_token = get_session_cookie_token(metadata_interceptor)

    # delete all login tokens
    with session_scope() as session:
        session.query(LoginToken).delete()

    # log out with non-existent token should still return a valid result
    with auth_api_session() as (auth_api, metadata_interceptor):
        auth_api.Deauthenticate(empty_pb2.Empty(),
                                metadata=(("cookie",
                                           f"couchers-sesh={reply_token}"), ))

    reply_token = get_session_cookie_token(metadata_interceptor)
    # make sure we set an empty cookie
    assert reply_token == ""
Пример #5
0
def test_signup_invalid_email(db):
    with auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError) as e:
            reply = auth_api.SignupFlow(
                auth_pb2.SignupFlowReq(
                    basic=auth_pb2.SignupBasic(name="frodo", email="a")))
        assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
        assert e.value.details() == errors.INVALID_EMAIL

    with auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError) as e:
            reply = auth_api.SignupFlow(
                auth_pb2.SignupFlowReq(
                    basic=auth_pb2.SignupBasic(name="frodo", email="a@b")))
        assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
        assert e.value.details() == errors.INVALID_EMAIL

    with auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError) as e:
            reply = auth_api.SignupFlow(
                auth_pb2.SignupFlowReq(
                    basic=auth_pb2.SignupBasic(name="frodo", email="a@b.")))
        assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
        assert e.value.details() == errors.INVALID_EMAIL

    with auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError) as e:
            reply = auth_api.SignupFlow(
                auth_pb2.SignupFlowReq(
                    basic=auth_pb2.SignupBasic(name="frodo", email="[email protected]")))
        assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
        assert e.value.details() == errors.INVALID_EMAIL
Пример #6
0
def test_logout_invalid_token(db):
    # Create our test user using signup
    _quick_signup()

    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.Login(auth_pb2.LoginReq(user="******"))
    assert reply.next_step == auth_pb2.LoginRes.LoginStep.NEED_PASSWORD

    with auth_api_session() as (auth_api, metadata_interceptor):
        auth_api.Authenticate(
            auth_pb2.AuthReq(user="******",
                             password="******"))

    reply_token = get_session_cookie_token(metadata_interceptor)

    # delete all login tokens
    with session_scope() as session:
        session.execute(delete(LoginToken))

    # log out with non-existent token should still return a valid result
    with auth_api_session() as (auth_api, metadata_interceptor):
        auth_api.Deauthenticate(empty_pb2.Empty(),
                                metadata=(("cookie",
                                           f"couchers-sesh={reply_token}"), ))

    reply_token = get_session_cookie_token(metadata_interceptor)
    # make sure we set an empty cookie
    assert reply_token == ""
Пример #7
0
def test_basic_signup(db):
    with auth_api_session(db) as auth_api:
        reply = auth_api.Signup(auth_pb2.SignupReq(email="*****@*****.**"))
    assert reply.next_step == auth_pb2.SignupRes.SignupStep.SENT_SIGNUP_EMAIL

    # read out the signup token directly from the database for now
    with session_scope(db) as session:
        entry = session.query(SignupToken).filter(
            SignupToken.email == "*****@*****.**").one_or_none()
        signup_token = entry.token

    with auth_api_session(db) as auth_api:
        reply = auth_api.SignupTokenInfo(
            auth_pb2.SignupTokenInfoReq(signup_token=signup_token))

    assert reply.email == "*****@*****.**"

    with auth_api_session(db) as auth_api:
        reply = auth_api.CompleteSignup(
            auth_pb2.CompleteSignupReq(
                signup_token=signup_token,
                username="******",
                name="Räksmörgås",
                city="Minas Tirith",
                birthdate="1980-12-31",
                gender="Robot",
                hosting_status=api_pb2.HOSTING_STATUS_CAN_HOST,
            ))
    assert isinstance(reply.token, str)
Пример #8
0
def test_signup_invalid_birthdate(db):
    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.Signup(auth_pb2.SignupReq(email="*****@*****.**"))
    assert reply.next_step == auth_pb2.SignupRes.SignupStep.SENT_SIGNUP_EMAIL

    # read out the signup token directly from the database for now
    with session_scope() as session:
        entry = session.query(SignupToken).filter(
            SignupToken.email == "*****@*****.**").one()
        signup_token = entry.token

    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.SignupTokenInfo(
            auth_pb2.SignupTokenInfoReq(signup_token=signup_token))

    assert reply.email == "*****@*****.**"

    with auth_api_session() as (auth_api, metadata_interceptor), pytest.raises(
            grpc.RpcError) as e:
        reply = auth_api.CompleteSignup(
            auth_pb2.CompleteSignupReq(
                signup_token=signup_token,
                username="******",
                name="Räksmörgås",
                city="Minas Tirith",
                birthdate="9999-12-31",  # arbitrary future birthdate
                gender="Robot",
                hosting_status=api_pb2.HOSTING_STATUS_CAN_HOST,
                lat=1,
                lng=1,
                radius=100,
                accept_tos=True,
            ))
    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
    assert e.value.details() == errors.INVALID_BIRTHDATE
Пример #9
0
def test_basic_login_without_password(db):
    # Create our test user using signup
    _quick_signup()

    with session_scope() as session:
        user = session.execute(select(User)).scalar_one()
        user.hashed_password = None

    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.Login(auth_pb2.LoginReq(user="******"))
    assert reply.next_step == auth_pb2.LoginRes.LoginStep.SENT_LOGIN_EMAIL

    # backdoor to find login token
    with session_scope() as session:
        entry = session.execute(select(LoginToken)).scalar_one()
        login_token = entry.token

    with auth_api_session() as (auth_api, metadata_interceptor):
        auth_api.CompleteTokenLogin(
            auth_pb2.CompleteTokenLoginReq(login_token=login_token))

    reply_token = get_session_cookie_token(metadata_interceptor)

    with session_scope() as session:
        token = (session.execute(
            select(UserSession).join(User, UserSession.user_id == User.id).
            where(User.username == "frodo").where(
                UserSession.token == reply_token)).scalar_one_or_none()).token
        assert token

    # log out
    with auth_api_session() as (auth_api, metadata_interceptor):
        auth_api.Deauthenticate(empty_pb2.Empty(),
                                metadata=(("cookie",
                                           f"couchers-sesh={reply_token}"), ))
Пример #10
0
def test_UsernameValid(db):
    with auth_api_session() as (auth_api, metadata_interceptor):
        assert auth_api.UsernameValid(
            auth_pb2.UsernameValidReq(username="******")).valid

    with auth_api_session() as (auth_api, metadata_interceptor):
        assert not auth_api.UsernameValid(
            auth_pb2.UsernameValidReq(username="")).valid
Пример #11
0
def test_UsernameValid(db):
    with auth_api_session(db) as auth_api:
        assert auth_api.UsernameValid(
            auth_pb2.UsernameValidReq(username="******")).valid

    with auth_api_session(db) as auth_api:
        assert not auth_api.UsernameValid(
            auth_pb2.UsernameValidReq(username="")).valid
Пример #12
0
def test_full_delete_account_with_recovery(db):
    user, token = generate_user()
    user_id = user.id

    with account_session(token) as account:
        with pytest.raises(grpc.RpcError) as e:
            account.DeleteAccount(account_pb2.DeleteAccountReq())
        assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
        assert e.value.details() == errors.MUST_CONFIRM_ACCOUNT_DELETE

        # Check the right email is sent
        with patch("couchers.email.queue_email") as mock:
            account.DeleteAccount(account_pb2.DeleteAccountReq(confirm=True))
        mock.assert_called_once()
        (_, _, _, subject, _, _), _ = mock.call_args
        assert subject == "[TEST] Confirm your Couchers.org account deletion"

    with session_scope() as session:
        token_o = session.execute(select(AccountDeletionToken)).scalar_one()
        token = token_o.token

        user = session.execute(
            select(User).where(User.id == user_id)).scalar_one()
        assert token_o.user == user
        assert not user.is_deleted
        assert not user.undelete_token
        assert not user.undelete_until

    with auth_api_session() as (auth_api, metadata_interceptor):
        auth_api.ConfirmDeleteAccount(
            auth_pb2.ConfirmDeleteAccountReq(token=token, ))

    with session_scope() as session:
        assert not session.execute(
            select(AccountDeletionToken)).scalar_one_or_none()

    with session_scope() as session:
        user = session.execute(
            select(User).where(User.id == user_id)).scalar_one()
        assert user.is_deleted
        assert user.undelete_token
        assert user.undelete_until > now()

        undelete_token = user.undelete_token

    with auth_api_session() as (auth_api, metadata_interceptor):
        auth_api.RecoverAccount(
            auth_pb2.RecoverAccountReq(token=undelete_token, ))

    with session_scope() as session:
        assert not session.execute(
            select(AccountDeletionToken)).scalar_one_or_none()

        user = session.execute(
            select(User).where(User.id == user_id)).scalar_one()
        assert not user.is_deleted
        assert not user.undelete_token
        assert not user.undelete_until
Пример #13
0
def test_successful_login(db):
    user, _ = generate_user()
    # Valid email login
    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.Login(auth_pb2.LoginReq(user=user.email))
    assert reply.next_step == auth_pb2.LoginRes.LoginStep.NEED_PASSWORD

    # Valid username login
    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.Login(auth_pb2.LoginReq(user=user.username))
    assert reply.next_step == auth_pb2.LoginRes.LoginStep.NEED_PASSWORD
Пример #14
0
def test_ChangeEmail_tokens_two_hour_window(db):
    def two_hours_one_minute_in_future():
        return now() + timedelta(hours=2, minutes=1)

    def one_minute_ago():
        return now() - timedelta(minutes=1)

    new_email = f"{random_hex()}@couchers.org.invalid"
    user, token = generate_user(hashed_password=None)

    with account_session(token) as account:
        account.ChangeEmail(account_pb2.ChangeEmailReq(new_email=new_email, ))

    with session_scope() as session:
        user = session.execute(
            select(User).where(User.id == user.id)).scalar_one()
        old_email_token = user.old_email_token
        new_email_token = user.new_email_token

    with patch("couchers.servicers.auth.now", one_minute_ago):
        with auth_api_session() as (auth_api, metadata_interceptor):
            with pytest.raises(grpc.RpcError) as e:
                auth_api.ConfirmChangeEmail(
                    auth_pb2.ConfirmChangeEmailReq(
                        change_email_token=old_email_token, ))
            assert e.value.code() == grpc.StatusCode.NOT_FOUND
            assert e.value.details() == errors.INVALID_TOKEN

            with pytest.raises(grpc.RpcError) as e:
                auth_api.ConfirmChangeEmail(
                    auth_pb2.ConfirmChangeEmailReq(
                        change_email_token=new_email_token, ))
            assert e.value.code() == grpc.StatusCode.NOT_FOUND
            assert e.value.details() == errors.INVALID_TOKEN

    with patch("couchers.servicers.auth.now", two_hours_one_minute_in_future):
        with auth_api_session() as (auth_api, metadata_interceptor):
            with pytest.raises(grpc.RpcError) as e:
                auth_api.ConfirmChangeEmail(
                    auth_pb2.ConfirmChangeEmailReq(
                        change_email_token=old_email_token, ))
            assert e.value.code() == grpc.StatusCode.NOT_FOUND
            assert e.value.details() == errors.INVALID_TOKEN

            with pytest.raises(grpc.RpcError) as e:
                auth_api.ConfirmChangeEmail(
                    auth_pb2.ConfirmChangeEmailReq(
                        change_email_token=new_email_token, ))
            assert e.value.code() == grpc.StatusCode.NOT_FOUND
            assert e.value.details() == errors.INVALID_TOKEN
Пример #15
0
def test_successful_authenticate(db):
    user, _ = generate_user(hashed_password=hash_password("password"))

    # Authenticate with username
    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.Authenticate(
            auth_pb2.AuthReq(user=user.username, password="******"))
    assert not reply.jailed

    # Authenticate with email
    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.Authenticate(
            auth_pb2.AuthReq(user=user.email, password="******"))
    assert not reply.jailed
Пример #16
0
def test_banned_user(db):
    _quick_signup()
    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.Login(auth_pb2.LoginReq(user="******"))
    assert reply.next_step == auth_pb2.LoginRes.LoginStep.NEED_PASSWORD

    with session_scope() as session:
        session.execute(select(User)).scalar_one().is_banned = True

    with auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError) as e:
            auth_api.Authenticate(
                auth_pb2.AuthReq(user="******",
                                 password="******"))
        assert e.value.details() == "Your account is suspended."
Пример #17
0
def test_multiple_delete_tokens(db):
    """
    Make sure deletion tokens are deleted on delete
    """
    user, token = generate_user()
    user_id = user.id

    with account_session(token) as account:
        account.DeleteAccount(account_pb2.DeleteAccountReq(confirm=True))
        account.DeleteAccount(account_pb2.DeleteAccountReq(confirm=True))
        account.DeleteAccount(account_pb2.DeleteAccountReq(confirm=True))

    with session_scope() as session:
        assert session.execute(
            select(func.count()).select_from(
                AccountDeletionToken)).scalar_one() == 3
        token = session.execute(
            select(AccountDeletionToken)).scalars().first().token

    with auth_api_session() as (auth_api, metadata_interceptor):
        auth_api.ConfirmDeleteAccount(
            auth_pb2.ConfirmDeleteAccountReq(token=token, ))

    with session_scope() as session:
        assert not session.execute(
            select(AccountDeletionToken)).scalar_one_or_none()
Пример #18
0
def test_ChangeEmail_wrong_token(db, fast_passwords):
    password = random_hex()
    new_email = f"{random_hex()}@couchers.org.invalid"
    user, token = generate_user(db, hashed_password=hash_password(password))

    with account_session(db, token) as account:
        account.ChangeEmail(
            account_pb2.ChangeEmailReq(
                password=wrappers_pb2.StringValue(value=password),
                new_email=new_email,
            ))

    with session_scope(db) as session:
        user_updated = (session.query(User).filter(User.id == user.id).filter(
            User.new_email == new_email).filter(
                User.new_email_token_created <= func.now()).filter(
                    User.new_email_token_expiry >= func.now())).one()

        token = user_updated.new_email_token

    with auth_api_session(db) as auth_api:
        with pytest.raises(grpc.RpcError) as e:
            res = auth_api.CompleteChangeEmail(
                auth_pb2.CompleteChangeEmailReq(
                    change_email_token="wrongtoken", ))
        assert e.value.code() == grpc.StatusCode.UNAUTHENTICATED
        assert e.value.details() == errors.INVALID_TOKEN

    with session_scope(db) as session:
        user_updated2 = session.query(User).filter(User.id == user.id).one()
        assert user_updated2.email == user.email
Пример #19
0
def test_ChangeEmail(db, fast_passwords):
    password = random_hex()
    new_email = f"{random_hex()}@couchers.org.invalid"
    user, token = generate_user(db, hashed_password=hash_password(password))

    with account_session(db, token) as account:
        account.ChangeEmail(
            account_pb2.ChangeEmailReq(
                password=wrappers_pb2.StringValue(value=password),
                new_email=new_email,
            ))

    with session_scope(db) as session:
        user_updated = (session.query(User).filter(User.id == user.id).filter(
            User.new_email == new_email).filter(
                User.new_email_token_created <= func.now()).filter(
                    User.new_email_token_expiry >= func.now())).one()

        token = user_updated.new_email_token

    with auth_api_session(db) as auth_api:
        res = auth_api.CompleteChangeEmail(
            auth_pb2.CompleteChangeEmailReq(change_email_token=token, ))

    with session_scope(db) as session:
        user_updated2 = session.query(User).filter(User.id == user.id).one()
        assert user_updated2.email == new_email
        assert user_updated2.new_email is None
        assert user_updated2.new_email_token is None

    # check there's no valid tokens left
    with session_scope(db) as session:
        assert (session.query(User).filter(
            User.new_email_token_created <= func.now()).filter(
                User.new_email_token_expiry >= func.now())).count() == 0
Пример #20
0
def test_purge_signup_tokens(db):
    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.Signup(auth_pb2.SignupReq(email="*****@*****.**"))

    # send email
    process_job()

    with session_scope() as session:
        signup_token = session.query(SignupToken).one()
        signup_token.expiry = func.now()
        assert session.query(SignupToken).count() == 1

    queue_job(BackgroundJobType.purge_signup_tokens, empty_pb2.Empty())

    # purge tokens
    process_job()

    with session_scope() as session:
        assert session.query(SignupToken).count() == 0

    with session_scope() as session:
        assert session.query(BackgroundJob).filter(
            BackgroundJob.state == BackgroundJobState.completed).count() == 2
        assert session.query(BackgroundJob).filter(
            BackgroundJob.state != BackgroundJobState.completed).count() == 0
Пример #21
0
def test_banned_user(db):
    test_basic_signup(db)
    with auth_api_session() as (auth_api, metadata_interceptor):
        reply = auth_api.Login(auth_pb2.LoginReq(user="******"))
    assert reply.next_step == auth_pb2.LoginRes.LoginStep.SENT_LOGIN_EMAIL

    with session_scope() as session:
        login_token = session.query(LoginToken).one().token

    with session_scope() as session:
        session.query(User).one().is_banned = True

    with auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError):
            auth_api.CompleteTokenLogin(
                auth_pb2.CompleteTokenLoginReq(login_token=login_token))
Пример #22
0
def test_unsuccessful_authenticate(db):
    user, _ = generate_user(hashed_password=hash_password("password"))

    # Invalid password
    with auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError) as e:
            reply = auth_api.Authenticate(
                auth_pb2.AuthReq(user=user.username,
                                 password="******"))
        assert e.value.code() == grpc.StatusCode.NOT_FOUND
        assert e.value.details() == errors.INVALID_USERNAME_OR_PASSWORD

    # Invalid username
    with auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError) as e:
            reply = auth_api.Authenticate(
                auth_pb2.AuthReq(user="******", password="******"))
        assert e.value.code() == grpc.StatusCode.NOT_FOUND
        assert e.value.details() == errors.INVALID_USERNAME_OR_PASSWORD

    # Invalid email
    with auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError) as e:
            reply = auth_api.Authenticate(
                auth_pb2.AuthReq(user=f"{random_hex(12)}@couchers.org.invalid",
                                 password="******"))
        assert e.value.code() == grpc.StatusCode.NOT_FOUND
        assert e.value.details() == errors.INVALID_USERNAME_OR_PASSWORD

    # Invalid id
    with auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError) as e:
            reply = auth_api.Authenticate(
                auth_pb2.AuthReq(user="******", password="******"))
        assert e.value.code() == grpc.StatusCode.NOT_FOUND
        assert e.value.details() == errors.INVALID_USERNAME_OR_PASSWORD

    # No Password
    user_without_pass, _ = generate_user(hashed_password=None)

    with auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError) as e:
            reply = auth_api.Authenticate(
                auth_pb2.AuthReq(user=user_without_pass.username,
                                 password="******"))
        assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
        assert e.value.details() == errors.NO_PASSWORD
Пример #23
0
def test_enforce_community_memberships_for_user(testing_communities):
    """
    Make sure the user is added to the right communities on signup
    """
    with auth_api_session() as (auth_api, metadata_interceptor):
        res = auth_api.SignupFlow(
            auth_pb2.SignupFlowReq(
                basic=auth_pb2.SignupBasic(name="testing",
                                           email="*****@*****.**"),
                account=auth_pb2.SignupAccount(
                    username="******",
                    password="******",
                    birthdate="1970-01-01",
                    gender="Bot",
                    hosting_status=api_pb2.HOSTING_STATUS_CAN_HOST,
                    city="Country 1, Region 1, City 2",
                    # lat=8, lng=1 is equivalent to creating this coordinate with create_coordinate(8)
                    lat=8,
                    lng=1,
                    radius=500,
                    accept_tos=True,
                ),
                feedback=auth_pb2.ContributorForm(),
                accept_community_guidelines=wrappers_pb2.BoolValue(value=True),
            ))
    with session_scope() as session:
        email_token = (session.execute(
            select(SignupFlow).where(SignupFlow.flow_token ==
                                     res.flow_token)).scalar_one().email_token)
    with auth_api_session() as (auth_api, metadata_interceptor):
        res = auth_api.SignupFlow(
            auth_pb2.SignupFlowReq(email_token=email_token))
    user_id = res.auth_res.user_id

    # now check the user is in the right communities
    with session_scope() as session:
        w_id = get_community_id(session, "Global")
        c1_id = get_community_id(session, "Country 1")
        c1r1_id = get_community_id(session, "Country 1, Region 1")
        c1r1c2_id = get_community_id(session, "Country 1, Region 1, City 2")

    token = get_session_cookie_token(metadata_interceptor)

    with communities_session(token) as api:
        res = api.ListUserCommunities(communities_pb2.ListUserCommunitiesReq())
        assert [c.community_id
                for c in res.communities] == [w_id, c1_id, c1r1_id, c1r1c2_id]
Пример #24
0
def test_login_tokens_invalidate_after_use(db):
    test_basic_signup(db)
    with auth_api_session(db) as auth_api:
        reply = auth_api.Login(auth_pb2.LoginReq(user="******"))
    assert reply.next_step == auth_pb2.LoginRes.LoginStep.SENT_LOGIN_EMAIL

    with session_scope(db) as session:
        login_token = session.query(LoginToken).one_or_none().token

    with auth_api_session(db) as auth_api:
        session_token = auth_api.CompleteTokenLogin(
            auth_pb2.CompleteTokenLoginReq(login_token=login_token)).token

    with auth_api_session(db) as auth_api, pytest.raises(grpc.RpcError):
        # check we can't login again
        auth_api.CompleteTokenLogin(
            auth_pb2.CompleteTokenLoginReq(login_token=login_token))
Пример #25
0
def test_signup_continue_with_email(db):
    testing_email = f"{random_hex(12)}@couchers.org.invalid"
    with auth_api_session() as (auth_api, metadata_interceptor):
        res = auth_api.SignupFlow(
            auth_pb2.SignupFlowReq(
                basic=auth_pb2.SignupBasic(name="frodo", email=testing_email)))
    flow_token = res.flow_token
    assert flow_token

    # continue with same email, should just send another email to the user
    with auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError) as e:
            res = auth_api.SignupFlow(
                auth_pb2.SignupFlowReq(basic=auth_pb2.SignupBasic(
                    name="frodo", email=testing_email)))
        assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
        assert e.value.details() == errors.SIGNUP_FLOW_EMAIL_STARTED_SIGNUP
Пример #26
0
def test_password_reset(db):
    user, token = generate_user(hashed_password=hash_password("mypassword"))

    with auth_api_session() as (auth_api, metadata_interceptor):
        res = auth_api.ResetPassword(
            auth_pb2.ResetPasswordReq(user=user.username, ))

    with session_scope() as session:
        token = session.execute(select(PasswordResetToken)).scalar_one().token

    with auth_api_session() as (auth_api, metadata_interceptor):
        res = auth_api.CompletePasswordReset(
            auth_pb2.CompletePasswordResetReq(password_reset_token=token))

    with session_scope() as session:
        user = session.execute(select(User)).scalar_one()
        assert not user.has_password
Пример #27
0
def test_password_reset(db, fast_passwords):
    user, token = generate_user(hashed_password=hash_password("mypassword"))

    with auth_api_session() as (auth_api, metadata_interceptor):
        res = auth_api.ResetPassword(
            auth_pb2.ResetPasswordReq(user=user.username, ))

    with session_scope() as session:
        token = session.query(PasswordResetToken).one().token

    with auth_api_session() as (auth_api, metadata_interceptor):
        res = auth_api.CompletePasswordReset(
            auth_pb2.CompletePasswordResetReq(password_reset_token=token))

    with session_scope() as session:
        user = session.query(User).one()
        assert user.hashed_password is None
Пример #28
0
def test_password_reset_invalid_token(db):
    password = random_hex()
    user, token = generate_user(hashed_password=hash_password(password))

    with auth_api_session() as (auth_api, metadata_interceptor):
        res = auth_api.ResetPassword(
            auth_pb2.ResetPasswordReq(user=user.username, ))

    with auth_api_session() as (auth_api, metadata_interceptor), pytest.raises(
            grpc.RpcError) as e:
        res = auth_api.CompletePasswordReset(
            auth_pb2.CompletePasswordResetReq(
                password_reset_token="wrongtoken"))
    assert e.value.code() == grpc.StatusCode.NOT_FOUND
    assert e.value.details() == errors.INVALID_TOKEN

    with session_scope() as session:
        user = session.execute(select(User)).scalar_one()
        assert user.hashed_password == hash_password(password)
Пример #29
0
def test_signup_existing_email(db):
    # Signed up user
    user, _ = generate_user()

    with auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError) as e:
            reply = auth_api.SignupFlow(
                auth_pb2.SignupFlowReq(basic=auth_pb2.SignupBasic(
                    name="frodo", email=user.email)))
        assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION
        assert e.value.details() == errors.SIGNUP_FLOW_EMAIL_TAKEN
Пример #30
0
def test_password_reset_no_such_user(db):
    user, token = generate_user()

    with auth_api_session() as (auth_api, metadata_interceptor):
        res = auth_api.ResetPassword(
            auth_pb2.ResetPasswordReq(user="******", ))

    with session_scope() as session:
        res = session.execute(select(PasswordResetToken)).scalar_one_or_none()

    assert res is None