# -*- coding: utf-8 -*- import flaskext_compat flaskext_compat.activate() import account import ldap import os from copy import deepcopy from flask import flash, Flask, g, redirect, request, session, url_for from utils import * 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.all_services = account.SERVICES #TODO: take that from our json file or so @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, app.all_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', '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') @logout_required def register(): #TODO: check for double uids 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') @logout_required def register_complete(token): #TODO: check for double uids 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 request.form.get('submit_main'): 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, session['password']) session['password'] = encrypt_password(form.password.data) flash(u'Passwort geändert', 'success') changed = True for service in app.all_services: field = form.get_servicepassword(service.id) if field.data: changed = True g.user.change_password(field.data, session['password'], service.id) if changed: g.ldap.update(g.user) return redirect(url_for('settings')) else: flash(u'Nichts geändert.') services = deepcopy(app.all_services) for s in services: s.changed = s.id in g.user.services return { 'form': form, 'services': services, } @app.route('/settings/change_mail/') @login_required 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() flash(u'Erfolgreich ausgeloggt.', 'success') return redirect(url_for('index')) @app.route('/debug') def debug(): raise Exception() # we need the app to exist before initializing the forms from forms import RegisterForm, RegisterCompleteForm, LoginForm, SettingsForm if __name__ == '__main__': app.run(debug=True)