Exemplo n.º 1
0
def test_ChangeEmail_sends_proper_emails_has_password(db, fast_passwords):
    password = random_hex()
    new_email = f"{random_hex()}@couchers.org.invalid"
    user, token = generate_user(hashed_password=hash_password(password))

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

    with session_scope() as session:
        jobs = (session.execute(
            select(BackgroundJob).where(
                BackgroundJob.job_type ==
                BackgroundJobType.send_email)).scalars().all())
        assert len(jobs) == 2
        payload_for_notification_email = jobs[0].payload
        payload_for_confirmation_email_new_address = jobs[1].payload
        unique_string_notification_email_as_bytes = b"You requested that your email on Couchers.org be changed to"
        unique_string_for_confirmation_email_new_email_address_as_bytes = (
            b"You requested that your email be changed to this email address on Couchers.org"
        )
        assert unique_string_notification_email_as_bytes in payload_for_notification_email
        assert (unique_string_for_confirmation_email_new_email_address_as_bytes
                in payload_for_confirmation_email_new_address)
Exemplo n.º 2
0
def test_GetAccountInfo(db, fast_passwords):
    # without password
    user1, token1 = generate_user(hashed_password=None)

    with account_session(token1) as account:
        res = account.GetAccountInfo(empty_pb2.Empty())
        assert res.login_method == account_pb2.GetAccountInfoRes.LoginMethod.MAGIC_LINK
        assert not res.has_password

    # with password
    user1, token1 = generate_user(hashed_password=hash_password(random_hex()))

    with account_session(token1) as account:
        res = account.GetAccountInfo(empty_pb2.Empty())
        assert res.login_method == account_pb2.GetAccountInfoRes.LoginMethod.PASSWORD
        assert res.has_password
Exemplo n.º 3
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()
Exemplo n.º 4
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
Exemplo n.º 5
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
Exemplo n.º 6
0
def test_VerifyPhone():
    user, token = generate_user()
    user_id = user.id
    with account_session(token) as account, api_session(token) as api:

        with pytest.raises(grpc.RpcError) as e:
            account.VerifyPhone(account_pb2.VerifyPhoneReq(token="123455"))
        assert e.value.code() == grpc.StatusCode.FAILED_PRECONDITION

        res = api.GetUser(api_pb2.GetUserReq(user=str(user_id)))
        assert res.verification == 0.0

        with session_scope() as session:
            user = session.execute(
                select(User).where(User.id == user_id)).scalar_one()
            user.phone = "+46701740605"
            user.phone_verification_token = "111112"
            user.phone_verification_sent = now()

        account.VerifyPhone(account_pb2.VerifyPhoneReq(token="111112"))

        res = api.GetUser(api_pb2.GetUserReq(user=str(user_id)))
        assert res.verification == 1.0

        # Phone number should finally show up on in your profile settings
        res = account.GetAccountInfo(empty_pb2.Empty())
        assert res.phone == "+46701740605"
Exemplo n.º 7
0
def test_DeleteAccount_message_storage(db):
    user, token = generate_user()

    with account_session(token) as account:
        account.DeleteAccount(
            account_pb2.DeleteAccountReq(confirm=True,
                                         reason=None))  # not stored
        account.DeleteAccount(
            account_pb2.DeleteAccountReq(confirm=True,
                                         reason=""))  # not stored
        account.DeleteAccount(
            account_pb2.DeleteAccountReq(confirm=True, reason="Reason"))
        account.DeleteAccount(
            account_pb2.DeleteAccountReq(confirm=True,
                                         reason="0192#(&!&#)*@//)(8"))
        account.DeleteAccount(
            account_pb2.DeleteAccountReq(confirm=True,
                                         reason="\n\n\t"))  # not stored
        account.DeleteAccount(
            account_pb2.DeleteAccountReq(confirm=True, reason="1337"))

    with session_scope() as session:
        assert session.execute(
            select(func.count()).select_from(
                AccountDeletionReason)).scalar_one() == 3
Exemplo n.º 8
0
def test_contributor_form(db):
    user, token = generate_user()

    with account_session(token) as account:
        res = account.GetContributorFormInfo(empty_pb2.Empty())
        assert not res.filled_contributor_form
        assert res.username == user.username
        assert res.name == user.name
        assert res.email == user.email
        assert res.age == user.age
        assert res.gender == user.gender
        assert res.location == user.city

        account.MarkContributorFormFilled(account_pb2.MarkContributorFormFilledReq(filled_contributor_form=True))

        res = account.GetContributorFormInfo(empty_pb2.Empty())
        assert res.filled_contributor_form
        assert res.username == user.username
        assert res.name == user.name
        assert res.email == user.email
        assert res.age == user.age
        assert res.gender == user.gender
        assert res.location == user.city

        account.MarkContributorFormFilled(account_pb2.MarkContributorFormFilledReq(filled_contributor_form=False))

        res = account.GetContributorFormInfo(empty_pb2.Empty())
        assert not res.filled_contributor_form
        assert res.username == user.username
        assert res.name == user.name
        assert res.email == user.email
        assert res.age == user.age
        assert res.gender == user.gender
        assert res.location == user.city
Exemplo n.º 9
0
def test_phone_uniqueness(monkeypatch):
    user1, token1 = generate_user()
    user2, token2 = generate_user()
    with account_session(token1) as account1, account_session(
            token2) as account2:

        def succeed(phone, message):
            return "success"

        monkeypatch.setattr(couchers.phone.sms, "send_sms", succeed)

        account1.ChangePhone(account_pb2.ChangePhoneReq(phone="+46701740605"))
        with session_scope() as session:
            user = session.execute(
                select(User).where(User.id == user1.id)).scalar_one()
            token = user.phone_verification_token
        account1.VerifyPhone(account_pb2.VerifyPhoneReq(token=token))
        res = account1.GetAccountInfo(empty_pb2.Empty())
        assert res.phone == "+46701740605"
        assert res.phone_verified

        # Let user2 steal user1:s phone number

        account2.ChangePhone(account_pb2.ChangePhoneReq(phone="+46701740605"))

        res = account1.GetAccountInfo(empty_pb2.Empty())
        assert res.phone == "+46701740605"
        assert res.phone_verified

        res = account2.GetAccountInfo(empty_pb2.Empty())
        assert res.phone == "+46701740605"
        assert not res.phone_verified

        with session_scope() as session:
            user = session.execute(
                select(User).where(User.id == user2.id)).scalar_one()
            token = user.phone_verification_token
        account2.VerifyPhone(account_pb2.VerifyPhoneReq(token=token))

        # number gets wiped when it's stolen
        res = account1.GetAccountInfo(empty_pb2.Empty())
        assert not res.phone
        assert not res.phone_verified

        res = account2.GetAccountInfo(empty_pb2.Empty())
        assert res.phone == "+46701740605"
        assert res.phone_verified
Exemplo n.º 10
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
Exemplo n.º 11
0
def test_GetAccountInfo(db, fast_passwords):
    # without password
    user1, token1 = generate_user(hashed_password=None, email="*****@*****.**")

    with account_session(token1) as account:
        res = account.GetAccountInfo(empty_pb2.Empty())
        assert res.login_method == account_pb2.GetAccountInfoRes.LoginMethod.MAGIC_LINK
        assert not res.has_password
        assert res.email == "*****@*****.**"

    # with password
    user1, token1 = generate_user(hashed_password=hash_password(random_hex()), email="*****@*****.**")

    with account_session(token1) as account:
        res = account.GetAccountInfo(empty_pb2.Empty())
        assert res.login_method == account_pb2.GetAccountInfoRes.LoginMethod.PASSWORD
        assert res.has_password
        assert res.email == "*****@*****.**"
Exemplo n.º 12
0
def test_contributor_form(db):
    user, token = generate_user()

    with account_session(token) as account:
        res = account.GetContributorFormInfo(empty_pb2.Empty())
        assert not res.filled_contributor_form

        account.FillContributorForm(
            account_pb2.FillContributorFormReq(
                contributor_form=auth_pb2.ContributorForm()))

        res = account.GetContributorFormInfo(empty_pb2.Empty())
        assert res.filled_contributor_form
Exemplo n.º 13
0
def test_ChangePassword_add_no_passwords(db, fast_passwords):
    # user does not have an old password and called with empty body
    user, token = generate_user(db, hashed_password=None)

    with account_session(db, token) as account:
        with pytest.raises(grpc.RpcError) as e:
            account.ChangePassword(account_pb2.ChangePasswordReq())
        assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
        assert e.value.details() == errors.MISSING_BOTH_PASSWORDS

    with session_scope(db) as session:
        updated_user = session.query(User).filter(User.id == user.id).one()
        assert updated_user.hashed_password == None
Exemplo n.º 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
Exemplo n.º 15
0
def test_ChangePassword_normal_no_passwords(db, fast_passwords):
    # user has old password and called with empty body
    old_password = random_hex()
    user, token = generate_user(hashed_password=hash_password(old_password))

    with account_session(token) as account:
        with pytest.raises(grpc.RpcError) as e:
            account.ChangePassword(account_pb2.ChangePasswordReq())
        assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
        assert e.value.details() == errors.MISSING_BOTH_PASSWORDS

    with session_scope() as session:
        updated_user = session.execute(
            select(User).where(User.id == user.id)).scalar_one()
        assert updated_user.hashed_password == hash_password(old_password)
Exemplo n.º 16
0
def test_ChangePassword_remove(db, fast_passwords):
    old_password = random_hex()
    user, token = generate_user(hashed_password=hash_password(old_password))

    with account_session(token) as account:
        with patch("couchers.servicers.account.send_password_changed_email") as mock:
            account.ChangePassword(
                account_pb2.ChangePasswordReq(
                    old_password=wrappers_pb2.StringValue(value=old_password),
                )
            )
        mock.assert_called_once()

    with session_scope() as session:
        updated_user = session.query(User).filter(User.id == user.id).one()
        assert updated_user.hashed_password is None
Exemplo n.º 17
0
def test_ChangeEmail_has_password(db, fast_passwords):
    password = random_hex()
    new_email = f"{random_hex()}@couchers.org.invalid"
    user, token = generate_user(hashed_password=hash_password(password))

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

    with session_scope() as session:
        user_updated = session.execute(
            select(User).where(User.id == user.id)).scalar_one()
        assert user_updated.email == user.email
        assert user_updated.new_email == new_email
        assert user_updated.old_email_token is None
        assert not user_updated.old_email_token_created
        assert not user_updated.old_email_token_expiry
        assert not user_updated.need_to_confirm_via_old_email
        assert user_updated.new_email_token is not None
        assert user_updated.new_email_token_created <= now()
        assert user_updated.new_email_token_expiry >= now()
        assert user_updated.need_to_confirm_via_new_email

        token = user_updated.new_email_token

    with auth_api_session() as (auth_api, metadata_interceptor):
        res = auth_api.ConfirmChangeEmail(
            auth_pb2.ConfirmChangeEmailReq(change_email_token=token, ))
        assert res.state == auth_pb2.EMAIL_CONFIRMATION_STATE_SUCCESS

    with session_scope() as session:
        user = session.execute(
            select(User).where(User.id == user.id)).scalar_one()
        assert user.email == new_email
        assert user.new_email is None
        assert user.old_email_token is None
        assert user.old_email_token_created is None
        assert user.old_email_token_expiry is None
        assert not user.need_to_confirm_via_old_email
        assert user.new_email_token is None
        assert user.new_email_token_created is None
        assert user.new_email_token_expiry is None
        assert not user.need_to_confirm_via_new_email
Exemplo n.º 18
0
def test_ChangePassword_add(db, fast_passwords):
    # user does not have an old password and is adding a new password
    new_password = random_hex()
    user, token = generate_user(db, hashed_password=None)

    with account_session(db, token) as account:
        with patch("couchers.servicers.account.send_password_changed_email"
                   ) as mock:
            account.ChangePassword(
                account_pb2.ChangePasswordReq(
                    new_password=wrappers_pb2.StringValue(
                        value=new_password), ))
        mock.assert_called_once()

    with session_scope(db) as session:
        updated_user = session.query(User).filter(User.id == user.id).one()
        assert updated_user.hashed_password == hash_password(new_password)
Exemplo n.º 19
0
def test_ChangePassword_remove_wrong_password(db, fast_passwords):
    old_password = random_hex()
    user, token = generate_user(db,
                                hashed_password=hash_password(old_password))

    with account_session(db, token) as account:
        with pytest.raises(grpc.RpcError) as e:
            account.ChangePassword(
                account_pb2.ChangePasswordReq(
                    old_password=wrappers_pb2.StringValue(
                        value="wrong password"), ))
        assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
        assert e.value.details() == errors.INVALID_USERNAME_OR_PASSWORD

    with session_scope(db) as session:
        updated_user = session.query(User).filter(User.id == user.id).one()
        assert updated_user.hashed_password == hash_password(old_password)
Exemplo n.º 20
0
def test_VerifyPhone_antibrute():
    user, token = generate_user()
    user_id = user.id
    with account_session(token) as account, api_session(token) as api:

        with session_scope() as session:
            user = session.execute(
                select(User).where(User.id == user_id)).scalar_one()
            user.phone_verification_token = "111112"
            user.phone_verification_sent = now()
            user.phone = "+46701740605"

        for i in range(10):
            with pytest.raises(grpc.RpcError) as e:
                account.VerifyPhone(account_pb2.VerifyPhoneReq(token="123455"))
            if e.value.code() != grpc.StatusCode.NOT_FOUND:
                break
        assert e.value.code() == grpc.StatusCode.RESOURCE_EXHAUSTED
Exemplo n.º 21
0
def test_GetAccountInfo_regression(db):
    # there was a bug in evaluating `has_completed_profile` on the backend (in python)
    # when about_me is None but the user has a key, it was failing because len(about_me) doesn't work on None
    uploader_user, _ = generate_user()
    with session_scope() as session:
        key = random_hex(32)
        filename = random_hex(32) + ".jpg"
        session.add(
            Upload(
                key=key,
                filename=filename,
                creator_user_id=uploader_user.id,
            ))
        session.commit()
    user, token = generate_user(about_me=None, avatar_key=key)

    with account_session(token) as account:
        res = account.GetAccountInfo(empty_pb2.Empty())
Exemplo n.º 22
0
def test_ChangePassword_regression(db, fast_passwords):
    # send_password_changed_email wasn't working
    # user has old password and is changing to new password
    old_password = random_hex()
    new_password = random_hex()
    user, token = generate_user(hashed_password=hash_password(old_password))

    with account_session(token) as account:
        account.ChangePassword(
            account_pb2.ChangePasswordReq(
                old_password=wrappers_pb2.StringValue(value=old_password),
                new_password=wrappers_pb2.StringValue(value=new_password),
            ))

    with session_scope() as session:
        updated_user = session.execute(
            select(User).where(User.id == user.id)).scalar_one()
        assert updated_user.hashed_password == hash_password(new_password)
Exemplo n.º 23
0
def test_DeleteAccount_start(db):
    user, token = generate_user()

    with account_session(token) as account:
        with patch("couchers.email.queue_email") as mock:
            account.DeleteAccount(
                account_pb2.DeleteAccountReq(confirm=True, reason=None))
        mock.assert_called_once()
        (_, _, _, subject, _, _), _ = mock.call_args
        assert subject == "[TEST] Confirm your Couchers.org account deletion"

    with session_scope() as session:
        deletion_token = session.execute(
            select(AccountDeletionToken).where(
                AccountDeletionToken.user_id == user.id)).scalar_one()

        assert deletion_token.is_valid
        assert not session.execute(
            select(User).where(User.id == user.id)).scalar_one().is_deleted
Exemplo n.º 24
0
def test_ChangePassword_normal_no_password(db, fast_passwords):
    # user has old password and is changing to new password, but didn't supply old password
    old_password = random_hex()
    new_password = random_hex()
    user, token = generate_user(db,
                                hashed_password=hash_password(old_password))

    with account_session(db, token) as account:
        with pytest.raises(grpc.RpcError) as e:
            account.ChangePassword(
                account_pb2.ChangePasswordReq(
                    new_password=wrappers_pb2.StringValue(
                        value=new_password), ))
        assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
        assert e.value.details() == errors.MISSING_PASSWORD

    with session_scope(db) as session:
        updated_user = session.query(User).filter(User.id == user.id).one()
        assert updated_user.hashed_password == hash_password(old_password)
Exemplo n.º 25
0
def test_ChangeEmail_no_change(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:
        with pytest.raises(grpc.RpcError) as e:
            account.ChangeEmail(
                account_pb2.ChangeEmailReq(
                    password=wrappers_pb2.StringValue(value=password),
                    new_email=user.email,
                ))
        assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
        assert e.value.details() == errors.INVALID_EMAIL

    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
Exemplo n.º 26
0
def test_ChangePassword_add_with_password(db, fast_passwords):
    # user does not have an old password and is adding a new password, but supplied a password
    new_password = random_hex()
    user, token = generate_user(db, hashed_password=None)

    with account_session(db, token) as account:
        with pytest.raises(grpc.RpcError) as e:
            account.ChangePassword(
                account_pb2.ChangePasswordReq(
                    old_password=wrappers_pb2.StringValue(
                        value="wrong password"),
                    new_password=wrappers_pb2.StringValue(value=new_password),
                ))
        assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
        assert e.value.details() == errors.NO_PASSWORD

    with session_scope(db) as session:
        updated_user = session.query(User).filter(User.id == user.id).one()
        assert updated_user.hashed_password == None
Exemplo n.º 27
0
def test_ChangeEmail_wrong_token(db, fast_passwords):
    password = random_hex()
    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 auth_api_session() as (auth_api, metadata_interceptor):
        with pytest.raises(grpc.RpcError) as e:
            res = auth_api.ConfirmChangeEmail(
                auth_pb2.ConfirmChangeEmailReq(
                    change_email_token="wrongtoken", ))
        assert e.value.code() == grpc.StatusCode.NOT_FOUND
        assert e.value.details() == errors.INVALID_TOKEN

    with session_scope() as session:
        user_updated = session.execute(
            select(User).where(User.id == user.id)).scalar_one()
        assert user_updated.email == user.email
Exemplo n.º 28
0
def test_ChangePassword_normal(db, fast_passwords):
    # user has old password and is changing to new password
    old_password = random_hex()
    new_password = random_hex()
    user, token = generate_user(hashed_password=hash_password(old_password))

    with account_session(token) as account:
        with patch("couchers.servicers.account.send_password_changed_email"
                   ) as mock:
            account.ChangePassword(
                account_pb2.ChangePasswordReq(
                    old_password=wrappers_pb2.StringValue(value=old_password),
                    new_password=wrappers_pb2.StringValue(value=new_password),
                ))
        mock.assert_called_once()

    with session_scope() as session:
        updated_user = session.execute(
            select(User).where(User.id == user.id)).scalar_one()
        assert updated_user.hashed_password == hash_password(new_password)
Exemplo n.º 29
0
def test_ChangeEmail_no_change(db, fast_passwords):
    password = random_hex()
    user, token = generate_user(hashed_password=hash_password(password))

    with account_session(token) as account:
        with pytest.raises(grpc.RpcError) as e:
            account.ChangeEmail(
                account_pb2.ChangeEmailReq(
                    password=wrappers_pb2.StringValue(value=password),
                    new_email=user.email,
                ))
        assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
        assert e.value.details() == errors.INVALID_EMAIL

    with session_scope() as session:
        assert (session.execute(
            select(func.count()).select_from(User).where(
                User.new_email_token_created <= func.now()).where(
                    User.new_email_token_expiry >= func.now()))
                ).scalar_one() == 0
Exemplo n.º 30
0
def test_ChangePassword_normal_long_password(db, fast_passwords):
    # user has old password and is changing to new password, but used short password
    old_password = random_hex()
    new_password = random_hex(length=1000)
    user, token = generate_user(hashed_password=hash_password(old_password))

    with account_session(token) as account:
        with pytest.raises(grpc.RpcError) as e:
            account.ChangePassword(
                account_pb2.ChangePasswordReq(
                    old_password=wrappers_pb2.StringValue(value=old_password),
                    new_password=wrappers_pb2.StringValue(value=new_password),
                )
            )
        assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
        assert e.value.details() == errors.PASSWORD_TOO_LONG

    with session_scope() as session:
        updated_user = session.query(User).filter(User.id == user.id).one()
        assert updated_user.hashed_password == hash_password(old_password)