From 313cf5d9f5d42a1ec754c3d41e50d982cf6b1f99 Mon Sep 17 00:00:00 2001 From: Nikolai R Kristiansen Date: Sun, 19 Oct 2014 16:34:25 +0200 Subject: [PATCH 1/5] email template update --- templates/registration/password_reset_email.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/registration/password_reset_email.html b/templates/registration/password_reset_email.html index 1acb884..8cf48b1 100644 --- a/templates/registration/password_reset_email.html +++ b/templates/registration/password_reset_email.html @@ -1,2 +1,2 @@ Noen har bedt om at passordet for brukeren {{ user.username }} med epostadresse {{ email }} skal endres. Vennligst følg lenken nedenfor for å sette et nytt passord: -{{ protocol }}://{{ site_name }}{% url "main.views.password_reset_confirm" uidb64=uid token=token %} +{{ protocol }}://{{ domain }}{% url "main.views.password_reset_confirm" uidb64=uid token=token %} From 85f09f7562dcc8a09648b6a97255b914972999d0 Mon Sep 17 00:00:00 2001 From: Nikolai R Kristiansen Date: Sun, 19 Oct 2014 22:34:22 +0200 Subject: [PATCH 2/5] deploy fix --- scripts/push_active_to_wordpress.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/push_active_to_wordpress.py b/scripts/push_active_to_wordpress.py index ab5566e..8695489 100644 --- a/scripts/push_active_to_wordpress.py +++ b/scripts/push_active_to_wordpress.py @@ -4,7 +4,7 @@ from django.conf import settings from main.models import * -PHP_SCRIPT_PATH = '/opt/django/neuf-userinfo/scripts' +PHP_SCRIPT_PATH = '/var/www/neuf.no/userinfo/scripts' OUT_FILENAME = os.path.join(PHP_SCRIPT_PATH,"users_in_group_active.json") usernames = LdapGroup.objects.get(name="dns-aktiv").usernames From 986df794ef8f66ee6b8f69c1d4a56cb8624dd9a7 Mon Sep 17 00:00:00 2001 From: Nikolai R Kristiansen Date: Sun, 2 Nov 2014 16:54:59 +0100 Subject: [PATCH 3/5] Minor --- scripts/import_users.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/import_users.php b/scripts/import_users.php index 42a0049..6ca7ee9 100644 --- a/scripts/import_users.php +++ b/scripts/import_users.php @@ -1,6 +1,6 @@ get_error_message()."(username: $username)"); continue; } - _log("[$site_name][new] $user_id : $username,$first_name,$last_name,$email\n"); + _log("[$site_name][new] $user_id : $username,$first_name,$last_name,$email"); /* LDAP login flag */ $flagged = add_user_meta( $user_id, "wpDirAuthFlag", "1"); if( !$flagged ) { - _log("$user_id not flagged\n"); + _log("$user_id not flagged"); } } } From c79a6f428280298faf86b8613750a81156e8faed Mon Sep 17 00:00:00 2001 From: Nikolai R Kristiansen Date: Mon, 3 Nov 2014 23:21:44 +0100 Subject: [PATCH 4/5] Adds LDAP email auth, testdata, readme upd --- README | 10 +++--- main/backends.py | 30 ++++++++++++++++ test/testdata.ldif | 63 +++++++++++++++++++++++++++++++++ userinfosite/settings-sample.py | 47 +++++++++++++++--------- 4 files changed, 129 insertions(+), 21 deletions(-) create mode 100644 main/backends.py create mode 100644 test/testdata.ldif diff --git a/README b/README index 2246116..aa7b084 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ # Installation - apt-get install libldap2-dev python-dev libmysqlclient-dev libsasl2-dev libldap2-dev libssl-dev + apt-get install libldap2-dev python-dev libmysqlclient-dev libsasl2-dev libldap2-dev libssl-dev ldap-utils virtualenv venv . venv/bin/activate pip install -r requirements.txt @@ -10,9 +10,11 @@ python manage.py syncdb --database=radius python manage.py runserver -# Apache: - - Make a Vhost - - add WSGIScriptAlias / /path/to/project/neuf-userinfo/userinfosite/wsgi.py +## LDAP + sudo docker run -e LDAP_DOMAIN=neuf.no -e LDAP_ORGANISATION="Neuf" -e LDAP_ROOTPASS="toor" -p 389:389 -d osixia/openldap + ldapadd -D "cn=admin,dc=neuf,dc=no" -w "toor" -f testdata.ldif + # Verify import + ldapsearch -x -b dc=neuf,dc=no # External dependencies: - LDAP: Read the tutorial on [Howto setup a LDAP server with Docker](https://edb.neuf.no/wiki/index.php?title=Howto_setup_a_LDAP_server_with_Docker) diff --git a/main/backends.py b/main/backends.py new file mode 100644 index 0000000..860e1cd --- /dev/null +++ b/main/backends.py @@ -0,0 +1,30 @@ +from django_auth_ldap.backend import LDAPBackend, _LDAPUser + + +class LDAPUsernameBackend(LDAPBackend): + settings_prefix = "AUTH_LDAP_U_" + + +class LDAPEmailBackend(LDAPBackend): + settings_prefix = "AUTH_LDAP_E_" + + def get_or_create_user(self, email, ldap_user): + """ + Use the PosixUser uid field as username instead of email. + + This must return a (User, created) 2-tuple for the given LDAP user. + username is the Django-friendly username of the user. ldap_user.dn is + the user's DN and ldap_user.attrs contains all of their LDAP attributes. + """ + model = self.get_user_model() + username_field = getattr(model, 'USERNAME_FIELD', 'username') + + kwargs = { + username_field + '__iexact': ldap_user.attrs['uid'][0], + 'defaults': { + username_field: ldap_user.attrs['uid'][0].lower(), + 'email': email + } + } + + return model.objects.get_or_create(**kwargs) \ No newline at end of file diff --git a/test/testdata.ldif b/test/testdata.ldif new file mode 100644 index 0000000..472a6ee --- /dev/null +++ b/test/testdata.ldif @@ -0,0 +1,63 @@ +# Root dn for all user accounts +dn: ou=People,dc=neuf,dc=no +objectClass: top +objectClass: organizationalUnit +ou: People + +# Account test with password "test" +dn: uid=test,ou=People,dc=neuf,dc=no +objectClass: inetOrgPerson +objectClass: posixAccount +objectClass: shadowAccount +uid: testesen +gecos: testesen +loginShell: /bin/bash +shadowExpire: -1 +shadowFlag: 0 +shadowWarning: 7 +shadowMin: 8 +shadowMax: 999999 +homeDirectory: /home/test +uidNumber: 1002 +gidNumber: 10005 +displayName: Test Testesen +cn: Test Testesen +sn: Testesen +givenName: Test +mail: test@example.com +userPassword: {SSHA}I3aQhofsUZi+TfWdOPhkr70GJ2FwuSv4 + +# Root dn for all groups +dn: ou=Groups,dc=neuf,dc=no +objectClass: top +objectClass: organizationalUnit +ou: Groups + +# Private group +dn: cn=test,ou=Groups,dc=neuf,dc=no +objectClass: posixGroup +cn: test +gidNumber: 10005 +description: Group account + +# Sample groups (matches settings-sample.py) +dn: cn=dns-alle,ou=Groups,dc=neuf,dc=no +objectClass: posixGroup +cn: dns-alle +gidNumber: 1 +description: Group account +memberUid: test + +dn: cn=edb,ou=Groups,dc=neuf,dc=no +objectClass: posixGroup +cn: edb +gidNumber: 2 +description: Group account +memberUid: test + +dn: cn=edbadmin,ou=Groups,dc=neuf,dc=no +objectClass: posixGroup +cn: edbadmin +gidNumber: 3 +description: Group account +memberUid: test diff --git a/userinfosite/settings-sample.py b/userinfosite/settings-sample.py index c4a60c6..72f201a 100644 --- a/userinfosite/settings-sample.py +++ b/userinfosite/settings-sample.py @@ -131,7 +131,8 @@ EMAIL_PORT = 25 DEFAULT_FROM_EMAIL = 'noreply@neuf.no' AUTHENTICATION_BACKENDS = ( - 'django_auth_ldap.backend.LDAPBackend', + 'main.backends.LDAPEmailBackend', + 'main.backends.LDAPUsernameBackend', 'django.contrib.auth.backends.ModelBackend', ) # No cleaningladies. @@ -139,46 +140,58 @@ SESSION_EXPIRE_AT_BROWSER_CLOSE = True SESSION_COOKIE_AGE = 60 * 15 # in seconds # 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'] +AUTH_LDAP_U_SERVER_URI = DATABASES['ldap']['NAME'] +AUTH_LDAP_U_BIND_DN = DATABASES['ldap']['USER'] +AUTH_LDAP_U_BIND_PASSWORD = DATABASES['ldap']['PASSWORD'] import ldap from django_auth_ldap.config import LDAPSearch, PosixGroupType # Basic user auth -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" +AUTH_LDAP_U_USER_SEARCH = LDAPSearch("ou=People,dc=neuf,dc=no", ldap.SCOPE_ONELEVEL, "(uid=%(user)s)") # Basic groups -AUTH_LDAP_GROUP_SEARCH = LDAPSearch("ou=Groups,dc=neuf,dc=no", - ldap.SCOPE_ONELEVEL, "(objectClass=posixGroup)" -) -AUTH_LDAP_GROUP_TYPE = PosixGroupType() +AUTH_LDAP_U_GROUP_SEARCH = LDAPSearch("ou=Groups,dc=neuf,dc=no", ldap.SCOPE_ONELEVEL, "(objectClass=posixGroup)") +AUTH_LDAP_U_GROUP_TYPE = PosixGroupType() # Mirror groups on each auth -AUTH_LDAP_MIRROR_GROUPS = True +AUTH_LDAP_U_MIRROR_GROUPS = True # Group to user flag mappings -AUTH_LDAP_USER_FLAGS_BY_GROUP = { +AUTH_LDAP_U_USER_FLAGS_BY_GROUP = { "is_active": "cn=dns-alle,ou=Groups,dc=neuf,dc=no", "is_staff": "cn=edb,ou=Groups,dc=neuf,dc=no", "is_superuser": "cn=edbadmin,ou=Groups,dc=neuf,dc=no" } # Group to profile flag mappings, not used. -AUTH_LDAP_PROFILE_FLAGS_BY_GROUP = { +AUTH_LDAP_U_PROFILE_FLAGS_BY_GROUP = { #"is_edb": "cn=edb,ou=Groups,dc=neuf,dc=no" } # User attribute mappings -AUTH_LDAP_USER_ATTR_MAP = { +AUTH_LDAP_U_USER_ATTR_MAP = { "first_name": "givenName", "last_name": "sn", "email": "mail", } # User profile attribute mappings -AUTH_LDAP_PROFILE_ATTR_MAP = { +AUTH_LDAP_U_PROFILE_ATTR_MAP = { "home_directory": "homeDirectory" } # Allways update the django user object on authentication. -AUTH_LDAP_ALWAYS_UPDATE_USER = True +AUTH_LDAP_U_ALWAYS_UPDATE_USER = True + +# Email LDAP auth +AUTH_LDAP_E_SERVER_URI = AUTH_LDAP_U_SERVER_URI +AUTH_LDAP_E_BIND_DN = AUTH_LDAP_U_BIND_DN +AUTH_LDAP_E_BIND_PASSWORD = AUTH_LDAP_U_BIND_PASSWORD + +AUTH_LDAP_E_USER_SEARCH = LDAPSearch("ou=People,dc=neuf,dc=no", ldap.SCOPE_ONELEVEL, "(mail=%(user)s)") + +AUTH_LDAP_E_GROUP_SEARCH = AUTH_LDAP_U_GROUP_SEARCH +AUTH_LDAP_E_GROUP_TYPE = AUTH_LDAP_U_GROUP_TYPE +AUTH_LDAP_E_MIRROR_GROUPS = AUTH_LDAP_U_MIRROR_GROUPS +AUTH_LDAP_E_USER_FLAGS_BY_GROUP = AUTH_LDAP_U_USER_FLAGS_BY_GROUP +AUTH_LDAP_E_PROFILE_FLAGS_BY_GROUP = AUTH_LDAP_U_PROFILE_FLAGS_BY_GROUP +AUTH_LDAP_E_USER_ATTR_MAP = AUTH_LDAP_U_USER_ATTR_MAP +AUTH_LDAP_E_PROFILE_ATTR_MAP = AUTH_LDAP_U_PROFILE_ATTR_MAP +AUTH_LDAP_E_ALWAYS_UPDATE_USER = AUTH_LDAP_U_ALWAYS_UPDATE_USER # Debug logging import logging From ed6152fb3a5434395fe03fc07ee1b584936fc21c Mon Sep 17 00:00:00 2001 From: Nikolai R Kristiansen Date: Mon, 3 Nov 2014 23:46:01 +0100 Subject: [PATCH 5/5] Template update --- templates/registration/login_form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/registration/login_form.html b/templates/registration/login_form.html index 44c3ea2..b877748 100644 --- a/templates/registration/login_form.html +++ b/templates/registration/login_form.html @@ -7,7 +7,7 @@ {% csrf_token %}
- +
{{ form.username }} {{ form.username.errors }}