Add support for ApiKey auth to rust-server (#22950)

This commit is contained in:
dsteeley
2026-02-12 11:51:49 +00:00
committed by GitHub
parent aeea8b1254
commit a53ebb3ad2
7 changed files with 69 additions and 4 deletions

View File

@@ -977,7 +977,6 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
for (CodegenSecurity s : op.authMethods) {
if (s.isApiKey && s.isKeyInHeader) {
s.vendorExtensions.put("x-api-key-name", toModelName(s.keyParamName));
headerAuthMethods = true;
}

View File

@@ -86,6 +86,12 @@ struct Cli {
bearer_token: Option<String>,
{{/hasOAuthMethods}}
{{/hasHttpBearerMethods}}
{{#hasApiKeyMethods}}
/// API key for authentication
#[arg(long, env = "{{#lambda.uppercase}}{{externCrateName}}{{/lambda.uppercase}}_API_KEY", hide_env = true)]
api_key: Option<String>,
{{/hasApiKeyMethods}}
}
#[derive(Parser, Debug)]
@@ -187,6 +193,12 @@ async fn main() -> Result<()> {
debug!("Using bearer token");
auth_data = AuthData::bearer(bearer_token);
}
{{#hasApiKeyMethods}}
if let Some(ref api_key) = args.api_key {
debug!("Using API key");
auth_data = Some(AuthData::apikey(api_key));
}
{{/hasApiKeyMethods}}
{{/hasHttpBearerMethods}}
{{^hasHttpBearerMethods}}
{{#hasOAuthMethods}}
@@ -196,11 +208,27 @@ async fn main() -> Result<()> {
debug!("Using bearer token");
auth_data = AuthData::bearer(bearer_token);
}
{{#hasApiKeyMethods}}
if let Some(ref api_key) = args.api_key {
debug!("Using API key");
auth_data = Some(AuthData::apikey(api_key));
}
{{/hasApiKeyMethods}}
{{/hasOAuthMethods}}
{{/hasHttpBearerMethods}}
{{^hasHttpBearerMethods}}
{{^hasOAuthMethods}}
{{#hasApiKeyMethods}}
let mut auth_data: Option<AuthData> = None;
if let Some(ref api_key) = args.api_key {
debug!("Using API key");
auth_data = Some(AuthData::apikey(api_key));
}
{{/hasApiKeyMethods}}
{{^hasApiKeyMethods}}
let auth_data: Option<AuthData> = None;
{{/hasApiKeyMethods}}
{{/hasOAuthMethods}}
{{/hasHttpBearerMethods}}

View File

@@ -99,7 +99,6 @@
#[allow(clippy::collapsible_match)]
if let Some(auth_data) = Has::<Option<AuthData>>::get(context).as_ref() {
use headers::authorization::Credentials;
{{! Currently only authentication with Basic and Bearer are supported }}
#[allow(clippy::single_match, clippy::match_single_binding)]
match auth_data {
{{#authMethods}}
@@ -135,6 +134,19 @@
},
{{/isBasicBearer}}
{{/isOAuth}}
{{#isApiKey}}
{{#isKeyInHeader}}
AuthData::ApiKey(ref api_key) => {
let header = match HeaderValue::from_str(api_key.as_str()) {
Ok(h) => h,
Err(e) => return Err(ApiError(format!("Unable to create header: {e}")))
};
request.headers_mut().insert(
HeaderName::from_static("{{#lambda.lowercase}}{{{keyParamName}}}{{/lambda.lowercase}}"),
header);
},
{{/isKeyInHeader}}
{{/isApiKey}}
{{/authMethods}}
_ => {}
}

View File

@@ -142,7 +142,7 @@ impl<T, A, B, C, ReqBody> Service<Request<ReqBody>> for AddContext<T, A>
{
use swagger::auth::api_key_from_header;
if let Some(header) = api_key_from_header(headers, "{{exts.x-key-param-name-lower}}") {
if let Some(header) = api_key_from_header(headers, "{{#lambda.lowercase}}{{{keyParamName}}}{{/lambda.lowercase}}") {
let auth_data = AuthData::ApiKey(header);
let context = context.push(Some(auth_data));

View File

@@ -97,6 +97,10 @@ struct Cli {
/// Bearer token if used for authentication
#[arg(env = "PETSTORE_WITH_FAKE_ENDPOINTS_MODELS_FOR_TESTING_BEARER_TOKEN", hide_env = true)]
bearer_token: Option<String>,
/// API key for authentication
#[arg(long, env = "PETSTORE_WITH_FAKE_ENDPOINTS_MODELS_FOR_TESTING_API_KEY", hide_env = true)]
api_key: Option<String>,
}
#[derive(Parser, Debug)]
@@ -398,6 +402,10 @@ async fn main() -> Result<()> {
debug!("Using bearer token");
auth_data = AuthData::bearer(bearer_token);
}
if let Some(ref api_key) = args.api_key {
debug!("Using API key");
auth_data = Some(AuthData::apikey(api_key));
}
#[allow(trivial_casts)]
let context = swagger::make_context!(

View File

@@ -2476,6 +2476,15 @@ impl<S, C, B> Api<C> for Client<S, C> where
use headers::authorization::Credentials;
#[allow(clippy::single_match, clippy::match_single_binding)]
match auth_data {
AuthData::ApiKey(ref api_key) => {
let header = match HeaderValue::from_str(api_key.as_str()) {
Ok(h) => h,
Err(e) => return Err(ApiError(format!("Unable to create header: {e}")))
};
request.headers_mut().insert(
HeaderName::from_static("api_key"),
header);
},
_ => {}
}
}
@@ -2848,6 +2857,15 @@ impl<S, C, B> Api<C> for Client<S, C> where
use headers::authorization::Credentials;
#[allow(clippy::single_match, clippy::match_single_binding)]
match auth_data {
AuthData::ApiKey(ref api_key) => {
let header = match HeaderValue::from_str(api_key.as_str()) {
Ok(h) => h,
Err(e) => return Err(ApiError(format!("Unable to create header: {e}")))
};
request.headers_mut().insert(
HeaderName::from_static("api_key"),
header);
},
_ => {}
}
}

View File

@@ -114,7 +114,7 @@ impl<T, A, B, C, ReqBody> Service<Request<ReqBody>> for AddContext<T, A>
{
use swagger::auth::api_key_from_header;
if let Some(header) = api_key_from_header(headers, "") {
if let Some(header) = api_key_from_header(headers, "api_key") {
let auth_data = AuthData::ApiKey(header);
let context = context.push(Some(auth_data));