Skip to content

Commit 56acf4b

Browse files
committed
make composite authentication provider synthetic
1 parent 62bba62 commit 56acf4b

File tree

17 files changed

+272
-176
lines changed

17 files changed

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

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

Lines changed: 77 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,18 @@
66
import java.util.stream.Collectors;
77

88
import jakarta.enterprise.context.Dependent;
9+
import jakarta.enterprise.inject.Instance;
910

1011
import org.jboss.jandex.AnnotationInstance;
12+
import org.jboss.jandex.ClassType;
1113
import org.jboss.jandex.DotName;
14+
import org.jboss.jandex.ParameterizedType;
1215

1316
import io.quarkiverse.openapi.generator.*;
1417
import io.quarkiverse.openapi.generator.markers.*;
1518
import io.quarkiverse.openapi.generator.providers.*;
19+
import io.quarkiverse.openapi.generator.providers.OAuth2AuthenticationProvider.OidcClientRequestFilterDelegate;
20+
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
1621
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
1722
import io.quarkus.deployment.Capabilities;
1823
import io.quarkus.deployment.Capability;
@@ -38,122 +43,165 @@ FeatureBuildItem feature() {
3843
return new FeatureBuildItem(FEATURE);
3944
}
4045

46+
@BuildStep
47+
void additionalBean(
48+
Capabilities capabilities,
49+
BuildProducer<AdditionalBeanBuildItem> additionalBeanBuildItem) {
50+
if (capabilities.isPresent(Capability.REST_CLIENT_REACTIVE)) {
51+
additionalBeanBuildItem.produce(
52+
AdditionalBeanBuildItem.builder().addBeanClass(ReactiveOidcClientRequestFilterDelegate.class)
53+
.setDefaultScope(DotName.createSimple(Dependent.class))
54+
.setUnremovable()
55+
.build());
56+
} else {
57+
additionalBeanBuildItem.produce(
58+
AdditionalBeanBuildItem.builder().addBeanClass(ClassicOidcClientRequestFilterDelegate.class)
59+
.setDefaultScope(DotName.createSimple(Dependent.class))
60+
.setUnremovable()
61+
.build());
62+
}
63+
}
64+
65+
@BuildStep
66+
@Record(ExecutionTime.STATIC_INIT)
67+
void produceCompositeProviders(AuthenticationRecorder recorder,
68+
List<AuthProviderBuildItem> authProviders,
69+
BuildProducer<SyntheticBeanBuildItem> beanProducer) {
70+
Map<String, List<AuthProviderBuildItem>> providersBySpec = authProviders.stream()
71+
.collect(Collectors.groupingBy(AuthProviderBuildItem::getOpenApiSpecId));
72+
providersBySpec.forEach((openApiSpecId, providers) -> {
73+
beanProducer.produce(SyntheticBeanBuildItem.configure(CompositeAuthenticationProvider.class)
74+
.scope(Dependent.class)
75+
.addQualifier()
76+
.annotation(Authentication.class)
77+
.addValue("openApiSpecId", openApiSpecId)
78+
.done()
79+
.addInjectionPoint(
80+
ParameterizedType.create(Instance.class, ClassType.create(AuthProvider.class)),
81+
AnnotationInstance.builder(Authentication.class)
82+
.add("openApiSpecId", openApiSpecId)
83+
.build())
84+
.createWith(recorder.recordCompositeProvider(openApiSpecId))
85+
.done());
86+
87+
});
88+
}
89+
4190
@BuildStep
4291
@Record(ExecutionTime.STATIC_INIT)
4392
void produceOauthAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
4493
Capabilities capabilities,
45-
BuildProducer<SyntheticBeanBuildItem> producer,
94+
BuildProducer<AuthProviderBuildItem> authenticationProviders,
95+
BuildProducer<SyntheticBeanBuildItem> beanProducer,
4696
AuthenticationRecorder recorder) {
4797
Collection<AnnotationInstance> authenticationMarkers = beanArchiveBuildItem.getIndex()
4898
.getAnnotations(OAUTH_AUTHENTICATION_MARKER);
4999

50100
Map<String, List<AnnotationInstance>> operationsBySpec = getOperationsBySpec(beanArchiveBuildItem);
51101

52102
for (AnnotationInstance authenticationMarker : authenticationMarkers) {
53-
54103
String name = authenticationMarker.value("name").asString();
55104
String openApiSpecId = authenticationMarker.value("openApiSpecId").asString();
56-
57105
List<OperationAuthInfo> operations = getOperations(operationsBySpec, openApiSpecId, name);
58-
59-
producer.produce(SyntheticBeanBuildItem.configure(OAuth2AuthenticationProvider.class)
106+
authenticationProviders.produce(new AuthProviderBuildItem(openApiSpecId, name));
107+
beanProducer.produce(SyntheticBeanBuildItem.configure(AuthProvider.class)
60108
.scope(Dependent.class)
61109
.addQualifier()
62110
.annotation(Authentication.class)
63-
.addValue("name", name)
64111
.addValue("openApiSpecId", openApiSpecId)
65112
.done()
66-
.runtimeValue(recorder.recordOauthAuthProvider(
113+
.addInjectionPoint(ClassType.create(OidcClientRequestFilterDelegate.class),
114+
AnnotationInstance.builder(OidcClient.class)
115+
.add("name", sanitizeAuthName(name))
116+
.build())
117+
.createWith(recorder.recordOauthAuthProvider(
67118
sanitizeAuthName(name),
68119
openApiSpecId,
69-
capabilities.isPresent(Capability.REST_CLIENT_REACTIVE)
70-
? recorder.recordReactiveDelegate(sanitizeAuthName(name))
71-
: recorder.recordClassicDelegate(sanitizeAuthName(name)),
72120
operations))
121+
.unremovable()
73122
.done());
74123
}
75-
76124
}
77125

78126
@BuildStep
79127
@Record(ExecutionTime.STATIC_INIT)
80128
void produceBasicAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
81-
BuildProducer<SyntheticBeanBuildItem> producer,
129+
BuildProducer<AuthProviderBuildItem> authenticationProviders,
130+
BuildProducer<SyntheticBeanBuildItem> beanProducer,
82131
AuthenticationRecorder recorder) {
83132

84133
Collection<AnnotationInstance> authenticationMarkers = beanArchiveBuildItem.getIndex()
85134
.getAnnotations(BASIC_AUTHENTICATION_MARKER);
86135

87136
Map<String, List<AnnotationInstance>> operationsBySpec = getOperationsBySpec(beanArchiveBuildItem);
88-
89137
for (AnnotationInstance authenticationMarker : authenticationMarkers) {
90138
String name = authenticationMarker.value("name").asString();
91139
String openApiSpecId = authenticationMarker.value("openApiSpecId").asString();
92140

93141
List<OperationAuthInfo> operations = getOperations(operationsBySpec, openApiSpecId, name);
94142

95-
producer.produce(SyntheticBeanBuildItem.configure(BasicAuthenticationProvider.class)
143+
authenticationProviders.produce(new AuthProviderBuildItem(openApiSpecId, name));
144+
145+
beanProducer.produce(SyntheticBeanBuildItem.configure(AuthProvider.class)
96146
.scope(Dependent.class)
97147
.addQualifier()
98148
.annotation(Authentication.class)
99-
.addValue("name", name)
100149
.addValue("openApiSpecId", openApiSpecId)
101150
.done()
102151
.createWith(recorder.recordBasicAuthProvider(
103152
sanitizeAuthName(name),
104153
openApiSpecId,
105154
operations))
155+
.unremovable()
106156
.done());
107157
}
108-
109158
}
110159

111160
@BuildStep
112161
@Record(ExecutionTime.STATIC_INIT)
113162
void produceBearerAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
114-
BuildProducer<SyntheticBeanBuildItem> producer,
163+
BuildProducer<AuthProviderBuildItem> authenticationProviders,
164+
BuildProducer<SyntheticBeanBuildItem> beanProducer,
115165
AuthenticationRecorder recorder) {
116166

117167
Collection<AnnotationInstance> authenticationMarkers = beanArchiveBuildItem.getIndex()
118168
.getAnnotations(BEARER_AUTHENTICATION_MARKER);
119169

120170
Map<String, List<AnnotationInstance>> operationsBySpec = getOperationsBySpec(beanArchiveBuildItem);
121-
122171
for (AnnotationInstance authenticationMarker : authenticationMarkers) {
123172
String name = authenticationMarker.value("name").asString();
124173
String scheme = authenticationMarker.value("scheme").asString();
125174
String openApiSpecId = authenticationMarker.value("openApiSpecId").asString();
126175

127176
List<OperationAuthInfo> operations = getOperations(operationsBySpec, openApiSpecId, name);
128-
129-
producer.produce(SyntheticBeanBuildItem.configure(BearerAuthenticationProvider.class)
177+
authenticationProviders.produce(new AuthProviderBuildItem(openApiSpecId, name));
178+
beanProducer.produce(SyntheticBeanBuildItem.configure(AuthProvider.class)
130179
.scope(Dependent.class)
131180
.addQualifier()
132181
.annotation(Authentication.class)
133-
.addValue("name", name)
134182
.addValue("openApiSpecId", openApiSpecId)
135183
.done()
136184
.createWith(recorder.recordBearerAuthProvider(
137185
sanitizeAuthName(name),
138186
scheme,
139187
openApiSpecId,
140188
operations))
189+
.unremovable()
141190
.done());
142-
}
143191

192+
}
144193
}
145194

146195
@BuildStep
147196
@Record(ExecutionTime.STATIC_INIT)
148197
void produceApiKeyAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
149-
BuildProducer<SyntheticBeanBuildItem> producer,
198+
BuildProducer<AuthProviderBuildItem> authenticationProviders,
199+
BuildProducer<SyntheticBeanBuildItem> beanProducer,
150200
AuthenticationRecorder recorder) {
151201

152202
Collection<AnnotationInstance> authenticationMarkers = beanArchiveBuildItem.getIndex()
153203
.getAnnotations(API_KEY_AUTHENTICATION_MARKER);
154-
155204
Map<String, List<AnnotationInstance>> operationsBySpec = getOperationsBySpec(beanArchiveBuildItem);
156-
157205
for (AnnotationInstance authenticationMarker : authenticationMarkers) {
158206
String name = authenticationMarker.value("name").asString();
159207
String openApiSpecId = authenticationMarker.value("openApiSpecId").asString();
@@ -162,11 +210,12 @@ void produceApiKeyAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
162210

163211
List<OperationAuthInfo> operations = getOperations(operationsBySpec, openApiSpecId, name);
164212

165-
producer.produce(SyntheticBeanBuildItem.configure(ApiKeyAuthenticationProvider.class)
213+
authenticationProviders.produce(new AuthProviderBuildItem(openApiSpecId, name));
214+
215+
beanProducer.produce(SyntheticBeanBuildItem.configure(AuthProvider.class)
166216
.scope(Dependent.class)
167217
.addQualifier()
168218
.annotation(Authentication.class)
169-
.addValue("name", name)
170219
.addValue("openApiSpecId", openApiSpecId)
171220
.done()
172221
.createWith(recorder.recordApiKeyAuthProvider(
@@ -175,6 +224,7 @@ void produceApiKeyAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
175224
apiKeyIn,
176225
apiKeyName,
177226
operations))
227+
.unremovable()
178228
.done());
179229
}
180230

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

0 commit comments

Comments
 (0)