Skip to content

Commit 8026891

Browse files
Fix #1156 - Move AuthProviders SyntheticBean generation to Runtime (#1163)
* Fix #1156 - Move AuthProviders SyntheticBean generation to Runtime Signed-off-by: Ricardo Zanini <[email protected]> * Add a meaningful log message to IT Signed-off-by: Ricardo Zanini <[email protected]> * Update client/integration-tests/override-credential-provider/src/test/java/io/quarkiverse/openapi/generator/it/creds/CustomCredentialsProviderTest.java Co-authored-by: Gonzalo Muñoz <[email protected]> --------- Signed-off-by: Ricardo Zanini <[email protected]> Co-authored-by: Gonzalo Muñoz <[email protected]>
1 parent 3894a6e commit 8026891

File tree

10 files changed

+213
-11
lines changed

10 files changed

+213
-11
lines changed

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

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ FeatureBuildItem feature() {
8484
}
8585

8686
@BuildStep
87-
void additionalBean(Capabilities capabilities, BuildProducer<AdditionalBeanBuildItem> producer) {
88-
87+
void registerOidcClientBean(Capabilities capabilities, BuildProducer<AdditionalBeanBuildItem> producer) {
8988
if (!isClassPresentAtRuntime(ABSTRACT_TOKEN_PRODUCER)) {
9089
LOGGER.debug("{} class not found in runtime, skipping OidcClientRequestFilterDelegate bean generation",
9190
ABSTRACT_TOKEN_PRODUCER);
@@ -101,7 +100,6 @@ void additionalBean(Capabilities capabilities, BuildProducer<AdditionalBeanBuild
101100
producer.produce(AdditionalBeanBuildItem.builder().addBeanClass(ClassicOidcClientRequestFilterDelegate.class)
102101
.setDefaultScope(DotName.createSimple(Dependent.class)).setUnremovable().build());
103102
}
104-
105103
}
106104

107105
@BuildStep
@@ -126,7 +124,7 @@ void produceCompositeProviders(AuthenticationRecorder recorder, List<AuthProvide
126124
}
127125

128126
@BuildStep
129-
@Record(ExecutionTime.STATIC_INIT)
127+
@Record(ExecutionTime.RUNTIME_INIT)
130128
void produceOauthAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
131129
BuildProducer<AuthProviderBuildItem> authenticationProviders,
132130
BuildProducer<SyntheticBeanBuildItem> beanProducer,
@@ -178,14 +176,16 @@ void produceOauthAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
178176
.done()
179177
.addInjectionPoint(ClassType.create(OAuth2AuthenticationProvider.OidcClientRequestFilterDelegate.class),
180178
AnnotationInstance.builder(OidcClient.class).add("name", sanitizeAuthName(name)).build())
179+
.addInjectionPoint(ClassType.create(DotName.createSimple(CredentialsProvider.class)))
181180
.createWith(oidcRecorder.recordOauthAuthProvider(sanitizeAuthName(name), openApiSpecId, operations))
181+
.setRuntimeInit()
182182
.unremovable()
183183
.done());
184184
}
185185
}
186186

187187
@BuildStep
188-
@Record(ExecutionTime.STATIC_INIT)
188+
@Record(ExecutionTime.RUNTIME_INIT)
189189
void produceBasicAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
190190
BuildProducer<AuthProviderBuildItem> authenticationProviders, BuildProducer<SyntheticBeanBuildItem> beanProducer,
191191
AuthenticationRecorder recorder) {
@@ -218,13 +218,14 @@ void produceBasicAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
218218
.done()
219219
.addInjectionPoint(ClassType.create(DotName.createSimple(CredentialsProvider.class)))
220220
.createWith(recorder.recordBasicAuthProvider(sanitizeAuthName(name), openApiSpecId, operations))
221+
.setRuntimeInit()
221222
.unremovable()
222223
.done());
223224
}
224225
}
225226

226227
@BuildStep
227-
@Record(ExecutionTime.STATIC_INIT)
228+
@Record(ExecutionTime.RUNTIME_INIT)
228229
void produceBearerAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
229230
BuildProducer<AuthProviderBuildItem> authenticationProviders, BuildProducer<SyntheticBeanBuildItem> beanProducer,
230231
AuthenticationRecorder recorder) {
@@ -258,14 +259,15 @@ void produceBearerAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
258259
.done()
259260
.addInjectionPoint(ClassType.create(DotName.createSimple(CredentialsProvider.class)))
260261
.createWith(recorder.recordBearerAuthProvider(sanitizeAuthName(name), scheme, openApiSpecId, operations))
262+
.setRuntimeInit()
261263
.unremovable()
262264
.done());
263265

264266
}
265267
}
266268

267269
@BuildStep
268-
@Record(ExecutionTime.STATIC_INIT)
270+
@Record(ExecutionTime.RUNTIME_INIT)
269271
void produceApiKeyAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
270272
BuildProducer<AuthProviderBuildItem> authenticationProviders, BuildProducer<SyntheticBeanBuildItem> beanProducer,
271273
AuthenticationRecorder recorder) {
@@ -302,6 +304,7 @@ void produceApiKeyAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
302304
.addInjectionPoint(ClassType.create(DotName.createSimple(CredentialsProvider.class)))
303305
.createWith(recorder.recordApiKeyAuthProvider(sanitizeAuthName(name), openApiSpecId, apiKeyIn, apiKeyName,
304306
operations))
307+
.setRuntimeInit()
305308
.unremovable()
306309
.done());
307310
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<artifactId>quarkus-openapi-generator-integration-tests</artifactId>
8+
<groupId>io.quarkiverse.openapi.generator</groupId>
9+
<version>3.0.0-SNAPSHOT</version>
10+
</parent>
11+
12+
<artifactId>quarkus-openapi-generatir-it-override-credential-provider</artifactId>
13+
<name>Quarkus - OpenAPI Generator - Integration Tests - Client - Override Credentials Provider</name>
14+
<description>Integration Test to verify https://github.com/quarkiverse/quarkus-openapi-generator/issues/1156</description>
15+
16+
<dependencies>
17+
<dependency>
18+
<groupId>io.quarkiverse.openapi.generator</groupId>
19+
<artifactId>quarkus-openapi-generator</artifactId>
20+
</dependency>
21+
<dependency>
22+
<groupId>org.assertj</groupId>
23+
<artifactId>assertj-core</artifactId>
24+
<scope>test</scope>
25+
</dependency>
26+
<dependency>
27+
<groupId>io.quarkus</groupId>
28+
<artifactId>quarkus-junit5</artifactId>
29+
<scope>test</scope>
30+
</dependency>
31+
<dependency>
32+
<groupId>org.wiremock</groupId>
33+
<artifactId>wiremock</artifactId>
34+
<scope>test</scope>
35+
</dependency>
36+
</dependencies>
37+
38+
<build>
39+
<plugins>
40+
<plugin>
41+
<groupId>io.quarkus</groupId>
42+
<artifactId>quarkus-maven-plugin</artifactId>
43+
<extensions>true</extensions>
44+
<executions>
45+
<execution>
46+
<goals>
47+
<goal>build</goal>
48+
<goal>generate-code</goal>
49+
<goal>generate-code-tests</goal>
50+
</goals>
51+
</execution>
52+
</executions>
53+
</plugin>
54+
</plugins>
55+
</build>
56+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package io.quarkiverse.openapi.generator.it.creds;
2+
3+
import jakarta.annotation.Priority;
4+
import jakarta.enterprise.context.Dependent;
5+
import jakarta.enterprise.inject.Alternative;
6+
import jakarta.ws.rs.client.ClientRequestContext;
7+
8+
import org.slf4j.Logger;
9+
import org.slf4j.LoggerFactory;
10+
11+
import io.quarkiverse.openapi.generator.providers.ConfigCredentialsProvider;
12+
13+
@Dependent
14+
@Alternative
15+
@Priority(200)
16+
public class CustomCredentialsProvider extends ConfigCredentialsProvider {
17+
private static final Logger LOGGER = LoggerFactory.getLogger(CustomCredentialsProvider.class);
18+
19+
public static String TOKEN = "FIXED_TEST_TOKEN";
20+
21+
@Override
22+
public String getBearerToken(ClientRequestContext requestContext, String openApiSpecId, String authName) {
23+
LOGGER.info("========> getBearerToken from CustomCredentialsProvider");
24+
return TOKEN;
25+
}
26+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
openapi: 3.0.3
2+
info:
3+
title: Simple server API
4+
description: |-
5+
Simple server API
6+
version: 1.0.0
7+
tags:
8+
- name: Simple server API
9+
description: Simple server API
10+
servers:
11+
- url: /
12+
paths:
13+
/simple:
14+
get:
15+
summary: Send requests to simple server with simple JWT security scheme
16+
description: Send requests to simple server to check the auth header
17+
operationId: getWithSimpleBearerTokenSecurityScheme
18+
responses:
19+
"200":
20+
description: Successful operation
21+
security:
22+
- SimpleBearerToken: []
23+
components:
24+
securitySchemes:
25+
SimpleBearerToken:
26+
type: http
27+
scheme: bearer
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
quarkus.openapi-generator.simple_server_yaml.auth.SimpleBearerToken.header-name=X-Authorization-Simple
2+
# We have a custom CredentialsProvider that will ignore this token set in the config and will return a hard-coded one.
3+
quarkus.openapi-generator.simple_server_yaml.auth.SimpleBearerToken.bearer-token=WILL_BE_OVERRIDED
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package io.quarkiverse.openapi.generator.it.creds;
2+
3+
import jakarta.inject.Inject;
4+
5+
import org.assertj.core.api.Assertions;
6+
import org.eclipse.microprofile.rest.client.inject.RestClient;
7+
import org.junit.jupiter.api.Test;
8+
import org.openapi.quarkus.simple_server_yaml.api.DefaultApi;
9+
10+
import com.github.tomakehurst.wiremock.WireMockServer;
11+
import com.github.tomakehurst.wiremock.client.WireMock;
12+
13+
import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
14+
import io.quarkus.test.common.WithTestResource;
15+
import io.quarkus.test.junit.QuarkusTest;
16+
17+
@WithTestResource(SimpleServerMockResource.class)
18+
@QuarkusTest
19+
public class CustomCredentialsProviderTest {
20+
21+
/**
22+
* @see SimpleServerMockResource#inject(QuarkusTestResourceLifecycleManager.TestInjector)
23+
*/
24+
WireMockServer simpleServer;
25+
26+
@RestClient
27+
@Inject
28+
DefaultApi defaultApi;
29+
30+
/**
31+
* This test validates whether the custom CredentialsProvider is overriden.
32+
*/
33+
@Test
34+
public void testGetHardCodedToken() {
35+
Assertions.assertThat(defaultApi.getWithSimpleBearerTokenSecurityScheme().getStatus()).isEqualTo(200);
36+
37+
simpleServer.verify(WireMock.getRequestedFor(WireMock.urlEqualTo("/simple")).withHeader("Authorization",
38+
WireMock.equalTo("Bearer " + CustomCredentialsProvider.TOKEN)));
39+
}
40+
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package io.quarkiverse.openapi.generator.it.creds;
2+
3+
import static com.github.tomakehurst.wiremock.client.WireMock.get;
4+
import static com.github.tomakehurst.wiremock.client.WireMock.ok;
5+
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
6+
7+
import java.util.Collections;
8+
import java.util.Map;
9+
10+
import com.github.tomakehurst.wiremock.WireMockServer;
11+
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
12+
13+
import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
14+
15+
public class SimpleServerMockResource implements QuarkusTestResourceLifecycleManager {
16+
17+
private WireMockServer wireMockServer;
18+
19+
@Override
20+
public Map<String, String> start() {
21+
wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().dynamicPort());
22+
wireMockServer.start();
23+
24+
wireMockServer.stubFor(get(urlMatching("/simple"))
25+
.willReturn(ok()));
26+
27+
return Collections.singletonMap("quarkus.rest-client.simple_server_yaml.url",
28+
wireMockServer.baseUrl());
29+
}
30+
31+
@Override
32+
public void inject(TestInjector testInjector) {
33+
testInjector.injectIntoFields(wireMockServer, f -> f.getName().equals("simpleServer"));
34+
}
35+
36+
@Override
37+
public void stop() {
38+
if (null != wireMockServer) {
39+
wireMockServer.stop();
40+
}
41+
}
42+
}

client/integration-tests/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
<module>without-oidc</module>
4848
<module>serializable-model</module>
4949
<module>equals-hashcode</module>
50+
<module>override-credential-provider</module>
5051
</modules>
5152
<dependencyManagement>
5253
<dependencies>

client/oidc/src/main/java/io/quarkiverse/openapi/generator/oidc/OidcAuthenticationRecorder.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import io.quarkiverse.openapi.generator.OidcClient;
77
import io.quarkiverse.openapi.generator.oidc.providers.OAuth2AuthenticationProvider;
88
import io.quarkiverse.openapi.generator.providers.AuthProvider;
9+
import io.quarkiverse.openapi.generator.providers.CredentialsProvider;
910
import io.quarkiverse.openapi.generator.providers.OperationAuthInfo;
1011
import io.quarkus.arc.SyntheticCreationalContext;
1112
import io.quarkus.runtime.annotations.Recorder;
@@ -20,6 +21,7 @@ public Function<SyntheticCreationalContext<AuthProvider>, AuthProvider> recordOa
2021
return context -> new OAuth2AuthenticationProvider(name, openApiSpecId,
2122
context.getInjectedReference(OAuth2AuthenticationProvider.OidcClientRequestFilterDelegate.class,
2223
new OidcClient.Literal(name)),
23-
operations);
24+
operations,
25+
context.getInjectedReference(CredentialsProvider.class));
2426
}
2527
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import org.slf4j.LoggerFactory;
1313

1414
import io.quarkiverse.openapi.generator.providers.AbstractAuthProvider;
15-
import io.quarkiverse.openapi.generator.providers.ConfigCredentialsProvider;
15+
import io.quarkiverse.openapi.generator.providers.CredentialsProvider;
1616
import io.quarkiverse.openapi.generator.providers.OperationAuthInfo;
1717
import io.quarkus.oidc.common.runtime.OidcConstants;
1818

@@ -23,8 +23,9 @@ public class OAuth2AuthenticationProvider extends AbstractAuthProvider {
2323
private final OidcClientRequestFilterDelegate delegate;
2424

2525
public OAuth2AuthenticationProvider(String name,
26-
String openApiSpecId, OidcClientRequestFilterDelegate delegate, List<OperationAuthInfo> operations) {
27-
super(name, openApiSpecId, operations, new ConfigCredentialsProvider());
26+
String openApiSpecId, OidcClientRequestFilterDelegate delegate, List<OperationAuthInfo> operations,
27+
CredentialsProvider credentialsProvider) {
28+
super(name, openApiSpecId, operations, credentialsProvider);
2829
this.delegate = delegate;
2930
validateConfig();
3031
}

0 commit comments

Comments
 (0)