
from django_otp import login as otp_login
from django_otp.middleware import OTPMiddleware

from .sotp.models import SOTPDevice
from .totp.models import TOTPDevice

def init_otp(request):
    """
    Initialize OTP after login. This sets up OTP devices
    for django_otp and calls the middleware to fill
    request.user.is_verified().
    """

    tdev, created = TOTPDevice.objects.get_or_create(
        user=request.user,
        defaults={
            'name': 'TOTP device with LDAP secret',
        })
    if created:
        tdev.save()

    sdev, created = SOTPDevice.objects.get_or_create(
        user=request.user,
        defaults={
            'name': 'SOTP device with LDAP passwords',
        })
    if created:
        sdev.save()

    # if OTP is disabled, it will match already
    if tdev.verify_token():
        otp_login(request, tdev)

    # add .is_verified()
    OTPMiddleware().process_request(request)


from django.db import IntegrityError
from django_otp import login as otp_login
from django_otp.middleware import OTPMiddleware

from .sotp.models import SOTPDevice
from .totp.models import TOTPDevice

def init_otp(request):
    """
    Initialize OTP after login. This sets up OTP devices
    for django_otp and calls the middleware to fill
    request.user.is_verified().
    """

    tdev = TOTPDevice(user=request.user,
                      name='TOTP device with LDAP secret')
    try:
        tdev.save()
    except IntegrityError:
        tdev = TOTPDevice.objects.get(user=request.user)

    sdev = SOTPDevice(user=request.user,
                      name='SOTP device with LDAP secret')
    try:
        sdev.save()
    except IntegrityError:
        pass

    # if OTP is disabled, it will match already
    if tdev.verify_token():
        otp_login(request, tdev)

    # add .is_verified()
    OTPMiddleware().process_request(request)

Make otp_init() race condition safe.
Make otp_init() race condition safe.

A race condition in get_or_create() may have resulted in two devices
created per user. Now we guarantee only one. Not that it matters real
much...

  
+ from django.db import IntegrityError
  from django_otp import login as otp_login
  from django_otp.middleware import OTPMiddleware
  
  from .sotp.models import SOTPDevice
  from .totp.models import TOTPDevice
  
  def init_otp(request):
      """
      Initialize OTP after login. This sets up OTP devices
      for django_otp and calls the middleware to fill
      request.user.is_verified().
      """
  
+     tdev = TOTPDevice(user=request.user,
-     tdev, created = TOTPDevice.objects.get_or_create(
-         user=request.user,
-         defaults={
-             'name': 'TOTP device with LDAP secret',
+                       name='TOTP device with LDAP secret')
+     try:
-         })
-     if created:
          tdev.save()
+     except IntegrityError:
+         tdev = TOTPDevice.objects.get(user=request.user)
  
+     sdev = SOTPDevice(user=request.user,
-     sdev, created = SOTPDevice.objects.get_or_create(
-         user=request.user,
-         defaults={
-             'name': 'SOTP device with LDAP passwords',
+                       name='SOTP device with LDAP secret')
+     try:
-         })
-     if created:
          sdev.save()
+     except IntegrityError:
+         pass
  
      # if OTP is disabled, it will match already
      if tdev.verify_token():
          otp_login(request, tdev)
  
      # add .is_verified()
      OTPMiddleware().process_request(request)
  
Make otp_init() race condition safe.
## Code Before:

from django_otp import login as otp_login
from django_otp.middleware import OTPMiddleware

from .sotp.models import SOTPDevice
from .totp.models import TOTPDevice

def init_otp(request):
    """
    Initialize OTP after login. This sets up OTP devices
    for django_otp and calls the middleware to fill
    request.user.is_verified().
    """

    tdev, created = TOTPDevice.objects.get_or_create(
        user=request.user,
        defaults={
            'name': 'TOTP device with LDAP secret',
        })
    if created:
        tdev.save()

    sdev, created = SOTPDevice.objects.get_or_create(
        user=request.user,
        defaults={
            'name': 'SOTP device with LDAP passwords',
        })
    if created:
        sdev.save()

    # if OTP is disabled, it will match already
    if tdev.verify_token():
        otp_login(request, tdev)

    # add .is_verified()
    OTPMiddleware().process_request(request)

## Instruction:
Make otp_init() race condition safe.
## Code After:

from django.db import IntegrityError
from django_otp import login as otp_login
from django_otp.middleware import OTPMiddleware

from .sotp.models import SOTPDevice
from .totp.models import TOTPDevice

def init_otp(request):
    """
    Initialize OTP after login. This sets up OTP devices
    for django_otp and calls the middleware to fill
    request.user.is_verified().
    """

    tdev = TOTPDevice(user=request.user,
                      name='TOTP device with LDAP secret')
    try:
        tdev.save()
    except IntegrityError:
        tdev = TOTPDevice.objects.get(user=request.user)

    sdev = SOTPDevice(user=request.user,
                      name='SOTP device with LDAP secret')
    try:
        sdev.save()
    except IntegrityError:
        pass

    # if OTP is disabled, it will match already
    if tdev.verify_token():
        otp_login(request, tdev)

    # add .is_verified()
    OTPMiddleware().process_request(request)
