text: # ******************************************************************************
  #
  # adapter.py:  django-allauth adapter for 2fa
  #
  # SPDX-License-Identifier: Apache-2.0
  #
  # django-allauth-2f2a, a 2fa adapter for django-allauth.
  #
  # ******************************************************************************
  #
  # Copyright 2016-2021 Víðir Valberg Guðmundsson and Percipient
  # Networks, LLC.
  # Copyright 2021 Jeremy A Gray <gray@flyquackswim.com>.
  #
  # Licensed under the Apache License, Version 2.0 (the "License"); you
  # may not use this file except in compliance with the License.  You
  # may obtain a copy of the License at
  #
  # http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  # implied.  See the License for the specific language governing
  # permissions and limitations under the License.
  #
  # ******************************************************************************
  #
  """Django-allauth adapter for 2fa."""
  
  from urllib.parse import urlencode
  
  from allauth.account.adapter import DefaultAccountAdapter
  from allauth.exceptions import ImmediateHttpResponse
  from django.http import HttpResponseRedirect
  from django.urls import reverse
  
  from allauth_2f2a.utils import user_has_valid_totp_device
  
  
  class OTPAdapter(DefaultAccountAdapter):
      """Django-allauth OTP adapter."""
  
      def has_2fa_enabled(self, user):
          """Determine if the user has 2fa configured.
  
          Returns
          -------
          boolean
              ``True`` if the user has 2fa configured, ``False``
              otherwise.
          """
          return user_has_valid_totp_device(user)
  
      def login(self, request, user):
          """Require 2fa for login if configured.
  
          Require 2fa for login if it has been configured by the user.
  
          Returns
          -------
          allauth.account.adapter.DefaultAccountAdapter
              The original django-allauth account adapter if 2fa is not
              enabled.
  
          Raises
          ------
          allauth.exceptions.ImmediateHttpResponse
              Redirects to 2fa URL if enabled.
          """
          if self.has_2fa_enabled(user):
              # Cast to string for the case when this is not a JSON
              # serializable object.
              request.session["allauth_2f2a_user_id"] = str(user.id)
  
              redirect_url = reverse("two-factor-authenticate")
              # Add "next" parameter to the URL.
              view = request.resolver_match.func.view_class()
              view.request = request
              success_url = view.get_success_url()
              query_params = request.GET.copy()
              if success_url:
                  query_params[view.redirect_field_name] = success_url
              if query_params:
                  redirect_url += "?" + urlencode(query_params)
  
              raise ImmediateHttpResponse(
                  response=HttpResponseRedirect(redirect_url),
              )
  
          # Otherwise defer to the original allauth adapter.
          return super(OTPAdapter, self).login(request, user)
  