diff options
-rw-r--r-- | app.py | 35 | ||||
-rw-r--r-- | forms.py | 12 | ||||
-rw-r--r-- | templates/index.html | 2 | ||||
-rw-r--r-- | templates/register.html | 2 | ||||
-rw-r--r-- | templates/settings.html | 4 | ||||
-rw-r--r-- | utils.py | 7 |
6 files changed, 49 insertions, 13 deletions
@@ -4,6 +4,7 @@ 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 templated, login_required, encrypt_password, decrypt_password, login_user, logout_user @@ -20,6 +21,8 @@ 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'])) @@ -50,7 +53,15 @@ def register(): username = form.username.data mail = form.mail.data password = form.password.data - return '<h1>501 Not Implemented</h1>' + + user = Account(form.username.data, form.mail.data, password=form.password.data) + service.register(user) + + # populate request context and session + assert login_user(user.username, user.password) + + flash(u'Benutzer erfolgreich angelegt.') + redirect(url_for('settings')) return {'form': form} @@ -62,8 +73,26 @@ def register(): def settings(): form = SettingsForm(request.form, mail=g.user.mail) if request.method == 'POST' and form.validate(): - flash(u'Gespeichert. Nicht.') - return redirect(url_for('index')) + 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} @@ -1,15 +1,15 @@ # -*- coding: utf-8 -*- from flask.ext.wtf import Form, validators, TextField, PasswordField +from utils import _username_re -username = TextField('Benutzername', [validators.Length(min=4, max=20)]) -mail = TextField('E-Mail-Adresse', [validators.Email(), validators.Length(min=6, max=50)]) +username = TextField('Benutzername', [validators.Regexp(_username_re, message=u'Benutzername darf nur aus a-z bestehen (2-16 Zeichen)')]) class RegisterForm(Form): username = username password = PasswordField('Passwort', [validators.Required(), validators.EqualTo('password_confirm', message=u'Passwörter stimmen nicht überein')]) password_confirm = PasswordField(u'Passwort bestätigen') - mail = mail + mail = TextField('E-Mail-Adresse', [validators.Email(), validators.Length(min=6, max=50)]) class LoginForm(Form): @@ -18,8 +18,8 @@ class LoginForm(Form): class SettingsForm(Form): - old_password = PasswordField('Passwort', [validators.Required()]) - password = PasswordField('Neues Passwort', [validators.Required(), + old_password = PasswordField('Passwort', [validators.Required(u'Bitte gib dein (altes) Passwort an, um deine Daten zu ändern.')]) + password = PasswordField('Neues Passwort', [validators.Optional(), validators.EqualTo('password_confirm', message=u'Passwörter stimmen nicht überein')]) password_confirm = PasswordField(u'Passwort bestätigen') - mail = mail + mail = TextField('E-Mail-Adresse', [validators.Optional(), validators.Email(), validators.Length(min=6, max=50)]) diff --git a/templates/index.html b/templates/index.html index 9177dea..6147883 100644 --- a/templates/index.html +++ b/templates/index.html @@ -6,7 +6,7 @@ <p>Hallo {{ session.username }}. <a href="{{ url_for('settings') }}">Einstellungen</a></p> {%- else %} <p><a href="/register">Account erstellen</a></p> -<form action="" method="post"> +<form action="{{ url_for('index') }}" method="post"> <dl> {{ render_field(form.username) }} {{ render_field(form.password) }} diff --git a/templates/register.html b/templates/register.html index f39c4a9..658f8d1 100644 --- a/templates/register.html +++ b/templates/register.html @@ -2,7 +2,7 @@ {%- from '_macros.html' import render_field %} {%- set title = 'Account erstellen' %} {%- block content %} -<form action="" method="post"> +<form action="{{ url_for('register') }}" method="post"> <dl> {{ render_field(form.username) }} {{ render_field(form.mail) }} diff --git a/templates/settings.html b/templates/settings.html index de7f898..29391b2 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -1,8 +1,8 @@ {%- extends 'base.html' %} {%- from '_macros.html' import render_field %} -{%- set title = 'Account erstellen' %} +{%- set title = 'Einstellungen' %} {%- block content %} -<form action="" method="post"> +<form action="{{ url_for('settings') }}" method="post"> <h2>Globale Einstellungen ändern</h2> <p> <dl> @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- import ldap +import re from functools import wraps from flask import flash, g, redirect, render_template, request, session, url_for from random import randint @@ -8,6 +9,8 @@ from werkzeug.exceptions import Forbidden +_username_re = re.compile(r'^[a-z]{2,16}') + # using http://flask.pocoo.org/docs/patterns/viewdecorators/ def templated(template=None): def templated_(f): @@ -50,6 +53,7 @@ def login_user(username, password): def logout_user(): session.pop('username', None) session.pop('password', None) + g.user = None def pad(s, numbytes=32, padding='\0'): @@ -62,6 +66,9 @@ def encrypt_password(password): """ assert len(app.config['PASSWORD_ENCRYPTION_KEY']) == 32 + if isinstance(password, unicode): + password = password.encode('utf8') + iv = ''.join(chr(randint(0, 0xff)) for i in range(16)) encryptor = AES.new(app.config['PASSWORD_ENCRYPTION_KEY'], AES.MODE_CBC, iv) return iv + encryptor.encrypt(pad(password)) |