|
- import web
- from uuid import uuid4
- from views.forms import reset_form, request_reset_form
- from views.utils import get_nav_bar, csrf_protected, get_render, password_weakness, sendmail
- import models.user
- import logging
- import bcrypt
-
- logger = logging.getLogger(__name__)
-
-
- class RequestReset:
- def GET(self):
- session = web.ctx.session
- nav = get_nav_bar(session)
-
- return get_render().reset_request(nav, request_reset_form, "")
-
- @csrf_protected
- def POST(self):
- session = web.ctx.session
- nav = get_nav_bar(session)
- data = web.input(username="", email="")
- render = get_render()
-
- user = models.user.get_user(data.username)
- if user and user[2] == data.email:
- password = uuid4().hex
- password_hash = bcrypt.hashpw(password.encode('UTF-8'), bcrypt.gensalt())
- models.user.set_temporary_password(user[0], password_hash)
-
- sendmail(
- 'Reset your Beelance password',
- """Hi!
-
- Someone requested a password reset for your account. If you didn't request this, you can ignore this email.
-
- If you want to reset your password, log in with this password: {password}
- Then you will be able to set a new password.
- """.format(password=password),
- "",
- data.email,
- )
-
- logger.info("User %s requested a password reset", data.username)
- else:
- logger.info("Incorrect reset request with username %s and email %s", data.username, data.email)
-
- return render.reset_request(nav, request_reset_form, "An email has been sent, if the username and email is correct")
-
-
- class Reset:
- def GET(self):
- session = web.ctx.session
- nav = get_nav_bar(session)
- render = get_render()
-
- if 'temporary_userid' not in session or not session.temporary_userid:
- return render.reset(nav, reset_form, "Something went wrong. Try logging in with the temporary password again.")
- return get_render().reset(nav, reset_form, "")
-
- @csrf_protected
- def POST(self):
- session = web.ctx.session
- nav = get_nav_bar(session)
- data = web.input(temporary="", password="", repeat="")
- render = get_render()
-
- if 'temporary_userid' not in session or not session.temporary_userid:
- return render.reset(nav, reset_form, "Something went wrong. Try logging in with the temporary password again.")
-
- userid = session.temporary_userid
- username = models.user.get_user_name_by_id(userid)
- user = models.user.get_user(username)
- temporary_password = user[4]
-
- # Check that the temporary password is correct
- if not bcrypt.checkpw(data.temporary.encode('UTF-8'), temporary_password.encode('UTF-8')):
- return render.reset(nav, reset_form, "Incorrect temporary password")
-
- # Check that the passwords match
- if data.password != data.repeat:
- return render.reset(nav, reset_form, "The repeated password doesn't match the first")
-
- # Check password security
- weakness = password_weakness(data.password, username)
- if weakness is not None:
- return render.reset(nav, reset_form, weakness)
-
- # Set the new password and log the user in
- password_hash = bcrypt.hashpw(data.password.encode('UTF-8'), bcrypt.gensalt())
- models.user.set_password(userid, password_hash)
- models.user.set_temporary_password(userid, "")
-
- session.temporary_userid = None
-
- logger.info("User %s has changed their password", username)
-
- return get_render().reset(nav, reset_form, "Your password has been reset. You can log in again now.")
|