Example #1
0
def ldap_create_user(user_info):
    """takes the result returned by the :func:`ldap_authenticate`

    and returns a :class:`UserAssociation` object
    """
    # create new user in local db
    user = User()
    user.username = user_info.get('django_username', user_info['ldap_username'])
    user.set_unusable_password()
    user.first_name = user_info['first_name']
    user.last_name = user_info['last_name']
    user.email = user_info['email']
    user.is_staff = False
    user.is_superuser = False
    user.is_active = True
    user.save()
    user_registered.send(None, user = user)
    LOG.info('Created New User : [{0}]'.format(user_info['ldap_username']))

    assoc = UserAssociation()
    assoc.user = user
    assoc.openid_url = user_info['ldap_username']
    assoc.provider_name = 'Wind River LDAP'
    assoc.save()
    return assoc
Example #2
0
def cas_get_or_create_user(cas_response):
    """takes the result returned by the :func:`ldap_authenticate`
    
    and returns a :class:`UserAssociation` object
    """
    # create new user in local db
    try:
        logging.debug("Getting user association for %s", cas_response.get('user'))
        assoc = UserAssociation.objects.get(
            openid_url = cas_response.get('user') + '@ldap',
            provider_name = 'ldap'
        )
        return assoc
    except UserAssociation.DoesNotExist:

        try:
            user = User.objects.get(username=cas_response.get('user'))
        except User.DoesNotExist:

            user = User()
        user.username = cas_response.get('django_username', cas_response.get('user'))
        user.set_unusable_password()

        user.first_name = cas_response['attributes'].get('firstName', None)

        user.last_name = cas_response['attributes'].get('lastName', None)

        user.email = cas_response['attributes'].get('email', None)
        user.is_staff = False
        user.is_superuser = False
        user.is_active = True
        user.save()
        user_registered.send(None, user = user)
        logging.debug('Created New User : [{0}]'.format(cas_response.get('user')))

        assoc = UserAssociation()
        assoc.user = user
        assoc.openid_url = cas_response.get('user') + '@ldap'
        assoc.provider_name = 'ldap'
        assoc.save()
        return assoc
Example #3
0
def create_authenticated_user_account(
    username=None, email=None, password=None,
    user_identifier=None, login_provider_name=None, subscribe=False
):
    """creates a user account, user association with
    the login method and the the default email subscriptions
    """

    user = User.objects.create_user(username, email)
    user_registered.send(None, user=user)
    
    logging.debug('creating new openid user association for %s')

    if password:
        user.set_password(password)
        user.save()
    else:
        UserAssociation(
            openid_url = user_identifier,
            user = user,
            provider_name = login_provider_name,
            last_used_timestamp = datetime.datetime.now()
        ).save()

    subscribe_form = askbot_forms.SimpleEmailSubscribeForm(
                                        {'subscribe': subscribe}
                                    )
    subscribe_form.full_clean()
    logging.debug('saving email feed settings')
    subscribe_form.save(user)

    logging.debug('logging the user in')
    user = authenticate(method='force', user_id=user.id)
    if user is None:
        error_message = 'please make sure that ' + \
                        'askbot.deps.django_authopenid.backends.AuthBackend' + \
                        'is in your settings.AUTHENTICATION_BACKENDS'
        raise Exception(error_message)

    return user
Example #4
0
def create_authenticated_user_account(username=None,
                                      email=None,
                                      password=None,
                                      user_identifier=None,
                                      login_provider_name=None,
                                      subscribe=False):
    """creates a user account, user association with
    the login method and the the default email subscriptions
    """

    user = User.objects.create_user(username, email)
    user_registered.send(None, user=user)

    logging.debug('creating new openid user association for %s')

    if password:
        user.set_password(password)
        user.save()
    else:
        UserAssociation(openid_url=user_identifier,
                        user=user,
                        provider_name=login_provider_name,
                        last_used_timestamp=datetime.datetime.now()).save()

    subscribe_form = askbot_forms.SimpleEmailSubscribeForm(
        {'subscribe': subscribe})
    subscribe_form.full_clean()
    logging.debug('saving email feed settings')
    subscribe_form.save(user)

    logging.debug('logging the user in')
    user = authenticate(method='force', user_id=user.id)
    if user is None:
        error_message = 'please make sure that ' + \
                        'askbot.deps.django_authopenid.backends.AuthBackend' + \
                        'is in your settings.AUTHENTICATION_BACKENDS'
        raise Exception(error_message)

    return user
Example #5
0
def ldap_authenticate(username, password):
    """
    Authenticate using ldap
    
    python-ldap must be installed
    http://pypi.python.org/pypi/python-ldap/2.4.6
    """
    import ldap
    user_information = None
    try:
        ldap_session = ldap.initialize(askbot_settings.LDAP_URL)
        ldap_session.protocol_version = ldap.VERSION3
        user_filter = "({0}={1})".format(askbot_settings.LDAP_USERID_FIELD, 
                                         username)
        # search ldap directory for user
        res = ldap_session.search_s(askbot_settings.LDAP_BASEDN, ldap.SCOPE_SUBTREE, user_filter, None)
        if res: # User found in LDAP Directory
            user_dn = res[0][0]
            user_information = res[0][1]
            ldap_session.simple_bind_s(user_dn, password) # <-- will throw  ldap.INVALID_CREDENTIALS if fails
            ldap_session.unbind_s()
            
            exact_username = user_information[askbot_settings.LDAP_USERID_FIELD][0]
            
            # Assuming last, first order
            # --> may be different
            last_name, first_name = user_information[askbot_settings.LDAP_COMMONNAME_FIELD][0].rsplit(" ", 1)
            email = user_information[askbot_settings.LDAP_EMAIL_FIELD][0]
            try:
                user = User.objects.get(username__exact=exact_username)
                # always update user profile to synchronize with ldap server
                user.set_password(password)
                user.first_name = first_name
                user.last_name = last_name
                user.email = email
                user.save()
            except User.DoesNotExist:
                # create new user in local db
                user = User()
                user.username = exact_username
                user.set_password(password)
                user.first_name = first_name
                user.last_name = last_name
                user.email = email
                user.is_staff = False
                user.is_superuser = False
                user.is_active = True
                user.save()
                user_registered.send(None, user = user)

                log.info('Created New User : [{0}]'.format(exact_username))
            return user
        else:
            # Maybe a user created internally (django admin user)
            try:
                user = User.objects.get(username__exact=username)
                if user.check_password(password):
                    return user
                else:
                    return None
            except User.DoesNotExist:
                return None 

    except ldap.INVALID_CREDENTIALS, e:
        return None # Will fail login on return of None
Example #6
0
    def authenticate(
                self,
                username = None,#for 'password' and 'ldap'
                password = None,#for 'password' and 'ldap'
                user_id = None,#for 'force'
                provider_name = None,#required with all except email_key
                openid_url = None,
                email_key = None,
                oauth_user_id = None,#used with oauth
                facebook_user_id = None,#user with facebook
                wordpress_url = None, # required for self hosted wordpress
                wp_user_id = None, # required for self hosted wordpress
                method = None,#requried parameter
            ):
        """this authentication function supports many login methods
        just which method it is going to use it determined
        from the signature of the function call
        """
        login_providers = util.get_enabled_login_providers()
        assoc = None # UserAssociation not needed for ldap
        if method == 'password':
            if login_providers[provider_name]['type'] != 'password':
                raise ImproperlyConfigured('login provider must use password')
            if provider_name == 'local':
                try:
                    user = User.objects.get(username=username)
                    if not user.check_password(password):
                        return None
                except User.DoesNotExist:
                    try:
                        email_address = username
                        user = User.objects.get(email = email_address)
                        if not user.check_password(password):
                            return None
                    except User.DoesNotExist:
                        return None
                    except User.MultipleObjectsReturned:
                        logging.critical(
                            ('have more than one user with email %s ' +
                            'he/she will not be able to authenticate with ' +
                            'the email address in the place of user name') % email_address
                        )
                        return None
            else:
                if login_providers[provider_name]['check_password'](username, password):
                    try:
                        #if have user associated with this username and provider,
                        #return the user
                        assoc = UserAssociation.objects.get(
                                        openid_url = username + '@' + provider_name,#a hack - par name is bad
                                        provider_name = provider_name
                                    )
                        return assoc.user
                    except UserAssociation.DoesNotExist:
                        #race condition here a user with this name may exist
                        user, created = User.objects.get_or_create(username = username)
                        if created:
                            user.set_password(password)
                            user.save()
                            user_registered.send(None, user = user)
                        else:
                            #have username collision - so make up a more unique user name
                            #bug: - if user already exists with the new username - we are in trouble
                            new_username = '******' % (username, provider_name)
                            user = User.objects.create_user(new_username, '', password)
                            user_registered.send(None, user = user)
                            message = _(
                                'Welcome! Please set email address (important!) in your '
                                'profile and adjust screen name, if necessary.'
                            )
                            user.message_set.create(message = message)
                else:
                    return None

            #this is a catch - make login token a little more unique
            #for the cases when passwords are the same for two users
            #from the same provider
            try:
                assoc = UserAssociation.objects.get(
                                            user = user,
                                            provider_name = provider_name
                                        )
            except UserAssociation.DoesNotExist:
                assoc = UserAssociation(
                                    user = user,
                                    provider_name = provider_name
                                )
            assoc.openid_url = username + '@' + provider_name#has to be this way for external pw logins

        elif method == 'openid':
            provider_name = util.get_provider_name(openid_url)
            try:
                assoc = UserAssociation.objects.get(
                                            openid_url = openid_url,
                                            provider_name = provider_name
                                        )
                user = assoc.user
            except UserAssociation.DoesNotExist:
                return None

        elif method == 'email':
            #with this method we do no use user association
            try:
                #todo: add email_key_timestamp field
                #and check key age
                user = User.objects.get(email_key = email_key)
                user.email_key = None #one time key so delete it
                user.email_isvalid = True
                user.save()
                return user
            except User.DoesNotExist:
                return None

        elif method == 'oauth':
            if login_providers[provider_name]['type'] == 'oauth':
                try:
                    assoc = UserAssociation.objects.get(
                                                openid_url = oauth_user_id,
                                                provider_name = provider_name
                                            )
                    user = assoc.user
                except UserAssociation.DoesNotExist:
                    return None
            else:
                return None

        elif method == 'facebook':
            try:
                #assert(provider_name == 'facebook')
                assoc = UserAssociation.objects.get(
                                            openid_url = facebook_user_id,
                                            provider_name = 'facebook'
                                        )
                user = assoc.user
            except UserAssociation.DoesNotExist:
                return None

        elif method == 'ldap':
            user = ldap_authenticate(username, password)

        elif method == 'wordpress_site':
            try:
                custom_wp_openid_url = '%s?user_id=%s' % (wordpress_url, wp_user_id)
                assoc = UserAssociation.objects.get(
                                            openid_url = custom_wp_openid_url,
                                            provider_name = 'wordpress_site'
                                            )
                user = assoc.user
            except UserAssociation.DoesNotExist:
                return None
        elif method == 'force':
            return self.get_user(user_id)
        else:
            raise TypeError('only openid and password supported')

        if assoc:
            #update last used time
            assoc.last_used_timestamp = datetime.datetime.now()
            assoc.save()
        return user
Example #7
0
def signup_with_password(request):
    """Create a password-protected account
    template: authopenid/signup_with_password.html
    """

    logging.debug(get_request_info(request))
    next = get_next_url(request)
    login_form = forms.LoginForm(initial={'next': next})
    #this is safe because second decorator cleans this field
    provider_name = request.REQUEST['login_provider']

    if askbot_settings.USE_RECAPTCHA:
        RegisterForm = forms.SafeClassicRegisterForm
    else:
        RegisterForm = forms.ClassicRegisterForm

    logging.debug('request method was %s' % request.method)
    if request.method == 'POST':
        form = RegisterForm(request.POST)
        email_feeds_form = askbot_forms.SimpleEmailSubscribeForm(request.POST)

        #validation outside if to remember form values
        logging.debug('validating classic register form')
        form1_is_valid = form.is_valid()
        if form1_is_valid:
            logging.debug('classic register form validated')
        else:
            logging.debug('classic register form is not valid')
        form2_is_valid = email_feeds_form.is_valid()
        if form2_is_valid:
            logging.debug('email feeds form validated')
        else:
            logging.debug('email feeds form is not valid')
        if form1_is_valid and form2_is_valid:
            logging.debug('both forms are valid')
            next = form.cleaned_data['next']
            username = form.cleaned_data['username']
            password = form.cleaned_data['password1']
            email = form.cleaned_data['email']
            provider_name = form.cleaned_data['login_provider']

            new_user = User.objects.create_user(username, email, password)
            user_registered.send(None, user=new_user)

            logging.debug('new user %s created' % username)
            if provider_name != 'local':
                raise NotImplementedError('must run create external user code')

            user = authenticate(username=username,
                                password=password,
                                provider_name=provider_name,
                                method='password')

            login(request, user)
            logging.debug('new user logged in')
            email_feeds_form.save(user)
            logging.debug('email feeds form saved')

            # send email
            #subject = _("Welcome email subject line")
            #message_template = get_emplate(
            #        'authopenid/confirm_email.txt'
            #)
            #message_context = Context({
            #    'signup_url': askbot_settings.APP_URL + reverse('user_signin'),
            #    'username': username,
            #    'password': password,
            #})
            #message = message_template.render(message_context)
            #send_mail(subject, message, settings.DEFAULT_FROM_EMAIL,
            #        [user.email])
            #logging.debug('new password acct created, confirmation email sent!')
            return HttpResponseRedirect(next)
        else:
            #todo: this can be solved with a decorator, maybe
            form.initial['login_provider'] = provider_name
            logging.debug('create classic account forms were invalid')
    else:
        #todo: here we have duplication of get_password_login_provider...
        form = RegisterForm(initial={
            'next': next,
            'login_provider': provider_name
        })
        email_feeds_form = askbot_forms.SimpleEmailSubscribeForm()
    logging.debug('printing legacy signup form')

    major_login_providers = util.get_enabled_major_login_providers()
    minor_login_providers = util.get_enabled_minor_login_providers()

    context_data = {
        'form': form,
        'page_class': 'openid-signin',
        'email_feeds_form': email_feeds_form,
        'major_login_providers': major_login_providers.values(),
        'minor_login_providers': minor_login_providers.values(),
        'login_form': login_form
    }
    return render_into_skin('authopenid/signup_with_password.html',
                            context_data, request)
Example #8
0
def register(request, login_provider_name=None, user_identifier=None):
    """
    this function is used via it's own url with request.method=POST
    or as a simple function call from "finalize_generic_signin"
    in which case request.method must ge 'GET'
    and login_provider_name and user_identifier arguments must not be None

    this function may need to be refactored to simplify the usage pattern
    
    template : authopenid/complete.html
    """

    logging.debug('')

    next_url = get_next_url(request)

    user = None
    is_redirect = False
    username = request.session.get('username', '')
    email = request.session.get('email', '')
    logging.debug('request method is %s' % request.method)

    register_form = forms.OpenidRegisterForm(
        initial={
            'next': next_url,
            'username': request.session.get('username', ''),
            'email': request.session.get('email', ''),
        })
    email_feeds_form = askbot_forms.SimpleEmailSubscribeForm()

    if request.method == 'GET':
        assert (login_provider_name is not None)
        assert (user_identifier is not None)
        #store this data into the session
        #to persist for the post request
        request.session['login_provider_name'] = login_provider_name
        request.session['user_identifier'] = user_identifier

    elif request.method == 'POST':

        if 'login_provider_name' not in request.session \
            or 'user_identifier' not in request.session:
            logging.critical('illegal attempt to register')
            return HttpResponseRedirect(reverse('user_signin'))

        #load this data from the session
        user_identifier = request.session['user_identifier']
        login_provider_name = request.session['login_provider_name']

        logging.debug('trying to create new account associated with openid')
        register_form = forms.OpenidRegisterForm(request.POST)
        email_feeds_form = askbot_forms.SimpleEmailSubscribeForm(request.POST)
        if not register_form.is_valid():
            logging.debug('OpenidRegisterForm is INVALID')
        elif not email_feeds_form.is_valid():
            logging.debug('SimpleEmailSubscribeForm is INVALID')
        else:
            logging.debug(
                'OpenidRegisterForm and SimpleEmailSubscribeForm are valid')
            is_redirect = True
            username = register_form.cleaned_data['username']
            email = register_form.cleaned_data['email']

            user = User.objects.create_user(username, email)
            user_registered.send(None, user=user)

            logging.debug('creating new openid user association for %s')

            UserAssociation(
                openid_url=user_identifier,
                user=user,
                provider_name=login_provider_name,
                last_used_timestamp=datetime.datetime.now()).save()

            del request.session['user_identifier']
            del request.session['login_provider_name']

            logging.debug('logging the user in')

            user = authenticate(method='force', user_id=user.id)
            if user is None:
                error_message = 'please make sure that ' + \
                                'askbot.deps.django_authopenid.backends.AuthBackend' + \
                                'is in your settings.AUTHENTICATION_BACKENDS'
                raise Exception(error_message)

            login(request, user)

            logging.debug('saving email feed settings')
            email_feeds_form.save(user)

        #check if we need to post a question that was added anonymously
        #this needs to be a function call becase this is also done
        #if user just logged in and did not need to create the new account

        if user != None:
            if askbot_settings.EMAIL_VALIDATION == True:
                logging.debug('sending email validation')
                send_new_email_key(user, nomessage=True)
                output = validation_email_sent(request)
                set_email_validation_message(
                    user)  #message set after generating view
                return output
            if user.is_authenticated():
                logging.debug('success, send user to main page')
                return HttpResponseRedirect(reverse('index'))
            else:
                logging.debug('have really strange error')
                raise Exception(
                    'openid login failed')  #should not ever get here

    providers = {
        'yahoo': '<font color="purple">Yahoo!</font>',
        'flickr':
        '<font color="#0063dc">flick</font><font color="#ff0084">r</font>&trade;',
        'google': 'Google&trade;',
        'aol': '<font color="#31658e">AOL</font>',
        'myopenid': 'MyOpenID',
    }
    if login_provider_name not in providers:
        provider_logo = login_provider_name
        logging.error(
            'openid provider named "%s" has no pretty customized logo' %
            login_provider_name)
    else:
        provider_logo = providers[login_provider_name]

    logging.debug('printing authopenid/complete.html output')
    data = {
        'openid_register_form': register_form,
        'email_feeds_form': email_feeds_form,
        'provider': mark_safe(provider_logo),
        'username': username,
        'email': email,
        'login_type': 'openid',
        'gravatar_faq_url': reverse('faq') + '#gravatar',
    }
    return render_into_skin('authopenid/complete.html', data, request)
Example #9
0
def ldap_authenticate(username, password):
    """
    Authenticate using ldap
   
    python-ldap must be installed
    http://pypi.python.org/pypi/python-ldap/2.4.6
    """
    import ldap
    user_information = None
    try:
        ldap_check = ldap.initialize(askbot_settings.LDAP_URL)
        ldap_check.protocol_version = ldap.VERSION3
        if askbot_settings.USE_LDAP_BOT:
            ldap_check.bind_s(askbot_settings.LDAP_BOT_USERNAME, askbot_settings.LDAP_BOT_PASSWORD)
        user_filter = "({0}={1})".format(askbot_settings.LDAP_USERID_FIELD, 
                                         username)
        res = ldap_check.search_s(askbot_settings.LDAP_BASEDN, ldap.SCOPE_SUBTREE, user_filter, None)
        if askbot_settings.USE_LDAP_BOT:
            ldap_check.unbind_s()
        if res: # User found in LDAP Directory
            user_dn = res[0][0]
            user_information = res[0][1]
            ldap_session = ldap.initialize(askbot_settings.LDAP_URL)
            ldap_session.protocol_version = ldap.VERSION3
            try:
                ldap_session.simple_bind_s(user_dn, password)
                ldap_session.unbind_s()

                exact_username = user_information[askbot_settings.LDAP_USERID_FIELD][0]            
                first_name = user_information[askbot_settings.LDAP_FNAME_FIELD][0]
                last_name = user_information[askbot_settings.LDAP_SNAME_FIELD][0]
                real_name = user_information[askbot_settings.LDAP_COMMONNAME_FIELD][0]
                email = user_information[askbot_settings.LDAP_EMAIL_FIELD][0]
                try:
                    user = User.objects.get(username__exact=exact_username)
                    # always update user profile to synchronize with ldap server
                    user.set_password(password)
                    user.first_name = first_name
                    user.last_name = last_name
                    user.real_name = real_name
                    user.email = email
                    user.is_staff = False
                    user.is_superuser = False
                    user.save()
                except User.DoesNotExist:
                    # create a new local user
                    user = User()
                    user.username = exact_username
                    user.set_password(password)
                    user.first_name = first_name
                    user.last_name = last_name
                    user.real_name = real_name
                    user.email = email
                    user.is_staff = False
                    user.is_superuser = False
                    user.is_active = True
                    user.save()
                    user_registered.send(None, user = user)

                    log.info('Created New User : [{0}]'.format(exact_username))
                return user
            except ldap.INVALID_CREDENTIALS:
                return None

        else:
            # Maybe a user created internally (django admin user)
            try:
                user = User.objects.get(username__exact=username)
                if user.check_password(password):
                    return user
                else:
                    return None
            except User.DoesNotExist:
                return None

    except Exception, e:
        log.error("Unexpected Exception Occurred")
        log.exception(e)
        raise e
        return None
Example #10
0
    def authenticate(
            self,
            username=None,  #for 'password' and 'ldap'
            password=None,  #for 'password' and 'ldap'
            user_id=None,  #for 'force'
            provider_name=None,  #required with all except email_key
            openid_url=None,
            email_key=None,
            oauth_user_id=None,  #used with oauth
            facebook_user_id=None,  #user with facebook
            wordpress_url=None,  # required for self hosted wordpress
            wp_user_id=None,  # required for self hosted wordpress
            method=None,  #requried parameter
    ):
        """this authentication function supports many login methods
        just which method it is going to use it determined
        from the signature of the function call
        """
        login_providers = util.get_enabled_login_providers()
        assoc = None  # UserAssociation not needed for ldap
        if method == 'password':
            if login_providers[provider_name]['type'] != 'password':
                raise ImproperlyConfigured('login provider must use password')
            if provider_name == 'local':
                try:
                    user = User.objects.get(username=username)
                    if not user.check_password(password):
                        return None
                except User.DoesNotExist:
                    try:
                        email_address = username
                        user = User.objects.get(email=email_address)
                        if not user.check_password(password):
                            return None
                    except User.DoesNotExist:
                        return None
                    except User.MultipleObjectsReturned:
                        LOG.critical(
                            ('have more than one user with email %s ' +
                             'he/she will not be able to authenticate with ' +
                             'the email address in the place of user name') %
                            email_address)
                        return None
            else:
                if login_providers[provider_name]['check_password'](username,
                                                                    password):
                    try:
                        #if have user associated with this username and provider,
                        #return the user
                        assoc = UserAssociation.objects.get(
                            openid_url=username + '@' +
                            provider_name,  #a hack - par name is bad
                            provider_name=provider_name)
                        return assoc.user
                    except UserAssociation.DoesNotExist:
                        #race condition here a user with this name may exist
                        user, created = User.objects.get_or_create(
                            username=username)
                        if created:
                            user.set_password(password)
                            user.save()
                            user_registered.send(None, user=user)
                        else:
                            #have username collision - so make up a more unique user name
                            #bug: - if user already exists with the new username - we are in trouble
                            new_username = '******' % (username, provider_name)
                            user = User.objects.create_user(
                                new_username, '', password)
                            user_registered.send(None, user=user)
                            message = _(
                                'Welcome! Please set email address (important!) in your '
                                'profile and adjust screen name, if necessary.'
                            )
                            user.message_set.create(message=message)
                else:
                    return None

            #this is a catch - make login token a little more unique
            #for the cases when passwords are the same for two users
            #from the same provider
            try:
                assoc = UserAssociation.objects.get(
                    user=user, provider_name=provider_name)
            except UserAssociation.DoesNotExist:
                assoc = UserAssociation(user=user, provider_name=provider_name)
            assoc.openid_url = username + '@' + provider_name  #has to be this way for external pw logins

        elif method == 'openid':
            try:
                assoc = UserAssociation.objects.get(openid_url=openid_url)
                user = assoc.user
            except UserAssociation.DoesNotExist:
                return None
            except UserAssociation.MultipleObjectsReturned:
                logging.critical('duplicate openid url in the database!!! %s' %
                                 openid_url)
                return None

        elif method == 'email':
            #with this method we do no use user association
            try:
                #todo: add email_key_timestamp field
                #and check key age
                user = User.objects.get(email_key=email_key)
                user.email_key = None  #one time key so delete it
                user.email_isvalid = True
                user.save()
                return user
            except User.DoesNotExist:
                return None

        elif method == 'oauth':
            if login_providers[provider_name]['type'] in ('oauth', 'oauth2'):
                try:
                    assoc = UserAssociation.objects.get(
                        openid_url=oauth_user_id, provider_name=provider_name)
                    user = assoc.user
                except UserAssociation.DoesNotExist:
                    return None
            else:
                return None

        elif method == 'facebook':
            try:
                #assert(provider_name == 'facebook')
                assoc = UserAssociation.objects.get(
                    openid_url=facebook_user_id, provider_name='facebook')
                user = assoc.user
            except UserAssociation.DoesNotExist:
                return None

        elif method == 'ldap':
            user_info = ldap_authenticate(username, password)
            if user_info['success'] == False:
                # Maybe a user created internally (django admin user)
                try:
                    user = User.objects.get(username__exact=username)
                    if user.check_password(password):
                        return user
                    else:
                        return None
                except User.DoesNotExist:
                    return None
            else:
                #load user by association or maybe auto-create one
                ldap_username = user_info['ldap_username']
                try:
                    #todo: provider_name is hardcoded - possible conflict
                    assoc = UserAssociation.objects.get(
                        openid_url=ldap_username + '@ldap',
                        provider_name='ldap')
                    user = assoc.user
                except UserAssociation.DoesNotExist:
                    #email address is required
                    if 'email' in user_info and askbot_settings.LDAP_AUTOCREATE_USERS:
                        assoc = ldap_create_user(user_info)
                        user = assoc.user
                    else:
                        return None

        elif method == 'wordpress_site':
            try:
                custom_wp_openid_url = '%s?user_id=%s' % (wordpress_url,
                                                          wp_user_id)
                assoc = UserAssociation.objects.get(
                    openid_url=custom_wp_openid_url,
                    provider_name='wordpress_site')
                user = assoc.user
            except UserAssociation.DoesNotExist:
                return None
        elif method == 'force':
            return self.get_user(user_id)
        else:
            raise TypeError('only openid and password supported')

        if assoc:
            #update last used time
            assoc.last_used_timestamp = datetime.datetime.now()
            assoc.save()
        return user
Example #11
0
def signup_with_password(request):
    """Create a password-protected account
    template: authopenid/signup_with_password.html
    """
    
    logging.debug(get_request_info(request))
    next = get_next_url(request)
    login_form = forms.LoginForm(initial = {'next': next})
    #this is safe because second decorator cleans this field
    provider_name = request.REQUEST['login_provider']

    if askbot_settings.USE_RECAPTCHA:
        RegisterForm = forms.SafeClassicRegisterForm
    else:
        RegisterForm = forms.ClassicRegisterForm

    logging.debug('request method was %s' % request.method)
    if request.method == 'POST':
        form = RegisterForm(request.POST)
        email_feeds_form = askbot_forms.SimpleEmailSubscribeForm(request.POST)
        
        #validation outside if to remember form values
        logging.debug('validating classic register form')
        form1_is_valid = form.is_valid()
        if form1_is_valid:
            logging.debug('classic register form validated')
        else:
            logging.debug('classic register form is not valid')
        form2_is_valid = email_feeds_form.is_valid()
        if form2_is_valid:
            logging.debug('email feeds form validated')
        else:
            logging.debug('email feeds form is not valid')
        if form1_is_valid and form2_is_valid:
            logging.debug('both forms are valid')
            next = form.cleaned_data['next']
            username = form.cleaned_data['username']
            password = form.cleaned_data['password1']
            email = form.cleaned_data['email']
            provider_name = form.cleaned_data['login_provider']
            
            new_user = User.objects.create_user(username, email, password)
            user_registered.send(None, user = new_user)

            logging.debug('new user %s created' % username)
            if provider_name != 'local':
                raise NotImplementedError('must run create external user code')

            user = authenticate(
                        username = username,
                        password = password,
                        provider_name = provider_name,
                        method = 'password'
                    )

            login(request, user)
            logging.debug('new user logged in')
            email_feeds_form.save(user)
            logging.debug('email feeds form saved')
            
            # send email
            #subject = _("Welcome email subject line")
            #message_template = get_emplate(
            #        'authopenid/confirm_email.txt'
            #)
            #message_context = Context({ 
            #    'signup_url': askbot_settings.APP_URL + reverse('user_signin'),
            #    'username': username,
            #    'password': password,
            #})
            #message = message_template.render(message_context)
            #send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, 
            #        [user.email])
            #logging.debug('new password acct created, confirmation email sent!')
            return HttpResponseRedirect(next)
        else:
            #todo: this can be solved with a decorator, maybe
            form.initial['login_provider'] = provider_name
            logging.debug('create classic account forms were invalid')
    else:
        #todo: here we have duplication of get_password_login_provider...
        form = RegisterForm(
                        initial={
                            'next':next,
                            'login_provider': provider_name
                        }
                    )
        email_feeds_form = askbot_forms.SimpleEmailSubscribeForm()
    logging.debug('printing legacy signup form')

    major_login_providers = util.get_enabled_major_login_providers()
    minor_login_providers = util.get_enabled_minor_login_providers()

    context_data = {
                'form': form, 
                'page_class': 'openid-signin',
                'email_feeds_form': email_feeds_form,
                'major_login_providers': major_login_providers.values(),
                'minor_login_providers': minor_login_providers.values(),
                'login_form': login_form
            }
    return render_into_skin(
                'authopenid/signup_with_password.html',
                context_data,
                request
            )
Example #12
0
def register(request, login_provider_name=None, user_identifier=None):
    """
    this function is used via it's own url with request.method=POST
    or as a simple function call from "finalize_generic_signin"
    in which case request.method must ge 'GET'
    and login_provider_name and user_identifier arguments must not be None

    this function may need to be refactored to simplify the usage pattern
    
    template : authopenid/complete.html
    """
    
    logging.debug('')

    next_url = get_next_url(request)

    user = None
    is_redirect = False
    username = request.session.get('username', '')
    email = request.session.get('email', '')
    logging.debug('request method is %s' % request.method)

    register_form = forms.OpenidRegisterForm(
                initial={
                    'next': next_url,
                    'username': request.session.get('username', ''),
                    'email': request.session.get('email', ''),
                }
            )
    email_feeds_form = askbot_forms.SimpleEmailSubscribeForm()

    if request.method == 'GET':
        assert(login_provider_name is not None)
        assert(user_identifier is not None)
        #store this data into the session
        #to persist for the post request
        request.session['login_provider_name'] = login_provider_name
        request.session['user_identifier'] = user_identifier

    elif request.method == 'POST':

        if 'login_provider_name' not in request.session \
            or 'user_identifier' not in request.session:
            logging.critical('illegal attempt to register')
            return HttpResponseRedirect(reverse('user_signin'))

        #load this data from the session
        user_identifier = request.session['user_identifier']
        login_provider_name = request.session['login_provider_name']

        logging.debug('trying to create new account associated with openid')
        register_form = forms.OpenidRegisterForm(request.POST)
        email_feeds_form = askbot_forms.SimpleEmailSubscribeForm(request.POST)
        if not register_form.is_valid():
            logging.debug('OpenidRegisterForm is INVALID')
        elif not email_feeds_form.is_valid():
            logging.debug('SimpleEmailSubscribeForm is INVALID')
        else:
            logging.debug('OpenidRegisterForm and SimpleEmailSubscribeForm are valid')
            is_redirect = True
            username = register_form.cleaned_data['username']
            email = register_form.cleaned_data['email']

            user = User.objects.create_user(username, email)
            user_registered.send(None, user = user)
            
            logging.debug('creating new openid user association for %s')

            UserAssociation(
                openid_url = user_identifier,
                user = user,
                provider_name = login_provider_name,
                last_used_timestamp = datetime.datetime.now()
            ).save()

            del request.session['user_identifier']
            del request.session['login_provider_name']
            
            logging.debug('logging the user in')

            user = authenticate(method = 'force', user_id = user.id)
            if user is None:
                error_message = 'please make sure that ' + \
                                'askbot.deps.django_authopenid.backends.AuthBackend' + \
                                'is in your settings.AUTHENTICATION_BACKENDS'
                raise Exception(error_message)

            login(request, user)

            logging.debug('saving email feed settings')
            email_feeds_form.save(user)

        #check if we need to post a question that was added anonymously
        #this needs to be a function call becase this is also done
        #if user just logged in and did not need to create the new account
        
        if user != None:
            if askbot_settings.EMAIL_VALIDATION == True:
                logging.debug('sending email validation')
                send_new_email_key(user, nomessage=True)
                output = validation_email_sent(request)
                set_email_validation_message(user) #message set after generating view
                return output
            if user.is_authenticated():
                logging.debug('success, send user to main page')
                return HttpResponseRedirect(reverse('index'))
            else:
                logging.debug('have really strange error')
                raise Exception('openid login failed')#should not ever get here
    
    providers = {
            'yahoo':'<font color="purple">Yahoo!</font>',
            'flickr':'<font color="#0063dc">flick</font><font color="#ff0084">r</font>&trade;',
            'google':'Google&trade;',
            'aol':'<font color="#31658e">AOL</font>',
            'myopenid':'MyOpenID',
        }
    if login_provider_name not in providers:
        provider_logo = login_provider_name
        logging.error('openid provider named "%s" has no pretty customized logo' % login_provider_name)
    else:
        provider_logo = providers[login_provider_name]
    
    logging.debug('printing authopenid/complete.html output')
    data = {
        'openid_register_form': register_form,
        'email_feeds_form': email_feeds_form,
        'provider':mark_safe(provider_logo),
        'username': username,
        'email': email,
        'login_type':'openid',
        'gravatar_faq_url':reverse('faq') + '#gravatar',
    }
    return render_into_skin('authopenid/complete.html', data, request)
Example #13
0
    def authenticate(
                self,
                username = None,#for 'password' and 'ldap'
                password = None,#for 'password' and 'ldap'
                user_id = None,#for 'force'
                provider_name = None,#required with all except email_key
                openid_url = None,
                email_key = None,
                oauth_user_id = None,#used with oauth
                facebook_user_id = None,#user with facebook
                wordpress_url = None, # required for self hosted wordpress
                wp_user_id = None, # required for self hosted wordpress
                cas_ticket = None, # the CAS ticket
                method = None,#requried parameter
            ):
        """this authentication function supports many login methods
        just which method it is going to use it determined
        from the signature of the function call
        """
        login_providers = util.get_enabled_login_providers()
        assoc = None # UserAssociation not needed for ldap
        if method == 'password':
            if login_providers[provider_name]['type'] != 'password':
                raise ImproperlyConfigured('login provider must use password')
            if provider_name == 'local':
                try:
                    user = User.objects.get(username=username)
                    if not user.check_password(password):
                        return None
                except User.DoesNotExist:
                    try:
                        email_address = username
                        user = User.objects.get(email = email_address)
                        if not user.check_password(password):
                            return None
                    except User.DoesNotExist:
                        return None
                    except User.MultipleObjectsReturned:
                        LOG.critical(
                            ('have more than one user with email %s ' +
                            'he/she will not be able to authenticate with ' +
                            'the email address in the place of user name') % email_address
                        )
                        return None
            else:
                if login_providers[provider_name]['check_password'](username, password):
                    try:
                        #if have user associated with this username and provider,
                        #return the user
                        assoc = UserAssociation.objects.get(
                                        openid_url = username + '@' + provider_name,#a hack - par name is bad
                                        provider_name = provider_name
                                    )
                        return assoc.user
                    except UserAssociation.DoesNotExist:
                        #race condition here a user with this name may exist
                        user, created = User.objects.get_or_create(username = username)
                        if created:
                            user.set_password(password)
                            user.save()
                            user_registered.send(None, user = user)
                        else:
                            #have username collision - so make up a more unique user name
                            #bug: - if user already exists with the new username - we are in trouble
                            new_username = '******' % (username, provider_name)
                            user = User.objects.create_user(new_username, '', password)
                            user_registered.send(None, user = user)
                            message = _(
                                'Welcome! Please set email address (important!) in your '
                                'profile and adjust screen name, if necessary.'
                            )
                            user.message_set.create(message = message)
                else:
                    return None

            #this is a catch - make login token a little more unique
            #for the cases when passwords are the same for two users
            #from the same provider
            try:
                assoc = UserAssociation.objects.get(
                                            user = user,
                                            provider_name = provider_name
                                        )
            except UserAssociation.DoesNotExist:
                assoc = UserAssociation(
                                    user = user,
                                    provider_name = provider_name
                                )
            assoc.openid_url = username + '@' + provider_name#has to be this way for external pw logins

        elif method == 'openid':
            try:
                assoc = UserAssociation.objects.get(openid_url=openid_url)
                user = assoc.user
            except UserAssociation.DoesNotExist:
                return None
            except UserAssociation.MultipleObjectsReturned:
                logging.critical(
                    'duplicate openid url in the database!!! %s' % openid_url
                )
                return None
                

        elif method == 'email':
            #with this method we do no use user association
            try:
                #todo: add email_key_timestamp field
                #and check key age
                user = User.objects.get(email_key = email_key)
                user.email_key = None #one time key so delete it
                user.email_isvalid = True
                user.save()
                return user
            except User.DoesNotExist:
                return None

        elif method == 'oauth':
            if login_providers[provider_name]['type'] == 'oauth':
                try:
                    assoc = UserAssociation.objects.get(
                                                openid_url = oauth_user_id,
                                                provider_name = provider_name
                                            )
                    user = assoc.user
                except UserAssociation.DoesNotExist:
                    return None
            else:
                return None

        elif method == 'facebook':
            try:
                #assert(provider_name == 'facebook')
                assoc = UserAssociation.objects.get(
                                            openid_url = facebook_user_id,
                                            provider_name = 'facebook'
                                        )
                user = assoc.user
            except UserAssociation.DoesNotExist:
                return None

        elif method == 'ldap':
            user_info = ldap_authenticate(username, password)
            if user_info['success'] == False:
                # Maybe a user created internally (django admin user)
                try:
                    user = User.objects.get(username__exact=username)
                    if user.check_password(password):
                        return user
                    else:
                        return None
                except User.DoesNotExist:
                    return None 
            else:
                #load user by association or maybe auto-create one
                ldap_username = user_info['ldap_username']
                try:
                    #todo: provider_name is hardcoded - possible conflict
                    assoc = UserAssociation.objects.get(
                                            openid_url = ldap_username + '@ldap',
                                            provider_name = 'ldap'
                                        )
                    user = assoc.user
                except UserAssociation.DoesNotExist:
                    #email address is required
                    if 'email' in user_info and askbot_settings.LDAP_AUTOCREATE_USERS:
                        assoc = ldap_create_user(user_info)
                        user = assoc.user
                    else:
                        return None
        elif method == 'cas':
            import caslib
            cas_response = caslib.cas_serviceValidate(cas_ticket)
            success, _user = cas_response.map[cas_response.type].get('user',None)

            if success:
                try:
                    assoc = UserAssociation.objects.get(
                                            openid_url = _user + '@ldap',
                                            provider_name = 'ldap'
                                            )
                    user = assoc.user
                except UserAssociation.DoesNotExist:
                    user = User()
                    user.username = _user
                    user.set_unusable_password()
                    user.is_staff = False
                    user.is_superuser = False
                    user.is_active = True
                    user.save()
                    user_registered.send(None, user = user)
                    LOG.info('Created New User : [{0}]'.format(_user))
                    
                    assoc = UserAssociation()
                    assoc.user = _user
                    assoc.openid_url = _user + '@ldap'
                    assoc.provider_name = 'ldap'
                    assoc.save()

            else:
                return None

            
        
        elif method == 'wordpress_site':
            try:
                custom_wp_openid_url = '%s?user_id=%s' % (wordpress_url, wp_user_id)
                assoc = UserAssociation.objects.get(
                                            openid_url = custom_wp_openid_url,
                                            provider_name = 'wordpress_site'
                                            )
                user = assoc.user
            except UserAssociation.DoesNotExist:
                return None
        elif method == 'force':
            return self.get_user(user_id)
        else:
            raise TypeError('only openid and password supported')

        if assoc:
            #update last used time
            assoc.last_used_timestamp = datetime.datetime.now()
            assoc.save()
        return user
Example #14
0
    def authenticate(
        self,
        username=None,  # for 'password' and 'ldap'
        password=None,  # for 'password' and 'ldap'
        user_id=None,  # for 'force'
        provider_name=None,  # required with all except email_key
        openid_url=None,
        email_key=None,
        oauth_user_id=None,  # used with oauth
        facebook_user_id=None,  # user with facebook
        wordpress_url=None,  # required for self hosted wordpress
        wp_user_id=None,  # required for self hosted wordpress
        method=None,  # requried parameter
    ):
        """this authentication function supports many login methods
        just which method it is going to use it determined
        from the signature of the function call
        """
        login_providers = util.get_enabled_login_providers()
        assoc = None  # UserAssociation not needed for ldap
        if method == "password":
            if login_providers[provider_name]["type"] != "password":
                raise ImproperlyConfigured("login provider must use password")
            if provider_name == "local":
                try:
                    user = User.objects.get(username=username)
                    if not user.check_password(password):
                        return None
                except User.DoesNotExist:
                    try:
                        email_address = username
                        user = User.objects.get(email=email_address)
                        if not user.check_password(password):
                            return None
                    except User.DoesNotExist:
                        return None
                    except User.MultipleObjectsReturned:
                        LOG.critical(
                            (
                                "have more than one user with email %s "
                                + "he/she will not be able to authenticate with "
                                + "the email address in the place of user name"
                            )
                            % email_address
                        )
                        return None
            else:
                if login_providers[provider_name]["check_password"](username, password):
                    try:
                        # if have user associated with this username and provider,
                        # return the user
                        assoc = UserAssociation.objects.get(
                            openid_url=username + "@" + provider_name,  # a hack - par name is bad
                            provider_name=provider_name,
                        )
                        return assoc.user
                    except UserAssociation.DoesNotExist:
                        # race condition here a user with this name may exist
                        user, created = User.objects.get_or_create(username=username)
                        if created:
                            user.set_password(password)
                            user.save()
                            user_registered.send(None, user=user)
                        else:
                            # have username collision - so make up a more unique user name
                            # bug: - if user already exists with the new username - we are in trouble
                            new_username = "******" % (username, provider_name)
                            user = User.objects.create_user(new_username, "", password)
                            user_registered.send(None, user=user)
                            message = _(
                                "Welcome! Please set email address (important!) in your "
                                "profile and adjust screen name, if necessary."
                            )
                            user.message_set.create(message=message)
                else:
                    return None

            # this is a catch - make login token a little more unique
            # for the cases when passwords are the same for two users
            # from the same provider
            try:
                assoc = UserAssociation.objects.get(user=user, provider_name=provider_name)
            except UserAssociation.DoesNotExist:
                assoc = UserAssociation(user=user, provider_name=provider_name)
            assoc.openid_url = username + "@" + provider_name  # has to be this way for external pw logins

        elif method == "openid":
            try:
                assoc = UserAssociation.objects.get(openid_url=openid_url)
                user = assoc.user
            except UserAssociation.DoesNotExist:
                return None
            except UserAssociation.MultipleObjectsReturned:
                logging.critical("duplicate openid url in the database!!! %s" % openid_url)
                return None

        elif method == "email":
            # with this method we do no use user association
            try:
                # todo: add email_key_timestamp field
                # and check key age
                user = User.objects.get(email_key=email_key)
                user.email_key = None  # one time key so delete it
                user.email_isvalid = True
                user.save()
                return user
            except User.DoesNotExist:
                return None

        elif method == "oauth":
            if login_providers[provider_name]["type"] in ("oauth", "oauth2"):
                try:
                    assoc = UserAssociation.objects.get(openid_url=oauth_user_id, provider_name=provider_name)
                    user = assoc.user
                except UserAssociation.DoesNotExist:
                    return None
            else:
                return None

        elif method == "facebook":
            try:
                # assert(provider_name == 'facebook')
                assoc = UserAssociation.objects.get(openid_url=facebook_user_id, provider_name="facebook")
                user = assoc.user
            except UserAssociation.DoesNotExist:
                return None

        elif method == "ldap":
            # user_info = ldap_authenticate(username, password)
            user_info = util.ldap_check_password(username, password)
            if user_info["success"] == False:
                # Maybe a user created internally (django admin user)
                try:
                    user = User.objects.get(username__exact=username)
                    if user.check_password(password):
                        return user
                    else:
                        return None
                except User.DoesNotExist:
                    return None
            else:
                # load user by association or maybe auto-create one
                ldap_username = user_info["ldap_username"]
                try:
                    # todo: provider_name is hardcoded - possible conflict
                    assoc = UserAssociation.objects.get(openid_url=ldap_username, provider_name="Wind River LDAP")
                    user = assoc.user
                except UserAssociation.DoesNotExist:
                    # email address is required
                    if "email" in user_info and askbot_settings.LDAP_AUTOCREATE_USERS:
                        assoc = ldap_create_user(user_info)
                        user = assoc.user
                    else:
                        return None

        elif method == "wordpress_site":
            try:
                custom_wp_openid_url = "%s?user_id=%s" % (wordpress_url, wp_user_id)
                assoc = UserAssociation.objects.get(openid_url=custom_wp_openid_url, provider_name="wordpress_site")
                user = assoc.user
            except UserAssociation.DoesNotExist:
                return None
        elif method == "force":
            return self.get_user(user_id)
        else:
            raise TypeError("only openid and password supported")

        if assoc:
            # update last used time
            assoc.last_used_timestamp = datetime.datetime.now()
            assoc.save()
        return user
Example #15
0
def ldap_authenticate(username, password):
    """
    Authenticate using ldap
    
    python-ldap must be installed
    http://pypi.python.org/pypi/python-ldap/2.4.6
    """
    import ldap
    user_information = None
    try:
        ldap_session = ldap.initialize(askbot_settings.LDAP_URL)

        #set protocol version
        if askbot_settings.LDAP_PROTOCOL_VERSION == '2':
            ldap_session.protocol_version = ldap.VERSION2
        elif askbot_settings.LDAP_PROTOCOL_VERSION == '3':
            ldap_session.protocol_version = ldap.VERSION3
        else:
            raise NotImplementedError('unsupported version of ldap protocol')

        ldap.set_option(ldap.OPT_REFERRALS, 0)

        #set extra ldap options, if given
        if hasattr(django_settings, 'LDAP_EXTRA_OPTIONS'):
            options = django_settings.LDAP_EXTRA_OPTIONS
            for key, value in options:
                if key.startswith('OPT_'):
                    ldap_key = getattr(ldap, key)
                    ldap.set_option(ldap_key, value)
                else:
                    raise ValueError('Invalid LDAP option %s' % key)

        #add optional "master" LDAP authentication, if required
        master_username = getattr(django_settings, 'LDAP_USER', None)
        master_password = getattr(django_settings, 'LDAP_PASSWORD', None)

        login_name_field = askbot_settings.LDAP_LOGIN_NAME_FIELD
        base_dn = askbot_settings.LDAP_BASE_DN
        login_template = login_name_field + '=%s,' + base_dn
        encoding = askbot_settings.LDAP_ENCODING

        if master_username and master_password:
            login_dn = login_template % master_username
            ldap_session.simple_bind_s(
                login_dn.encode(encoding),
                master_password.encode(encoding)
            )

        user_filter = askbot_settings.LDAP_USER_FILTER_TEMPLATE % (
                        askbot_settings.LDAP_LOGIN_NAME_FIELD,
                        username
                    )

        email_field = askbot_settings.LDAP_EMAIL_FIELD

        get_attrs = [
            email_field.encode(encoding),
            login_name_field.encode(encoding)
            #str(askbot_settings.LDAP_USERID_FIELD)
            #todo: here we have a chance to get more data from LDAP
            #maybe a point for some plugin
        ]

        common_name_field = askbot_settings.LDAP_COMMON_NAME_FIELD.strip()
        given_name_field = askbot_settings.LDAP_GIVEN_NAME_FIELD.strip()
        surname_field = askbot_settings.LDAP_SURNAME_FIELD.strip()

        if given_name_field and surname_field:
            get_attrs.append(given_name_field.encode(encoding))
            get_attrs.append(surname_field.encode(encoding))
        elif common_name_field:
            get_attrs.append(common_name_field.encode(encoding))

        # search ldap directory for user
        user_search_result = ldap_session.search_s(
            askbot_settings.LDAP_BASE_DN.encode(encoding),
            ldap.SCOPE_SUBTREE,
            user_filter.encode(encoding),
            get_attrs 
        )
        if user_search_result: # User found in LDAP Directory
            user_dn = user_search_result[0][0]
            user_information = user_search_result[0][1]
            ldap_session.simple_bind_s(user_dn, password.encode(encoding)) #raises INVALID_CREDENTIALS
            ldap_session.unbind_s()
            
            exact_username = user_information[login_name_field][0]
            email = user_information[email_field][0]

            if given_name_field and surname_field:
                last_name = user_information[surname_field][0]
                first_name = user_information[given_name_field][0]
            elif surname_field:
                common_name_format = askbot_settings.LDAP_COMMON_NAME_FIELD_FORMAT
                common_name = user_information[common_name_field][0]
                first_name, last_name = split_name(common_name, common_name_format)
            
            #here we have an opportunity to copy password in the auth_user table
            #but we don't do it for security reasons
            try:
                user = User.objects.get(username__exact=exact_username)
                # always update user profile to synchronize with ldap server
                user.set_unusable_password()
                #user.first_name = first_name
                #user.last_name = last_name
                user.email = email
                user.save()
            except User.DoesNotExist:
                # create new user in local db
                user = User()
                user.username = exact_username
                user.set_unusable_password()
                #user.first_name = first_name
                #user.last_name = last_name
                user.email = email
                user.is_staff = False
                user.is_superuser = False
                user.is_active = True
                user.save()
                user_registered.send(None, user = user)

                log.info('Created New User : [{0}]'.format(exact_username))
            return user
        else:
            # Maybe a user created internally (django admin user)
            try:
                user = User.objects.get(username__exact=username)
                if user.check_password(password):
                    return user
                else:
                    return None
            except User.DoesNotExist:
                return None 

    except ldap.INVALID_CREDENTIALS, e:
        return None # Will fail login on return of None
Example #16
0
def ldap_authenticate(username, password):
    """
    Authenticate using ldap
    
    python-ldap must be installed
    http://pypi.python.org/pypi/python-ldap/2.4.6
    """
    import ldap
    user_information = None
    try:
        ldap_session = ldap.initialize(askbot_settings.LDAP_URL)
        ldap_session.protocol_version = ldap.VERSION3
        user_filter = "({0}={1})".format(askbot_settings.LDAP_USERID_FIELD,
                                         username)
        # search ldap directory for user
        res = ldap_session.search_s(askbot_settings.LDAP_BASEDN,
                                    ldap.SCOPE_SUBTREE, user_filter, None)
        if res:  # User found in LDAP Directory
            user_dn = res[0][0]
            user_information = res[0][1]
            ldap_session.simple_bind_s(
                user_dn,
                password)  # <-- will throw  ldap.INVALID_CREDENTIALS if fails
            ldap_session.unbind_s()

            exact_username = user_information[
                askbot_settings.LDAP_USERID_FIELD][0]

            # Assuming last, first order
            # --> may be different
            last_name, first_name = user_information[
                askbot_settings.LDAP_COMMONNAME_FIELD][0].rsplit(" ", 1)
            email = user_information[askbot_settings.LDAP_EMAIL_FIELD][0]
            try:
                user = User.objects.get(username__exact=exact_username)
                # always update user profile to synchronize with ldap server
                user.set_password(password)
                user.first_name = first_name
                user.last_name = last_name
                user.email = email
                user.save()
            except User.DoesNotExist:
                # create new user in local db
                user = User()
                user.username = exact_username
                user.set_password(password)
                user.first_name = first_name
                user.last_name = last_name
                user.email = email
                user.is_staff = False
                user.is_superuser = False
                user.is_active = True
                user.save()
                user_registered.send(None, user=user)

                log.info('Created New User : [{0}]'.format(exact_username))
            return user
        else:
            # Maybe a user created internally (django admin user)
            try:
                user = User.objects.get(username__exact=username)
                if user.check_password(password):
                    return user
                else:
                    return None
            except User.DoesNotExist:
                return None

    except ldap.INVALID_CREDENTIALS, e:
        return None  # Will fail login on return of None