# -*- coding: utf-8 -*- import flaskext_compat flaskext_compat.activate() import account import ldap import os from flask import flash, Flask, g, redirect, request, session, url_for from utils import * from forms import RegisterForm, RegisterCompleteForm, LoginForm, SettingsForm app = Flask(__name__) app.config.from_object('default_settings') if 'SPLINE_ACCOUNT_WEB_SETTINGS' in os.environ: app.config.from_envvar('SPLINE_ACCOUNT_WEB_SETTINGS') @app.before_request def ldap_connect(): g.ldap = account.AccountService(account.LDAP_HOST, account.LDAP_BASE_DN, account.LDAP_ADMIN_USER, account.LDAP_ADMIN_PASS, account.SERVICES) g.user = None if 'username' in session and 'password' in session: try: g.user = g.ldap.auth(session['username'], decrypt_password(session['password'])) except ldap.INVALID_CREDENTIALS: # we had crap in the session, delete it logout_user() @app.route('/', methods=['GET', 'POST']) @templated('index.html') 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)' % g.user.uid, 'success') return redirect(url_for('settings')) else: flash(u'Ungültiger Benutzername und/oder Passwort', 'error') return {'form': form} @app.route('/register', methods=['GET', 'POST']) @templated('register.html') def register(): form = RegisterForm(request.form) if request.method == 'POST' and form.validate(): username = form.username.data mail = form.mail.data confirm_token = make_confirmation('register', (username, mail)) confirm_link = url_for('register_complete', token=confirm_token, _external=True) body = render_template('mail/register.txt', username=username, mail=mail, link=confirm_link) send_mail(mail, 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.') return redirect(url_for('index')) return {'form': form} @app.route('/register/', methods=['GET', 'POST']) @templated('register_complete.html') def register_complete(token): username, mail = http_verify_confirmation('register', token.encode('ascii'), timeout=3*24*60*60) form = RegisterCompleteForm(request.form) if request.method == 'POST' and form.validate(): password = form.password.data user = account.Account(username, mail, password=form.password.data) g.ldap.register(user) # populate request context and session assert login_user(user.uid, user.password) flash(u'Benutzer erfolgreich angelegt.') return redirect(url_for('settings')) return { 'form': form, 'token': token, 'username': username, 'mail': mail, } @app.route('/settings', methods=['GET', 'POST']) @templated('settings.html') @login_required def settings(): form = SettingsForm(request.form, mail=g.user.mail) if request.method == 'POST' and form.validate(): changed = False if form.mail.data and form.mail.data != g.user.mail: 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) g.ldap.update(g.user) session['password'] = encrypt_password(form.password.data) 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(): logout_user() return redirect(url_for('index')) @app.route('/debug') def debug(): raise Exception() if __name__ == '__main__': app.run(debug=True) # wir brauchen: # registrieren # login # passwort ändern (master-passwort, einzelne) # email ändern # später: # account löschen # openid-provider (ggf mehr Details: Realname, Zeitzone, ...)