MyHost / src / accounts / backends.py

# -*- coding: utf-8 -*-

"""
Authentication Backends

http://djangosnippets.org/snippets/901/
"""
import os

from django.contrib.auth.models import User, Group
from django.conf import settings
import ldap

class ActiveDirectoryGroupMembershipSSLBackend(object):

    def __init__(self):
        ldap.set_option(ldap.OPT_REFERRALS,0) # DO NOT TURN THIS OFF OR SEARCH WON'T WORK!
        self.ldap_server = ldap.initialize(settings.AD_LDAP_URL)
        # after successful authentication self.ldap_server will be un-bound
        if hasattr(settings, 'AD_CERT_FILE'):
            try:
                ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, settings.AD_CERT_FILE)
            except IOError:
                raise("Did not find AD certificate file at {0}".format(settings.AD_CERT_FILE))
        #self.ldap_server.set_option(ldap.OPT_PROTOCOL_VERSION, 3)

    def authenticate(self,username=None,password=None):
        """
        authenticate the user

        :param username:
        :param password:
        :return: User() or None if not successful
        """
        try:
            if len(password) == 0:
                return None
            bind_dn = "%s@%s" % (username, settings.AD_NT4_DOMAIN)
            self.ldap_server.simple_bind_s(bind_dn, password)
            #self.ldap_server.unbind_s()
            return self.get_or_create_user(username, password)
        except ImportError:
            # fall through authentication if no ldap module there
            pass
        except ldap.INVALID_CREDENTIALS:
            pass

    def get_or_create_user(self, username, password):
        """
        return user obj or create user and copy data from active directory
        :param username: login name
        :param password: the password
        :return: user obj
        """
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:

            try:
                # search
                #result = self.ldap_server.search_ext_s(settings.AD_SEARCH_DN, ldap.SCOPE_SUBTREE,"sAMAccountName=%s" % username,settings.AD_SEARCH_FIELDS)[0][1]
                result = self.ldap_server.search_s(settings.AD_SEARCH_DN, ldap.SCOPE_SUBTREE,"sAMAccountName={0}".format(username))[0][1]
                user_attrs = dict([(key, val[0]) for (key, val) in result.iteritems()])

                # Validate that they are a member of the right department
                if not (user_attrs.has_key('department') and
                   user_attrs['department'] in settings.AD_DEPARTMENT_REQ):
                    return None

                # get email
                if user_attrs.has_key('mail'):
                    mail = result['mail'][0]
                else:
                    mail = None
                if user_attrs.has_key('sn'):
                    last_name = result['sn'][0]
                else:
                    last_name = None

                # get display name
                if result.has_key('givenName'):
                    first_name = result['givenName'][0]
                else:
                    first_name = None


                user = User.objects.create_user(username, email=mail)
                user.first_name=first_name
                user.last_name=last_name

            except Exception, e:
                return None

            user.is_staff = True
            user.is_superuser = False
            # a random password is set automatically
            #user.set_password('ldap authenticated')
            user.save()


            # add user to default group
            #group=Group.objects.get(pk=1)
            #user.groups.add(group)
            #user.save()

        self.ldap_server.unbind_s()
        return user

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.