Esempio n. 1
0
    def auth_by_ldap(self, username, password):
        user_info = ldap_authenticate(username, password)
        if user_info['success'] == False:
            return self.auth_by_local_password(username, password)

        #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')
            assoc.update_timestamp()
            return 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)
                return assoc.user
            else:
                return None
Esempio n. 2
0
    def auth_by_ldap(self, username, password):
        user_info = ldap_authenticate(username, password)
        if user_info['success'] == False:
            return self.auth_by_local_password(username, password)

        #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'
                                )
            assoc.update_timestamp()
            return 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)
                return assoc.user
            else:
                return None
Esempio n. 3
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,
                email = None, # used with mozilla-persona method
                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 == 'mozilla-persona':
            try:
                assoc = UserAssociation.objects.get(
                                        openid_url=email,
                                        provider_name='mozilla-persona'
                                    )
                return assoc.user
            except UserAssociation.DoesNotExist:
                return None
            except UserAssociation.MultipleObjectsReturned:
                logging.critical(
                    'duplicate user with mozilla persona %s!!!' % email
                )

        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 in ('valid_email', 'any_email'):
            try:
                user = User.objects.get(email=email)
            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

            if method == 'valid_email' and user.email_isvalid == False:
                return None

            return user

        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
Esempio n. 4
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,
            email=None,  # used with mozilla-persona method
            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 == 'mozilla-persona':
            try:
                assoc = UserAssociation.objects.get(
                    openid_url=email, provider_name='mozilla-persona')
                return assoc.user
            except UserAssociation.DoesNotExist:
                return None
            except UserAssociation.MultipleObjectsReturned:
                logging.critical('duplicate user with mozilla persona %s!!!' %
                                 email)

        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 == 'valid_email':
            try:
                user = User.objects.get(email=email)
            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

            if user.email_isvalid == False:
                return None

            return user

        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
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

    user_identifier will be stored in the UserAssociation as openid_url
    login_provider_name - as provider_name

    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
    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', ''),
                }
            )

    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)
        if not register_form.is_valid():
            logging.debug('OpenidRegisterForm is INVALID')
        else:
            username = register_form.cleaned_data['username']
            email = register_form.cleaned_data['email']

            if 'ldap_user_info' in request.session:
                user_info = request.session['ldap_user_info']
                #we take this info from the user input where
                #they can override the default provided by LDAP
                user_info['django_username'] = username
                user_info['email'] = email
                user = ldap_create_user(user_info).user
                del request.session['ldap_user_info']
                login(request, user)
                cleanup_post_register_session(request)
                return HttpResponseRedirect(next_url)

            elif askbot_settings.REQUIRE_VALID_EMAIL_FOR == 'nothing':

                user = create_authenticated_user_account(
                            username=username,
                            email=email,
                            user_identifier=user_identifier,
                            login_provider_name=login_provider_name,
                        )
                login(request, user)
                cleanup_post_register_session(request)
                return HttpResponseRedirect(next_url)
            else:
                request.session['username'] = username
                request.session['email'] = email
                key = util.generate_random_key()
                email = request.session['email']
                send_email_key(email, key, handler_url_name='verify_email_and_register')
                request.session['validation_code'] = key
                redirect_url = reverse('verify_email_and_register') + '?next=' + next_url
                return HttpResponseRedirect(redirect_url)

    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,
        'default_form_action': django_settings.LOGIN_URL,
        '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)
def signin(request, template_name='authopenid/signin.html'):
    """
    signin page. It manages the legacy authentification (user/password)
    and openid authentification

    url: /signin/

    template : authopenid/signin.htm
    """
    logging.debug('in signin view')
    on_failure = signin_failure

    #we need a special priority on where to redirect on successful login
    #here:
    #1) url parameter "next" - if explicitly set
    #2) url from django setting LOGIN_REDIRECT_URL
    #3) home page of the forum
    login_redirect_url = getattr(django_settings, 'LOGIN_REDIRECT_URL', None)
    next_url = get_next_url(request, default = login_redirect_url)
    logging.debug('next url is %s' % next_url)

    if askbot_settings.ALLOW_ADD_REMOVE_LOGIN_METHODS == False \
        and request.user.is_authenticated():
        return HttpResponseRedirect(next_url)

    if next_url == reverse('user_signin'):
        next_url = '%(next)s?next=%(next)s' % {'next': next_url}

    login_form = forms.LoginForm(initial = {'next': next_url})

    #todo: get next url make it sticky if next is 'user_signin'
    if request.method == 'POST':

        login_form = forms.LoginForm(request.POST)
        if login_form.is_valid():

            provider_name = login_form.cleaned_data['login_provider_name']
            if login_form.cleaned_data['login_type'] == 'password':

                password_action = login_form.cleaned_data['password_action']
                if askbot_settings.USE_LDAP_FOR_PASSWORD_LOGIN:
                    assert(password_action == 'login')
                    username = login_form.cleaned_data['username']
                    password = login_form.cleaned_data['password']

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

                    if user:
                        login(request, user)
                        return HttpResponseRedirect(next_url)
                    else:
                        #try to login again via LDAP
                        user_info = ldap_authenticate(username, password)
                        if user_info['success']:
                            if askbot_settings.LDAP_AUTOCREATE_USERS:
                                #create new user or 
                                user = ldap_create_user(user_info).user
                                user = authenticate(method='force', user_id=user.id)
                                assert(user is not None)
                                login(request, user)
                                return HttpResponseRedirect(next_url)
                            else:
                                #continue with proper registration
                                ldap_username = user_info['ldap_username']
                                request.session['email'] = user_info['email']
                                request.session['ldap_user_info'] = user_info
                                if askbot_settings.AUTOFILL_USER_DATA:
                                    request.session['username'] = ldap_username
                                    request.session['first_name'] = \
                                        user_info['first_name']
                                    request.session['last_name'] = \
                                        user_info['last_name']
                                return finalize_generic_signin(
                                    request,
                                    login_provider_name = 'ldap', 
                                    user_identifier = ldap_username + '@ldap',
                                    redirect_url = next_url
                                )
                        else:
                            auth_fail_func_path = getattr(
                                                django_settings,
                                                'LDAP_AUTHENTICATE_FAILURE_FUNCTION',
                                                None
                                            )

                            if auth_fail_func_path:
                                auth_fail_func = load_module(auth_fail_func_path)
                                auth_fail_func(user_info, login_form)
                            else:
                                login_form.set_password_login_error()
                            #return HttpResponseRedirect(request.path)
                else:
                    if password_action == 'login':
                        user = authenticate(
                                username = login_form.cleaned_data['username'],
                                password = login_form.cleaned_data['password'],
                                provider_name = provider_name,
                                method = 'password'
                            )
                        if user is None:
                            login_form.set_password_login_error()
                        else:
                            login(request, user)
                            #todo: here we might need to set cookies
                            #for external login sites
                            return HttpResponseRedirect(next_url)
                    elif password_action == 'change_password':
                        if request.user.is_authenticated():
                            new_password = \
                                login_form.cleaned_data['new_password']
                            AuthBackend.set_password(
                                            user=request.user,
                                            password=new_password,
                                            provider_name=provider_name
                                        )
                            request.user.message_set.create(
                                        message = _('Your new password saved')
                                    )
                            return HttpResponseRedirect(next_url)
                    else:
                        logging.critical(
                            'unknown password action %s' % password_action
                        )
                        raise Http404

            elif login_form.cleaned_data['login_type'] == 'openid':
                #initiate communication process
                logging.debug('processing signin with openid submission')

                #todo: make a simple-use wrapper for openid protocol

                sreg_req = sreg.SRegRequest(optional=['nickname', 'email'])
                redirect_to = "%s%s?%s" % (
                        get_url_host(request),
                        reverse('user_complete_signin'),
                        urllib.urlencode({'next':next_url})
                )
                return ask_openid(
                            request,
                            login_form.cleaned_data['openid_url'],
                            redirect_to,
                            on_failure=signin_failure,
                            sreg_request=sreg_req
                        )

            elif login_form.cleaned_data['login_type'] == 'oauth':
                try:
                    #this url may need to have "next" piggibacked onto
                    callback_url = reverse('user_complete_oauth_signin')

                    connection = util.OAuthConnection(
                                        provider_name,
                                        callback_url = callback_url
                                    )

                    connection.start()

                    request.session['oauth_token'] = connection.get_token()
                    request.session['oauth_provider_name'] = provider_name
                    request.session['next_url'] = next_url#special case for oauth

                    oauth_url = connection.get_auth_url(login_only = False)
                    return HttpResponseRedirect(oauth_url)

                except util.OAuthError, e:
                    logging.critical(unicode(e))
                    msg = _('Unfortunately, there was some problem when '
                            'connecting to %(provider)s, please try again '
                            'or use another provider'
                        ) % {'provider': provider_name}
                    request.user.message_set.create(message = msg)

            elif login_form.cleaned_data['login_type'] == 'facebook':
                #have to redirect for consistency
                #there is a requirement that 'complete_signin'
                try:
                    #this call may raise FacebookError
                    user_id = util.get_facebook_user_id(request)

                    user = authenticate(
                                method = 'facebook',
                                facebook_user_id = user_id
                            )

                    return finalize_generic_signin(
                                    request = request,
                                    user = user,
                                    user_identifier = user_id,
                                    login_provider_name = provider_name,
                                    redirect_url = next_url
                                )

                except util.FacebookError, e:
                    logging.critical(unicode(e))
                    msg = _('Unfortunately, there was some problem when '
                            'connecting to %(provider)s, please try again '
                            'or use another provider'
                        ) % {'provider': 'Facebook'}
                    request.user.message_set.create(message = msg)

            elif login_form.cleaned_data['login_type'] == 'wordpress_site':
                #here wordpress_site means for a self hosted wordpress blog not a wordpress.com blog
                wp = Client(askbot_settings.WORDPRESS_SITE_URL, login_form.cleaned_data['username'], login_form.cleaned_data['password'])
                try:
                    wp_user = wp.call(GetUserInfo())
                    custom_wp_openid_url = '%s?user_id=%s' % (wp.url, wp_user.user_id)
                    user = authenticate(
                            method = 'wordpress_site',
                            wordpress_url = wp.url,
                            wp_user_id = wp_user.user_id
                           )
                    return finalize_generic_signin(
                                    request = request,
                                    user = user,
                                    user_identifier = custom_wp_openid_url,
                                    login_provider_name = provider_name,
                                    redirect_url = next_url
                                    )
                except WpFault, e:
                    logging.critical(unicode(e))
                    msg = _('The login password combination was not correct')
                    request.user.message_set.create(message = msg)
Esempio n. 7
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

    user_identifier will be stored in the UserAssociation as openid_url
    login_provider_name - as provider_name

    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
    username = request.session.get("username", "")
    email = request.session.get("email", "")
    logging.debug("request method is %s" % request.method)

    form_class = forms.get_registration_form_class()
    register_form = form_class(
        initial={
            "next": next_url,
            "username": request.session.get("username", ""),
            "email": request.session.get("email", ""),
        }
    )

    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")
        form_class = forms.get_registration_form_class()
        register_form = form_class(request.POST)
        if not register_form.is_valid():
            logging.debug("registration form is INVALID")
        else:
            username = register_form.cleaned_data["username"]
            email = register_form.cleaned_data["email"]

            if "ldap_user_info" in request.session:
                user_info = request.session["ldap_user_info"]
                # we take this info from the user input where
                # they can override the default provided by LDAP
                user_info["django_username"] = username
                user_info["email"] = email
                user = ldap_create_user(user_info).user
                user = authenticate(user_id=user.id, method="force")
                del request.session["ldap_user_info"]
                login(request, user)
                cleanup_post_register_session(request)
                return HttpResponseRedirect(next_url)

            elif askbot_settings.REQUIRE_VALID_EMAIL_FOR == "nothing":

                user = create_authenticated_user_account(
                    username=username,
                    email=email,
                    user_identifier=user_identifier,
                    login_provider_name=login_provider_name,
                )
                login(request, user)
                cleanup_post_register_session(request)
                return HttpResponseRedirect(next_url)
            else:
                email_verifier = UserEmailVerifier(key=generate_random_key())
                email_verifier.value = {
                    "username": username,
                    "email": email,
                    "user_identifier": user_identifier,
                    "login_provider_name": login_provider_name,
                }
                email_verifier.save()
                send_email_key(email, email_verifier.key, handler_url_name="verify_email_and_register")
                redirect_url = reverse("verify_email_and_register") + "?next=" + next_url
                return HttpResponseRedirect(redirect_url)

    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
    else:
        provider_logo = providers[login_provider_name]

    logging.debug("printing authopenid/complete.html output")
    data = {
        "openid_register_form": register_form,
        "default_form_action": django_settings.LOGIN_URL,
        "provider": mark_safe(provider_logo),
        "username": username,
        "email": email,
        "login_type": "openid",
        "gravatar_faq_url": reverse("faq") + "#gravatar",
    }
    return render(request, "authopenid/complete.html", data)
Esempio n. 8
0
def signin(request, template_name="authopenid/signin.html"):
    """
    signin page. It manages the legacy authentification (user/password)
    and openid authentification

    url: /signin/

    template : authopenid/signin.htm
    """
    logging.debug("in signin view")
    on_failure = signin_failure

    # we need a special priority on where to redirect on successful login
    # here:
    # 1) url parameter "next" - if explicitly set
    # 2) url from django setting LOGIN_REDIRECT_URL
    # 3) home page of the forum
    login_redirect_url = getattr(django_settings, "LOGIN_REDIRECT_URL", None)
    next_url = get_next_url(request, default=login_redirect_url)
    logging.debug("next url is %s" % next_url)

    if askbot_settings.ALLOW_ADD_REMOVE_LOGIN_METHODS == False and request.user.is_authenticated():
        return HttpResponseRedirect(next_url)

    if next_url == reverse("user_signin"):
        next_url = "%(next)s?next=%(next)s" % {"next": next_url}

    login_form = forms.LoginForm(initial={"next": next_url})

    # todo: get next url make it sticky if next is 'user_signin'
    if request.method == "POST":

        login_form = forms.LoginForm(request.POST)
        if login_form.is_valid():

            provider_name = login_form.cleaned_data["login_provider_name"]
            if login_form.cleaned_data["login_type"] == "password":

                password_action = login_form.cleaned_data["password_action"]
                if askbot_settings.USE_LDAP_FOR_PASSWORD_LOGIN:
                    assert password_action == "login"
                    username = login_form.cleaned_data["username"]
                    password = login_form.cleaned_data["password"]

                    user = authenticate(username=username, password=password, method="ldap")

                    if user:
                        login(request, user)
                        return HttpResponseRedirect(next_url)
                    else:
                        # try to login again via LDAP
                        user_info = ldap_authenticate(username, password)
                        if user_info["success"]:
                            if askbot_settings.LDAP_AUTOCREATE_USERS:
                                # create new user or
                                user = ldap_create_user(user_info).user
                                user = authenticate(method="force", user_id=user.id)
                                assert user is not None
                                login(request, user)
                                return HttpResponseRedirect(next_url)
                            else:
                                # continue with proper registration
                                ldap_username = user_info["ldap_username"]
                                request.session["email"] = user_info["email"]
                                request.session["ldap_user_info"] = user_info
                                if askbot_settings.AUTOFILL_USER_DATA:
                                    request.session["username"] = ldap_username
                                    request.session["first_name"] = user_info["first_name"]
                                    request.session["last_name"] = user_info["last_name"]
                                return finalize_generic_signin(
                                    request,
                                    login_provider_name="ldap",
                                    user_identifier=ldap_username + "@ldap",
                                    redirect_url=next_url,
                                )
                        else:
                            auth_fail_func_path = getattr(django_settings, "LDAP_AUTHENTICATE_FAILURE_FUNCTION", None)

                            if auth_fail_func_path:
                                auth_fail_func = load_module(auth_fail_func_path)
                                auth_fail_func(user_info, login_form)
                            else:
                                login_form.set_password_login_error()
                            # return HttpResponseRedirect(request.path)
                else:
                    if password_action == "login":
                        user = authenticate(
                            username=login_form.cleaned_data["username"],
                            password=login_form.cleaned_data["password"],
                            provider_name=provider_name,
                            method="password",
                        )
                        if user is None:
                            login_form.set_password_login_error()
                        else:
                            login(request, user)
                            # todo: here we might need to set cookies
                            # for external login sites
                            return HttpResponseRedirect(next_url)
                    elif password_action == "change_password":
                        if request.user.is_authenticated():
                            new_password = login_form.cleaned_data["new_password"]
                            AuthBackend.set_password(
                                user=request.user, password=new_password, provider_name=provider_name
                            )
                            request.user.message_set.create(message=_("Your new password saved"))
                            return HttpResponseRedirect(next_url)
                    else:
                        logging.critical("unknown password action %s" % password_action)
                        raise Http404

            elif login_form.cleaned_data["login_type"] == "openid":
                # initiate communication process
                logging.debug("processing signin with openid submission")

                # todo: make a simple-use wrapper for openid protocol

                sreg_req = sreg.SRegRequest(optional=["nickname", "email"])
                redirect_to = "%s%s?%s" % (
                    get_url_host(request),
                    reverse("user_complete_signin"),
                    urllib.urlencode({"next": next_url}),
                )
                return ask_openid(
                    request,
                    login_form.cleaned_data["openid_url"],
                    redirect_to,
                    on_failure=signin_failure,
                    sreg_request=sreg_req,
                )

            elif login_form.cleaned_data["login_type"] == "oauth":
                try:
                    # this url may need to have "next" piggibacked onto
                    connection = util.OAuthConnection(provider_name, callback_url=reverse("user_complete_oauth_signin"))

                    connection.start()

                    request.session["oauth_token"] = connection.get_token()
                    request.session["oauth_provider_name"] = provider_name
                    request.session["next_url"] = next_url  # special case for oauth

                    oauth_url = connection.get_auth_url(login_only=True)
                    return HttpResponseRedirect(oauth_url)

                except util.OAuthError, e:
                    logging.critical(unicode(e))
                    msg = _(
                        "Unfortunately, there was some problem when "
                        "connecting to %(provider)s, please try again "
                        "or use another provider"
                    ) % {"provider": provider_name}
                    request.user.message_set.create(message=msg)

            elif login_form.cleaned_data["login_type"] == "oauth2":
                try:
                    csrf_token = generate_random_key(length=32)
                    redirect_url = util.get_oauth2_starter_url(provider_name, csrf_token)
                    request.session["oauth2_csrf_token"] = csrf_token
                    request.session["provider_name"] = provider_name
                    return HttpResponseRedirect(redirect_url)
                except util.OAuthError, e:
                    logging.critical(unicode(e))
                    msg = _(
                        "Unfortunately, there was some problem when "
                        "connecting to %(provider)s, please try again "
                        "or use another provider"
                    ) % {"provider": provider_name}
                    request.user.message_set.create(message=msg)

            elif login_form.cleaned_data["login_type"] == "wordpress_site":
                # here wordpress_site means for a self hosted wordpress blog not a wordpress.com blog
                wp = Client(
                    askbot_settings.WORDPRESS_SITE_URL,
                    login_form.cleaned_data["username"],
                    login_form.cleaned_data["password"],
                )
                try:
                    wp_user = wp.call(GetUserInfo())
                    custom_wp_openid_url = "%s?user_id=%s" % (wp.url, wp_user.user_id)
                    user = authenticate(method="wordpress_site", wordpress_url=wp.url, wp_user_id=wp_user.user_id)
                    return finalize_generic_signin(
                        request=request,
                        user=user,
                        user_identifier=custom_wp_openid_url,
                        login_provider_name=provider_name,
                        redirect_url=next_url,
                    )
                except WpFault, e:
                    logging.critical(unicode(e))
                    msg = _("The login password combination was not correct")
                    request.user.message_set.create(message=msg)