Ejemplo n.º 1
0
    def execute(self, user_id: int, name: str, code: str) -> Set[str]:
        mfa = self._mfa_model.objects.get_by_name(user_id=user_id, name=name)

        get_mfa_handler(mfa).confirm_activation(code)

        rows_affected = self._mfa_model.objects.filter(
            user_id=user_id, name=name).update(
                is_active=True,
                is_primary=not self._mfa_model.objects.primary_exists(
                    user_id=user_id),
            )

        if rows_affected < 1:
            raise MFAMethodDoesNotExistError()

        backup_codes = regenerate_backup_codes_for_mfa_method_command(
            user_id=user_id,
            name=name,
        )

        return backup_codes
Ejemplo n.º 2
0
 def is_authenticated(self, user_id: int, code: str) -> None:
     for auth_method in self._mfa_model.objects.list_active(user_id=user_id):
         validated_backup_code = validate_backup_code_command(
             value=code, backup_codes=auth_method.backup_codes
         )
         if get_mfa_handler(mfa_method=auth_method).validate_code(code=code):
             return
         if validated_backup_code:
             remove_backup_code_command(
                 user_id=auth_method.user_id, method_name=auth_method.name, code=code
             )
             return
     raise InvalidCodeError()
Ejemplo n.º 3
0
 def post(self, request: Request) -> Response:
     serializer = LoginSerializer(data=request.data)
     serializer.is_valid(raise_exception=True)
     try:
         user = authenticate_user_command(
             request=request,
             username=serializer.validated_data[User.USERNAME_FIELD],
             password=serializer.validated_data["password"],
         )
     except MFAValidationError as cause:
         return ErrorResponse(error=cause)
     try:
         mfa_model = get_mfa_model()
         mfa_method = mfa_model.objects.get_primary_active(user_id=user.id)
         get_mfa_handler(mfa_method=mfa_method).dispatch_message()
         return Response(
             data={
                 "ephemeral_token": user_token_generator.make_token(user),
                 "method": mfa_method.name,
             })
     except MFAMethodDoesNotExistError:
         return self._successful_authentication_response(user=user)
Ejemplo n.º 4
0
 def post(request: Request) -> Response:
     serializer = MFAMethodCodeSerializer(data=request.data)
     serializer.is_valid(raise_exception=True)
     try:
         method = serializer.validated_data.get("method")
         mfa_model = get_mfa_model()
         if method is None:
             method = mfa_model.objects.get_primary_active_name(
                 user_id=request.user.id)
         mfa = mfa_model.objects.get_by_name(user_id=request.user.id,
                                             name=method)
         return get_mfa_handler(mfa_method=mfa).dispatch_message()
     except MFAValidationError as cause:
         return ErrorResponse(error=cause)
Ejemplo n.º 5
0
 def authenticate_multi_factor(
     self,
     mfa_method: MFAMethod,
     user: AbstractUser,
     path: str = PATH_AUTH_JWT_LOGIN,
     path_2nd_factor: str = PATH_AUTH_JWT_LOGIN_CODE,
 ) -> Response:
     response = self._first_factor_request(user=user, path=path)
     ephemeral_token = self._extract_ephemeral_token_from_response(
         response=response)
     handler = get_mfa_handler(mfa_method=mfa_method)
     response = self._second_factor_request(handler=handler,
                                            ephemeral_token=ephemeral_token,
                                            path=path_2nd_factor)
     self._update_jwt_from_response(response=response)
     return response
Ejemplo n.º 6
0
 def post(request: Request, method: str) -> Response:
     try:
         source_field = get_mfa_config_by_name_query(
             name=method).get(SOURCE_FIELD)
     except MFAMethodDoesNotExistError as cause:
         return ErrorResponse(error=cause)
     if source_field is not None:
         serializer_class = generate_model_serializer(
             name="MFAMethodActivationValidator",
             model=request.user.__class__,
             fields=(source_field, ),
         )
         serializer = serializer_class(data=request.data)
         serializer.is_valid(raise_exception=True)
     try:
         mfa = create_mfa_method_command(
             user_id=request.user.id,
             name=method,
         )
     except MFAValidationError as cause:
         return ErrorResponse(error=cause)
     return get_mfa_handler(mfa_method=mfa).dispatch_message()
Ejemplo n.º 7
0
    def validate_code(self, value: str) -> str:
        if not value:
            raise OTPCodeMissingError()
        mfa_model = get_mfa_model()
        mfa = mfa_model.objects.get_by_name(user_id=self._user.id,
                                            name=self._mfa_method_name)
        self._validate_mfa_method(mfa)

        validated_backup_code = validate_backup_code_command(
            value=value, backup_codes=mfa.backup_codes)

        handler = get_mfa_handler(mfa)
        validation_method = getattr(handler,
                                    self._get_validation_method_name())
        if validation_method(value):
            return value

        if validated_backup_code:
            remove_backup_code_command(user_id=mfa.user_id,
                                       method_name=mfa.name,
                                       code=value)
            return value

        raise CodeInvalidOrExpiredError()