Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ object Paths {
{{#allParams}}* @param {{paramName}} {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}*/
{{#hasParams}}
@Serializable @Resource("{{{path}}}") class {{operationId}}({{#allParams}}val {{paramName}}: {{{dataType}}}{{^required}}? = null{{/required}}{{#required}}{{#isNullable}}?{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
@Serializable @Resource("{{{path}}}") class {{operationId}}({{#allParams}}@SerialName("{{baseName}}") val {{paramName}}: {{{dataType}}}{{^required}}? = null{{/required}}{{#required}}{{#isNullable}}?{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
{{/hasParams}}
{{^hasParams}}
@Serializable @Resource("{{{path}}}") class {{operationId}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ paths:
- petstore_auth:
- write:pets
- read:pets
- petstore_auth2:
- write:pets
- read:pets
summary: Add a new pet to the store
tags:
- pet
Expand Down Expand Up @@ -3136,6 +3139,14 @@ components:
write:pets: modify pets in your account
read:pets: read your pets
type: oauth2
petstore_auth2:
flows:
implicit:
authorizationUrl: http://petstore.swagger.io/api/oauth/dialog
scopes:
write:pets: modify pets in your account
read:pets: read your pets
type: oauth2
api_key:
in: header
name: api-key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ void (empty response body)

### Authorization

[petstore_auth](../README.md#petstore_auth), [http_signature_test](../README.md#http_signature_test)
[petstore_auth](../README.md#petstore_auth), [petstore_auth2](../README.md#petstore_auth2), [http_signature_test](../README.md#http_signature_test)

### HTTP request headers

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ public class DependencyInjectionTest

OAuthToken oauthToken1 = new("token", timeout: TimeSpan.FromSeconds(1));
options.AddTokens(oauthToken1);

OAuthToken oauthToken2 = new("token", timeout: TimeSpan.FromSeconds(1));
options.AddTokens(oauthToken2);
})
.Build();

Expand All @@ -67,8 +70,11 @@ public class DependencyInjectionTest
HttpSignatureToken httpSignatureToken1 = new(config1, timeout: TimeSpan.FromSeconds(1));
options.AddTokens(httpSignatureToken1);

OAuthToken oauthToken = new("token", timeout: TimeSpan.FromSeconds(1));
options.AddTokens(oauthToken);
OAuthToken oauthToken1 = new("token", timeout: TimeSpan.FromSeconds(1));
options.AddTokens(oauthToken1);

OAuthToken oauthToken2 = new("token", timeout: TimeSpan.FromSeconds(1));
options.AddTokens(oauthToken2);
options.AddApiHttpClients(client => client.BaseAddress = new Uri(ClientUtils.BASE_ADDRESS));
})
.Build();
Expand Down Expand Up @@ -96,6 +102,9 @@ public class DependencyInjectionTest

OAuthToken oauthToken1 = new("token", timeout: TimeSpan.FromSeconds(1));
options.AddTokens(oauthToken1);

OAuthToken oauthToken2 = new("token", timeout: TimeSpan.FromSeconds(1));
options.AddTokens(oauthToken2);
});
})
.Build();
Expand Down Expand Up @@ -123,6 +132,9 @@ public class DependencyInjectionTest

OAuthToken oauthToken1 = new("token", timeout: TimeSpan.FromSeconds(1));
options.AddTokens(oauthToken1);

OAuthToken oauthToken2 = new("token", timeout: TimeSpan.FromSeconds(1));
options.AddTokens(oauthToken2);
options.AddApiHttpClients(client => client.BaseAddress = new Uri(ClientUtils.BASE_ADDRESS));
});
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -849,14 +849,20 @@ public async Task<IAddPetApiResponse> AddPetAsync(Pet pet, System.Threading.Canc

oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");

HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
OAuthToken oauthTokenLocalVar2 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: AddPetAsync applies OAuth twice, retrieving and adding a second token/header, unlike other operations. This redundant OAuth call is likely unintended and can cause duplicate/overwritten auth headers and unnecessary rate-limit tracking.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/csharp/generichost/latest/UseDateTimeOffset/src/Org.OpenAPITools/Api/PetApi.cs, line 852:

<comment>AddPetAsync applies OAuth twice, retrieving and adding a second token/header, unlike other operations. This redundant OAuth call is likely unintended and can cause duplicate/overwritten auth headers and unnecessary rate-limit tracking.</comment>

<file context>
@@ -849,14 +849,20 @@ public async Task<IAddPetApiResponse> AddPetAsync(Pet pet, System.Threading.Canc
                     oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, "");
 
-                    HttpSignatureToken httpSignatureTokenLocalVar2 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
+                    OAuthToken oauthTokenLocalVar2 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);
 
-                    tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
</file context>
Fix with Cubic

Copy link
Copy Markdown
Contributor Author

@kdefives kdefives Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code has been changed by those cli execution:

./mvnw clean package
./bin/generate-samples.sh ./bin/configs/*.yaml
./bin/utils/export_docs_generators.sh


tokenBaseLocalVars.Add(httpSignatureTokenLocalVar2);
tokenBaseLocalVars.Add(oauthTokenLocalVar2);

oauthTokenLocalVar2.UseInHeader(httpRequestMessageLocalVar, "");

HttpSignatureToken httpSignatureTokenLocalVar3 = (HttpSignatureToken) await HttpSignatureTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false);

tokenBaseLocalVars.Add(httpSignatureTokenLocalVar3);

if (httpRequestMessageLocalVar.Content != null) {
string requestBodyLocalVar = await httpRequestMessageLocalVar.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);

httpSignatureTokenLocalVar2.UseInHeader(httpRequestMessageLocalVar, requestBodyLocalVar, cancellationToken);
httpSignatureTokenLocalVar3.UseInHeader(httpRequestMessageLocalVar, requestBodyLocalVar, cancellationToken);
}

string[] contentTypes = new string[] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,43 +21,43 @@ object Paths {
*
* @param pet Pet object that needs to be added to the store
*/
@Serializable @Resource("/pet") class addPet(val pet: Pet)
@Serializable @Resource("/pet") class addPet(@SerialName("Pet") val pet: Pet)

/**
* Deletes a pet
*
* @param petId Pet id to delete
* @param apiKey (optional)
*/
@Serializable @Resource("/pet/{petId}") class deletePet(val petId: kotlin.Long, val apiKey: kotlin.String? = null)
@Serializable @Resource("/pet/{petId}") class deletePet(@SerialName("petId") val petId: kotlin.Long, @SerialName("api_key") val apiKey: kotlin.String? = null)

/**
* Finds Pets by status
* Multiple status values can be provided with comma separated strings
* @param status Status values that need to be considered for filter
*/
@Serializable @Resource("/pet/findByStatus") class findPetsByStatus(val status: kotlin.collections.List<kotlin.String>)
@Serializable @Resource("/pet/findByStatus") class findPetsByStatus(@SerialName("status") val status: kotlin.collections.List<kotlin.String>)

/**
* Finds Pets by tags
* Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
* @param tags Tags to filter by
*/
@Serializable @Resource("/pet/findByTags") class findPetsByTags(val tags: kotlin.collections.List<kotlin.String>)
@Serializable @Resource("/pet/findByTags") class findPetsByTags(@SerialName("tags") val tags: kotlin.collections.List<kotlin.String>)

/**
* Find pet by ID
* Returns a single pet
* @param petId ID of pet to return
*/
@Serializable @Resource("/pet/{petId}") class getPetById(val petId: kotlin.Long)
@Serializable @Resource("/pet/{petId}") class getPetById(@SerialName("petId") val petId: kotlin.Long)

/**
* Update an existing pet
*
* @param pet Pet object that needs to be added to the store
*/
@Serializable @Resource("/pet") class updatePet(val pet: Pet)
@Serializable @Resource("/pet") class updatePet(@SerialName("Pet") val pet: Pet)

/**
* Updates a pet in the store with form data
Expand All @@ -66,7 +66,7 @@ object Paths {
* @param name Updated name of the pet (optional)
* @param status Updated status of the pet (optional)
*/
@Serializable @Resource("/pet/{petId}") class updatePetWithForm(val petId: kotlin.Long, val name: kotlin.String? = null, val status: kotlin.String? = null)
@Serializable @Resource("/pet/{petId}") class updatePetWithForm(@SerialName("petId") val petId: kotlin.Long, @SerialName("name") val name: kotlin.String? = null, @SerialName("status") val status: kotlin.String? = null)

/**
* uploads an image
Expand All @@ -75,14 +75,14 @@ object Paths {
* @param additionalMetadata Additional data to pass to server (optional)
* @param file file to upload (optional)
*/
@Serializable @Resource("/pet/{petId}/uploadImage") class uploadFile(val petId: kotlin.Long, val additionalMetadata: kotlin.String? = null, val file: java.io.File? = null)
@Serializable @Resource("/pet/{petId}/uploadImage") class uploadFile(@SerialName("petId") val petId: kotlin.Long, @SerialName("additionalMetadata") val additionalMetadata: kotlin.String? = null, @SerialName("file") val file: java.io.File? = null)

/**
* Delete purchase order by ID
* For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors
* @param orderId ID of the order that needs to be deleted
*/
@Serializable @Resource("/store/order/{orderId}") class deleteOrder(val orderId: kotlin.String)
@Serializable @Resource("/store/order/{orderId}") class deleteOrder(@SerialName("orderId") val orderId: kotlin.String)

/**
* Returns pet inventories by status
Expand All @@ -95,57 +95,57 @@ object Paths {
* For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generate exceptions
* @param orderId ID of pet that needs to be fetched
*/
@Serializable @Resource("/store/order/{orderId}") class getOrderById(val orderId: kotlin.Long)
@Serializable @Resource("/store/order/{orderId}") class getOrderById(@SerialName("orderId") val orderId: kotlin.Long)

/**
* Place an order for a pet
*
* @param order order placed for purchasing the pet
*/
@Serializable @Resource("/store/order") class placeOrder(val order: Order)
@Serializable @Resource("/store/order") class placeOrder(@SerialName("Order") val order: Order)

/**
* Create user
* This can only be done by the logged in user.
* @param user Created user object
*/
@Serializable @Resource("/user") class createUser(val user: User)
@Serializable @Resource("/user") class createUser(@SerialName("User") val user: User)

/**
* Creates list of users with given input array
*
* @param user List of user object
*/
@Serializable @Resource("/user/createWithArray") class createUsersWithArrayInput(val user: kotlin.collections.List<User>)
@Serializable @Resource("/user/createWithArray") class createUsersWithArrayInput(@SerialName("User") val user: kotlin.collections.List<User>)

/**
* Creates list of users with given input array
*
* @param user List of user object
*/
@Serializable @Resource("/user/createWithList") class createUsersWithListInput(val user: kotlin.collections.List<User>)
@Serializable @Resource("/user/createWithList") class createUsersWithListInput(@SerialName("User") val user: kotlin.collections.List<User>)

/**
* Delete user
* This can only be done by the logged in user.
* @param username The name that needs to be deleted
*/
@Serializable @Resource("/user/{username}") class deleteUser(val username: kotlin.String)
@Serializable @Resource("/user/{username}") class deleteUser(@SerialName("username") val username: kotlin.String)

/**
* Get user by user name
*
* @param username The name that needs to be fetched. Use user1 for testing.
*/
@Serializable @Resource("/user/{username}") class getUserByName(val username: kotlin.String)
@Serializable @Resource("/user/{username}") class getUserByName(@SerialName("username") val username: kotlin.String)

/**
* Logs user into the system
*
* @param username The user name for login
* @param password The password for login in clear text
*/
@Serializable @Resource("/user/login") class loginUser(val username: kotlin.String, val password: kotlin.String)
@Serializable @Resource("/user/login") class loginUser(@SerialName("username") val username: kotlin.String, @SerialName("password") val password: kotlin.String)

/**
* Logs out current logged in user session
Expand All @@ -159,6 +159,6 @@ object Paths {
* @param username name that need to be deleted
* @param user Updated user object
*/
@Serializable @Resource("/user/{username}") class updateUser(val username: kotlin.String, val user: User)
@Serializable @Resource("/user/{username}") class updateUser(@SerialName("username") val username: kotlin.String, @SerialName("User") val user: User)

}
Loading