summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Sulfrian <alexander@sulfrian.net>2012-09-21 02:51:28 +0200
committerAlexander Sulfrian <alexander@sulfrian.net>2012-09-21 02:51:28 +0200
commitd331fc54b448f980fb7806aed99a48651b734037 (patch)
treea3f565d7401b2f5844bc450bdcf2c5cc2a53818f
parent2ef00343d82204755bd1867eff3f7e9776f7a2db (diff)
parent71ce07733bfbfac18e93dfd5fed3b8d513bf5158 (diff)
downloadweb-d331fc54b448f980fb7806aed99a48651b734037.tar.gz
web-d331fc54b448f980fb7806aed99a48651b734037.tar.bz2
web-d331fc54b448f980fb7806aed99a48651b734037.zip
Merge branch 'master' of ssh://git.spline.de/account-web
* 'master' of ssh://git.spline.de/account-web: use AccountService AccountService: expect admin credentials at initialization.
-rw-r--r--account.py64
-rw-r--r--app.py21
-rw-r--r--templates/settings.html2
-rw-r--r--utils.py14
4 files changed, 59 insertions, 42 deletions
diff --git a/account.py b/account.py
index 49051ed..c4fd225 100644
--- a/account.py
+++ b/account.py
@@ -6,7 +6,7 @@ LDAP_HOST = 'ldap://localhost:5678'
LDAP_BASE_DN = 'dc=account,dc=spline,dc=inf,dc=fu-berlin,dc=de'
LDAP_ADMIN_USER = 'admin'
LDAP_ADMIN_PASS = 'admin'
-SERVICES = ['foren','jabber''gitlab']
+SERVICES = ['foren','jabber', 'gitlab']
@@ -35,7 +35,7 @@ class AccountService:
>> service.update(foo) # save changes in ldap backend
# save changes in ldap backend as admin user
>> service.update(foo, LDAP_ADMIN_USER, LDAP_ADMIN_PASS)
-
+
* delete an account
>> service = AccountService(LDAP_HOST, LDAP_BASE_DN,SERVICES)
>> service.delete(Account)
@@ -47,9 +47,11 @@ class AccountService:
>> print([x.uid for x in all_accounts])
"""
- def __init__(self, ldap_host, base_dn, services):
+ def __init__(self, ldap_host, base_dn, admin_user, admin_pass, services):
self.ldap_host = ldap_host
self.base_dn = base_dn
+ self.admin_user = admin_user
+ self.admin_pass = admin_pass
self.services = services
@@ -80,11 +82,11 @@ class AccountService:
return acc
- def find(self, admin_user, admin_pass, filterstr = '(objectClass=*)'):
+ def find(self, filterstr = '(objectClass=*)'):
"""
Find accounts with raw ldap filter syntax
"""
- self._bind('cn=%s,%s' % (admin_user, self.base_dn), admin_pass)
+ self._bind_as_admin()
dn = 'ou=users,%s' % self.base_dn
data = self.connection.search_s(dn,ldap.SCOPE_SUBTREE,filterstr)
@@ -98,11 +100,11 @@ class AccountService:
return accounts
- def register(self, account, admin_user, admin_pass):
+ def register(self, account):
"""
Persists an account in the ldap backend
"""
- self._bind('cn=%s,%s' % (admin_user, self.base_dn), admin_pass)
+ self._bind_as_admin()
dn = 'uid=%s,ou=users,%s' % (account.uid, self.base_dn)
attr = [
@@ -118,19 +120,16 @@ class AccountService:
self._unbind()
- def update(self, account, admin_user = None, admin_pass = None):
+ def update(self, account, as_admin=False):
"""
Updates account informations like passwords or email.
"""
- user = 'uid=%s,ou=users' % account.uid
- if admin_user:
- user = 'cn=%s' % admin_user
-
- password = account.password
- if admin_pass:
- password = admin_pass
-
- self._bind('%s,%s' % (user, self.base_dn), password)
+ if as_admin:
+ self._bind_as_admin()
+ else:
+ user = 'uid=%s,ou=users' % account.uid
+ password = account.password
+ self._bind('%s,%s' % (user, self.base_dn), password)
attr = [(ldap.MOD_REPLACE, 'mail', account.mail)]
dn = 'uid=%s,ou=users,%s' % (account.uid, self.base_dn)
@@ -144,18 +143,16 @@ class AccountService:
"""
Deletes an account permanently.
"""
- try: dn_user = account.dn
- except: dn_user = 'uid=%s,ou=users,%s' % (account, self.base_dn)
- user = dn_user
- if admin_user:
- user = 'cn=%s,%s' % (admin_user, self.base_dn)
-
- password = account.password
- if admin_pass:
- password = admin_pass
+ if as_admin:
+ self._bind_as_admin()
+ else:
+ try: dn_user = account.dn
+ except: dn_user = 'uid=%s,ou=users,%s' % (account, self.base_dn)
+ user = dn_user
- self._bind(user, password)
+ password = account.password
+ self._bind('%s,%s' % (user, self.base_dn), password)
dn = ['uid=%s,cn=%s,ou=services,%s' % (account.uid,s,self.base_dn) for s in account.services]
dn.append(dn_user)
@@ -171,6 +168,9 @@ class AccountService:
self.connection.simple_bind_s(dn, password)
+ def _bind_as_admin():
+ self._bind('cn=%s,%s' % (self.admin_user, self.base_dn), self.admin_pass)
+
def _unbind(self):
self.connection.unbind_s()
@@ -218,9 +218,9 @@ class Account:
def change_password(self, new_password, service = None):
"""
- Changes a password for a given service. You have to use the Ldap class
- to make the changes permanent. If no service is given, the root
- password will be changed.
+ Changes a password for a given service. You have to use the
+ AccountService class to make the changes permanent. If no service is
+ given, the root password will be changed.
"""
if not service:
self.new_password_root = new_password
@@ -230,7 +230,7 @@ class Account:
def change_email(self, new_mail):
"""
- Changes the mail address of an account. You have to use the Ldap class
- to make changes permanent.
+ Changes the mail address of an account. You have to use the
+ AccountService class to make changes permanent.
"""
self.mail = new_mail
diff --git a/app.py b/app.py
index 46ca682..4819a51 100644
--- a/app.py
+++ b/app.py
@@ -3,8 +3,9 @@
import flaskext_compat
flaskext_compat.activate()
+import account
import os
-from flask import Flask, request, redirect, url_for, flash, session
+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
from forms import RegisterForm, LoginForm, SettingsForm
@@ -14,6 +15,18 @@ 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)
+
+ 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')
@@ -21,8 +34,8 @@ 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 (%s)' % session['username'])
- return redirect(url_for('index'))
+ flash(u'Erfolgreich eingeloggt (als %s)' % session['username'])
+ return redirect(url_for('settings'))
else:
flash(u'Ungültiger Benutzername und/oder Passwort', 'error')
@@ -47,7 +60,7 @@ def register():
@templated('settings.html')
@login_required
def settings():
- form = SettingsForm(request.form, mail='mail aus ldap #TODO')
+ form = SettingsForm(request.form, mail=g.user.mail)
if request.method == 'POST' and form.validate():
flash(u'Gespeichert. Nicht.')
return redirect(url_for('index'))
diff --git a/templates/settings.html b/templates/settings.html
index addd137..de7f898 100644
--- a/templates/settings.html
+++ b/templates/settings.html
@@ -24,5 +24,7 @@
{%- else %}
setzen
{%- endif %}
+ </li>
+ {%- endfor %}
</form>
{%- endblock %}
diff --git a/utils.py b/utils.py
index 39d07de..da6d741 100644
--- a/utils.py
+++ b/utils.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
+import ldap
from functools import wraps
-from flask import flash, request, redirect, render_template, session, url_for
+from flask import flash, g, redirect, render_template, request, session, url_for
from random import randint
from Crypto.Cipher import AES
from werkzeug.exceptions import Forbidden
@@ -28,21 +29,21 @@ def templated(template=None):
def login_required(f):
@wraps(f)
def login_required_(*args, **kwargs):
- if 'username' not in session:
+ if not g.user:
raise Forbidden
return f(*args, **kwargs)
return login_required_
def login_user(username, password):
-# if not ldap_bind():
-# return False
+ try:
+ g.user = g.ldap.auth(username, password)
+ except ldap.INVALID_CREDENTIALS:
+ return False
session['username'] = username
session['password'] = encrypt_password(password)
- #ldap_unbind()
-
return True
@@ -74,5 +75,6 @@ def decrypt_password(ciphertext):
return encryptor.decrypt(ciphertext[16:]).rstrip('\0')
+
# circular import
from app import app