def CompleteSignup(self, request, context): """ Completes user sign up by creating the user in question, then logs them in. TODO: nice error handling for dupe username/email? """ with session_scope(self._Session) as session: signup_token = ( session.query(SignupToken) .filter(SignupToken.token == request.signup_token) .filter(SignupToken.is_valid) .one_or_none() ) if not signup_token: context.abort(grpc.StatusCode.NOT_FOUND, errors.INVALID_TOKEN) # should be in YYYY-MM-DD format try: birthdate = datetime.fromisoformat(request.birthdate) except ValueError: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.INVALID_BIRTHDATE) # check email again if not is_valid_email(signup_token.email): context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.INVALID_EMAIL) # check username validity if not is_valid_username(request.username): context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.INVALID_USERNAME) # check name validity if not is_valid_name(request.name): context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.INVALID_NAME) if not request.hosting_status: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.HOSTING_STATUS_REQUIRED) if not self._username_available(request.username): context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.USERNAME_NOT_AVAILABLE) user = User( email=signup_token.email, username=request.username, name=request.name, city=request.city, gender=request.gender, birthdate=birthdate, hosting_status=hostingstatus2sql[request.hosting_status], ) # happens in same transaction session.delete(signup_token) # enforces email/username uniqueness session.add(user) session.commit() token = self._create_session(context, session, user) return auth_pb2.AuthRes(token=token, jailed=user.is_jailed)
def test_is_valid_username(): assert is_valid_username("user") assert is_valid_username("us") assert is_valid_username("us_er") assert is_valid_username("us_er1") assert not is_valid_username("us_") assert not is_valid_username("u") assert not is_valid_username("1us") assert not is_valid_username("User")
def _username_available(self, username): """ Checks if the given username adheres to our rules and isn't taken already. """ logging.debug(f"Checking if {username=} is valid") if not is_valid_username(username): return False with session_scope(self._Session) as session: user = session.query(User).filter(User.username == username).one_or_none() # return False if user exists, True otherwise return user is None
def CompleteSignup(self, request, context): """ Completes user sign up by creating the user in question, then logs them in. TODO: nice error handling for dupe username/email? """ with session_scope(self._Session) as session: signup_token = session.query(SignupToken) \ .filter(SignupToken.token == request.signup_token) \ .filter(SignupToken.created <= func.now()) \ .filter(SignupToken.expiry >= func.now()) \ .one_or_none() if not signup_token: context.abort(grpc.StatusCode.NOT_FOUND, "Invalid token.") # should be in YYYY/MM/DD format, will raise exception if can't parse birthdate = datetime.fromisoformat(request.birthdate) # check email again if not is_valid_email(signup_token.email): context.abort(grpc.StatusCode.INVALID_ARGUMENT, "Invalid email") # check username validity if not is_valid_username(request.username): context.abort(grpc.StatusCode.INVALID_ARGUMENT, "Invalid username") user = User( email=signup_token.email, username=request.username, name=request.name, city=request.city, gender=request.gender, birthdate=birthdate ) # happens in same transaction session.delete(signup_token) # enforces email/username uniqueness session.add(user) session.commit() token = self._create_session(session, user) return auth_pb2.AuthRes(token=token)
def CompleteSignup(self, request, context): """ Completes user sign up by creating the user in question, then logs them in. TODO: nice error handling for dupe username/email? """ with session_scope() as session: signup_token = ( session.query(SignupToken) .filter(SignupToken.token == request.signup_token) .filter(SignupToken.is_valid) .one_or_none() ) if not signup_token: context.abort(grpc.StatusCode.NOT_FOUND, errors.INVALID_TOKEN) # check birthdate validity (YYYY-MM-DD format and in the past) try: birthdate = datetime.fromisoformat(request.birthdate) except ValueError: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.INVALID_BIRTHDATE) if pytz.UTC.localize(birthdate) >= now(): context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.INVALID_BIRTHDATE) # check email again if not is_valid_email(signup_token.email): context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.INVALID_EMAIL) # check username validity if not is_valid_username(request.username): context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.INVALID_USERNAME) # check name validity if not is_valid_name(request.name): context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.INVALID_NAME) if not request.hosting_status: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.HOSTING_STATUS_REQUIRED) if not self._username_available(request.username): context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.USERNAME_NOT_AVAILABLE) if request.lat == 0 and request.lng == 0: context.abort(grpc.StatusCode.INVALID_ARGUMENT, errors.INVALID_COORDINATE) user = User( email=signup_token.email, username=request.username, name=request.name, gender=request.gender, birthdate=birthdate, hosting_status=hostingstatus2sql[request.hosting_status], city=request.city, geom=create_coordinate(request.lat, request.lng), geom_radius=request.radius, accepted_tos=1 if request.accept_tos else 0, ) # happens in same transaction session.delete(signup_token) # enforces email/username uniqueness session.add(user) session.commit() token, expiry = self._create_session(context, session, user, False) context.send_initial_metadata( [ ("set-cookie", create_session_cookie(token, expiry)), ] ) return auth_pb2.AuthRes(jailed=user.is_jailed)