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
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
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
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>™', 'google':'Google™', '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)
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>™', "google": "Google™", "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)
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)