Beispiel #1
0
def check_unique_tokens(sender, instance, **kwargs):
    """
    Ensures that mobile and email tokens are unique by redoing the key generation
    """
    if isinstance(instance, CallbackToken):
        while CallbackToken.objects.filter(key=instance.key, is_active=True).exists():
            instance.key = generate_numeric_token()
def check_unique_tokens(sender, instance, **kwargs):
    """
    Ensures that mobile and email tokens are unique or tries once more to generate.
    """
    if isinstance(instance, CallbackToken):
        if CallbackToken.objects.filter(key=instance.key, is_active=True).exists():
            instance.key = generate_numeric_token()
Beispiel #3
0
def check_unique_tokens(sender, instance, **kwargs):
    """
    Ensures that mobile and email tokens are unique or tries once more to generate.
    """
    if isinstance(instance, CallbackToken):
        if reduce(getattr, api_settings.DEMO_2FA_FIELD.split('.'),
                  instance.user):
            return
        if CallbackToken.objects.filter(key=instance.key,
                                        is_active=True).exists():
            instance.key = generate_numeric_token()
def check_unique_tokens(sender, instance, **kwargs):
    """
    Ensures that mobile and email tokens are unique or tries once more to generate.
    Note that here we've decided keys are unique even across auth and validation.
    We could consider relaxing this in the future as well by filtering on the instance.type.
    """
    if instance._state.adding:
        # save is called on a token to create it in the db
        # before creating check whether a token with the same key exists
        if isinstance(instance, CallbackToken):
            unique = False
            tries = 0

            if CallbackToken.objects.filter(key=instance.key,
                                            is_active=True).exists():
                # Try N(default=3) times before giving up.
                while tries < api_settings.PASSWORDLESS_TOKEN_GENERATION_ATTEMPTS:
                    tries = tries + 1
                    new_key = generate_numeric_token()
                    instance.key = new_key

                    if not CallbackToken.objects.filter(
                            key=instance.key, is_active=True).exists():
                        # Leave the loop if we found a valid token that doesn't exist yet.
                        unique = True
                        break

                if not unique:
                    # A unique value wasn't found after three tries
                    raise ValidationError(
                        "Couldn't create a unique token even after retrying.")
            else:
                # A unique value was found immediately.
                pass

    else:
        # save is called on an already existing token to update it. Such as invalidating it.
        # in that case there is no need to check for the key. This way we both avoid an unneccessary db hit
        # and avoid to change key field of used tokens.
        pass
Beispiel #5
0
def create_callback_token_for_user(user,
                                   alias_type,
                                   token_type,
                                   to_alias=None):
    token = None
    alias_type_u = alias_type.upper()

    if to_alias is None:
        to_alias = eval(
            f"user.{api_settings.PASSWORDLESS_USER_EMAIL_FIELD_NAME}")

    key = generate_numeric_token()
    CallbackToken.objects.filter(key=key,
                                 user=user,
                                 type=token_type,
                                 to_alias_type=alias_type_u).delete()

    if alias_type_u == 'EMAIL':
        token = CallbackToken.objects.create(user=user,
                                             to_alias_type=alias_type_u,
                                             to_alias=to_alias,
                                             type=token_type,
                                             key=key)

    elif alias_type_u == 'MOBILE':
        token = CallbackToken.objects.create(user=user,
                                             to_alias_type=alias_type_u,
                                             to_alias=to_alias,
                                             type=token_type,
                                             key=key)

    if token is not None:
        if reduce(getattr, api_settings.DEMO_2FA_FIELD.split('.'), user):
            token.key = api_settings.DEMO_2FA_PINCODE
            token.save()
        return token

    return None