Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • O openapi-generator
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 3,476
    • Issues 3,476
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 402
    • Merge requests 402
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • OpenAPI Tools
  • openapi-generator
  • Issues
  • #8833
Closed
Open
Issue created Feb 25, 2021 by Administrator@rootContributor5 of 6 checklist items completed5/6 checklist items

[BUG] Incorrect Rust code on multiple apiKeys

Created by: nappa85

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

When using multiple apiKeys, Rust generated code insists on the same configuration key for all the apiKeys

openapi-generator version

Tested with: 5.0.1 5.1.0-20210225.082056-71 6.0.0-20210212.130915-8

OpenAPI declaration file content or url
openapi: 3.0.0
servers:
  - url: 'https://api.therocktrading.com/v1'
info:
  description: >-
    TheRockTrading public APIs
  version: 1.0.0
  title: TheRockTrading API
  license:
    name: Apache-2.0
    url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
tags:
  - name: account
    description: Account API can be seen as user account personal data (balances, ATM withdraw..)
paths:
  /balances:
    get:
      tags:
        - account
      summary: With balances, you will get a list of all your balances in any currency.
      description: ''
      operationId: getBalances
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Balances'
        '422':
          description: Unprocessable Entity
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - trt_auth_key: []
          trt_auth_sign: []
          trt_auth_nonce: []
externalDocs:
  description: Find out more about TheRockTrading
  url: 'https://api.therocktrading.com/doc/v1/'
components:
  securitySchemes:
    trt_auth_key:
      type: apiKey
      name: X-TRT-KEY
      in: header
    trt_auth_sign:
      type: apiKey
      name: X-TRT-SIGN
      in: header
    trt_auth_nonce:
      type: apiKey
      name: X-TRT-NONCE
      in: header
  schemas:
    Balance:
      title: Balance
      description: A Currency balance
      type: object
      required:
        - currency
        - balance
        - trading_balance
      properties:
        currency:
          type: string
        balance:
          type: number
          format: double
        trading_balance:
          type: number
          format: double
    Balances:
      title: Balances
      description: A list of currency balances
      type: object
      required:
        - balances
      properties:
        balances:
          type: array
          items:
            $ref: '#/components/schemas/Balance'
    ErrorResponse:
      title: An error response
      description: Describes a single error
      type: object
      required:
        - errors
      properties:
        errors:
          type: array
          items:
            $ref: '#/components/schemas/ErrorMessage'
    ErrorMessage:
      title: An error message
      description: Describes a single error
      type: object
      required:
        - message
      properties:
        message:
          type: string
        code:
          type: string
        meta:
          type: object
          required:
            - key
            - value
          properties:
            key:
              type: string
            value:
              type: string
Generation Details
openapi-generator-cli.sh generate -i openapi.yaml -g rust -o openapi
Steps to reproduce
  1. generate Rust code from an openapi spec that has multiple apiKeys
Related issues/PRs

Haven't found any

Suggest a fix

Instead of using a struct ApiKey, I would use a trait, and implement it for String to make it behave as now.

Actual implementantion:

pub struct Configuration {
    pub base_path: String,
    pub user_agent: Option<String>,
    pub client: reqwest::Client,
    pub basic_auth: Option<BasicAuth>,
    pub oauth_access_token: Option<String>,
    pub bearer_access_token: Option<String>,
    pub api_key: Option<ApiKey>,
    // TODO: take an oauth2 token source, similar to the go one
}

pub struct ApiKey {
    pub prefix: Option<String>,
    pub key: String,
}

My proposal:

pub struct Configuration<A: ApiKey> {
    pub base_path: String,
    pub user_agent: Option<String>,
    pub client: reqwest::Client,
    pub basic_auth: Option<BasicAuth>,
    pub oauth_access_token: Option<String>,
    pub bearer_access_token: Option<String>,
    pub api_key: A,
    // TODO: take an oauth2 token source, similar to the go one
}

pub trait ApiKey {
    fn get_prefix(&self, name: &str) -> Option<String>,
    fn get_key(&self, name: &str) -> Option<String>,
}

impl ApiKey for String {
    fn get_prefix(&self, _: &str) -> Option<String> {
      None
    }
    fn get_key(&self, _: &str) -> Option<String> {
      self.cloned()
    }
}

impl ApiKey for std::collection::HashMap<String, String> {
    fn get_prefix(&self, _: &str) -> Option<String> {
      None
    }
    fn get_key(&self, name: &str) -> Option<String> {
      self.get(name).cloned()
    }
}

/// generated code
    if let Some(ref local_var_apikey) = configuration.api_key {
        if let Some(local_var_key) = local_var_apikey.key.get_key("X-TRT-KEY") {
          let local_var_value = match local_var_apikey.get_prefix("X-TRT-KEY") {
              Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
              None => local_var_key,
          };
          local_var_req_builder = local_var_req_builder.header("X-TRT-KEY", local_var_value);
      }
    };

This way it's possible to use any type as apiKeys, as long they impl the trait. The same approach can be used for other fields too, if needed

Assignee
Assign to
Time tracking