OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.23k stars 6.43k forks source link

[BUG][scala-sttp] using APIKeyQuery and APIKeyHeader simultaneously generates invalid code #13474

Open polentino opened 1 year ago

polentino commented 1 year ago

Bug Report Checklist

Description

I would like to give to the users of our API the possibility to choose among different types of authentication mechanisms; however, if I define APIKeyQuery and APIKeyHeader simultaneously within one security section and use scala-sttp generator, the generated code will create a method with two identical parameters

  def entitiesGet(apiKey: String, apiKey: String)(
  ): Request[Either[ResponseException[String, Exception], String], Any] =
    basicRequest
      .method(Method.GET, uri"$baseUrl/entities/")
      .contentType("application/json")
      .header("X-Api-Key", apiKey)
      .response(asJson[String])

which will cause compilation errors:

[error] [E1] openapi/src/main/scala/org/openapitools/client/api/DefaultApi.scala
[error]      apiKey is already defined as value apiKey
[error]      L34:   def entitiesGet(apiKey: String, apiKey: String)(
[error]                                             ^
[error] [E2] openapi/src/main/scala/org/openapitools/client/api/DefaultApi.scala
[error]      ambiguous reference to overloaded definition,
[error]      both value apiKey of type String
[error]      and  value apiKey of type String
[error]      match expected type ?
[error]      L39:       .header("X-Api-Key", apiKey)
[error]                                      ^

Furthermore, as you may have noticed, there's no logic to assign the two apiKey parameters as header and query param.

As a counter example, I tried using the java generator, and the code

  1. does compile
  2. recognizes the presence of two auth methods and sets them up properly
public ApiClient() {
        init();
        initHttpClient();

        // Setup authentications (key: authentication name, value: authentication).
        authentications.put("APIKeyHeader", new ApiKeyAuth("header", "X-Api-Key"));
        authentications.put("APIKeyQuery", new ApiKeyAuth("query", "api_key"));
        // Prevent the authentications from being modified.
        authentications = Collections.unmodifiableMap(authentications);
    }
  1. forwards the proper auth names from within the public method call
public okhttp3.Call entitiesGetCall(final ApiCallback _callback) throws ApiException {
        String basePath = null;
        // omitted for brevity
        String localVarPath = "/entities/";

        // omitted for brevity
        String[] localVarAuthNames = new String[] { "APIKeyHeader", "APIKeyQuery" };
        return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback);
    }
openapi-generator version

tested latest openapi-generator from master (but disabled openapi-generator-gradle-plugin because it causes compilation errors on my machine)

OpenAPI declaration file content or url

link to public Gist for openapi.json

Generation Details
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate \
  -i testgen/openapi.json \
  -c testgen/config.yaml \
  -o testgen/out \
  -g scala-sttp

config.yaml :

generatorName: "scala-sttp"
additionalProperties:
  jsonLibrary: "circe"
Steps to reproduce
  1. git clone https://github.com/OpenAPITools/openapi-generator
  2. cd openapi-generator
  3. ./mvnw clean install -Dmaven.test.skip=true -Dmaven.javadoc.skip=true
  4. create a folder testgen, and save openapi.json from my Gist and config.yaml in there

now you can execute

java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate \
  -i testgen/openapi.json \
  -c testgen/config.yaml \
  -o testgen/out \
  -g scala-sttp
Related issues/PRs
Suggest a fix

Similar to what happens with the Java counterpart, there should be an Authentication object that represents the authorizations defined in the openapi spec and, when a sttp Request is applied to it, the Authentication object will enrich it with all the auth defined.

polentino commented 1 year ago

bump 🙏

wing328 commented 1 year ago

@polentino thanks for reporting the issue.

Would you have time to file a fix? One way to look at how Java client handle this as it should work with API keys in query and header.

Or would you like to sponsor the fix?