Skip to content

processor_service

django_spire.auth.sms.services.processor_service

AuthSmsProcessorService

Bases: BaseDjangoModelService['AuthSms']

Source code in django_spire/contrib/constructor/constructor.py
def __init__(self, obj: Any = None):
    self._obj_type_name: str = str(next(iter(self.__class__.__annotations__.values()))).split(
        '.'
    )[-1]

    if obj is None:
        return

    self._obj_mro_type_names = [cls.__name__ for cls in obj.__class__.__mro__]

    if self._obj_type_name not in self._obj_mro_type_names:
        message = f'{self.__class__.__name__} was instantiated with obj type "{obj.__class__.__name__}" and failed as it was expecting "{self._obj_type_name}".'
        raise ConstructorError(message)

    self._obj_type: type[TypeAny] = obj.__class__

    if self._obj_type is None or self._obj_type is ...:
        message = f'{self.__class__.__name__} top class attribute must have an annotated type.'
        raise ConstructorError(message)

    self.obj: TypeAny = obj

    if ABC not in self.__class__.__bases__:
        if not self._obj_is_valid:
            message = f'{self._obj_type_name} failed to validate on {self.__class__.__name__}'
            raise ConstructorError(message)

    self.__post_init__()

obj instance-attribute

clear_code

Source code in django_spire/auth/sms/services/processor_service.py
def clear_code(self) -> None:
    self.obj.services.save_model_obj(
        code_hash='',
        code_purpose='',
        code_expiration_datetime=None,
        code_attempt_count=0,
    )

close_session

Source code in django_spire/auth/sms/services/processor_service.py
def close_session(self) -> None:
    self.obj.services.save_model_obj(
        session_started_datetime=None,
        session_last_activity_datetime=None,
    )

confirm_code

Source code in django_spire/auth/sms/services/processor_service.py
def confirm_code(self, code: str, purpose: str) -> bool:
    if (
        self.obj.code_hash == ''
        or self.obj.code_purpose != purpose
        or self.obj.code_expiration_datetime is None
    ):
        return False

    if now() > self.obj.code_expiration_datetime:
        self.clear_code()
        return False

    attempt_count_max = settings.DJANGO_SPIRE_AUTH_SMS_CODE_ATTEMPT_COUNT_MAX

    if self.obj.code_attempt_count >= attempt_count_max:
        self.clear_code()
        return False

    if not check_password(code, self.obj.code_hash):
        self.obj.services.save_model_obj(
            code_attempt_count=self.obj.code_attempt_count + 1
        )
        return False

    self.clear_code()
    return True

issue_code

Source code in django_spire/auth/sms/services/processor_service.py
def issue_code(self, purpose: str) -> str:
    if purpose not in AuthSmsCodePurposeChoices.values:
        message = f'Unknown SMS auth purpose: {purpose}'
        raise ValueError(message)

    code = f'{secrets.randbelow(10 ** CODE_DIGIT_COUNT):0{CODE_DIGIT_COUNT}d}'
    expiry_minutes = settings.DJANGO_SPIRE_AUTH_SMS_CODE_EXPIRY_MINUTES

    self.obj.services.save_model_obj(
        code_hash=make_password(code),
        code_purpose=purpose,
        code_expiration_datetime=now() + timedelta(minutes=expiry_minutes),
        code_attempt_count=0,
    )
    return code

mark_verified

Source code in django_spire/auth/sms/services/processor_service.py
def mark_verified(self) -> None:
    self.obj.services.save_model_obj(is_verified=True, verified_datetime=now())

open_session

Source code in django_spire/auth/sms/services/processor_service.py
def open_session(self) -> None:
    current_datetime = now()

    self.obj.services.save_model_obj(
        session_started_datetime=current_datetime,
        session_last_activity_datetime=current_datetime,
    )

touch_session

Source code in django_spire/auth/sms/services/processor_service.py
def touch_session(self) -> None:
    self.obj.services.save_model_obj(session_last_activity_datetime=now())