def Authenticate(self, request, context): """ Authenticates a classic password based login request. request.user can be any of id/username/email """ logger.debug(f"Logging in with {request.user=}, password=*******") with session_scope() as session: user = get_user_by_field(session, request.user) if user: logger.debug(f"Found user") if not user.hashed_password: logger.debug(f"User doesn't have a password!") context.abort(grpc.StatusCode.FAILED_PRECONDITION, errors.NO_PASSWORD) if verify_password(user.hashed_password, request.password): logger.debug(f"Right password") # correct password token, expiry = self._create_session(context, session, user, request.remember_device) context.send_initial_metadata( [ ("set-cookie", create_session_cookie(token, expiry)), ] ) return auth_pb2.AuthRes(jailed=user.is_jailed) else: logger.debug(f"Wrong password") # wrong password context.abort(grpc.StatusCode.NOT_FOUND, errors.INVALID_USERNAME_OR_PASSWORD) else: # user not found logger.debug(f"Didn't find user") # do about as much work as if the user was found, reduces timing based username enumeration attacks hash_password(request.password) context.abort(grpc.StatusCode.NOT_FOUND, errors.INVALID_USERNAME_OR_PASSWORD)
def Authenticate(self, request, context): """ Authenticates a classic password based login request. request.user can be any of id/username/email """ logging.debug(f"Logging in with {request.user=}, password=*******") with session_scope(self._Session) as session: user = get_user_by_field(session, request.user) if user: logging.debug(f"Found user") if not user.hashed_password: logging.debug(f"User doesn't have a password!") context.abort(grpc.StatusCode.FAILED_PRECONDITION, "User does not have a password") if verify_password(user.hashed_password, request.password): logging.debug(f"Right password") # correct password token = self._create_session(session, user) return auth_pb2.AuthRes(token=token) else: logging.debug(f"Wrong password") # wrong password context.abort(grpc.StatusCode.UNAUTHENTICATED, "Invalid username or password") else: # user not found logging.debug(f"Didn't find user") # do about as much work as if the user was found, reduces timing based username enumeration attacks hash_password(request.password) context.abort(grpc.StatusCode.UNAUTHENTICATED, "Invalid username or password")
def _check_password(user, field_name, request, context): """ Internal utility function: given a request with a StringValue `field_name` field, checks the password is correct or that the user does not have a password """ if user.has_password: # the user has a password if not request.HasField(field_name): # no password supplied context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.MISSING_PASSWORD) if not verify_password(user.hashed_password, getattr(request, field_name).value): # wrong password context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.INVALID_USERNAME_OR_PASSWORD) elif request.HasField(field_name): # the user doesn't have a password, but one was supplied context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.NO_PASSWORD)