Skip to content

Commit 699d955

Browse files
Fix #1088 - Add support for custom credentials provider in runtime (#1104)
Signed-off-by: Ricardo Zanini <[email protected]>
1 parent c3e144b commit 699d955

File tree

14 files changed

+270
-65
lines changed

14 files changed

+270
-65
lines changed

client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/GeneratorProcessor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import io.quarkiverse.openapi.generator.providers.ApiKeyIn;
3535
import io.quarkiverse.openapi.generator.providers.AuthProvider;
3636
import io.quarkiverse.openapi.generator.providers.BaseCompositeAuthenticationProvider;
37+
import io.quarkiverse.openapi.generator.providers.CredentialsProvider;
3738
import io.quarkiverse.openapi.generator.providers.OperationAuthInfo;
3839
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
3940
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
@@ -201,6 +202,7 @@ void produceBasicAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
201202
.annotation(OpenApiSpec.class)
202203
.addValue("openApiSpecId", openApiSpecId)
203204
.done()
205+
.addInjectionPoint(ClassType.create(DotName.createSimple(CredentialsProvider.class)))
204206
.createWith(recorder.recordBasicAuthProvider(sanitizeAuthName(name), openApiSpecId, operations))
205207
.unremovable()
206208
.done());
@@ -240,6 +242,7 @@ void produceBearerAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
240242
.annotation(OpenApiSpec.class)
241243
.addValue("openApiSpecId", openApiSpecId)
242244
.done()
245+
.addInjectionPoint(ClassType.create(DotName.createSimple(CredentialsProvider.class)))
243246
.createWith(recorder.recordBearerAuthProvider(sanitizeAuthName(name), scheme, openApiSpecId, operations))
244247
.unremovable()
245248
.done());
@@ -282,6 +285,7 @@ void produceApiKeyAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
282285
.annotation(OpenApiSpec.class)
283286
.addValue("openApiSpecId", openApiSpecId)
284287
.done()
288+
.addInjectionPoint(ClassType.create(DotName.createSimple(CredentialsProvider.class)))
285289
.createWith(recorder.recordApiKeyAuthProvider(sanitizeAuthName(name), openApiSpecId, apiKeyIn, apiKeyName,
286290
operations))
287291
.unremovable()

client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/template/QuteTemplatingEngineAdapter.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.quarkiverse.openapi.generator.deployment.template;
22

3-
import java.io.IOException;
43
import java.util.Map;
54

65
import org.openapitools.codegen.api.AbstractTemplatingEngineAdapter;
@@ -12,8 +11,8 @@
1211

1312
public class QuteTemplatingEngineAdapter extends AbstractTemplatingEngineAdapter {
1413

15-
public static final String IDENTIFIER = "qute";
16-
public static final String[] INCLUDE_TEMPLATES = {
14+
private static final String IDENTIFIER = "qute";
15+
private static final String[] DEFAULT_TEMPLATES = {
1716
"additionalEnumTypeAnnotations.qute",
1817
"additionalEnumTypeUnexpectedMember.qute",
1918
"additionalModelTypeAnnotations.qute",
@@ -60,8 +59,7 @@ public String[] getFileExtensions() {
6059
}
6160

6261
@Override
63-
public String compileTemplate(TemplatingExecutor executor, Map<String, Object> bundle, String templateFile)
64-
throws IOException {
62+
public String compileTemplate(TemplatingExecutor executor, Map<String, Object> bundle, String templateFile) {
6563
this.cacheTemplates(executor);
6664
Template template = engine.getTemplate(templateFile);
6765
if (template == null) {
@@ -72,7 +70,7 @@ public String compileTemplate(TemplatingExecutor executor, Map<String, Object> b
7270
}
7371

7472
public void cacheTemplates(TemplatingExecutor executor) {
75-
for (String templateId : INCLUDE_TEMPLATES) {
73+
for (String templateId : DEFAULT_TEMPLATES) {
7674
Template incTemplate = engine.getTemplate(templateId);
7775
if (incTemplate == null) {
7876
incTemplate = engine.parse(executor.getFullTemplateContents(templateId));

client/oidc/src/main/java/io/quarkiverse/openapi/generator/oidc/providers/OAuth2AuthenticationProvider.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.slf4j.LoggerFactory;
1313

1414
import io.quarkiverse.openapi.generator.providers.AbstractAuthProvider;
15+
import io.quarkiverse.openapi.generator.providers.ConfigCredentialsProvider;
1516
import io.quarkiverse.openapi.generator.providers.OperationAuthInfo;
1617
import io.quarkus.oidc.common.runtime.OidcConstants;
1718

@@ -23,7 +24,7 @@ public class OAuth2AuthenticationProvider extends AbstractAuthProvider {
2324

2425
public OAuth2AuthenticationProvider(String name,
2526
String openApiSpecId, OidcClientRequestFilterDelegate delegate, List<OperationAuthInfo> operations) {
26-
super(name, openApiSpecId, operations);
27+
super(name, openApiSpecId, operations, new ConfigCredentialsProvider());
2728
this.delegate = delegate;
2829
validateConfig();
2930
}

client/runtime/src/main/java/io/quarkiverse/openapi/generator/AuthenticationRecorder.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import io.quarkiverse.openapi.generator.providers.BaseCompositeAuthenticationProvider;
1414
import io.quarkiverse.openapi.generator.providers.BasicAuthenticationProvider;
1515
import io.quarkiverse.openapi.generator.providers.BearerAuthenticationProvider;
16+
import io.quarkiverse.openapi.generator.providers.CredentialsProvider;
1617
import io.quarkiverse.openapi.generator.providers.OperationAuthInfo;
1718
import io.quarkus.arc.SyntheticCreationalContext;
1819
import io.quarkus.runtime.annotations.Recorder;
@@ -35,22 +36,27 @@ public Function<SyntheticCreationalContext<AuthProvider>, AuthProvider> recordAp
3536
ApiKeyIn apiKeyIn,
3637
String apiKeyName,
3738
List<OperationAuthInfo> operations) {
38-
return context -> new ApiKeyAuthenticationProvider(openApiSpecId, name, apiKeyIn, apiKeyName, operations);
39+
return context -> new ApiKeyAuthenticationProvider(openApiSpecId, name, apiKeyIn,
40+
apiKeyName, operations, context.getInjectedReference(CredentialsProvider.class));
3941
}
4042

4143
public Function<SyntheticCreationalContext<AuthProvider>, AuthProvider> recordBearerAuthProvider(
4244
String name,
4345
String scheme,
4446
String openApiSpecId,
4547
List<OperationAuthInfo> operations) {
46-
return context -> new BearerAuthenticationProvider(openApiSpecId, name, scheme, operations);
48+
return context -> new BearerAuthenticationProvider(openApiSpecId, name, scheme,
49+
operations, context.getInjectedReference(CredentialsProvider.class));
4750
}
4851

4952
public Function<SyntheticCreationalContext<AuthProvider>, AuthProvider> recordBasicAuthProvider(
5053
String name,
5154
String openApiSpecId,
5255
List<OperationAuthInfo> operations) {
53-
return context -> new BasicAuthenticationProvider(openApiSpecId, name, operations);
56+
57+
return context -> new BasicAuthenticationProvider(openApiSpecId, name,
58+
operations, context.getInjectedReference(CredentialsProvider.class));
59+
5460
}
5561

5662
}

client/runtime/src/main/java/io/quarkiverse/openapi/generator/providers/AbstractAuthProvider.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
public abstract class AbstractAuthProvider implements AuthProvider {
1818

19+
CredentialsProvider credentialsProvider;
20+
1921
private static final String BEARER_WITH_SPACE = "Bearer ";
2022
private static final String CANONICAL_AUTH_CONFIG_PROPERTY_NAME = "quarkus." + RUNTIME_TIME_CONFIG_PREFIX
2123
+ ".%s.auth.%s.%s";
@@ -24,10 +26,12 @@ public abstract class AbstractAuthProvider implements AuthProvider {
2426
private final String name;
2527
private final List<OperationAuthInfo> applyToOperations = new ArrayList<>();
2628

27-
protected AbstractAuthProvider(String name, String openApiSpecId, List<OperationAuthInfo> operations) {
29+
protected AbstractAuthProvider(String name, String openApiSpecId, List<OperationAuthInfo> operations,
30+
CredentialsProvider credentialsProvider) {
2831
this.name = name;
2932
this.openApiSpecId = openApiSpecId;
3033
this.applyToOperations.addAll(operations);
34+
this.credentialsProvider = credentialsProvider;
3135
}
3236

3337
protected static String sanitizeBearerToken(String token) {
@@ -69,6 +73,10 @@ public List<OperationAuthInfo> operationsToFilter() {
6973
}
7074

7175
public final String getCanonicalAuthConfigPropertyName(String authPropertyName) {
72-
return String.format(CANONICAL_AUTH_CONFIG_PROPERTY_NAME, getOpenApiSpecId(), getName(), authPropertyName);
76+
return getCanonicalAuthConfigPropertyName(authPropertyName, getOpenApiSpecId(), getName());
77+
}
78+
79+
public static String getCanonicalAuthConfigPropertyName(String authPropertyName, String openApiSpecId, String authName) {
80+
return String.format(CANONICAL_AUTH_CONFIG_PROPERTY_NAME, openApiSpecId, authName, authPropertyName);
7381
}
7482
}

client/runtime/src/main/java/io/quarkiverse/openapi/generator/providers/ApiKeyAuthenticationProvider.java

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
import jakarta.ws.rs.core.UriBuilder;
1212

1313
import org.eclipse.microprofile.config.ConfigProvider;
14-
import org.slf4j.Logger;
15-
import org.slf4j.LoggerFactory;
1614

1715
import io.quarkiverse.openapi.generator.OpenApiGeneratorException;
1816

@@ -21,50 +19,47 @@
2119
*/
2220
public class ApiKeyAuthenticationProvider extends AbstractAuthProvider {
2321

24-
private static final Logger LOGGER = LoggerFactory.getLogger(ApiKeyAuthenticationProvider.class);
25-
26-
static final String API_KEY = "api-key";
2722
static final String USE_AUTHORIZATION_HEADER_VALUE = "use-authorization-header-value";
28-
2923
private final ApiKeyIn apiKeyIn;
3024
private final String apiKeyName;
3125

3226
public ApiKeyAuthenticationProvider(final String openApiSpecId, final String name, final ApiKeyIn apiKeyIn,
33-
final String apiKeyName, List<OperationAuthInfo> operations) {
34-
super(name, openApiSpecId, operations);
27+
final String apiKeyName, List<OperationAuthInfo> operations, CredentialsProvider credentialsProvider) {
28+
super(name, openApiSpecId, operations, credentialsProvider);
3529
this.apiKeyIn = apiKeyIn;
3630
this.apiKeyName = apiKeyName;
3731
validateConfig();
3832
}
3933

34+
public ApiKeyAuthenticationProvider(final String openApiSpecId, final String name, final ApiKeyIn apiKeyIn,
35+
final String apiKeyName, List<OperationAuthInfo> operations) {
36+
this(openApiSpecId, name, apiKeyIn, apiKeyName, operations, new ConfigCredentialsProvider());
37+
}
38+
4039
@Override
4140
public void filter(ClientRequestContext requestContext) throws IOException {
4241
switch (apiKeyIn) {
4342
case query:
44-
requestContext.setUri(UriBuilder.fromUri(requestContext.getUri()).queryParam(apiKeyName, getApiKey()).build());
43+
requestContext.setUri(
44+
UriBuilder.fromUri(requestContext.getUri()).queryParam(apiKeyName, getApiKey(requestContext)).build());
4545
break;
4646
case cookie:
47-
requestContext.getHeaders().add(HttpHeaders.COOKIE, new Cookie.Builder(apiKeyName).value(getApiKey()).build());
47+
requestContext.getHeaders().add(HttpHeaders.COOKIE,
48+
new Cookie.Builder(apiKeyName).value(getApiKey(requestContext)).build());
4849
break;
4950
case header:
5051
if (requestContext.getHeaderString("Authorization") != null
5152
&& !requestContext.getHeaderString("Authorization").isEmpty()
5253
&& isUseAuthorizationHeaderValue()) {
5354
requestContext.getHeaders().putSingle(apiKeyName, requestContext.getHeaderString("Authorization"));
5455
} else
55-
requestContext.getHeaders().putSingle(apiKeyName, getApiKey());
56+
requestContext.getHeaders().putSingle(apiKeyName, getApiKey(requestContext));
5657
break;
5758
}
5859
}
5960

60-
private String getApiKey() {
61-
final String key = ConfigProvider.getConfig()
62-
.getOptionalValue(getCanonicalAuthConfigPropertyName(API_KEY), String.class).orElse("");
63-
if (key.isEmpty()) {
64-
LOGGER.warn("configured {} property (see application.properties) is empty. hint: configure it.",
65-
getCanonicalAuthConfigPropertyName(API_KEY));
66-
}
67-
return key;
61+
private String getApiKey(ClientRequestContext requestContext) {
62+
return credentialsProvider.getApiKey(requestContext, getOpenApiSpecId(), getName());
6863
}
6964

7065
private boolean isUseAuthorizationHeaderValue() {

client/runtime/src/main/java/io/quarkiverse/openapi/generator/providers/BasicAuthenticationProvider.java

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
import jakarta.ws.rs.client.ClientRequestContext;
99
import jakarta.ws.rs.core.HttpHeaders;
1010

11-
import org.eclipse.microprofile.config.ConfigProvider;
12-
1311
import io.quarkiverse.openapi.generator.OpenApiGeneratorException;
1412

1513
/**
@@ -19,28 +17,28 @@
1917
*/
2018
public class BasicAuthenticationProvider extends AbstractAuthProvider {
2119

22-
static final String USER_NAME = "username";
23-
static final String PASSWORD = "password";
20+
public BasicAuthenticationProvider(final String openApiSpecId, String name, List<OperationAuthInfo> operations,
21+
CredentialsProvider credentialsProvider) {
22+
super(name, openApiSpecId, operations, credentialsProvider);
23+
validateConfig();
24+
}
2425

2526
public BasicAuthenticationProvider(final String openApiSpecId, String name, List<OperationAuthInfo> operations) {
26-
super(name, openApiSpecId, operations);
27-
validateConfig();
27+
this(openApiSpecId, name, operations, new ConfigCredentialsProvider());
2828
}
2929

30-
private String getUsername() {
31-
return ConfigProvider.getConfig().getOptionalValue(getCanonicalAuthConfigPropertyName(USER_NAME), String.class)
32-
.orElse("");
30+
private String getUsername(ClientRequestContext requestContext) {
31+
return credentialsProvider.getBasicUsername(requestContext, getOpenApiSpecId(), getName());
3332
}
3433

35-
private String getPassword() {
36-
return ConfigProvider.getConfig().getOptionalValue(getCanonicalAuthConfigPropertyName(PASSWORD), String.class)
37-
.orElse("");
34+
private String getPassword(ClientRequestContext requestContext) {
35+
return credentialsProvider.getBasicPassword(requestContext, getOpenApiSpecId(), getName());
3836
}
3937

4038
@Override
4139
public void filter(ClientRequestContext requestContext) throws IOException {
4240
requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION,
43-
AuthUtils.basicAuthAccessToken(getUsername(), getPassword()));
41+
AuthUtils.basicAuthAccessToken(getUsername(requestContext), getPassword(requestContext)));
4442
}
4543

4644
private void validateConfig() {

client/runtime/src/main/java/io/quarkiverse/openapi/generator/providers/BearerAuthenticationProvider.java

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,42 +6,41 @@
66
import jakarta.ws.rs.client.ClientRequestContext;
77
import jakarta.ws.rs.core.HttpHeaders;
88

9-
import org.eclipse.microprofile.config.ConfigProvider;
10-
119
/**
1210
* Provides bearer token authentication or any other valid scheme.
1311
*
1412
* @see <a href="https://swagger.io/docs/specification/authentication/bearer-authentication/">Bearer Authentication</a>
1513
*/
1614
public class BearerAuthenticationProvider extends AbstractAuthProvider {
1715

18-
static final String BEARER_TOKEN = "bearer-token";
19-
2016
private final String scheme;
2117

2218
public BearerAuthenticationProvider(final String openApiSpecId, final String name, final String scheme,
23-
List<OperationAuthInfo> operations) {
24-
super(name, openApiSpecId, operations);
19+
List<OperationAuthInfo> operations, CredentialsProvider credentialsProvider) {
20+
super(name, openApiSpecId, operations, credentialsProvider);
2521
this.scheme = scheme;
2622
}
2723

24+
public BearerAuthenticationProvider(final String openApiSpecId, final String name, final String scheme,
25+
List<OperationAuthInfo> operations) {
26+
this(openApiSpecId, name, scheme, operations, new ConfigCredentialsProvider());
27+
}
28+
2829
@Override
2930
public void filter(ClientRequestContext requestContext) throws IOException {
3031
String bearerToken;
3132
if (isTokenPropagation()) {
3233
bearerToken = getTokenForPropagation(requestContext.getHeaders());
3334
bearerToken = sanitizeBearerToken(bearerToken);
3435
} else {
35-
bearerToken = getBearerToken();
36+
bearerToken = getBearerToken(requestContext);
3637
}
3738
if (!bearerToken.isBlank()) {
38-
requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION,
39-
AuthUtils.authTokenOrBearer(this.scheme, bearerToken));
39+
requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, AuthUtils.authTokenOrBearer(this.scheme, bearerToken));
4040
}
4141
}
4242

43-
private String getBearerToken() {
44-
return ConfigProvider.getConfig().getOptionalValue(getCanonicalAuthConfigPropertyName(BEARER_TOKEN), String.class)
45-
.orElse("");
43+
private String getBearerToken(ClientRequestContext requestContext) {
44+
return credentialsProvider.getBearerToken(requestContext, getOpenApiSpecId(), getName());
4645
}
4746
}

0 commit comments

Comments
 (0)