def create_user_helper(event: ApiGatewayEvent, new_user: User) -> dict: users_service = UsersService() if not new_user.new_user_fields_present(): return event.bad_request_response({"message": "A field is missing."}) new_user.email = new_user.email.lower() response = validate_user_fields(users_service, new_user) if len(response.keys()) > 0: return event.bad_request_response(response) if users_service.get_user_by_email(new_user): response["email"] = "Email is taken." if len(response.keys()) > 0: return event.bad_request_response(response) new_user.email = new_user.email.lower() saved_user = UsersService().create_user(new_user) return (event.ok_response(saved_user.as_json_response()) if saved_user else event.internal_server_error_response( {"message": "There was an error saving your user."}))
def update_user(self, updated_user: User) -> Optional[User]: updated_user.last_updated = datetime.now() try: updated_user.save() updated_user.refresh() return updated_user except Exception as e: LOG.exception(str(e)) return None
def setUp(self) -> None: self.valid_new_user = User( first_name="first", last_name="last", email="*****@*****.**", password="******", city="Ames", state="Iowa", phone_number="9999999999", authority=None, role=None, id=str(uuid.uuid4()), ) self.invalid_new_user = User( first_name="first", last_name="last", email="emailgmail.com", password="******", city="Ames", state="Iowa", phone_number="999999999", authority=None, role=None, id=str(uuid.uuid4()), ) self.valid_jwt_payload = { "email": "lukeshay", "id": "some_id", "authorities": "ADMIN", "expires_in": "never", "issued_at": "10000", } self.valid_basic_jwt_payload = { "email": "lukeshay", "id": "some_id", "authorities": "BASIC", "expires_in": "never", "issued_at": "10000", } self.basic_headers = { "Authorization": f"Bearer {generate_jwt(self.valid_basic_jwt_payload)}" } self.admin_headers = { "Authorization": f"Bearer {generate_jwt(self.valid_jwt_payload)}" }
def get_user(id): """Gets information about the user for the given ID.""" user = User.get_by_id(id) if user == None: return (jsonify({"Error": "User not found."}), 404) else: return user.username
def login_handler(event: ApiGatewayEvent): logging.info(event) users_service = UsersService() user, headers = users_service.login(User.from_camel_dict(event.body)) if not user: return event.forbidden_response() return event.ok_response(user.as_json_response(), headers)
def create_user(new_user: User) -> Optional[User]: new_user.id = str(uuid.uuid4()) new_user.password = UsersService.encrypt_password(new_user.password) new_user.last_updated = datetime.now() try: new_user.save() new_user.refresh() return new_user except Exception as e: LOG.exception(str(e)) return None
def username_available(username): """Determines if a username is available. If the username is already registered, username_available returns false, else true. Args: username: A string of the username. Returns: A boolean, representing whether the username is available or not. """ return len(User.query(User.username == username).fetch()) == 0
def test_create_valid_basic_user(self): response = OfflineHandler(create_user_handler).handle_v2( body=self.valid_new_user.as_camel_dict()) user = User.from_camel_dict(response["body"]) logging.info(response["body"]) self.assertEqual(200, response["statusCode"]) self.assertEqual(self.valid_new_user.email, user.email) self.assertEqual(self.valid_new_user.first_name, user.first_name) self.assertEqual(self.valid_new_user.last_name, user.last_name) self.assertEqual(self.valid_new_user.phone_number, user.phone_number) self.assertEqual(self.valid_new_user.city, user.city) self.assertEqual(self.valid_new_user.state, user.state)
def update_user_handler(event: ApiGatewayEvent) -> dict: updated_user = User.from_camel_dict(event.body) if event.id != updated_user.id: return event.unauthorized_response() users_service = UsersService() current_user = users_service.get_user_by_id(updated_user) if not current_user: return event.bad_request_response({"message": "User does not exist."}) updated_user += current_user response = {} updated_user.email = updated_user.email.lower() if updated_user.email != current_user.email and users_service.get_user_by_email( updated_user): response["email"] = "Email is taken." if len(response.keys()) > 0: return event.bad_request_response(response) response = validate_user_fields(users_service, updated_user) if len(response.keys()) > 0: return event.bad_request_response(response) if current_user.password != updated_user.password: updated_user.password = users_service.encrypt_password( updated_user.password) updated_user = users_service.update_user(updated_user) return (event.ok_response(updated_user.as_json_response()) if updated_user else event.internal_server_error_response())
def create_admin_user_handler(event: ApiGatewayEvent) -> dict: new_user = User.from_camel_dict(event.body) new_user.authority = "ADMIN" new_user.role = "ADMIN_ROLE" return create_user_helper(event, new_user)
def create_user(): """Creates a new user, if and only if the following criteria are satisfied: * The username does not already exist. * The phone number is not already registered. * The password is at least 8 characters long. Args: request: A JSON object of the username, password, and phone number. The phone number is used for account verification and for fetching user accounts for a contact list. Returns: A tuple of the following: * A JSON object specifying an error, if any. * An HTTP status that is 400 if there was an error, and 201 if the account creation was successful. * An HTTP header specifying the URI of the created user. """ DEV_BAD_USER_MSG = ("Username has inappropriate characters. " "The username must match the following regex: " "^(?![_.-])(?!.*[_.-]{2})[a-zA-Z0-9._-]+(?<![_.-])$. " "That is, the allowed characters are alphanumeric, " "with {., _, -} allowed in the middle of the string.") USER_BAD_USER_MSG = ("The username has inappropriate characters. " "Please use numbers, letters, underscores, and " "hyphens.") DEV_USERNAME_TAKEN_MSG = ("The username has already been taken.") USER_USERNAME_TAKEN_MSG = ( "Sorry! Looks like someone got that awesome username " "before you. Try again.") DEV_BAD_PASS_MSG = ("The password was not a minimum of 8 characters.") USER_BAD_PASS_MSG = ("Your password is weak. Try something a bit longer.") username = request.form["username"] password = request.form["password"] if not username_is_valid(username): return (jsonify(status=400, developer_message=DEV_BAD_USER_MSG, user_message=USER_BAD_USER_MSG), 400) elif not username_available(username): return (jsonify(status=400, developer_message=DEV_USERNAME_TAKEN_MSG, user_message=USER_USERNAME_TAKEN_MSG), 400) elif not password_is_valid(password): return (jsonify(status=400, developer_message=DEV_BAD_PASS_MSG, user_message=USER_BAD_PASS_MSG), 400) else: pass_hash = generate_password_hash(password) user_to_insert = User(username=username, password_hash=pass_hash) user_id = user_to_insert.put() return ("Well done!", 201, {"id": user_id.id()})
def create_user(): """Creates a new user, if and only if the following criteria are satisfied: * The username does not already exist. * The phone number is not already registered. * The password is at least 8 characters long. Args: request: A JSON object of the username, password, and phone number. The phone number is used for account verification and for fetching user accounts for a contact list. Returns: A tuple of the following: * A JSON object specifying an error, if any. * An HTTP status that is 400 if there was an error, and 201 if the account creation was successful. * An HTTP header specifying the URI of the created user. """ DEV_BAD_USER_MSG = ("Username has inappropriate characters. " "The username must match the following regex: " "^(?![_.-])(?!.*[_.-]{2})[a-zA-Z0-9._-]+(?<![_.-])$. " "That is, the allowed characters are alphanumeric, " "with {., _, -} allowed in the middle of the string.") USER_BAD_USER_MSG = ("The username has inappropriate characters. " "Please use numbers, letters, underscores, and " "hyphens.") DEV_USERNAME_TAKEN_MSG = ("The username has already been taken.") USER_USERNAME_TAKEN_MSG = ("Sorry! Looks like someone got that awesome username " "before you. Try again.") DEV_BAD_PASS_MSG = ("The password was not a minimum of 8 characters.") USER_BAD_PASS_MSG = ("Your password is weak. Try something a bit longer.") username = request.form["username"] password = request.form["password"] if not username_is_valid(username): return (jsonify(status=400, developer_message=DEV_BAD_USER_MSG, user_message=USER_BAD_USER_MSG), 400) elif not username_available(username): return (jsonify(status=400, developer_message=DEV_USERNAME_TAKEN_MSG, user_message=USER_USERNAME_TAKEN_MSG), 400) elif not password_is_valid(password): return (jsonify(status=400, developer_message=DEV_BAD_PASS_MSG, user_message=USER_BAD_PASS_MSG), 400) else: pass_hash = generate_password_hash(password) user_to_insert = User(username=username, password_hash=pass_hash) user_id = user_to_insert.put() return ("Well done!", 201, { "id": user_id.id() })
def tearDown(self): if User.exists(): User.delete_table() User.create_table()
class TestCreateUsersHandlers(TestBase): def setUp(self) -> None: self.valid_new_user = User( first_name="first", last_name="last", email="*****@*****.**", password="******", city="Ames", state="Iowa", phone_number="9999999999", authority=None, role=None, id=str(uuid.uuid4()), ) self.invalid_new_user = User( first_name="first", last_name="last", email="emailgmail.com", password="******", city="Ames", state="Iowa", phone_number="999999999", authority=None, role=None, id=str(uuid.uuid4()), ) self.valid_jwt_payload = { "email": "lukeshay", "id": "some_id", "authorities": "ADMIN", "expires_in": "never", "issued_at": "10000", } self.valid_basic_jwt_payload = { "email": "lukeshay", "id": "some_id", "authorities": "BASIC", "expires_in": "never", "issued_at": "10000", } self.basic_headers = { "Authorization": f"Bearer {generate_jwt(self.valid_basic_jwt_payload)}" } self.admin_headers = { "Authorization": f"Bearer {generate_jwt(self.valid_jwt_payload)}" } def test_create_valid_basic_user(self): response = OfflineHandler(create_user_handler).handle_v2( body=self.valid_new_user.as_camel_dict()) user = User.from_camel_dict(response["body"]) logging.info(response["body"]) self.assertEqual(200, response["statusCode"]) self.assertEqual(self.valid_new_user.email, user.email) self.assertEqual(self.valid_new_user.first_name, user.first_name) self.assertEqual(self.valid_new_user.last_name, user.last_name) self.assertEqual(self.valid_new_user.phone_number, user.phone_number) self.assertEqual(self.valid_new_user.city, user.city) self.assertEqual(self.valid_new_user.state, user.state) def test_create_missing_field_basic_user(self): response = OfflineHandler(create_user_handler).handle_v2(body={}) self.assertEqual({"message": "A field is missing."}, response["body"]) self.assertEqual(400, response["statusCode"])
def __init__(self): self.jwt = Jwt() if not User.exists(): User.create_table(wait=True)
def get_user_by_email(request_user: User) -> Optional[User]: try: return User.get(hash_key=request_user.email) except DoesNotExist: return None