diff --git a/main/forms.py b/main/forms.py new file mode 100644 index 0000000..bbb713c --- /dev/null +++ b/main/forms.py @@ -0,0 +1,3 @@ +from django.contrib.auth.forms import PasswordChangeForm +class LDAPPasswordChangeForm(PasswordChangeForm): + pass diff --git a/main/models.py b/main/models.py index 7883642..83745fc 100644 --- a/main/models.py +++ b/main/models.py @@ -6,7 +6,7 @@ class LdapUser(ldapdb.models.Model): Class for representing an LDAP user entry. """ # LDAP meta-data - base_dn = "ou=People,dc=neuf,dc=no" + base_dn = "ou=People,dc=neuf,dc=no" # CONFIG object_classes = ['inetOrgPerson', 'posixAccount', 'shadowAccount'] # inetOrgPerson @@ -27,6 +27,11 @@ class LdapUser(ldapdb.models.Model): username = CharField(db_column='uid', primary_key=True) password = CharField(db_column='userPassword') + def set_new_password(self, new_pw): + import passwd + self.password = passwd.ldap_create(new_pw) + self.save() + def __str__(self): return self.username @@ -38,7 +43,7 @@ class LdapGroup(ldapdb.models.Model): Class for representing an LDAP group entry. """ # LDAP meta-data - base_dn = "ou=Groups,dc=neuf,dc=no" + base_dn = "ou=Groups,dc=neuf,dc=no" # CONFIG object_classes = ['posixGroup'] # posixGroup attributes diff --git a/main/passwd.py b/main/passwd.py new file mode 100644 index 0000000..6fd6cff --- /dev/null +++ b/main/passwd.py @@ -0,0 +1,25 @@ +import hashlib +import os +from base64 import encodestring as encode +from base64 import decodestring as decode + +# Ref: +# - http://www.openldap.org/faq/data/cache/347.html +# - http://www.openldap.org/doc/admin24/security.html + +def ldap_create(password, hash_type='ssha'): + # Generate a salted SHA hash + salt = os.urandom(4) + h = hashlib.sha1(password) + h.update(salt) + return "{SSHA}" + encode(h.digest() + salt)[:-1] + +def ldap_validate(challenge_password, password): + # challenge_password is hash from db + # password is the cleartext password. + challenge_bytes = decode(challenge_password[6:]) + digest = challenge_bytes[:20] + salt = challenge_bytes[20:] + hr = hashlib.sha1(password) + hr.update(salt) + return digest == hr.digest() diff --git a/main/views.py b/main/views.py index 1aceb96..5347a00 100644 --- a/main/views.py +++ b/main/views.py @@ -1,12 +1,21 @@ from django.http import HttpResponse from django.shortcuts import render_to_response, get_object_or_404 from django.template import RequestContext +from django.contrib.auth.decorators import login_required + +from models import * # My views +@login_required def index(request): return render_to_response('public/index.html', locals(), context_instance=RequestContext(request)) -def profile(request, username): +@login_required +def profile(request, username=None): + ldap_user = "" + try: + ldap_user = LdapUser.objects.get(username=request.user) + except: + pass + return render_to_response('private/profile.html', locals(), context_instance=RequestContext(request)) - - diff --git a/settings-sample.py b/settings-sample.py index 057ee53..497d5f5 100644 --- a/settings-sample.py +++ b/settings-sample.py @@ -107,14 +107,15 @@ AUTHENTICATION_BACKENDS = ( 'django_auth_ldap.backend.LDAPBackend', 'django.contrib.auth.backends.ModelBackend', ) -# LDAP server URI +# LDAP server URI and BIND_DN, same as db-settings AUTH_LDAP_SERVER_URI = DATABASES['ldap']['NAME'] +AUTH_LDAP_BIND_DN = DATABASES['ldap']['USER'] +AUTH_LDAP_BIND_PASSWORD = DATABASES['ldap']['PASSWORD'] import ldap from django_auth_ldap.config import LDAPSearch, PosixGroupType + # Basic user auth -AUTH_LDAP_BIND_DN = DATABASES['ldap']['USER'] -AUTH_LDAP_BIND_PASSWORD = DATABASES['ldap']['PASSWORD'] AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=People,dc=neuf,dc=no", ldap.SCOPE_ONELEVEL, "(uid=%(user)s)") AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=People,dc=neuf,dc=no" diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..f714b30 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,14 @@ + + + {%block title%}Userinfo{%endblock%} + {%block headinc %} + {%endblock%} + + + {%block content%} + {%endblock%} + + {%block tailinc %} + {%endblock%} + + diff --git a/templates/private/profile.html b/templates/private/profile.html new file mode 100644 index 0000000..9f82bca --- /dev/null +++ b/templates/private/profile.html @@ -0,0 +1,12 @@ + + diff --git a/templates/public/index.html b/templates/public/index.html new file mode 100644 index 0000000..ad3fa74 --- /dev/null +++ b/templates/public/index.html @@ -0,0 +1 @@ +{{request.user}}s profile diff --git a/templates/registration/login.html b/templates/registration/login.html new file mode 100644 index 0000000..cbe358d --- /dev/null +++ b/templates/registration/login.html @@ -0,0 +1,27 @@ +{% extends "base.html" %} +{% load url from future %} + +{% block content %} + +{% if form.errors %} +

Your username and password didn't match. Please try again.

+{% endif %} + +
+{% csrf_token %} + + + + + + + + + +
{{ form.username.label_tag }}{{ form.username }}
{{ form.password.label_tag }}{{ form.password }}
+ + + +
+ +{% endblock %} diff --git a/templates/registration/password_change_form.html b/templates/registration/password_change_form.html new file mode 100644 index 0000000..e69de29 diff --git a/urls.py b/urls.py index 52a4fe2..d6f65eb 100644 --- a/urls.py +++ b/urls.py @@ -1,9 +1,17 @@ from django.conf.urls.defaults import * from django.contrib import admin +from main.forms import LDAPPasswordChangeForm admin.autodiscover() urlpatterns = patterns('', - #(r'^main/', include('neuf-userinfo.main.urls')), (r'^admin/', include(admin.site.urls)), (r'^admin/doc/', include('django.contrib.admindocs.urls')), + (r'^accounts/$', 'main.views.profile'), + (r'^accounts/logout/$', 'django.contrib.auth.views.logout'), + (r'^accounts/password/change$', 'django.contrib.auth.views.password_change', + {'password_change_form': LDAPPasswordChangeForm}), + (r'^accounts/password/change/done$', 'django.contrib.auth.views.password_change_done'), + (r'^accounts/login/$', 'django.contrib.auth.views.login'), + (r'^accounts/(?P)/', 'main.views.profile'), + (r'^$', 'main.views.index'), )