From 2bdceb1209a081e9ccb80a35dd605c120aaf32e9 Mon Sep 17 00:00:00 2001 From: Marian Sigler Date: Fri, 21 Sep 2012 16:12:30 +0200 Subject: Send verify mail on change of mail address --- app.py | 49 ++++++++++++++++++++++++++++-------------- static/layout.css | 4 ++-- templates/base.html | 4 ++-- templates/mail/change_mail.txt | 15 +++++++++++++ utils.py | 13 +++++++++++ 5 files changed, 65 insertions(+), 20 deletions(-) create mode 100644 templates/mail/change_mail.txt diff --git a/app.py b/app.py index 0d56298..e07c853 100644 --- a/app.py +++ b/app.py @@ -37,7 +37,7 @@ def index(): form = LoginForm(request.form) if request.method == 'POST' and form.validate(): if login_user(form.username.data, form.password.data): - flash(u'Erfolgreich eingeloggt (als %s)' % session['username'], 'success') + flash(u'Erfolgreich eingeloggt (als %s)' % g.user.uid, 'success') return redirect(url_for('settings')) else: flash(u'Ungültiger Benutzername und/oder Passwort', 'error') @@ -74,12 +74,7 @@ def register(): @app.route('/register/', methods=['GET', 'POST']) @templated('register_complete.html') def register_complete(token): - try: - username, mail = verify_confirmation('register', token.encode('ascii'), timeout=3*24*60*60) - except ConfirmationInvalid: - raise Forbidden(u'Ungültiger Bestätigungslink') - except ConfirmationTimeout: - raise Forbidden(u'Bestätigungslink ist zu alt') + username, mail = http_verify_confirmation('register', token.encode('ascii'), timeout=3*24*60*60) form = RegisterCompleteForm(request.form) @@ -110,29 +105,51 @@ def register_complete(token): def settings(): form = SettingsForm(request.form, mail=g.user.mail) if request.method == 'POST' and form.validate(): - changed = [] + changed = False if form.mail.data and form.mail.data != g.user.mail: - g.user.change_email(form.mail.data) - changed.append(u'E-Mail-Adresse') + confirm_token = make_confirmation('change_mail', (g.user.uid, form.mail.data)) + confirm_link = url_for('change_mail', token=confirm_token, _external=True) + + body = render_template('mail/change_mail.txt', username=g.user.uid, + mail=form.mail.data, link=confirm_link) + + send_mail(form.mail.data, u'E-Mail-Adresse bestätigen', body, + sender=app.config.get('MAIL_CONFIRM_SENDER')) + + flash(u'Es wurde eine E-Mail an die angegebene Adresse geschickt, ' + u'um diese zu überprüfen. Bitte folge den Anweisungen in der ' + u'E-Mail.') + changed = True if form.password.data: g.user.change_password(form.password.data) - changed.append(u'Passwort') - + g.ldap.update(g.user) session['password'] = encrypt_password(form.password.data) - if changed: - g.ldap.update(g.user) - flash(u'%s geändert' % u' und '.join(changed), 'success') + flash(u'Passwort geändert', 'success') + changed = True + if changed: return redirect(url_for('settings')) - else: flash(u'Nichts geändert') return {'form': form} +@login_required +@app.route('/settings/change_mail/') +def change_mail(token): + username, mail = http_verify_confirmation('change_mail', token.encode('ascii'), timeout=3*24*60*60) + + if g.user.uid != username: + raise Forbidden(u'Bitte logge dich als der Benutzer ein, dessen E-Mail-Adresse du ändern willst.') + g.user.change_email(mail) + g.ldap.update(g.user) + + flash(u'E-Mail-Adresse geändert.', 'success') + return redirect(url_for('settings')) + @app.route('/logout') def logout(): diff --git a/static/layout.css b/static/layout.css index 2d7be98..ce5461a 100644 --- a/static/layout.css +++ b/static/layout.css @@ -7,7 +7,7 @@ ul.flashes { } ul.flashes li { list-style: none; - margin-left: 0; + margin: .2em 0; display: block; padding: .2em .4em; @@ -26,7 +26,7 @@ ul.flashes li.success { body { margin: 0 auto; - width: 640px; + max-width: 40em; } #header { diff --git a/templates/base.html b/templates/base.html index 1873dd3..1886d12 100644 --- a/templates/base.html +++ b/templates/base.html @@ -19,8 +19,8 @@

{{ title }}

{% endif %} - {%- if session.username %} -

Logged in as {{ session.username }}. Log out

+ {%- if g.user %} +

Logged in as {{ g.user.uid }}. Log out

{%- else %}

Not logged in. Log in

{%- endif %} diff --git a/templates/mail/change_mail.txt b/templates/mail/change_mail.txt new file mode 100644 index 0000000..c3db6b2 --- /dev/null +++ b/templates/mail/change_mail.txt @@ -0,0 +1,15 @@ +Hallo, + +Jemand, vermutlich du, möchte auf spline accounts [1] die +E-Mail-Adresse des Accounts {{ username }} auf diese Adresse + {{ mail }} +ändern. + +Um diese Änderung zu bestätigen, benutze bitte folgenden Link: + <{{ link }}> + +Wenn du dies nicht möchtest, brauchst du nichts weiter zu tun. +Ohne deine Bestätigung wird deine Adresse nicht eingetragen. + + +[1] {{ url_for('index', _external=True) }} diff --git a/utils.py b/utils.py index 49a69d3..a20b034 100644 --- a/utils.py +++ b/utils.py @@ -131,6 +131,19 @@ def verify_confirmation(realm, token, timeout=None): return pickle.loads(payload) +def http_verify_confirmation(*args, **kwargs): + """ + Like `verify_confirmation`, but raise HTTP exceptions with appropriate + messages instead of `Confirmation{Invalid,Timeout}`. + """ + + try: + return verify_confirmation(*args, **kwargs) + except ConfirmationInvalid: + raise Forbidden(u'Ungültiger Bestätigungslink') + except ConfirmationTimeout: + raise Forbidden(u'Bestätigungslink ist zu alt') + def send_mail(recipient, subject, body, sender=None): if sender is None: -- cgit v1.2.3-1-g7c22