From 7ee2c696aed7efb64b62b7f91e2230dcc151a1a9 Mon Sep 17 00:00:00 2001 From: zPlus Date: Fri, 3 May 2019 20:17:03 +0200 Subject: [PATCH] Fix #92 "reset password form not working" --- freepost/__init__.py | 46 ++++++++++----------- freepost/database.py | 6 +-- freepost/mail.py | 11 +++-- freepost/templates/email/password_reset.txt | 2 +- settings.yaml | 5 ++- 5 files changed, 34 insertions(+), 36 deletions(-) diff --git a/freepost/__init__.py b/freepost/__init__.py index 830ee17e..29c8dfb0 100755 --- a/freepost/__init__.py +++ b/freepost/__init__.py @@ -302,46 +302,45 @@ def password_reset_send_code (): code via email. """ - username = request.forms.getunicode ('username') - email = request.forms.getunicode ('email') + username = request.forms.getunicode('username') + email = request.forms.getunicode('email') if not username or not email: - redirect (application.get_url ('change_password')) + redirect(application.get_url('change_password')) - user = database.get_user_by_username (username) + user = database.get_user_by_username(username) if not user: - redirect (application.get_url ('change_password')) + redirect(application.get_url('change_password')) # Make sure the given email matches the one that we have in the database if user['email'] != email: - redirect (application.get_url ('change_password')) + redirect(application.get_url('change_password')) # Is there another valid token already (from a previous request)? # If yes, do not send another one (to prevent multiple requests or spam) - if database.is_password_reset_token_valid (user['id']): - redirect (application.get_url ('change_password')) + if database.is_password_reset_token_valid(user['id']): + redirect(application.get_url('change_password')) # Generate secret token to send via email - secret_token = random.ascii_string (32) + secret_token = random.ascii_string(32) # Add token to database - database.set_password_reset_token (user['id'], secret_token) + database.set_password_reset_token(user['id'], secret_token) # Send token via email - client_ip = request.environ.get ('HTTP_X_FORWARDED_FOR') or \ - request.environ.get ('REMOTE_ADDR') - email_from = 'freepost ' + client_ip = request.environ.get('HTTP_X_FORWARDED_FOR') or \ + request.environ.get('REMOTE_ADDR') email_to = user['email'] email_subject = 'freepost password reset' - email_body = template ( + email_body = template( 'email/password_reset.txt', ip=client_ip, secret_token=secret_token) - mail.send (email_from, email_to, email_subject, email_body) + mail.send(email_to, email_subject, email_body) - redirect (application.get_url ('change_password')) + redirect(application.get_url('change_password')) @get ('/change_password', name='change_password') @requires_logout @@ -361,14 +360,14 @@ def validate_new_password (): is OK change the user password. """ - username = request.forms.getunicode ('username') - email = request.forms.getunicode ('email') - password = request.forms.getunicode ('password') - secret_token = request.forms.getunicode ('token') + username = request.forms.getunicode('username') + email = request.forms.getunicode('email') + password = request.forms.getunicode('password') + secret_token = request.forms.getunicode('token') # We must have all fields if not username or not email or not password or not secret_token: - redirect (application.get_url ('login')) + redirect(application.get_url('login')) # Password too short? if len (password) < 8: @@ -377,7 +376,7 @@ def validate_new_password (): flash = 'Password must be at least 8 characters long') # OK, everything should be fine now. Reset user password. - database.reset_password (username, email, password, secret_token) + database.reset_password(username, email, password, secret_token) # Check if the password was successfully reset user = database.check_user_credentials (username, password) @@ -388,12 +387,11 @@ def validate_new_password (): # Everything matched! # Notify user of password change. - email_from = 'freepost ' email_to = user['email'] email_subject = 'freepost password changed' email_body = template ('email/password_changed.txt') - mail.send (email_from, email_to, email_subject, email_body) + mail.send (email_to, email_subject, email_body) # Start new session and redirect user session.start (user['id']) diff --git a/freepost/database.py b/freepost/database.py index d7133ba7..1a883526 100644 --- a/freepost/database.py +++ b/freepost/database.py @@ -705,7 +705,7 @@ def set_password_reset_token (user_id = None, token = None): """ UPDATE user SET passwordResetToken = SHA512(:token), - passwordResetTokenExpire = NOW() + INTERVAL 1 HOUR + passwordResetTokenExpire = DATETIME('now', '+1 HOUR') WHERE id = :user """, { @@ -739,7 +739,7 @@ def is_password_reset_token_valid (user_id = None): WHERE id = :user AND passwordResetToken IS NOT NULL AND passwordResetTokenExpire IS NOT NULL - AND passwordResetTokenExpire > DATE() + AND passwordResetTokenExpire > DATETIME('now') """, { 'user': user_id @@ -757,7 +757,7 @@ def reset_password (username = None, email = None, new_password = None, secret_t db.execute ( """ UPDATE user - SET password = SHA512(:password || `salt`), + SET password = SHA512(:password || salt), passwordResetToken = NULL, passwordResetTokenExpire = NULL WHERE username = :user diff --git a/freepost/mail.py b/freepost/mail.py index e40e46fd..3754934c 100644 --- a/freepost/mail.py +++ b/freepost/mail.py @@ -3,13 +3,12 @@ from email.mime.text import MIMEText from freepost import settings from subprocess import Popen, PIPE -def send (from_address, to_address, subject, body): - email_message = MIMEMultipart () - email_message['From'] = from_address +def send(to_address, subject, body): + email_message = MIMEText(body) + email_message['From'] = settings['email']['from'] email_message['To'] = to_address email_message['Subject'] = subject - email_message.attach (MIMEText (body, 'plain')) # Open pipe to sendmail - Popen ([ settings['sendmail']['path'] , "-t" ], stdin=PIPE) \ - .communicate (email_message.as_bytes ()) + child_process = Popen([ settings['email']['sendmail_path'], "-t" ], stdin=PIPE) + child_process.communicate(email_message.as_bytes()) diff --git a/freepost/templates/email/password_reset.txt b/freepost/templates/email/password_reset.txt index 2aa4f157..5ab6a2c7 100644 --- a/freepost/templates/email/password_reset.txt +++ b/freepost/templates/email/password_reset.txt @@ -1,6 +1,6 @@ Somebody from IP:{{ ip }} has requested to reset your freepost password. The secret code to reset your password is {{ secret_token|safe }} -This code can only be used one time, and will automatically expire in 1 hour. +This code can only be used once, and will automatically expire in 1 hour. If you did not request to change your password, please ignore this message or contact support. diff --git a/settings.yaml b/settings.yaml index 7311c09f..cb39d0fa 100644 --- a/settings.yaml +++ b/settings.yaml @@ -16,8 +16,9 @@ sqlite: database: ./database.sqlite # Emails are sent using the local sendmail MTA. -sendmail: - path: /usr/sbin/sendmail +email: + sendmail_path: /usr/sbin/sendmail + from: "freepost " session: # Name to use for the session cookie