Skip to content

Commit a53ebb3

Browse files
authored
Add support for ApiKey auth to rust-server (#22950)
1 parent aeea8b1 commit a53ebb3

7 files changed

Lines changed: 69 additions & 4 deletions

File tree

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,6 @@ private void postProcessOperationWithModels(CodegenOperation op, List<ModelMap>
977977

978978
for (CodegenSecurity s : op.authMethods) {
979979
if (s.isApiKey && s.isKeyInHeader) {
980-
s.vendorExtensions.put("x-api-key-name", toModelName(s.keyParamName));
981980
headerAuthMethods = true;
982981
}
983982

modules/openapi-generator/src/main/resources/rust-server/bin-cli.mustache

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ struct Cli {
8686
bearer_token: Option<String>,
8787
{{/hasOAuthMethods}}
8888
{{/hasHttpBearerMethods}}
89+
{{#hasApiKeyMethods}}
90+
91+
/// API key for authentication
92+
#[arg(long, env = "{{#lambda.uppercase}}{{externCrateName}}{{/lambda.uppercase}}_API_KEY", hide_env = true)]
93+
api_key: Option<String>,
94+
{{/hasApiKeyMethods}}
8995
}
9096

9197
#[derive(Parser, Debug)]
@@ -187,6 +193,12 @@ async fn main() -> Result<()> {
187193
debug!("Using bearer token");
188194
auth_data = AuthData::bearer(bearer_token);
189195
}
196+
{{#hasApiKeyMethods}}
197+
if let Some(ref api_key) = args.api_key {
198+
debug!("Using API key");
199+
auth_data = Some(AuthData::apikey(api_key));
200+
}
201+
{{/hasApiKeyMethods}}
190202
{{/hasHttpBearerMethods}}
191203
{{^hasHttpBearerMethods}}
192204
{{#hasOAuthMethods}}
@@ -196,11 +208,27 @@ async fn main() -> Result<()> {
196208
debug!("Using bearer token");
197209
auth_data = AuthData::bearer(bearer_token);
198210
}
211+
{{#hasApiKeyMethods}}
212+
if let Some(ref api_key) = args.api_key {
213+
debug!("Using API key");
214+
auth_data = Some(AuthData::apikey(api_key));
215+
}
216+
{{/hasApiKeyMethods}}
199217
{{/hasOAuthMethods}}
200218
{{/hasHttpBearerMethods}}
201219
{{^hasHttpBearerMethods}}
202220
{{^hasOAuthMethods}}
221+
{{#hasApiKeyMethods}}
222+
let mut auth_data: Option<AuthData> = None;
223+
224+
if let Some(ref api_key) = args.api_key {
225+
debug!("Using API key");
226+
auth_data = Some(AuthData::apikey(api_key));
227+
}
228+
{{/hasApiKeyMethods}}
229+
{{^hasApiKeyMethods}}
203230
let auth_data: Option<AuthData> = None;
231+
{{/hasApiKeyMethods}}
204232
{{/hasOAuthMethods}}
205233
{{/hasHttpBearerMethods}}
206234

modules/openapi-generator/src/main/resources/rust-server/client-operation.mustache

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@
9999
#[allow(clippy::collapsible_match)]
100100
if let Some(auth_data) = Has::<Option<AuthData>>::get(context).as_ref() {
101101
use headers::authorization::Credentials;
102-
{{! Currently only authentication with Basic and Bearer are supported }}
103102
#[allow(clippy::single_match, clippy::match_single_binding)]
104103
match auth_data {
105104
{{#authMethods}}
@@ -135,6 +134,19 @@
135134
},
136135
{{/isBasicBearer}}
137136
{{/isOAuth}}
137+
{{#isApiKey}}
138+
{{#isKeyInHeader}}
139+
AuthData::ApiKey(ref api_key) => {
140+
let header = match HeaderValue::from_str(api_key.as_str()) {
141+
Ok(h) => h,
142+
Err(e) => return Err(ApiError(format!("Unable to create header: {e}")))
143+
};
144+
request.headers_mut().insert(
145+
HeaderName::from_static("{{#lambda.lowercase}}{{{keyParamName}}}{{/lambda.lowercase}}"),
146+
header);
147+
},
148+
{{/isKeyInHeader}}
149+
{{/isApiKey}}
138150
{{/authMethods}}
139151
_ => {}
140152
}

modules/openapi-generator/src/main/resources/rust-server/context.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ impl<T, A, B, C, ReqBody> Service<Request<ReqBody>> for AddContext<T, A>
142142
{
143143
use swagger::auth::api_key_from_header;
144144
145-
if let Some(header) = api_key_from_header(headers, "{{exts.x-key-param-name-lower}}") {
145+
if let Some(header) = api_key_from_header(headers, "{{#lambda.lowercase}}{{{keyParamName}}}{{/lambda.lowercase}}") {
146146
let auth_data = AuthData::ApiKey(header);
147147
let context = context.push(Some(auth_data));
148148

samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/bin/cli.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ struct Cli {
9797
/// Bearer token if used for authentication
9898
#[arg(env = "PETSTORE_WITH_FAKE_ENDPOINTS_MODELS_FOR_TESTING_BEARER_TOKEN", hide_env = true)]
9999
bearer_token: Option<String>,
100+
101+
/// API key for authentication
102+
#[arg(long, env = "PETSTORE_WITH_FAKE_ENDPOINTS_MODELS_FOR_TESTING_API_KEY", hide_env = true)]
103+
api_key: Option<String>,
100104
}
101105

102106
#[derive(Parser, Debug)]
@@ -398,6 +402,10 @@ async fn main() -> Result<()> {
398402
debug!("Using bearer token");
399403
auth_data = AuthData::bearer(bearer_token);
400404
}
405+
if let Some(ref api_key) = args.api_key {
406+
debug!("Using API key");
407+
auth_data = Some(AuthData::apikey(api_key));
408+
}
401409

402410
#[allow(trivial_casts)]
403411
let context = swagger::make_context!(

samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2476,6 +2476,15 @@ impl<S, C, B> Api<C> for Client<S, C> where
24762476
use headers::authorization::Credentials;
24772477
#[allow(clippy::single_match, clippy::match_single_binding)]
24782478
match auth_data {
2479+
AuthData::ApiKey(ref api_key) => {
2480+
let header = match HeaderValue::from_str(api_key.as_str()) {
2481+
Ok(h) => h,
2482+
Err(e) => return Err(ApiError(format!("Unable to create header: {e}")))
2483+
};
2484+
request.headers_mut().insert(
2485+
HeaderName::from_static("api_key"),
2486+
header);
2487+
},
24792488
_ => {}
24802489
}
24812490
}
@@ -2848,6 +2857,15 @@ impl<S, C, B> Api<C> for Client<S, C> where
28482857
use headers::authorization::Credentials;
28492858
#[allow(clippy::single_match, clippy::match_single_binding)]
28502859
match auth_data {
2860+
AuthData::ApiKey(ref api_key) => {
2861+
let header = match HeaderValue::from_str(api_key.as_str()) {
2862+
Ok(h) => h,
2863+
Err(e) => return Err(ApiError(format!("Unable to create header: {e}")))
2864+
};
2865+
request.headers_mut().insert(
2866+
HeaderName::from_static("api_key"),
2867+
header);
2868+
},
28512869
_ => {}
28522870
}
28532871
}

samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl<T, A, B, C, ReqBody> Service<Request<ReqBody>> for AddContext<T, A>
114114
{
115115
use swagger::auth::api_key_from_header;
116116

117-
if let Some(header) = api_key_from_header(headers, "") {
117+
if let Some(header) = api_key_from_header(headers, "api_key") {
118118
let auth_data = AuthData::ApiKey(header);
119119
let context = context.push(Some(auth_data));
120120

0 commit comments

Comments
 (0)