def signin_success(request, identity_url, openid_response): """ this is not a view, has no url pointing to this this function is called when OpenID provider returns successful response to user authentication Does actual authentication in Django site and redirects to the registration page, if necessary or adds another login method. """ logging.debug("") openid_data = util.from_openid_response(openid_response) # create janrain OpenID object request.session["openid"] = openid_data provider_name = util.get_openid_provider_name(openid_data.openid) user = authenticate(identifier=openid_data.openid, provider_name=provider_name, method="openid") next_url = get_next_url(request) request.session["email"] = openid_data.sreg.get("email", "") request.session["username"] = openid_data.sreg.get("nickname", "") return finalize_generic_signin( request=request, user=user, user_identifier=openid_data.openid, login_provider_name=provider_name, redirect_url=next_url, )
def signin_success(request, identity_url, openid_response): """ this is not a view, has no url pointing to this this function is called when OpenID provider returns successful response to user authentication Does actual authentication in Django site and redirects to the registration page, if necessary or adds another login method. """ logging.debug('') openid_data = util.from_openid_response( openid_response) #create janrain OpenID object request.session['openid'] = openid_data provider_name = util.get_openid_provider_name(openid_data.openid) user = authenticate(identifier=openid_data.openid, provider_name=provider_name, method='openid') next_url = get_next_url(request) request.session['email'] = openid_data.sreg.get('email', '') request.session['username'] = openid_data.sreg.get('nickname', '') return finalize_generic_signin(request=request, user=user, user_identifier=openid_data.openid, login_provider_name=provider_name, redirect_url=next_url)
def changeemail(request, action="change"): """ changeemail view. requires openid with request type GET todo: rewrite this view to not require openid signin just to enter email address when the external provider does not give email, because this application requires an email address to allow users recover lost logins to their accounts url: /email/* template : authenticator/changeemail.html """ logging.debug("") msg = request.GET.get("msg", None) extension_args = {} user_ = request.user if request.POST: if "cancel" in request.POST: msg = _("your email was not changed") request.user.message_set.create(message=msg) return HttpResponseRedirect(get_next_url(request)) form = forms.ChangeEmailForm(request.POST, user=user_) if form.is_valid(): new_email = form.cleaned_data["email"] if new_email != user_.email: if settings.EMAIL_VALIDATION == True: action = "validate" else: action = "done_novalidate" set_new_email(user_, new_email, nomessage=True) else: action = "keep" else: form = forms.ChangeEmailForm(initial={"email": user_.email}, user=user_) output = render_to_response( "authenticator/changeemail.html", { "form": form, "email": user_.email, "action_type": action, "gravatar_faq_url": reverse("faq") + "#gravatar", "change_email_url": reverse("user_changeemail"), "msg": msg, }, context_instance=RequestContext(request), ) if action == "validate": set_email_validation_message(user_) return output
def decorated_function(request): login_provider = request.REQUEST.get('login_provider', '').strip() try: forms.PasswordLoginProviderField().clean(login_provider) return view_func(request) except ValidationError: redirect_url = reverse('user_signin') next = get_next_url(request) if next: redirect_url += '?next=%s' % next return HttpResponseRedirect(redirect_url)
def changeemail(request, action='change'): """ changeemail view. requires openid with request type GET todo: rewrite this view to not require openid signin just to enter email address when the external provider does not give email, because this application requires an email address to allow users recover lost logins to their accounts url: /email/* template : authenticator/changeemail.html """ logging.debug('') msg = request.GET.get('msg', None) extension_args = {} user_ = request.user if request.POST: if 'cancel' in request.POST: msg = _('your email was not changed') request.user.message_set.create(message=msg) return HttpResponseRedirect(get_next_url(request)) form = forms.ChangeEmailForm(request.POST, user=user_) if form.is_valid(): new_email = form.cleaned_data['email'] if new_email != user_.email: if settings.EMAIL_VALIDATION == True: action = 'validate' else: action = 'done_novalidate' set_new_email(user_, new_email, nomessage=True) else: action = 'keep' else: form = forms.ChangeEmailForm(initial={'email': user_.email}, user=user_) output = render_to_response('authenticator/changeemail.html', { 'form': form, 'email': user_.email, 'action_type': action, 'gravatar_faq_url': reverse('faq') + '#gravatar', 'change_email_url': reverse('user_changeemail'), 'msg': msg }, context_instance=RequestContext(request)) if action == 'validate': set_email_validation_message(user_) return output
def signout(request): """ signout from the website. Remove openid from session and kill it. url : /signout/" """ logging.debug("") try: logging.debug("deleting openid session var") del request.session["openid"] except KeyError: logging.debug("failed") pass logout(request) logging.debug("user logged out") return HttpResponseRedirect(get_next_url(request))
def signout(request): """ signout from the website. Remove openid from session and kill it. url : /signout/" """ logging.debug('') try: logging.debug('deleting openid session var') del request.session['openid'] except KeyError: logging.debug('failed') pass logout(request) logging.debug('user logged out') return HttpResponseRedirect(get_next_url(request))
def show_signin_view( request, login_form=None, account_recovery_form=None, account_recovery_message=None, sticky=False, view_subtype="default", ): """url-less utility function that populates context of template 'authenticator/signin.html' and returns its rendered output """ allowed_subtypes = ("default", "add_openid", "email_sent", "change_openid", "bad_key") assert view_subtype in allowed_subtypes if sticky: next_url = reverse("user_signin") else: next_url = get_next_url(request) if login_form is None: login_form = forms.LoginForm(initial={"next": next_url}) if account_recovery_form is None: account_recovery_form = forms.AccountRecoveryForm() # initial = initial_data) # if request is GET if request.method == "GET": logging.debug("request method was GET") if request.user.is_authenticated(): existing_login_methods = UserAssociation.objects.filter(user=request.user) # annotate objects with extra data providers = util.get_enabled_login_providers() for login_method in existing_login_methods: provider_data = providers[login_method.provider_name] if provider_data["type"] == "password": # only external password logins will not be deletable # this is because users with those can lose access to their accounts permanently login_method.is_deletable = provider_data.get("password_changeable", False) else: login_method.is_deletable = True if view_subtype == "default": page_title = _("Please click any of the icons below to sign in") elif view_subtype == "email_sent": page_title = _("Account recovery email sent") elif view_subtype == "change_openid": if len(existing_login_methods) == 0: page_title = _("Please add one or more login methods.") else: page_title = _("If you wish, please add, remove or re-validate your login methods") elif view_subtype == "add_openid": page_title = _("Please wait a second! Your account is recovered, but ...") elif view_subtype == "bad_key": page_title = _("Sorry, this account recovery key has expired or is invalid") logging.debug("showing signin view") data = { "page_class": "openid-signin", "view_subtype": view_subtype, # add_openid|default "page_title": page_title, "login_form": login_form, "use_password_login": util.use_password_login(), "account_recovery_form": account_recovery_form, "openid_error_message": request.REQUEST.get("msg", ""), "account_recovery_message": account_recovery_message, "use_password_login": util.use_password_login(), } major_login_providers = util.get_enabled_major_login_providers() minor_login_providers = util.get_enabled_minor_login_providers() # determine if we are only using password login active_provider_names = [p["name"] for p in major_login_providers.values()] active_provider_names.extend([p["name"] for p in minor_login_providers.values()]) have_buttons = True if len(active_provider_names) == 1 and active_provider_names[0] == "local": if settings.SIGNIN_ALWAYS_SHOW_LOCAL_LOGIN == True: # in this case the form is not using javascript, so set initial values # here have_buttons = False login_form.initial["login_provider_name"] = "local" if request.user.is_authenticated(): login_form.initial["password_action"] = "change_password" else: login_form.initial["password_action"] = "login" data["have_buttons"] = have_buttons if request.user.is_authenticated(): data["existing_login_methods"] = existing_login_methods active_provider_names = [item.provider_name for item in existing_login_methods] util.set_login_provider_tooltips(major_login_providers, active_provider_names=active_provider_names) util.set_login_provider_tooltips(minor_login_providers, active_provider_names=active_provider_names) data["major_login_providers"] = major_login_providers.values() data["minor_login_providers"] = minor_login_providers.values() return render_to_response("authenticator/signin.html", RequestContext(request, data))
def signin(request): """ signin page. It manages the legacy authentification (user/password) and openid authentification url: /signin/ template : authenticator/signin.htm """ logging.debug("in signin view") on_failure = signin_failure next_url = get_next_url(request) logging.debug("next url is %s" % next_url) if 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 settings.USE_LDAP_FOR_PASSWORD_LOGIN: assert password_action == "login" ldap_provider_name = settings.LDAP_PROVIDER_NAME username = login_form.cleaned_data["username"] if util.ldap_check_password(username, login_form.cleaned_data["password"]): user = authenticate(identifier=username, provider_name=ldap_provider_name, method="ldap") if user: login(request, user) return HttpResponseRedirect(next_url) else: return finalize_generic_signin( request=request, user=user, user_identifier=username, login_provider_name=ldap_provider_name, redirect_url=next_url, ) else: login_form.set_password_login_error() else: if password_action == "login": username = login_form.cleaned_data["username"] user = authenticate( identifier="%s@%s" % (username, provider_name), username=username, password=login_form.cleaned_data["password"], provider_name=provider_name, method="password", ) if user: login(request, user) # todo: here we might need to set cookies # for external login sites if user.email.strip() == "": redirect_url = reverse_with_next("user_changeemail", next_url) return HttpResponseRedirect(redirect_url) return HttpResponseRedirect(next_url) else: login_form.set_password_login_error() 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 return ask_openid( request, openid_url=login_form.cleaned_data["openid_url"], next_url=next_url, on_failure=signin_failure, ) 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(identifier=user_id, method="facebook", provider_name="facebook") 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 try: wp_user_identifier = backends.authenticate_by_wordpress_site( username=login_form.cleaned_data["username"], password=login_form.cleaned_data["password"] ) if wp_user_identifier: user = authenticate( method="wordpress_site", identifier=wp_user_identifier, provider_name=u"wordpress_site" ) return finalize_generic_signin( request=request, user=user, user_identifier=wp_user_identifier, login_provider_name=provider_name, redirect_url=next_url, ) else: login_form.set_password_login_error() except Exception, e: logging.critical(unicode(e)) msg = _("Unfortunately there was some problem connecting " "to the wordpress blog") request.user.message_set.create(message=msg)
def decorated(request, *args, **kwargs): if request.user.is_authenticated(): return HttpResponseRedirect(get_next_url(request)) return func(request, *args, **kwargs)
def show_signin_view(request, login_form=None, account_recovery_form=None, account_recovery_message=None, sticky=False, view_subtype='default'): """url-less utility function that populates context of template 'authenticator/signin.html' and returns its rendered output """ allowed_subtypes = ('default', 'add_openid', 'email_sent', 'change_openid', 'bad_key') assert (view_subtype in allowed_subtypes) if sticky: next_url = reverse('user_signin') else: next_url = get_next_url(request) if login_form is None: login_form = forms.LoginForm(initial={'next': next_url}) if account_recovery_form is None: account_recovery_form = forms.AccountRecoveryForm( ) #initial = initial_data) #if request is GET if request.method == 'GET': logging.debug('request method was GET') if request.user.is_authenticated(): existing_login_methods = UserAssociation.objects.filter( user=request.user) #annotate objects with extra data providers = util.get_enabled_login_providers() for login_method in existing_login_methods: provider_data = providers[login_method.provider_name] if provider_data['type'] == 'password': #only external password logins will not be deletable #this is because users with those can lose access to their accounts permanently login_method.is_deletable = provider_data.get( 'password_changeable', False) else: login_method.is_deletable = True if view_subtype == 'default': page_title = _('Please click any of the icons below to sign in') elif view_subtype == 'email_sent': page_title = _('Account recovery email sent') elif view_subtype == 'change_openid': if len(existing_login_methods) == 0: page_title = _('Please add one or more login methods.') else: page_title = _( 'If you wish, please add, remove or re-validate your login methods' ) elif view_subtype == 'add_openid': page_title = _( 'Please wait a second! Your account is recovered, but ...') elif view_subtype == 'bad_key': page_title = _( 'Sorry, this account recovery key has expired or is invalid') logging.debug('showing signin view') data = { 'page_class': 'openid-signin', 'view_subtype': view_subtype, #add_openid|default 'page_title': page_title, 'login_form': login_form, 'use_password_login': util.use_password_login(), 'account_recovery_form': account_recovery_form, 'openid_error_message': request.REQUEST.get('msg', ''), 'account_recovery_message': account_recovery_message, 'use_password_login': util.use_password_login(), } major_login_providers = util.get_enabled_major_login_providers() minor_login_providers = util.get_enabled_minor_login_providers() #determine if we are only using password login active_provider_names = [p['name'] for p in major_login_providers.values()] active_provider_names.extend( [p['name'] for p in minor_login_providers.values()]) have_buttons = True if (len(active_provider_names) == 1 and active_provider_names[0] == 'local'): if settings.SIGNIN_ALWAYS_SHOW_LOCAL_LOGIN == True: #in this case the form is not using javascript, so set initial values #here have_buttons = False login_form.initial['login_provider_name'] = 'local' if request.user.is_authenticated(): login_form.initial['password_action'] = 'change_password' else: login_form.initial['password_action'] = 'login' data['have_buttons'] = have_buttons if request.user.is_authenticated(): data['existing_login_methods'] = existing_login_methods active_provider_names = [ item.provider_name for item in existing_login_methods ] util.set_login_provider_tooltips( major_login_providers, active_provider_names=active_provider_names) util.set_login_provider_tooltips( minor_login_providers, active_provider_names=active_provider_names) data['major_login_providers'] = major_login_providers.values() data['minor_login_providers'] = minor_login_providers.values() return render_to_response('authenticator/signin.html', RequestContext(request, data))
def signin(request): """ signin page. It manages the legacy authentification (user/password) and openid authentification url: /signin/ template : authenticator/signin.htm """ logging.debug('in signin view') on_failure = signin_failure next_url = get_next_url(request) logging.debug('next url is %s' % next_url) if 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 settings.USE_LDAP_FOR_PASSWORD_LOGIN: assert (password_action == 'login') ldap_provider_name = settings.LDAP_PROVIDER_NAME username = login_form.cleaned_data['username'] if util.ldap_check_password( username, login_form.cleaned_data['password']): user = authenticate(identifier=username, provider_name=ldap_provider_name, method='ldap') if user: login(request, user) return HttpResponseRedirect(next_url) else: return finalize_generic_signin( request=request, user=user, user_identifier=username, login_provider_name=ldap_provider_name, redirect_url=next_url) else: login_form.set_password_login_error() else: if password_action == 'login': username = login_form.cleaned_data['username'] user = authenticate( identifier='%s@%s' % (username, provider_name), username=username, password=login_form.cleaned_data['password'], provider_name=provider_name, method='password') if user: login(request, user) #todo: here we might need to set cookies #for external login sites if user.email.strip() == '': redirect_url = reverse_with_next( 'user_changeemail', next_url) return HttpResponseRedirect(redirect_url) return HttpResponseRedirect(next_url) else: login_form.set_password_login_error() 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 return ask_openid( request, openid_url=login_form.cleaned_data['openid_url'], next_url=next_url, on_failure=signin_failure) 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(identifier=user_id, method='facebook', provider_name='facebook') 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 try: wp_user_identifier = backends.authenticate_by_wordpress_site( username=login_form.cleaned_data['username'], password=login_form.cleaned_data['password']) if wp_user_identifier: user = authenticate(method='wordpress_site', identifier=wp_user_identifier, provider_name=u'wordpress_site') return finalize_generic_signin( request=request, user=user, user_identifier=wp_user_identifier, login_provider_name=provider_name, redirect_url=next_url) else: login_form.set_password_login_error() except Exception, e: logging.critical(unicode(e)) msg = _('Unfortunately there was some problem connecting ' 'to the wordpress blog') request.user.message_set.create(message=msg)