예제 #1
0
    def test_too_small(self, endpoint: Endpoint) -> None:
        """
        An ``UNAUTHORIZED`` response is given if the given content length is
        too small.
        """
        endpoint_headers = dict(endpoint.prepared_request.headers)
        if not endpoint_headers.get('Content-Type'):
            return

        content_length = str(int(endpoint_headers['Content-Length']) - 1)
        headers = {**endpoint_headers, 'Content-Length': content_length}

        endpoint.prepared_request.headers = CaseInsensitiveDict(data=headers)
        session = requests.Session()
        response = session.send(  # type: ignore
            request=endpoint.prepared_request,
        )

        url = str(endpoint.prepared_request.url)
        netloc = urlparse(url).netloc
        if netloc == 'cloudreco.vuforia.com':
            assert_vwq_failure(
                response=response,
                status_code=HTTPStatus.UNAUTHORIZED,
                content_type='application/json',
            )
            return

        assert_vws_failure(
            response=response,
            status_code=HTTPStatus.UNAUTHORIZED,
            result_code=ResultCodes.AUTHENTICATION_FAILURE,
        )
    def test_incorrect_date_format(
        self,
        endpoint: Endpoint,
    ) -> None:
        """
        A `BAD_REQUEST` response is returned when the date given in the date
        header is not in the expected format (RFC 1123) to VWS API.

        An `UNAUTHORIZED` response is returned to the VWQ API.
        """
        gmt = ZoneInfo('GMT')
        with freeze_time(datetime.now(tz=gmt)):
            now = datetime.now()
            date_incorrect_format = now.strftime('%a %b %d %H:%M:%S')

        endpoint_headers = dict(endpoint.prepared_request.headers)
        content = endpoint.prepared_request.body or b''
        assert isinstance(content, bytes)

        authorization_string = authorization_header(
            access_key=endpoint.access_key,
            secret_key=endpoint.secret_key,
            method=str(endpoint.prepared_request.method),
            content=content,
            content_type=endpoint.auth_header_content_type,
            date=date_incorrect_format,
            request_path=endpoint.prepared_request.path_url,
        )

        headers = {
            **endpoint_headers,
            'Authorization': authorization_string,
            'Date': date_incorrect_format,
        }

        endpoint.prepared_request.headers = CaseInsensitiveDict(data=headers)
        session = requests.Session()
        response = session.send(request=endpoint.prepared_request)

        url = str(endpoint.prepared_request.url)
        netloc = urlparse(url).netloc
        if netloc == 'cloudreco.vuforia.com':
            assert response.text == 'Malformed date header.'
            assert_vwq_failure(
                response=response,
                status_code=HTTPStatus.UNAUTHORIZED,
                content_type='text/plain;charset=iso-8859-1',
                cache_control=None,
                www_authenticate='VWS',
                connection='keep-alive',
            )
            return

        assert_vws_failure(
            response=response,
            status_code=HTTPStatus.BAD_REQUEST,
            result_code=ResultCodes.FAIL,
        )
예제 #3
0
    def test_missing_signature(
        self,
        endpoint: Endpoint,
        authorization_string: str,
    ) -> None:
        """
        If a signature is missing `Authorization` header is given, a
        ``BAD_REQUEST`` response is given.
        """
        date = rfc_1123_date()

        headers: Dict[str, str] = {
            **endpoint.prepared_request.headers,
            'Authorization': authorization_string,
            'Date': date,
        }

        endpoint.prepared_request.headers = CaseInsensitiveDict(data=headers)
        session = requests.Session()
        response = session.send(request=endpoint.prepared_request)

        url = str(endpoint.prepared_request.url)
        netloc = urlparse(url).netloc
        if netloc == 'cloudreco.vuforia.com':
            assert_vwq_failure(
                response=response,
                status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
                content_type='text/html;charset=iso-8859-1',
                cache_control='must-revalidate,no-cache,no-store',
                www_authenticate=None,
                connection='keep-alive',
            )
            content_filename = 'jetty_error_array_out_of_bounds.html'
            content_filename_2 = 'jetty_error_array_out_of_bounds_2.html'
            content_filename_3 = 'jetty_error_array_out_of_bounds_3.html'
            content_path = Path(__file__).parent / content_filename
            content_path_2 = Path(__file__).parent / content_filename_2
            content_path_3 = Path(__file__).parent / content_filename_3
            content_text = content_path.read_text()
            content_2_text = content_path_2.read_text()
            content_3_text = content_path_3.read_text()
            # We make a new variable for response text so that it is printed
            # with ``pytest --showlocals``.
            response_text = response.text
            assert response_text in (
                content_text,
                content_2_text,
                content_3_text,
            )
            return

        assert_vws_failure(
            response=response,
            status_code=HTTPStatus.BAD_REQUEST,
            result_code=ResultCodes.FAIL,
        )
    def test_no_date_header(
        self,
        endpoint: Endpoint,
    ) -> None:
        """
        A `BAD_REQUEST` response is returned when no `Date` header is given.
        """
        endpoint_headers = dict(endpoint.prepared_request.headers)
        content = endpoint.prepared_request.body or b''
        assert isinstance(content, bytes)

        authorization_string = authorization_header(
            access_key=endpoint.access_key,
            secret_key=endpoint.secret_key,
            method=str(endpoint.prepared_request.method),
            content=content,
            content_type=endpoint.auth_header_content_type,
            date='',
            request_path=endpoint.prepared_request.path_url,
        )

        headers: Dict[str, str] = {
            **endpoint_headers,
            'Authorization': authorization_string,
        }
        headers.pop('Date', None)
        endpoint.prepared_request.headers = CaseInsensitiveDict(data=headers)
        session = requests.Session()
        response = session.send(request=endpoint.prepared_request)

        url = str(endpoint.prepared_request.url)
        netloc = urlparse(url).netloc
        if netloc == 'cloudreco.vuforia.com':
            expected_content_type = 'text/plain;charset=iso-8859-1'
            assert response.text == 'Date header required.'
            assert_vwq_failure(
                response=response,
                status_code=HTTPStatus.BAD_REQUEST,
                content_type=expected_content_type,
                cache_control=None,
                www_authenticate=None,
                connection='keep-alive',
            )
            return

        assert_vws_failure(
            response=response,
            status_code=HTTPStatus.BAD_REQUEST,
            result_code=ResultCodes.FAIL,
        )
예제 #5
0
    def test_one_part_no_space(
        self,
        endpoint: Endpoint,
        authorization_string: str,
    ) -> None:
        """
        A valid authorization string is two "parts" when split on a space. When
        a string is given which is one "part", a ``BAD_REQUEST`` or
        ``UNAUTHORIZED`` response is returned.
        """
        date = rfc_1123_date()

        headers: Dict[str, str] = {
            **endpoint.prepared_request.headers,
            'Authorization': authorization_string,
            'Date': date,
        }

        endpoint.prepared_request.headers = CaseInsensitiveDict(data=headers)
        session = requests.Session()
        response = session.send(request=endpoint.prepared_request)

        url = str(endpoint.prepared_request.url)
        netloc = urlparse(url).netloc
        if netloc == 'cloudreco.vuforia.com':
            assert_vwq_failure(
                response=response,
                status_code=HTTPStatus.UNAUTHORIZED,
                content_type='text/plain;charset=iso-8859-1',
                cache_control=None,
                www_authenticate='VWS',
                connection='keep-alive',
            )
            assert response.text == 'Malformed authorization header.'
            return

        assert_vws_failure(
            response=response,
            status_code=HTTPStatus.BAD_REQUEST,
            result_code=ResultCodes.FAIL,
        )
    def test_missing_signature(
        self,
        endpoint: Endpoint,
        authorization_string: str,
    ) -> None:
        """
        If a signature is missing `Authorization` header is given, a
        ``BAD_REQUEST`` response is given.
        """
        date = rfc_1123_date()

        headers: Dict[str, str] = {
            **endpoint.prepared_request.headers,
            'Authorization': authorization_string,
            'Date': date,
        }

        endpoint.prepared_request.headers = CaseInsensitiveDict(data=headers)
        session = requests.Session()
        response = session.send(  # type: ignore
            request=endpoint.prepared_request, )

        url = str(endpoint.prepared_request.url)
        netloc = urlparse(url).netloc
        if netloc == 'cloudreco.vuforia.com':
            assert_vwq_failure(
                response=response,
                status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
                content_type='text/html; charset=ISO-8859-1',
            )
            # We have seen multiple responses given.
            assert 'Powered by Jetty' in response.text
            assert '500 Server Error' in response.text
            return

        assert_vws_failure(
            response=response,
            status_code=HTTPStatus.BAD_REQUEST,
            result_code=ResultCodes.FAIL,
        )
예제 #7
0
    def test_bad_secret_key_query(
        self,
        vuforia_database: VuforiaDatabase,
        high_quality_image: io.BytesIO,
    ) -> None:
        """
        If the client secret key given is incorrect, an ``UNAUTHORIZED``
        response is returned.
        """
        cloud_reco_client = CloudRecoService(
            client_access_key=vuforia_database.client_access_key,
            client_secret_key='example',
        )

        with pytest.raises(cloud_reco_exceptions.AuthenticationFailure) as exc:
            cloud_reco_client.query(image=high_quality_image)

        response = exc.value.response

        assert_vwq_failure(
            response=response,
            status_code=HTTPStatus.UNAUTHORIZED,
            content_type='application/json',
            cache_control=None,
            www_authenticate='VWS',
            connection='keep-alive',
        )

        assert response.json().keys() == {'transaction_id', 'result_code'}
        assert_valid_transaction_id(response=response)
        assert_valid_date_header(response=response)
        result_code = response.json()['result_code']
        transaction_id = response.json()['transaction_id']
        assert result_code == ResultCodes.AUTHENTICATION_FAILURE.value
        # The separators are inconsistent and we test this.
        expected_text = ('{"transaction_id":'
                         f'"{transaction_id}",'
                         f'"result_code":"{result_code}"'
                         '}')
        assert response.text == expected_text
예제 #8
0
    def test_missing(self, endpoint: Endpoint) -> None:
        """
        An `UNAUTHORIZED` response is returned when no `Authorization` header
        is given.
        """
        date = rfc_1123_date()
        endpoint_headers = dict(endpoint.prepared_request.headers)

        headers: Dict[str, str] = {
            **endpoint_headers,
            'Date': date,
        }

        headers.pop('Authorization', None)

        endpoint.prepared_request.headers = CaseInsensitiveDict(data=headers)
        session = requests.Session()
        response = session.send(request=endpoint.prepared_request)

        url = str(endpoint.prepared_request.url)
        netloc = urlparse(url).netloc
        if netloc == 'cloudreco.vuforia.com':
            assert_vwq_failure(
                response=response,
                status_code=HTTPStatus.UNAUTHORIZED,
                content_type='text/plain;charset=iso-8859-1',
                cache_control=None,
                www_authenticate='VWS',
                connection='keep-alive',
            )
            assert response.text == 'Authorization header missing.'
            return

        assert_vws_failure(
            response=response,
            status_code=HTTPStatus.UNAUTHORIZED,
            result_code=ResultCodes.AUTHENTICATION_FAILURE,
        )
예제 #9
0
    def test_invalid_json(
        self,
        endpoint: Endpoint,
        date_skew_minutes: int,
    ) -> None:
        """
        Giving invalid JSON to endpoints returns error responses.
        """
        date_is_skewed = not date_skew_minutes == 0
        content = b'a'
        gmt = ZoneInfo('GMT')
        now = datetime.now(tz=gmt)
        time_to_freeze = now + timedelta(minutes=date_skew_minutes)
        with freeze_time(time_to_freeze):
            date = rfc_1123_date()

        endpoint_headers = dict(endpoint.prepared_request.headers)
        authorization_string = authorization_header(
            access_key=endpoint.access_key,
            secret_key=endpoint.secret_key,
            method=str(endpoint.prepared_request.method),
            content=content,
            content_type=endpoint.auth_header_content_type,
            date=date,
            request_path=endpoint.prepared_request.path_url,
        )

        headers = {
            **endpoint_headers,
            'Authorization': authorization_string,
            'Date': date,
        }

        endpoint.prepared_request.body = content
        endpoint.prepared_request.headers = CaseInsensitiveDict(data=headers)
        endpoint.prepared_request.prepare_content_length(body=content)
        session = requests.Session()
        response = session.send(  # type: ignore
            request=endpoint.prepared_request,
        )

        takes_json_data = (
            endpoint.auth_header_content_type == 'application/json'
        )

        assert_valid_date_header(response=response)

        if date_is_skewed and takes_json_data:
            # On the real implementation, we get `HTTPStatus.FORBIDDEN` and
            # `REQUEST_TIME_TOO_SKEWED`.
            # See https://github.com/VWS-Python/vws-python-mock/issues/4 for
            # implementing this on them mock.
            return

        if not date_is_skewed and takes_json_data:
            assert_vws_failure(
                response=response,
                status_code=HTTPStatus.BAD_REQUEST,
                result_code=ResultCodes.FAIL,
            )
            return

        assert response.status_code == HTTPStatus.BAD_REQUEST
        url = str(endpoint.prepared_request.url)
        netloc = urlparse(url).netloc
        if netloc == 'cloudreco.vuforia.com':
            assert_vwq_failure(
                response=response,
                status_code=HTTPStatus.BAD_REQUEST,
                content_type='text/html;charset=UTF-8',
            )
            expected_text = (
                'java.lang.RuntimeException: RESTEASY007500: '
                'Could find no Content-Disposition header within part'
            )
            assert response.text == expected_text
            return

        assert response.text == ''
        assert 'Content-Type' not in response.headers
예제 #10
0
    def test_does_not_take_data(
        self,
        endpoint: Endpoint,
    ) -> None:
        """
        Giving JSON to endpoints which do not take any JSON data returns error
        responses.
        """
        if (
            endpoint.prepared_request.headers.get(
                'Content-Type',
            )
            == 'application/json'
        ):
            return
        content = bytes(json.dumps({'key': 'value'}), encoding='utf-8')
        content_type = 'application/json'
        date = rfc_1123_date()

        endpoint_headers = dict(endpoint.prepared_request.headers)

        authorization_string = authorization_header(
            access_key=endpoint.access_key,
            secret_key=endpoint.secret_key,
            method=str(endpoint.prepared_request.method),
            content=content,
            content_type=content_type,
            date=date,
            request_path=endpoint.prepared_request.path_url,
        )

        headers = {
            **endpoint_headers,
            'Authorization': authorization_string,
            'Date': date,
            'Content-Type': content_type,
        }

        endpoint.prepared_request.body = content
        endpoint.prepared_request.headers = CaseInsensitiveDict(data=headers)
        endpoint.prepared_request.prepare_content_length(body=content)
        session = requests.Session()
        response = session.send(  # type: ignore
            request=endpoint.prepared_request,
        )

        url = str(endpoint.prepared_request.url)
        netloc = urlparse(url).netloc
        if netloc == 'cloudreco.vuforia.com':
            # The multipart/formdata boundary is no longer in the given
            # content.
            assert response.text == ''
            assert_vwq_failure(
                response=response,
                status_code=HTTPStatus.UNSUPPORTED_MEDIA_TYPE,
                content_type=None,
            )
            return

        assert response.status_code == HTTPStatus.BAD_REQUEST
        assert response.text == ''
        assert 'Content-Type' not in response.headers