def handle_password_reset(username, new_password, new_password2): """ Handles the submitted password reset request. Returns True if successful, False otherwise. Also handles all messages displayed to the user. """ if not validation_utils.validate_password(new_password, new_password2): return False auth_utils.set_password(username, new_password) # Clean up the password reset key, so that it cannot be used again. query = sqlalchemy.text(""" UPDATE users SET password_reset_key = NULL, password_reset_expiration = NULL WHERE username = :u """) flask.g.db.execute(query, u=username) # Get the user's email. query = sqlalchemy.text(""" SELECT name, email FROM members NATURAL JOIN members_extra NATURAL JOIN users WHERE username = :u """) result = flask.g.db.execute(query, u=username).first() # Send confirmation email to user. email = result['email'] name = result['name'] msg = email_templates.ResetPasswordSuccessfulEmail.format(name) subject = "Password reset successful" email_utils.send_email(email, msg, subject) return True
def authenticate(username, password): """ Takes a username and password and checks if this corresponds to an actual user. Returns user_id if successful, else None. If a legacy algorithm is used, then the password is rehashed using the current algorithm. """ # Make sure the password is not too long (hashing extremely long passwords # can be used to attack the site, so we set an upper limit well beyond what # people generally use for passwords). if len(password) > constants.MAX_PASSWORD_LENGTH: return None # Get the correct password hash and user_id from the database. query = sqlalchemy.text( """ SELECT user_id, password_hash FROM users WHERE username=:u """ ) result = flask.g.db.execute(query, u=username).first() if result is None: # Invalid username. return None user_id = result["user_id"] password_hash = result["password_hash"] # Parse the hash into a PasswordHashParser object. parser = auth_utils.PasswordHashParser() if parser.parse(password_hash): if parser.verify_password(password): # Check if password was legacy. if parser.is_legacy(): # Rehash the password. auth_utils.set_password(username, password) # User is authenticated. return user_id return None
def authenticate(username, password): """ Takes a username and password and checks if this corresponds to an actual user. Returns user_id if successful, else None. If a legacy algorithm is used, then the password is rehashed using the current algorithm. """ # Make sure the password is not too long (hashing extremely long passwords # can be used to attack the site, so we set an upper limit well beyond what # people generally use for passwords). if len(password) > constants.MAX_PASSWORD_LENGTH: return None # Get the correct password hash and user_id from the database. query = sqlalchemy.text(""" SELECT user_id, password_hash FROM users WHERE username=:u """) result = flask.g.db.execute(query, u=username).first() if result is None: # Invalid username. return None user_id = result['user_id'] password_hash = result['password_hash'] # Parse the hash into a PasswordHashParser object. parser = auth_utils.PasswordHashParser() if parser.parse(password_hash): if parser.verify_password(password): # Check if password was legacy. if parser.is_legacy(): # Rehash the password. auth_utils.set_password(username, password) # User is authenticated. return user_id return None
def handle_password_reset(username, new_password, new_password2): """ Handles the submitted password reset request. Returns True if successful, False otherwise. Also handles all messages displayed to the user. """ if not validation_utils.validate_password(new_password, new_password2): return False auth_utils.set_password(username, new_password) # Clean up the password reset key, so that it cannot be used again. query = sqlalchemy.text( """ UPDATE users SET password_reset_key = NULL, password_reset_expiration = NULL WHERE username = :u """ ) flask.g.db.execute(query, u=username) # Get the user's email. query = sqlalchemy.text( """ SELECT name, email FROM members NATURAL JOIN members_extra NATURAL JOIN users WHERE username = :u """ ) result = flask.g.db.execute(query, u=username).first() # Send confirmation email to user. email = result["email"] name = result["name"] msg = email_templates.ResetPasswordSuccessfulEmail.format(name) subject = "Password reset successful" email_utils.send_email(email, msg, subject) return True
def handle_create_account(user_id, username, password, password2, birthday): """Handles account creation. Creates account if all values provided are valid. Returns: bool indicating success. """ # Validate username and password. The validate_* functions will flash errors. # We want to check all fields and not just stop at the first error. is_valid = True if not validation_utils.validate_username(username): is_valid = False if not validation_utils.validate_password(password, password2): is_valid = False if not validation_utils.validate_date(birthday): is_valid = False if not is_valid: return False # Insert new values into the database. Because the password is updated in a # separate step, we must use a transaction to execute this query. transaction = flask.g.db.begin() try: # Insert the new row into users. query = sqlalchemy.text(""" INSERT INTO users (user_id, username, password_hash) VALUES (:user_id, :username, :password_hash) """) flask.g.db.execute(query, user_id=user_id, username=username, password_hash="") # Set the password. auth_utils.set_password(username, password) # Set the birthday and invalidate the account creation key. query = sqlalchemy.text(""" UPDATE members SET birthday = :birthday, create_account_key = NULL WHERE user_id = :user_id """) flask.g.db.execute(query, birthday=birthday, user_id=user_id) transaction.commit() except Exception: transaction.rollback() flask.flash("An unexpected error occurred. Please find an IMSS rep.") return False # Email the user. query = sqlalchemy.text(""" SELECT name, email FROM members NATURAL JOIN members_extra NATURAL JOIN users WHERE username = :u """) result = flask.g.db.execute(query, u=username).first() # Send confirmation email to user. email = result["email"] name = result["name"] msg = email_templates.CreateAccountSuccessfulEmail.format(name, username) subject = "Thanks for creating an account!" email_utils.send_email(email, msg, subject) return True