django-rest-framework-passwordless icon indicating copy to clipboard operation
django-rest-framework-passwordless copied to clipboard

Unique constraint violation on CallbackToken

Open poco-loco-athul opened this issue 3 years ago • 2 comments

Trace back:

[ERROR   ] Internal Server Error: /auth/mobile/
Traceback (most recent call last):
  File "/home/ubuntu/.virtualenvs/project/lib/python3.6/site-packages/django/db/backends/utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
  File "/home/ubuntu/.virtualenvs/project/lib/python3.6/site-packages/newrelic/hooks/database_psycopg2.py", line 65, in execute
    **kwargs)
  File "/home/ubuntu/.virtualenvs/project/lib/python3.6/site-packages/newrelic/hooks/database_dbapi2.py", line 39, in execute
    *args, **kwargs)
psycopg2.errors.UniqueViolation: duplicate key value violates unique constraint "drfpasswordless_callbacktoken_is_active_key_type_78906b19_uniq"
DETAIL:  Key (is_active, key, type)=(f, 585258, AUTH) already exists.

There is about 14,000 Callback token in the system. Using drfpasswordless==1.5.6

Here is my understanding of the problem: In this scenario, there is two callback token with key '585258'. For one active is true, for others it is false. When passwordless try to create another token for the user with active true, drfpasswordless.signals.invalidate_previous_tokens runs and creates this error.

@receiver(signals.post_save, sender=CallbackToken)
def invalidate_previous_tokens(sender, instance, created, **kwargs):
    """
    Invalidates all previously issued tokens of that type when a new one is created, used, or anything like that.
    """

    if instance.user.pk in api_settings.PASSWORDLESS_DEMO_USERS.keys():
        return

    if isinstance(instance, CallbackToken):
        CallbackToken.objects.active().filter(user=instance.user, type=instance.type).exclude(id=instance.id).update(is_active=False)

poco-loco-athul avatar Nov 11 '20 10:11 poco-loco-athul

Hm– we could try generating a few more times on an IntegrityError.

aaronn avatar Nov 17 '20 02:11 aaronn

Why do we need unique keys here? I mean, ok we will generate 2 times the code 123456 (in theory this can happen). What's wrong with that? Only the last one key should be active and we don't care about all previous keys, right?

taime avatar May 02 '22 01:05 taime