# -*- 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)' % session['username']) 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): 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') 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 = [] if form.mail.data and form.mail.data != g.user.mail: g.user.change_email(form.mail.data) changed.append(u'E-Mail-Adresse') if form.password.data: g.user.change_password(form.password.data) changed.append(u'Passwort') session['password'] = encrypt_password(form.password.data) if changed: g.ldap.update(g.user) flash(u'%s geändert' % u' und '.join(changed)) return redirect(url_for('settings')) else: flash(u'Nichts geändert') return {'form': form} @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, ...)