def handle(self, *args, **options):
     # datetime.now minus expiry hours
     now_minus_expiry_time = timezone.now() - timedelta(
         hours=get_password_reset_token_expiry_time())
     clear_expired(now_minus_expiry_time)
Esempio n. 2
0
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        email = serializer.validated_data.get("email")

        # before we continue, delete all existing expired tokens
        password_reset_token_validation_time = get_password_reset_token_expiry_time()

        # datetime.now minus expiry hours
        now_minus_expiry_time = timezone.now() - timedelta(
            hours=password_reset_token_validation_time
        )

        # delete all tokens where created_at < now - 24 hours
        clear_expired(now_minus_expiry_time)

        # construct the condition
        # q = Q(username__iexact=email) | Q(email__iexact=email)

        # the hack is from https://stackoverflow.com/questions/28610144/q-object-parameters
        filters = get_password_reset_lookup_fields()
        filter_params = Q()
        for filter_obj in filters:
            filter_params |= Q(**{filter_obj: email})

        # find a user by  specified resetting field(case insensitive search)
        users = User.objects.filter(filter_params)

        active_user_found = False

        # iterate over all users and check if there is any user that is active
        # also check whether the password can be changed (is useable), as there could be users that are not allowed
        # to change their password (e.g., LDAP user)
        for user in users:
            if user.eligible_for_reset():
                active_user_found = True

        # No active user found, raise a validation error
        # but not if DJANGO_REST_RESETPASSWORD_NO_INFORMATION_LEAKAGE == True
        if not active_user_found and not getattr(
            settings, "DJANGO_REST_RESETPASSWORD_NO_INFORMATION_LEAKAGE", False
        ):
            raise exceptions.ValidationError(
                {
                    "email": [
                        _(
                            "There is no active user associated with this e-mail address or username or the password can not be changed"
                        )
                    ],
                }
            )

        # last but not least: iterate over all users that are active and can change their password
        # and create a Reset Password Token and send a signal with the created token
        for user in users:
            if user.eligible_for_reset():
                # define the token as none for now
                token = None

                # check if the user already has a token
                if user.password_reset_tokens.all().count() > 0:
                    # yes, already has a token, re-use this token
                    token = user.password_reset_tokens.all()[0]
                else:
                    # no token exists, generate a new token
                    token = ResetPasswordToken.objects.create(
                        user=user,
                        user_agent=request.META.get(HTTP_USER_AGENT_HEADER, ""),
                        ip_address=request.META.get(HTTP_IP_ADDRESS_HEADER, ""),
                    )
                # send a signal that the password token was created
                # let whoever receives this signal handle sending the email for the password reset
                reset_password_token_created.send(
                    sender=self.__class__, instance=self, reset_password_token=token
                )
        # done
        response_format[
            "message"
        ] = "A password reset token has been sent to the provided email address"
        response_format["status"] = True
        response_format["error"] = []
        return Response(response_format)
Esempio n. 3
0
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        try:
            serializer.is_valid(raise_exception=True)
            email = serializer.validated_data['email']
        except:
            email = ''
            user = request.data.get('email')

        # before we continue, delete all existing expired tokens
        password_reset_token_validation_time = get_password_reset_token_expiry_time(
        )

        # datetime.now minus expiry hours
        now_minus_expiry_time = timezone.now() - timedelta(
            hours=password_reset_token_validation_time)

        # delete all tokens where created_at < now - 24 hours
        clear_expired(now_minus_expiry_time)

        # find a user by email address (case insensitive search)
        users = AdvUser.objects.filter(
            **{'{}__iexact'.format(get_password_reset_lookup_field()): email})

        if not users:
            users = AdvUser.objects.filter(username=user)
        active_user_found = False

        # iterate over all users and check if there is any user that is active
        # also check whether the password can be changed (is useable), as there could be users that are not allowed
        # to change their password (e.g., LDAP user)
        for user in users:
            if user.eligible_for_reset():
                active_user_found = True

        # No active user found, raise a validation error
        # but not if DJANGO_REST_RESETPASSWORD_NO_INFORMATION_LEAKAGE == True
        if not active_user_found and not getattr(
                settings, 'DJANGO_REST_RESETPASSWORD_NO_INFORMATION_LEAKAGE',
                False):
            response_data = {
                'email': 'There is no user with this email or username'
            }
            return Response(response_data, status=status.HTTP_400_BAD_REQUEST)

        # last but not least: iterate over all users that are active and can change their password
        # and create a Reset Password Token and send a signal with the created token
        for user in users:
            if user.eligible_for_reset():
                # define the token as none for now
                token = None

                # check if the user already has a token
                if user.password_reset_tokens.all().count() > 0:
                    # yes, already has a token, re-use this token
                    token = user.password_reset_tokens.all()[0]
                else:
                    # no token exists, generate a new token
                    token = ResetPasswordToken.objects.create(
                        user=user,
                        user_agent=request.META.get(HTTP_USER_AGENT_HEADER,
                                                    ''),
                        ip_address=request.META.get(HTTP_IP_ADDRESS_HEADER,
                                                    ''),
                    )
                # send a signal that the password token was created
                # let whoever receives this signal handle sending the email for the password reset
                reset_password_token_created.send(sender=self.__class__,
                                                  instance=self,
                                                  reset_password_token=token,
                                                  username=user.username,
                                                  email=user.email)
        # done
        response_format = HttpRes().response
        response_format[
            'message'] = "A password reset token has been sent to the provided email address"
        response_format['status'] = True
        response_format['error'] = []
        return Response(response_format)