summaryrefslogtreecommitdiffstats
path: root/accounts/__init__.py
diff options
context:
space:
mode:
authorAlexander Sulfrian <alexander@sulfrian.net>2016-01-23 13:04:35 +0100
committerAlexander Sulfrian <alexander@sulfrian.net>2016-01-25 01:56:13 +0100
commit899947bd00df10cca15aca1b3c14125b38b35ecf (patch)
treecbe0cd8023efa657b478476a70f83d2f5cb5509b /accounts/__init__.py
parentbd20d0ff1c7a582f3c53d30bfc387139c419ef35 (diff)
downloadweb-899947bd00df10cca15aca1b3c14125b38b35ecf.tar.gz
web-899947bd00df10cca15aca1b3c14125b38b35ecf.tar.bz2
web-899947bd00df10cca15aca1b3c14125b38b35ecf.zip
Moved everything into a package
Diffstat (limited to 'accounts/__init__.py')
-rw-r--r--accounts/__init__.py301
1 files changed, 301 insertions, 0 deletions
diff --git a/accounts/__init__.py b/accounts/__init__.py
new file mode 100644
index 0000000..8fbcdd0
--- /dev/null
+++ b/accounts/__init__.py
@@ -0,0 +1,301 @@
+# -*- coding: utf-8 -*-
+
+import account
+import ldap
+import os
+from copy import deepcopy
+from flask import flash, Flask, g, redirect, request, session
+from utils import *
+from uuid import uuid4
+
+from views import admin
+
+app = Flask(__name__)
+app.register_blueprint(admin.bp, url_prefix='/admin')
+app.config.from_object('accounts.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.username_blacklist = list()
+
+@app.before_request
+def session_permanent():
+ if app.config.get('PERMANENT_SESSION_LIFETIME'):
+ session.permanent = True
+ else:
+ session.permanent = False
+
+@app.before_request
+def ldap_connect():
+ g.ldap = account.AccountService(app.config['LDAP_HOST'], app.config['LDAP_BASE_DN'],
+ app.config['LDAP_ADMIN_USER'], app.config['LDAP_ADMIN_PASS'], app.all_services)
+
+@app.before_request
+def initialize_user():
+ g.user = None
+
+ if 'username' in session and 'password' in session:
+ username = ensure_utf8(session['username'])
+ password = ensure_utf8(decrypt_password(session['password']))
+ try:
+ g.user = g.ldap.auth(username, password)
+ except ldap.INVALID_CREDENTIALS:
+ # we had crap in the session, delete it
+ logout_user()
+
+@app.before_first_request
+def read_blacklist():
+ if app.config.get('USERNAME_BLACKLIST_FILE'):
+ with open(app.config['USERNAME_BLACKLIST_FILE']) as f:
+ app.username_blacklist = f.read().split('\n')
+
+@app.context_processor
+def template_default_context():
+ return {
+ 'app': app
+ }
+
+
+@app.route('/', methods=['GET', 'POST'])
+@templated('index.html')
+def index():
+ if not g.user:
+ form = LoginForm(request.form, csrf_enabled=False)
+ 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')
+ else:
+ return redirect(url_for('settings'))
+
+ return {'form': form}
+
+
+@app.route('/register', methods=['GET', 'POST'])
+@templated('register.html')
+@logout_required
+def register():
+ form = RegisterForm(request.form, csrf_enabled=False)
+ if request.method == 'POST' and form.validate():
+ send_register_confirmation_mail(form.username.data, form.mail.data)
+
+ 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.', 'success')
+
+ return redirect(url_for('index'))
+
+ return {'form': form}
+
+
+@app.route('/register/<token>', methods=['GET', 'POST'])
+@templated('register_complete.html')
+@logout_required
+def register_complete(token):
+ #TODO: check for double uids and mail
+ username, mail = http_verify_confirmation('register', token.encode('ascii'), timeout=3*24*60*60)
+
+ try:
+ g.ldap.get_by_uid(username)
+ g.ldap.get_by_mail(mail)
+ except account.NoSuchUserError:
+ pass
+ else:
+ flash(u'Du hast den Benutzer bereits angelegt! Du kannst dich jetzt einfach einloggen:')
+ return redirect(url_for('index'))
+
+ form = RegisterCompleteForm(request.form, csrf_enabled=False)
+ 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)
+
+ if app.config.get('MAIL_REGISTER_NOTIFY'):
+ send_mail(
+ app.config['MAIL_REGISTER_NOTIFY'],
+ u'[accounts] Neuer Benutzer %s erstellt' % username,
+ u'Benutzername: %s\nE-Mail: %s\n\nSpammer? Deaktivieren: '
+ u'%s\n' % (username, mail,
+ url_for('admin_disable_account', uid=username, _external=True))
+ )
+
+ flash(u'Benutzer erfolgreich angelegt.', 'success')
+ return redirect(url_for('settings'))
+
+ return {
+ 'form': form,
+ 'token': token,
+ 'username': username,
+ 'mail': mail,
+ }
+
+
+@app.route('/lost_password', methods=['GET', 'POST'])
+@templated('lost_password.html')
+@logout_required
+def lost_password():
+ form = LostPasswordForm(request.form, csrf_enabled=False)
+ if request.method == 'POST' and form.validate():
+ #TODO: make the link only usable once (e.g include a hash of the old pw)
+ # atm the only thing we do is make the link valid for only little time
+ confirm_token = make_confirmation('lost_password', (form.user.uid,))
+ confirm_link = url_for('lost_password_complete', token=confirm_token, _external=True)
+
+ body = render_template('mail/lost_password.txt', username=form.user.uid,
+ link=confirm_link)
+
+ send_mail(form.user.attributes['mail'], u'Passwort vergessen', body,
+ sender=app.config.get('MAIL_CONFIRM_SENDER'))
+
+ flash(u'Wir haben dir eine E-Mail mit einem Link zum Passwort ändern '
+ u'geschickt. Bitte folge den Anweisungen in der E-Mail.', 'success')
+
+ return redirect(url_for('index'))
+
+ return {'form': form}
+
+
+@app.route('/lost_password/<token>', methods=['GET', 'POST'])
+@templated('lost_password_complete.html')
+@logout_required
+def lost_password_complete(token):
+ username, = http_verify_confirmation('lost_password', token.encode('ascii'), timeout=4*60*60)
+
+ form = RegisterCompleteForm(request.form, csrf_enabled=False)
+ if request.method == 'POST' and form.validate():
+ user = g.ldap.get_by_uid(username)
+ user.change_password(form.password.data)
+ g.ldap.update(user, as_admin=True)
+
+ session['username'] = username
+ session['password'] = encrypt_password(form.password.data)
+ flash(u'Passwort geändert.', 'success')
+
+ return redirect(url_for('settings'))
+
+ return {
+ 'form': form,
+ 'token': token,
+ 'username': username,
+ }
+
+
+@app.route('/settings', methods=['GET', 'POST'])
+@templated('settings.html')
+@login_required
+def settings():
+ form = SettingsForm(request.form, mail=g.user.attributes['mail'])
+ if request.method == 'POST' and form.validate():
+ changed = False
+
+ if request.form.get('submit_services'):
+ for service in app.all_services:
+ field = form.get_servicedelete(service.id)
+ if(field.data):
+ g.user.reset_password(service.id)
+ changed = True
+
+ elif request.form.get('submit_main'):
+ if form.mail.data and form.mail.data != g.user.attributes['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.', 'success')
+ changed = True
+
+ if form.password.data:
+ g.user.change_password(form.password.data, form.old_password.data)
+ 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, None, service.id)
+
+ if changed:
+ g.ldap.update(g.user, as_admin=True) #XXX: as_admin wieder wegmachen sobald ACLs richtig gesetzt sind
+ 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/<token>')
+@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.')
+
+ results = g.ldap.find_by_mail(mail)
+ for user in results:
+ if user.uid != g.user.uid:
+ raise Forbidden(u'Diese E-Mail-Adresse wird schon von einem anderen account benutzt!')
+
+ 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('/about')
+@templated('about.html')
+def about():
+ return {}
+
+
+@app.errorhandler(403)
+@app.errorhandler(404)
+def errorhandler(e):
+ return render_template('error.html', error=e), e.code
+
+
+@app.route('/debug')
+def debug():
+ raise Exception()
+
+
+# we need the app to exist before initializing the forms
+from forms import RegisterForm, RegisterCompleteForm, LoginForm, SettingsForm,\
+ LostPasswordForm, AdminCreateAccountForm,\
+ AdminDisableAccountForm
+
+
+if __name__ == '__main__':
+ app.run()