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
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
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}"), ))
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 == ""
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}"), ))
def test_deleted_user(db): _quick_signup() with session_scope() as session: session.execute(select(User)).scalar_one().is_deleted = True 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
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."
def test_banned_user_without_password(db): _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 with session_scope() as session: login_token = session.execute(select(LoginToken)).scalar_one().token 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.CompleteTokenLogin( auth_pb2.CompleteTokenLoginReq(login_token=login_token)) assert e.value.details() == "Your account is suspended."
def test_login_tokens_invalidate_after_use(db): _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 with session_scope() as session: login_token = session.execute(select(LoginToken)).scalar_one().token with auth_api_session() as (auth_api, metadata_interceptor): auth_api.CompleteTokenLogin( auth_pb2.CompleteTokenLoginReq(login_token=login_token)) session_token = get_session_cookie_token(metadata_interceptor) with auth_api_session() as (auth_api, metadata_interceptor), pytest.raises( grpc.RpcError): # check we can't login again auth_api.CompleteTokenLogin( auth_pb2.CompleteTokenLoginReq(login_token=login_token))