diff options
author | Pavlos Ratis <dastergon@gentoo.org> | 2013-08-17 13:31:32 +0200 |
---|---|---|
committer | Theo Chatzimichos <tampakrap@gentoo.org> | 2013-08-17 13:31:32 +0200 |
commit | 5a02c06cc07dfb09e61445fe5966cc1b300a421a (patch) | |
tree | 9e8dbc70a707427969468eb3bc36a562e315a13c /okupy | |
parent | various minor fixes in login tests (diff) | |
download | identity.gentoo.org-5a02c06cc07dfb09e61445fe5966cc1b300a421a.tar.gz identity.gentoo.org-5a02c06cc07dfb09e61445fe5966cc1b300a421a.tar.bz2 identity.gentoo.org-5a02c06cc07dfb09e61445fe5966cc1b300a421a.zip |
Add support for secondary password
Using OkupyCipher I generate a new random secondary password and I add it to
the session. This feature improves user experience and prevents user
from submitting password all time.
Diffstat (limited to 'okupy')
-rw-r--r-- | okupy/accounts/views.py | 17 | ||||
-rw-r--r-- | okupy/common/ldap_helpers.py | 47 |
2 files changed, 62 insertions, 2 deletions
diff --git a/okupy/accounts/views.py b/okupy/accounts/views.py index 9b069b6..9502b8b 100644 --- a/okupy/accounts/views.py +++ b/okupy/accounts/views.py @@ -29,7 +29,8 @@ from urlparse import urljoin, urlparse, parse_qsl from .forms import LoginForm, SSLCertLoginForm, OTPForm, SignupForm, SiteAuthForm from .models import LDAPUser, OpenID_Attributes, Queue from .openid_store import DjangoDBOpenIDStore -from ..common.ldap_helpers import get_ldap_connection +from ..common.ldap_helpers import (get_ldap_connection, set_secondary_password, + remove_secondary_password) from ..common.crypto import cipher from ..common.exceptions import OkupyError from ..common.log import log_extra_data @@ -134,6 +135,12 @@ def login(request): _login(request, user) # prepare devices, and see if OTP is enabled init_otp(request) + try: + set_secondary_password(request=request, password=password) + except Exception as error: + logger.critical(error, extra=log_extra_data(request)) + logger_mail.exception(error) + raise OkupyError("Can't contact LDAP server") if request.user.is_authenticated(): if request.user.is_verified(): return redirect(next) @@ -220,7 +227,13 @@ def ssl_auth(request): def logout(request): """ The logout page """ - _logout(request) + try: + remove_secondary_password(request) + except Exception as error: + logger.critical(error, extra=log_extra_data(request)) + logger_mail.exception(error) + finally: + _logout(request) return redirect(login) diff --git a/okupy/common/ldap_helpers.py b/okupy/common/ldap_helpers.py index 64c5ae5..b4bf94f 100644 --- a/okupy/common/ldap_helpers.py +++ b/okupy/common/ldap_helpers.py @@ -1,6 +1,14 @@ # vim:fileencoding=utf8:et:ts=4:sts=4:sw=4:ft=python from django.conf import settings + +from base64 import b64encode +from Crypto import Random +from passlib.hash import ldap_md5_crypt + +from .crypto import cipher +from ..accounts.models import LDAPUser + import edpwd import ldap @@ -34,3 +42,42 @@ def get_ldap_connection(request=None, username=None, password=None, conn.simple_bind_s(dn, password) return conn + + +def set_secondary_password(request, password): + """ Generate a secondary passsword and encrypt it in the session """ + settings.DATABASES['ldap']['USER'] = settings.AUTH_LDAP_USER_DN_TEMPLATE \ + % {'user': request.user.username} + settings.DATABASES['ldap']['PASSWORD'] = password + + user = LDAPUser.objects.get(username=request.user.username) + + secondary_password = Random.get_random_bytes(48) + request.session['secondary_password'] = cipher.encrypt(secondary_password) + # Clean up possible leftover secondary passwords from the LDAP account + if len(user.password) > 1: + for hash in user.password: + if not ldap_md5_crypt.verify(password, hash): + user.password.remove(hash) + # Add a new generated encrypted password to LDAP + user.password.append(ldap_md5_crypt.encrypt(b64encode(secondary_password))) + user.save() + + +def remove_secondary_password(request): + """ Remove secondary password on logout """ + settings.DATABASES['ldap']['USER'] = settings.AUTH_LDAP_USER_DN_TEMPLATE \ + % {'user': request.user.username} + try: + password = b64encode(cipher.decrypt( + request.session['secondary_password'], 48)) + except KeyError: + return + settings.DATABASES['ldap']['PASSWORD'] = password + + user = LDAPUser.objects.get(username=request.user.username) + if len(user.password) > 1: + for hash in user.password: + if ldap_md5_crypt.verify(password, hash): + user.password.remove(hash) + user.save() |