Skip to content

Commit 67ccec9

Browse files
committed
make composite authentication provider synthetic
1 parent 3809339 commit 67ccec9

File tree

10 files changed

+155
-154
lines changed

10 files changed

+155
-154
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package io.quarkiverse.openapi.generator.deployment;
2+
3+
import io.quarkiverse.openapi.generator.providers.AuthProvider;
4+
import io.quarkus.builder.item.MultiBuildItem;
5+
import io.quarkus.runtime.RuntimeValue;
6+
7+
public final class AuthProviderBuildItem extends MultiBuildItem {
8+
9+
AuthProviderBuildItem(String openApiSpecId, RuntimeValue<AuthProvider> authProvider) {
10+
this.openApiSpecId = openApiSpecId;
11+
this.authProvider = authProvider;
12+
}
13+
14+
final String openApiSpecId;
15+
final RuntimeValue<AuthProvider> authProvider;
16+
17+
public RuntimeValue<AuthProvider> getAuthProvider() {
18+
return authProvider;
19+
}
20+
21+
public String getOpenApiSpecId() {
22+
return openApiSpecId;
23+
}
24+
}

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

Lines changed: 56 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import io.quarkus.deployment.annotations.Record;
2323
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
2424
import io.quarkus.deployment.builditem.FeatureBuildItem;
25+
import io.quarkus.runtime.RuntimeValue;
2526

2627
public class GeneratorProcessor {
2728

@@ -38,11 +39,32 @@ FeatureBuildItem feature() {
3839
return new FeatureBuildItem(FEATURE);
3940
}
4041

42+
@BuildStep
43+
@Record(ExecutionTime.STATIC_INIT)
44+
void produceCompositeProviders(AuthenticationRecorder recorder,
45+
List<AuthProviderBuildItem> authProviders,
46+
BuildProducer<SyntheticBeanBuildItem> producer) {
47+
Map<String, List<AuthProviderBuildItem>> providersBySpec = authProviders.stream()
48+
.collect(Collectors.groupingBy(AuthProviderBuildItem::getOpenApiSpecId));
49+
providersBySpec.forEach((openApiSpecId, providers) -> {
50+
producer.produce(SyntheticBeanBuildItem.configure(CompositeAuthenticationProvider.class)
51+
.scope(Dependent.class)
52+
.addQualifier()
53+
.annotation(Authentication.class)
54+
.addValue("openApiSpecId", openApiSpecId)
55+
.done()
56+
.runtimeValue(recorder
57+
.recordCompositeProvider(providers.stream().map(AuthProviderBuildItem::getAuthProvider).toList()))
58+
.done());
59+
60+
});
61+
}
62+
4163
@BuildStep
4264
@Record(ExecutionTime.STATIC_INIT)
4365
void produceOauthAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
4466
Capabilities capabilities,
45-
BuildProducer<SyntheticBeanBuildItem> producer,
67+
BuildProducer<AuthProviderBuildItem> authenticationProviders,
4668
AuthenticationRecorder recorder) {
4769
Collection<AnnotationInstance> authenticationMarkers = beanArchiveBuildItem.getIndex()
4870
.getAnnotations(OAUTH_AUTHENTICATION_MARKER);
@@ -56,29 +78,22 @@ void produceOauthAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
5678

5779
List<OperationAuthInfo> operations = getOperations(operationsBySpec, openApiSpecId, name);
5880

59-
producer.produce(SyntheticBeanBuildItem.configure(OAuth2AuthenticationProvider.class)
60-
.scope(Dependent.class)
61-
.addQualifier()
62-
.annotation(Authentication.class)
63-
.addValue("name", name)
64-
.addValue("openApiSpecId", openApiSpecId)
65-
.done()
66-
.runtimeValue(recorder.recordOauthAuthProvider(
67-
sanitizeAuthName(name),
68-
openApiSpecId,
69-
capabilities.isPresent(Capability.REST_CLIENT_REACTIVE)
70-
? recorder.recordReactiveDelegate(sanitizeAuthName(name))
71-
: recorder.recordClassicDelegate(sanitizeAuthName(name)),
72-
operations))
73-
.done());
74-
}
81+
RuntimeValue<AuthProvider> authProvider = recorder.recordOauthAuthProvider(
82+
sanitizeAuthName(name),
83+
openApiSpecId,
84+
capabilities.isPresent(Capability.REST_CLIENT_REACTIVE)
85+
? recorder.recordReactiveDelegate(sanitizeAuthName(name))
86+
: recorder.recordClassicDelegate(sanitizeAuthName(name)),
87+
operations);
7588

89+
authenticationProviders.produce(new AuthProviderBuildItem(openApiSpecId, authProvider));
90+
}
7691
}
7792

7893
@BuildStep
7994
@Record(ExecutionTime.STATIC_INIT)
8095
void produceBasicAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
81-
BuildProducer<SyntheticBeanBuildItem> producer,
96+
BuildProducer<AuthProviderBuildItem> authenticationProviders,
8297
AuthenticationRecorder recorder) {
8398

8499
Collection<AnnotationInstance> authenticationMarkers = beanArchiveBuildItem.getIndex()
@@ -92,26 +107,19 @@ void produceBasicAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
92107

93108
List<OperationAuthInfo> operations = getOperations(operationsBySpec, openApiSpecId, name);
94109

95-
producer.produce(SyntheticBeanBuildItem.configure(BasicAuthenticationProvider.class)
96-
.scope(Dependent.class)
97-
.addQualifier()
98-
.annotation(Authentication.class)
99-
.addValue("name", name)
100-
.addValue("openApiSpecId", openApiSpecId)
101-
.done()
102-
.createWith(recorder.recordBasicAuthProvider(
103-
sanitizeAuthName(name),
104-
openApiSpecId,
105-
operations))
106-
.done());
107-
}
110+
RuntimeValue<AuthProvider> authProvider = recorder.recordBasicAuthProvider(
111+
sanitizeAuthName(name),
112+
openApiSpecId,
113+
operations);
108114

115+
authenticationProviders.produce(new AuthProviderBuildItem(openApiSpecId, authProvider));
116+
}
109117
}
110118

111119
@BuildStep
112120
@Record(ExecutionTime.STATIC_INIT)
113121
void produceBearerAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
114-
BuildProducer<SyntheticBeanBuildItem> producer,
122+
BuildProducer<AuthProviderBuildItem> authenticationProviders,
115123
AuthenticationRecorder recorder) {
116124

117125
Collection<AnnotationInstance> authenticationMarkers = beanArchiveBuildItem.getIndex()
@@ -126,27 +134,20 @@ void produceBearerAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
126134

127135
List<OperationAuthInfo> operations = getOperations(operationsBySpec, openApiSpecId, name);
128136

129-
producer.produce(SyntheticBeanBuildItem.configure(BearerAuthenticationProvider.class)
130-
.scope(Dependent.class)
131-
.addQualifier()
132-
.annotation(Authentication.class)
133-
.addValue("name", name)
134-
.addValue("openApiSpecId", openApiSpecId)
135-
.done()
136-
.createWith(recorder.recordBearerAuthProvider(
137-
sanitizeAuthName(name),
138-
scheme,
139-
openApiSpecId,
140-
operations))
141-
.done());
142-
}
137+
RuntimeValue<AuthProvider> authProvider = recorder.recordBearerAuthProvider(
138+
sanitizeAuthName(name),
139+
scheme,
140+
openApiSpecId,
141+
operations);
143142

143+
authenticationProviders.produce(new AuthProviderBuildItem(openApiSpecId, authProvider));
144+
}
144145
}
145146

146147
@BuildStep
147148
@Record(ExecutionTime.STATIC_INIT)
148149
void produceApiKeyAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
149-
BuildProducer<SyntheticBeanBuildItem> producer,
150+
BuildProducer<AuthProviderBuildItem> authenticationProviders,
150151
AuthenticationRecorder recorder) {
151152

152153
Collection<AnnotationInstance> authenticationMarkers = beanArchiveBuildItem.getIndex()
@@ -162,20 +163,14 @@ void produceApiKeyAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
162163

163164
List<OperationAuthInfo> operations = getOperations(operationsBySpec, openApiSpecId, name);
164165

165-
producer.produce(SyntheticBeanBuildItem.configure(ApiKeyAuthenticationProvider.class)
166-
.scope(Dependent.class)
167-
.addQualifier()
168-
.annotation(Authentication.class)
169-
.addValue("name", name)
170-
.addValue("openApiSpecId", openApiSpecId)
171-
.done()
172-
.createWith(recorder.recordApiKeyAuthProvider(
173-
sanitizeAuthName(name),
174-
openApiSpecId,
175-
apiKeyIn,
176-
apiKeyName,
177-
operations))
178-
.done());
166+
RuntimeValue<AuthProvider> authProvider = recorder.recordApiKeyAuthProvider(
167+
sanitizeAuthName(name),
168+
openApiSpecId,
169+
apiKeyIn,
170+
apiKeyName,
171+
operations);
172+
173+
authenticationProviders.produce(new AuthProviderBuildItem(openApiSpecId, authProvider));
179174
}
180175

181176
}

client/deployment/src/main/resources/templates/libraries/microprofile/auth/compositeAuthenticationProvider.qute

Lines changed: 7 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,48 +19,14 @@ package {apiPackage}.auth;
1919
@io.quarkiverse.openapi.generator.markers.ApiKeyAuthenticationMarker(name="{auth.name}", openApiSpecId="{quarkus-generator.openApiSpecId}", apiKeyIn=io.quarkiverse.openapi.generator.providers.ApiKeyIn.cookie, apiKeyName="{auth.keyParamName}")
2020
{/if}
2121
{/for}
22-
public class CompositeAuthenticationProvider extends io.quarkiverse.openapi.generator.providers.AbstractCompositeAuthenticationProvider {
22+
public class CompositeAuthenticationProvider implements jakarta.ws.rs.client.ClientRequestFilter {
2323

24-
25-
26-
@jakarta.inject.Inject
27-
io.quarkiverse.openapi.generator.OpenApiGeneratorConfig generatorConfig;
28-
29-
{#for auth in oauthMethods.orEmpty}
3024
@jakarta.inject.Inject
31-
@io.quarkiverse.openapi.generator.Authentication(name="{auth.name}", openApiSpecId="{configKey}")
32-
io.quarkiverse.openapi.generator.providers.OAuth2AuthenticationProvider oAuth2Provider{auth_index};
33-
{/for}
34-
35-
{#for auth in httpBasicMethods.orEmpty}
36-
@io.quarkiverse.openapi.generator.Authentication(name="{auth.name}", openApiSpecId="{quarkus-generator.openApiSpecId}")
37-
io.quarkiverse.openapi.generator.providers.BasicAuthenticationProvider basicAuthProvider{auth_index};
38-
{/for}
39-
40-
{#for auth in httpBearerMethods.orEmpty}
41-
@io.quarkiverse.openapi.generator.Authentication(name="{auth.name}", openApiSpecId="{quarkus-generator.openApiSpecId}")
42-
io.quarkiverse.openapi.generator.providers.BearerAuthenticationProvider bearerProvider{auth_index};
43-
{/for}
44-
45-
{#for auth in apiKeyMethods.orEmpty}
46-
@io.quarkiverse.openapi.generator.Authentication(name="{auth.name}", openApiSpecId="{quarkus-generator.openApiSpecId}")
47-
io.quarkiverse.openapi.generator.providers.ApiKeyAuthenticationProvider apiKeyQueryProvider{auth_index};
48-
{/for}
49-
25+
@io.quarkiverse.openapi.generator.Authentication(openApiSpecId="{configKey}")
26+
io.quarkiverse.openapi.generator.providers.CompositeAuthenticationProvider compositeProvider;
5027

51-
@jakarta.annotation.PostConstruct
52-
public void init() {
53-
{#for auth in httpBasicMethods.orEmpty}
54-
this.addAuthenticationProvider(basicAuthProvider{auth_index});
55-
{/for}
56-
{#for auth in oauthMethods.orEmpty}
57-
this.addAuthenticationProvider(oAuth2Provider{auth_index});
58-
{/for}
59-
{#for auth in httpBearerMethods.orEmpty}
60-
this.addAuthenticationProvider(bearerProvider{auth_index});
61-
{/for}
62-
{#for auth in apiKeyMethods.orEmpty}
63-
this.addAuthenticationProvider(apiKeyQueryProvider{auth_index});
64-
{/for}
65-
}
28+
@java.lang.Override
29+
public void filter(jakarta.ws.rs.client.ClientRequestContext context) throws java.io.IOException {
30+
compositeProvider.filter(context);
31+
};
6632
}

client/deployment/src/main/resources/templates/libraries/microprofile/auth/headersFactory.qute

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package {apiPackage}.auth;
33
public class AuthenticationPropagationHeadersFactory extends io.quarkiverse.openapi.generator.providers.AbstractAuthenticationPropagationHeadersFactory {
44

55
@jakarta.inject.Inject
6-
public AuthenticationPropagationHeadersFactory(CompositeAuthenticationProvider compositeProvider, io.quarkiverse.openapi.generator.OpenApiGeneratorConfig generatorConfig, io.quarkiverse.openapi.generator.providers.HeadersProvider headersProvider) {
6+
public AuthenticationPropagationHeadersFactory(@io.quarkiverse.openapi.generator.Authentication(openApiSpecId="{configKey}") io.quarkiverse.openapi.generator.providers.CompositeAuthenticationProvider compositeProvider, io.quarkiverse.openapi.generator.OpenApiGeneratorConfig generatorConfig, io.quarkiverse.openapi.generator.providers.HeadersProvider headersProvider) {
77
super(compositeProvider, generatorConfig, headersProvider);
88
}
99

client/deployment/src/test/java/io/quarkiverse/openapi/generator/deployment/authentication/AuthenticationProviderTest.java

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,46 +15,57 @@
1515
import io.quarkiverse.openapi.generator.markers.ApiKeyAuthenticationMarker;
1616
import io.quarkiverse.openapi.generator.markers.BasicAuthenticationMarker;
1717
import io.quarkiverse.openapi.generator.markers.OauthAuthenticationMarker;
18-
import io.quarkiverse.openapi.generator.providers.ApiKeyAuthenticationProvider;
19-
import io.quarkiverse.openapi.generator.providers.BasicAuthenticationProvider;
20-
import io.quarkiverse.openapi.generator.providers.OAuth2AuthenticationProvider;
18+
import io.quarkiverse.openapi.generator.providers.*;
2119
import io.quarkus.test.QuarkusUnitTest;
2220

2321
public class AuthenticationProviderTest {
2422

2523
@RegisterExtension
2624
static final QuarkusUnitTest unitTest = new QuarkusUnitTest()
2725
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
28-
.addClass(CompositeAuthenticationProvider.class)
26+
.addClass(LocalAuthenticationProvider.class)
2927
.addAsResource(
3028
new StringAsset("\n"),
3129
"application.properties"));
3230

3331
@Test
3432
public void test() {
35-
Assertions.assertEquals("petstore_auth", oAuth2Provider.getName());
36-
Assertions.assertEquals("spec_1", oAuth2Provider.getOpenApiSpecId());
37-
Assertions.assertEquals("basic_auth", basicAuthProvider.getName());
38-
Assertions.assertEquals("spec_1", basicAuthProvider.getOpenApiSpecId());
39-
Assertions.assertEquals("api_key", apiKeyQueryProvider.getName());
40-
Assertions.assertEquals("spec_2", apiKeyQueryProvider.getOpenApiSpecId());
33+
Assertions.assertEquals(1, spec1CompositeProvider.getAuthenticationProviders().size());
34+
Assertions.assertEquals(1, spec2CompositeProvider.getAuthenticationProviders().size());
35+
Assertions.assertEquals(1, spec3CompositeProvider.getAuthenticationProviders().size());
36+
37+
AuthProvider authProvider = spec1CompositeProvider.getAuthenticationProviders().get(0);
38+
Assertions.assertInstanceOf(OAuth2AuthenticationProvider.class, authProvider);
39+
Assertions.assertEquals("petstore_auth", authProvider.getName());
40+
Assertions.assertEquals("spec_1", ((OAuth2AuthenticationProvider) authProvider).getOpenApiSpecId());
41+
42+
authProvider = spec2CompositeProvider.getAuthenticationProviders().get(0);
43+
Assertions.assertInstanceOf(BasicAuthenticationProvider.class, authProvider);
44+
Assertions.assertEquals("basic_auth", authProvider.getName());
45+
Assertions.assertEquals("spec_2", ((BasicAuthenticationProvider) authProvider).getOpenApiSpecId());
46+
47+
authProvider = spec3CompositeProvider.getAuthenticationProviders().get(0);
48+
Assertions.assertInstanceOf(ApiKeyAuthenticationProvider.class, authProvider);
49+
Assertions.assertEquals("api_key", authProvider.getName());
50+
Assertions.assertEquals("spec_3", ((ApiKeyAuthenticationProvider) authProvider).getOpenApiSpecId());
51+
4152
}
4253

4354
@Inject
44-
@Authentication(name = "petstore_auth", openApiSpecId = "spec_1")
45-
OAuth2AuthenticationProvider oAuth2Provider;
55+
@Authentication(openApiSpecId = "spec_1")
56+
CompositeAuthenticationProvider spec1CompositeProvider;
4657

47-
@Authentication(name = "basic_auth", openApiSpecId = "spec_1")
48-
BasicAuthenticationProvider basicAuthProvider;
58+
@Authentication(openApiSpecId = "spec_2")
59+
CompositeAuthenticationProvider spec2CompositeProvider;
4960

50-
@Authentication(name = "api_key", openApiSpecId = "spec_2")
51-
ApiKeyAuthenticationProvider apiKeyQueryProvider;
61+
@Authentication(openApiSpecId = "spec_3")
62+
CompositeAuthenticationProvider spec3CompositeProvider;
5263

5364
@jakarta.annotation.Priority(jakarta.ws.rs.Priorities.AUTHENTICATION)
5465
@OauthAuthenticationMarker(name = "petstore_auth", openApiSpecId = "spec_1")
55-
@BasicAuthenticationMarker(name = "basic_auth", openApiSpecId = "spec_1")
56-
@ApiKeyAuthenticationMarker(name = "api_key", openApiSpecId = "spec_2", apiKeyIn = header, apiKeyName = "api_key")
57-
public static class CompositeAuthenticationProvider {
66+
@BasicAuthenticationMarker(name = "basic_auth", openApiSpecId = "spec_2")
67+
@ApiKeyAuthenticationMarker(name = "api_key", openApiSpecId = "spec_3", apiKeyIn = header, apiKeyName = "api_key")
68+
public static class LocalAuthenticationProvider {
5869

5970
}
6071

0 commit comments

Comments
 (0)