diff options
-rw-r--r-- | app.py | 49 | ||||
-rw-r--r-- | static/layout.css | 4 | ||||
-rw-r--r-- | templates/base.html | 4 | ||||
-rw-r--r-- | templates/mail/change_mail.txt | 15 | ||||
-rw-r--r-- | utils.py | 13 |
5 files changed, 65 insertions, 20 deletions
@@ -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/<token>', 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/<token>') +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 @@ <h2>{{ title }}</h2> {% endif %} - {%- if session.username %} - <p>Logged in as {{ session.username }}. <a href="{{ url_for('logout') }}">Log out</a></p> + {%- if g.user %} + <p>Logged in as {{ g.user.uid }}. <a href="{{ url_for('logout') }}">Log out</a></p> {%- else %} <p>Not logged in. <a href="{{ url_for('index') }}">Log in</a></p> {%- 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) }} @@ -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: |