def confirm_email(token): try: email, token_type = confirm_token(token, expiration=7200) except (SignatureExpired, BadSignature) as e: if e == SignatureExpired: logging.debug(f"Signature Expired for token {token}") raise BadRequestError("Signature Expired.", "Request another email confirmation and try again.") else: logging.debug(f"Bad Expired for token {token}") raise BadRequestError("Bad Signature.", "Request another password reset and try again.") else: if token_type != "confirm": logging.debug(f"Wrong token type for token {token}") raise BadRequestError("Wrong token type.") user = User.get_or_none(email=email) if not user: raise NotFoundError("User not found.") if user.is_confirmed: logging.debug("User already confirmed") raise BadRequestError("Email already confirmed.", "") else: user.is_confirmed = True user.confirmed_on = datetime.utcnow() user.save() logging.debug(f"User {user.id} confirmed.") return Success("Confirmation successful.")
def register_user(): data = request.get_json() first_name = data["first_name"] last_name = data["last_name"] email = data["email"] password = data["password"] User.register(first_name=first_name, last_name=last_name, email=email, password=password) token = generate_confirmation_token(email=email, token_type="confirm") link = FRONTEND_EMAIL_CONFIRMATION_URL + token body = """Thank you for creating an account on Unusual Organisation! Here's your confirmation link: {} Note: This link expires in an hour """.format( link ) send_mail_text.delay(email, "Confirm your account", body) return Success("User created successfully.")
def forgot_password(): data = request.get_json() email = data["email"] if not User.get_or_none(email=email): logging.debug("User not found, no email sent") pass else: token = generate_confirmation_token(email=email, token_type="reset") link = FRONTEND_PASSWORD_RESET_URL + token logging.debug("Sending worker request to send email") body = """Password change request: Here's your password change link: {} Note: This link expires in an hour """.format(link) send_mail_text.delay(email, "Change your password", body) logging.debug("Password reset mail sent successfully for user.") return Success( "Password reset mail sent successfully if user exists in DB.")
def login_user(): data = request.get_json() email = data["email"] password = data["password"] try: user = User.get(email=email) except User.DoesNotExist: raise UnauthorizedError("Incorrect username or password.") if not check_password(user.password, password): raise UnauthorizedError("Incorrect username or password.") if not user.is_confirmed: raise UnauthorizedError( "User needs to be confirmed first.", "Try again when you have confirmed your email.") access_token = create_access_token(identity=user.get_jwt_info(), fresh=True) refresh_token = create_refresh_token(identity=user.get_jwt_info()) access_jti = get_jti(access_token) refresh_jti = get_jti(refresh_token) redis.set("is_revoked_jti:" + access_jti, "false", ACCESS_TOKEN_EXPIRES * 1.2) redis.set("is_revoked_jti:" + refresh_jti, "false", REFRESH_TOKEN_EXPIRES * 1.2) ret = { "access_token": access_token, "refresh_token": refresh_token, "user_id": user.id } send_mail_text.delay( dest=user.email, subject="[Unusual Organisation] Login notification", body=f"Someone logged in into your account at {datetime.utcnow()}." f"If you believe it wasn't you, please change your password immediately!", ) return SuccessOutput("return", ret)
def check_token_validity(): data = request.get_json() token = data["token"] try: email, token_type = confirm_token(token, expiration=7200) except (SignatureExpired, BadSignature) as e: if e == SignatureExpired: logging.debug(f"Signature Expired for {token}") raise BadRequestError( "Signature Expired.", "Request another password reset and try again.") else: logging.debug(f"Bad Signature for {token}") raise BadRequestError( "Bad Signature.", "Request another password reset and try again.") else: user = User.get_or_none(email=email) if not user: raise NotFoundError("User not found.") return SuccessOutputMessage("email", user.email, "Reset token is correct.")
def request_new_email_conf(): data = request.get_json() email = data["email"] user = User.get_or_none(email=email) if not user: pass else: if user.is_confirmed: logging.debug("Already confirmed.") else: logging.debug("/auth/confirm/new -> User found, sending new confirmation email") token = generate_confirmation_token(email=email, token_type="confirm") link = FRONTEND_EMAIL_CONFIRMATION_URL + token body = """Thank you for creating an account on Unusual Organisation! Here's your confirmation link: {} Note: This link expires in an hour """.format( link ) send_mail_text.delay(email, "Confirm your account", body) logging.debug("/auth/confirm/new -> New confirmation email sent if user exists in database") return Success("New confirmation email sent if user exists in database and isn't already confirmed.")
def reset_password(): data = request.get_json() token = data["token"] try: email, token_type = confirm_token(token, expiration=7200) except (SignatureExpired, BadSignature) as e: if e == SignatureExpired: logging.debug(f"Signature Expired for {token}") raise BadRequestError( "Signature Expired.", "Request another password reset and try again.") else: logging.debug(f"Bad Signature for {token}") raise BadRequestError( "Bad Signature.", "Request another password reset and try again.") else: if token_type != "reset": logging.debug(f"Wrong token type for {token}") raise BadRequestError("Wrong token type.") user = User.get_or_none(email=email) if not user: raise NotFoundError("User not found.") user.password = hash_password(data["password"]) user.previous_reset_token = token user.save() body = """Someone changed your password Hello, your password was changed on {}. If you believe it wasn't you, please contact us immediatly. """.format(datetime.datetime.utcnow()) send_mail_text.delay(email, "Password change notification", body) logging.debug("Password reset successfully") return Success("Password reset successful.")
db=2) # Initializes the PostgreSQL DB uorg_db = peewee.MySQLDatabase(database=DB_NAME, user=DB_USER, password=DB_PASSWORD, host=DB_HOST, port=DB_PORT) import uorg.utils.jwt_callbacks # noqa from uorg.routes.api.home import home_bp from uorg.routes.api.auth.register import register_bp from uorg.routes.api.auth.login import login_bp from uorg.routes.api.auth.password import password_bp logging.debug("Registering Flask blueprints") application.register_blueprint(home_bp) application.register_blueprint(register_bp) application.register_blueprint(login_bp) application.register_blueprint(password_bp) # import tasks here to be registered by celery from uorg.worker import * # noqa from uorg.models.user import User if not User.table_exists(): User.create_table()
def jwt_user_callback(identity): return User.get_or_none(id=identity["id"])