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, )
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, )
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, )
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
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, )
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
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