def form_valid(self, form): """ The allauth 2fa login flow is now done (the user logged in successfully with 2FA), continue the logic from allauth.account.utils.perform_login since it was interrupted earlier. """ adapter = get_adapter(self.request) # Skip over the (already done) 2fa login flow and continue the original # allauth login flow. super(adapter.__class__, adapter).login(self.request, form.user) # Perform the rest of allauth.account.utils.perform_login, this is # copied from commit cedad9f156a8c78bfbe43a0b3a723c1a0b840dbd. # TODO Support redirect_url. response = HttpResponseRedirect(get_login_redirect_url(self.request)) # TODO Support signal_kwargs. signals.user_logged_in.send(sender=form.user.__class__, request=self.request, response=response, user=form.user) adapter.add_message(self.request, messages.SUCCESS, 'account/messages/logged_in.txt', {'user': form.user}) return response
def perform_login(request, user, email_verification, redirect_url=None, signal_kwargs=None, signup=False): """ Overridden from allauth: we needed access to the EmailAddress object and it wasn't possible to extend it otherwise. We need to append the 'donate=True' param to the confirm email link so that the user can resume donation. Keyword arguments: signup -- Indicates whether or not sending the email is essential (during signup), or if it can be skipped (e.g. in case email verification is optional and we are only logging in). """ from .models import SmallsEmailAddress has_verified_email = SmallsEmailAddress.objects.filter( user=user, verified=True).exists() if email_verification == EmailVerificationMethod.NONE: pass elif email_verification == EmailVerificationMethod.OPTIONAL: # In case of OPTIONAL verification: send on signup. if not has_verified_email and signup: send_email_confirmation(request, user, signup=signup, activate_view='account_confirm_email') elif email_verification == EmailVerificationMethod.MANDATORY: if not has_verified_email: send_email_confirmation(request, user, signup=signup, activate_view='account_confirm_email') return HttpResponseRedirect( reverse('account_email_verification_sent')) # Local users are stopped due to form validation checking # is_active, yet, adapter methods could toy with is_active in a # `user_signed_up` signal. Furthermore, social users should be # stopped anyway. if not user.is_active: return HttpResponseRedirect(reverse('account_inactive')) get_adapter().login(request, user) response = HttpResponseRedirect( get_login_redirect_url(request, redirect_url)) if signal_kwargs is None: signal_kwargs = {} signals.user_logged_in.send(sender=user.__class__, request=request, response=response, user=user, **signal_kwargs) return response
def pre_social_login(self, request, sociallogin): """ Login and redirect This is done in order to tackle the situation where user's email retrieved from one provider is different from already existing email in the database (e.g facebook and google both use same email-id). Specifically, this is done to tackle following issues: * https://github.com/pennersr/django-allauth/issues/215 """ email_address = sociallogin.account.extra_data.get('email', None) if not email_address: return try: user = get_user_model().objects.get(email=email_address) perform_login(request, user, email_verification=app_settings.EMAIL_VERIFICATION) if not sociallogin.is_existing: sociallogin.connect(request, user) raise ImmediateHttpResponse(redirect(get_login_redirect_url(request))) except get_user_model().DoesNotExist: pass
def get_connect_redirect_url(self, request: HttpRequest, socialaccount: SocialAccount): try: return super().get_connect_redirect_url(request, socialaccount) except NoReverseMatch: return get_login_redirect_url(request)