diff --git a/openapi_python_client/parser/openapi.py b/openapi_python_client/parser/openapi.py index 4f83ae93e..cc22fd07d 100644 --- a/openapi_python_client/parser/openapi.py +++ b/openapi_python_client/parser/openapi.py @@ -30,6 +30,13 @@ _PATH_PARAM_REGEX = re.compile("{([a-zA-Z_-][a-zA-Z0-9_-]*)}") +def requires_authenticated_client(security: list[dict[str, list[str]]] | None) -> bool: + """Return false when an operation permits anonymous access.""" + if not security: + return False + return not any(not requirement for requirement in security) + + def import_string_from_class(class_: Class, prefix: str = "") -> str: """Create a string which is used to import a reference""" return f"from {prefix}.{class_.module_name} import {class_.name}" @@ -420,7 +427,7 @@ def from_data( summary=utils.remove_string_escapes(data.summary) if data.summary else "", description=utils.remove_string_escapes(data.description) if data.description else "", name=name, - requires_security=bool(data.security), + requires_security=requires_authenticated_client(data.security), tags=tags, ) diff --git a/tests/test_parser/test_openapi.py b/tests/test_parser/test_openapi.py index 3bd743804..c682cd113 100644 --- a/tests/test_parser/test_openapi.py +++ b/tests/test_parser/test_openapi.py @@ -555,6 +555,49 @@ def test_from_data_no_security(self, mocker, config): config=config, ) + @pytest.mark.parametrize( + ("security", "expected_requires_security"), + [ + ([{}], False), + ([{"apiKey": []}, {}], False), + ([{"apiKey": []}], True), + ], + ) + def test_from_data_security_allows_anonymous_alternative( + self, + security, + expected_requires_security, + mocker, + config, + ): + data = oai.Operation.model_construct( + description=mocker.MagicMock(), + operationId=mocker.MagicMock(), + security=security, + responses=mocker.MagicMock(), + ) + add_parameters = mocker.patch.object( + Endpoint, "add_parameters", return_value=(mocker.MagicMock(), mocker.MagicMock(), mocker.MagicMock()) + ) + mocker.patch.object(Endpoint, "_add_responses", return_value=(mocker.MagicMock(), mocker.MagicMock())) + path = mocker.MagicMock() + method = mocker.MagicMock() + mocker.patch("openapi_python_client.utils.remove_string_escapes", return_value=data.description) + + Endpoint.from_data( + data=data, + path=path, + method=method, + tags=["default"], + schemas=mocker.MagicMock(), + responses={}, + parameters=mocker.MagicMock(), + config=config, + request_bodies={}, + ) + + assert add_parameters.call_args.kwargs["endpoint"].requires_security is expected_requires_security + def test_from_data_some_bad_bodies(self, config): endpoint, _, _ = Endpoint.from_data( data=oai.Operation(