Skip to content

Commit

Permalink
add AuthName qualifier to fix mutliple synthetic bean with same signa…
Browse files Browse the repository at this point in the history
…ture issue
  • Loading branch information
rmanibus committed Sep 18, 2024
1 parent 334c66f commit 5e48fd9
Show file tree
Hide file tree
Showing 14 changed files with 115 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,23 @@
import org.jboss.jandex.DotName;
import org.jboss.jandex.ParameterizedType;

import io.quarkiverse.openapi.generator.*;
import io.quarkiverse.openapi.generator.markers.*;
import io.quarkiverse.openapi.generator.providers.*;
import io.quarkiverse.openapi.generator.AuthName;
import io.quarkiverse.openapi.generator.AuthenticationRecorder;
import io.quarkiverse.openapi.generator.ClassicOidcClientRequestFilterDelegate;
import io.quarkiverse.openapi.generator.OidcClient;
import io.quarkiverse.openapi.generator.OpenApiGeneratorConfig;
import io.quarkiverse.openapi.generator.OpenApiSpec;
import io.quarkiverse.openapi.generator.ReactiveOidcClientRequestFilterDelegate;
import io.quarkiverse.openapi.generator.markers.ApiKeyAuthenticationMarker;
import io.quarkiverse.openapi.generator.markers.BasicAuthenticationMarker;
import io.quarkiverse.openapi.generator.markers.BearerAuthenticationMarker;
import io.quarkiverse.openapi.generator.markers.OauthAuthenticationMarker;
import io.quarkiverse.openapi.generator.markers.OperationMarker;
import io.quarkiverse.openapi.generator.providers.ApiKeyIn;
import io.quarkiverse.openapi.generator.providers.AuthProvider;
import io.quarkiverse.openapi.generator.providers.CompositeAuthenticationProvider;
import io.quarkiverse.openapi.generator.providers.OAuth2AuthenticationProvider.OidcClientRequestFilterDelegate;
import io.quarkiverse.openapi.generator.providers.OperationAuthInfo;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.deployment.Capabilities;
Expand Down Expand Up @@ -74,12 +87,12 @@ void produceCompositeProviders(AuthenticationRecorder recorder,
beanProducer.produce(SyntheticBeanBuildItem.configure(CompositeAuthenticationProvider.class)
.scope(Dependent.class)
.addQualifier()
.annotation(Authentication.class)
.annotation(OpenApiSpec.class)
.addValue("openApiSpecId", openApiSpecId)
.done()
.addInjectionPoint(
ParameterizedType.create(Instance.class, ClassType.create(AuthProvider.class)),
AnnotationInstance.builder(Authentication.class)
AnnotationInstance.builder(OpenApiSpec.class)
.add("openApiSpecId", openApiSpecId)
.build())
.createWith(recorder.recordCompositeProvider(openApiSpecId))
Expand All @@ -91,12 +104,11 @@ void produceCompositeProviders(AuthenticationRecorder recorder,
@BuildStep
@Record(ExecutionTime.STATIC_INIT)
void produceOauthAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
Capabilities capabilities,
BuildProducer<AuthProviderBuildItem> authenticationProviders,
BuildProducer<SyntheticBeanBuildItem> beanProducer,
AuthenticationRecorder recorder) {
Collection<AnnotationInstance> authenticationMarkers = beanArchiveBuildItem.getIndex()
.getAnnotations(OAUTH_AUTHENTICATION_MARKER);
.getAnnotationsWithRepeatable(OAUTH_AUTHENTICATION_MARKER, beanArchiveBuildItem.getIndex());

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

Expand All @@ -108,7 +120,11 @@ void produceOauthAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
beanProducer.produce(SyntheticBeanBuildItem.configure(AuthProvider.class)
.scope(Dependent.class)
.addQualifier()
.annotation(Authentication.class)
.annotation(AuthName.class)
.addValue("name", name)
.done()
.addQualifier()
.annotation(OpenApiSpec.class)
.addValue("openApiSpecId", openApiSpecId)
.done()
.addInjectionPoint(ClassType.create(OidcClientRequestFilterDelegate.class),
Expand All @@ -132,7 +148,7 @@ void produceBasicAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
AuthenticationRecorder recorder) {

Collection<AnnotationInstance> authenticationMarkers = beanArchiveBuildItem.getIndex()
.getAnnotations(BASIC_AUTHENTICATION_MARKER);
.getAnnotationsWithRepeatable(BASIC_AUTHENTICATION_MARKER, beanArchiveBuildItem.getIndex());

Map<String, List<AnnotationInstance>> operationsBySpec = getOperationsBySpec(beanArchiveBuildItem);
for (AnnotationInstance authenticationMarker : authenticationMarkers) {
Expand All @@ -146,7 +162,11 @@ void produceBasicAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
beanProducer.produce(SyntheticBeanBuildItem.configure(AuthProvider.class)
.scope(Dependent.class)
.addQualifier()
.annotation(Authentication.class)
.annotation(AuthName.class)
.addValue("name", name)
.done()
.addQualifier()
.annotation(OpenApiSpec.class)
.addValue("openApiSpecId", openApiSpecId)
.done()
.createWith(recorder.recordBasicAuthProvider(
Expand All @@ -166,7 +186,7 @@ void produceBearerAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
AuthenticationRecorder recorder) {

Collection<AnnotationInstance> authenticationMarkers = beanArchiveBuildItem.getIndex()
.getAnnotations(BEARER_AUTHENTICATION_MARKER);
.getAnnotationsWithRepeatable(BEARER_AUTHENTICATION_MARKER, beanArchiveBuildItem.getIndex());

Map<String, List<AnnotationInstance>> operationsBySpec = getOperationsBySpec(beanArchiveBuildItem);
for (AnnotationInstance authenticationMarker : authenticationMarkers) {
Expand All @@ -179,7 +199,11 @@ void produceBearerAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
beanProducer.produce(SyntheticBeanBuildItem.configure(AuthProvider.class)
.scope(Dependent.class)
.addQualifier()
.annotation(Authentication.class)
.annotation(AuthName.class)
.addValue("name", name)
.done()
.addQualifier()
.annotation(OpenApiSpec.class)
.addValue("openApiSpecId", openApiSpecId)
.done()
.createWith(recorder.recordBearerAuthProvider(
Expand All @@ -201,7 +225,7 @@ void produceApiKeyAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
AuthenticationRecorder recorder) {

Collection<AnnotationInstance> authenticationMarkers = beanArchiveBuildItem.getIndex()
.getAnnotations(API_KEY_AUTHENTICATION_MARKER);
.getAnnotationsWithRepeatable(API_KEY_AUTHENTICATION_MARKER, beanArchiveBuildItem.getIndex());
Map<String, List<AnnotationInstance>> operationsBySpec = getOperationsBySpec(beanArchiveBuildItem);
for (AnnotationInstance authenticationMarker : authenticationMarkers) {
String name = authenticationMarker.value("name").asString();
Expand All @@ -216,7 +240,11 @@ void produceApiKeyAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
beanProducer.produce(SyntheticBeanBuildItem.configure(AuthProvider.class)
.scope(Dependent.class)
.addQualifier()
.annotation(Authentication.class)
.annotation(AuthName.class)
.addValue("name", name)
.done()
.addQualifier()
.annotation(OpenApiSpec.class)
.addValue("openApiSpecId", openApiSpecId)
.done()
.createWith(recorder.recordApiKeyAuthProvider(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ package {apiPackage}.auth;
public class CompositeAuthenticationProvider implements jakarta.ws.rs.client.ClientRequestFilter {

@jakarta.inject.Inject
@io.quarkiverse.openapi.generator.Authentication(openApiSpecId="{configKey}")
@io.quarkiverse.openapi.generator.OpenApiSpec(openApiSpecId="{configKey}")
io.quarkiverse.openapi.generator.providers.CompositeAuthenticationProvider compositeProvider;

@java.lang.Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package {apiPackage}.auth;
public class AuthenticationPropagationHeadersFactory extends io.quarkiverse.openapi.generator.providers.AbstractAuthenticationPropagationHeadersFactory {

@jakarta.inject.Inject
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) {
public AuthenticationPropagationHeadersFactory(@io.quarkiverse.openapi.generator.OpenApiSpec(openApiSpecId="{configKey}") io.quarkiverse.openapi.generator.providers.CompositeAuthenticationProvider compositeProvider, io.quarkiverse.openapi.generator.OpenApiGeneratorConfig generatorConfig, io.quarkiverse.openapi.generator.providers.HeadersProvider headersProvider) {
super(compositeProvider, generatorConfig, headersProvider);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static io.quarkiverse.openapi.generator.providers.ApiKeyIn.header;

import jakarta.annotation.Priority;
import jakarta.inject.Inject;

import org.jboss.shrinkwrap.api.ShrinkWrap;
Expand All @@ -11,25 +12,27 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkiverse.openapi.generator.Authentication;
import io.quarkiverse.openapi.generator.OpenApiSpec;
import io.quarkiverse.openapi.generator.markers.ApiKeyAuthenticationMarker;
import io.quarkiverse.openapi.generator.markers.BasicAuthenticationMarker;
import io.quarkiverse.openapi.generator.markers.OauthAuthenticationMarker;
import io.quarkiverse.openapi.generator.providers.*;
import io.quarkus.test.QuarkusUnitTest;

public class AuthenticationProviderTest {
public class OpenApiSpecProviderTest {

@RegisterExtension
static final QuarkusUnitTest unitTest = new QuarkusUnitTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addClass(LocalAuthenticationProvider.class)
.addAsResource(
new StringAsset("quarkus.oidc-client.oauth_auth.auth-server-url=localhost\n"),
new StringAsset("quarkus.oidc-client.oauth_auth.auth-server-url=localhost\n" +
"quarkus.oidc-client.oauth_auth1.auth-server-url=localhost\n" +
"quarkus.oidc-client.oauth_auth2.auth-server-url=localhost\n"),
"application.properties"));

@Test
public void test() {
public void checkCompositeProvider() {
Assertions.assertEquals(1, spec1CompositeProvider.getAuthenticationProviders().size());
Assertions.assertEquals(1, spec2CompositeProvider.getAuthenticationProviders().size());
Assertions.assertEquals(1, spec3CompositeProvider.getAuthenticationProviders().size());
Expand All @@ -51,22 +54,38 @@ public void test() {

}

@Test
public void checkCompositeProviderWithMultipleAuth() {
Assertions.assertEquals(4, multiCompositeProvider.getAuthenticationProviders().size());
}

@Inject
@Authentication(openApiSpecId = "spec_1")
@OpenApiSpec(openApiSpecId = "spec_1")
CompositeAuthenticationProvider spec1CompositeProvider;

@Authentication(openApiSpecId = "spec_2")
@Inject
@OpenApiSpec(openApiSpecId = "spec_2")
CompositeAuthenticationProvider spec2CompositeProvider;

@Authentication(openApiSpecId = "spec_3")
@Inject
@OpenApiSpec(openApiSpecId = "spec_3")
CompositeAuthenticationProvider spec3CompositeProvider;

@jakarta.annotation.Priority(jakarta.ws.rs.Priorities.AUTHENTICATION)
@Inject
@OpenApiSpec(openApiSpecId = "spec_multi")
CompositeAuthenticationProvider multiCompositeProvider;

@Priority(jakarta.ws.rs.Priorities.AUTHENTICATION)
@OauthAuthenticationMarker(name = "oauth_auth", openApiSpecId = "spec_1")
@BasicAuthenticationMarker(name = "basic_auth", openApiSpecId = "spec_2")
@ApiKeyAuthenticationMarker(name = "api_key", openApiSpecId = "spec_3", apiKeyIn = header, apiKeyName = "api_key")

@OauthAuthenticationMarker(name = "oauth_auth1", openApiSpecId = "spec_multi")
@OauthAuthenticationMarker(name = "oauth_auth2", openApiSpecId = "spec_multi")
@BasicAuthenticationMarker(name = "basic_auth1", openApiSpecId = "spec_multi")
@BasicAuthenticationMarker(name = "basic_auth2", openApiSpecId = "spec_multi")
public static class LocalAuthenticationProvider {

}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkiverse.openapi.generator.Authentication;
import io.quarkiverse.openapi.generator.OpenApiSpec;
import io.quarkiverse.openapi.generator.annotations.GeneratedClass;
import io.quarkiverse.openapi.generator.markers.BasicAuthenticationMarker;
import io.quarkiverse.openapi.generator.markers.OauthAuthenticationMarker;
Expand Down Expand Up @@ -48,10 +48,10 @@ public void test() {
}

@Inject
@Authentication(openApiSpecId = "petstore_json")
@OpenApiSpec(openApiSpecId = "petstore_json")
CompositeAuthenticationProvider compositeProvider;
@Inject
@Authentication(openApiSpecId = "other_spec_json")
@OpenApiSpec(openApiSpecId = "other_spec_json")
CompositeAuthenticationProvider otherProvider;

@RegisterRestClient(baseUri = "http://localhost/api/v3", configKey = "petstore_json")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.quarkiverse.openapi.generator;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import jakarta.enterprise.util.AnnotationLiteral;
import jakarta.inject.Qualifier;

@Qualifier
@Retention(RUNTIME)
@Target({ METHOD, FIELD, PARAMETER, TYPE })
public @interface AuthName {

String name();

final class Literal extends AnnotationLiteral<AuthName> implements AuthName {
public Literal(String name) {
this.name = name;
}

final String name;

@Override
public String name() {
return name;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import jakarta.enterprise.inject.Instance;
import jakarta.enterprise.util.TypeLiteral;

import io.quarkiverse.openapi.generator.Authentication.Literal;
import io.quarkiverse.openapi.generator.OpenApiSpec.Literal;
import io.quarkiverse.openapi.generator.providers.*;
import io.quarkiverse.openapi.generator.providers.OAuth2AuthenticationProvider.OidcClientRequestFilterDelegate;
import io.quarkus.arc.SyntheticCreationalContext;
Expand All @@ -27,7 +27,6 @@ public Function<SyntheticCreationalContext<CompositeAuthenticationProvider>, Com
return ctx -> {
List<AuthProvider> providers = ctx.getInjectedReference(new TypeLiteral<Instance<AuthProvider>>() {
}, new Literal(openApiSpec)).stream().toList();
System.out.println(providers.size());
return new CompositeAuthenticationProvider(providers);
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ protected java.util.Optional<String> clientId() {
return java.util.Optional.of(clientId);
}

@Override
public void filter(ClientRequestContext requestContext) throws IOException {
try {
String accessToken = this.getAccessToken();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
@Qualifier
@Retention(RUNTIME)
@Target({ METHOD, FIELD, PARAMETER, TYPE })
public @interface Authentication {
public @interface OpenApiSpec {

String openApiSpecId();

final class Literal extends AnnotationLiteral<Authentication> implements Authentication {
final class Literal extends AnnotationLiteral<OpenApiSpec> implements OpenApiSpec {
public Literal(String openApiSpecId) {
this.openApiSpecId = openApiSpecId;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ protected java.util.Optional<String> clientId() {
return java.util.Optional.of(clientId);
}

@Override
protected void initTokens() {
if (earlyTokenAcquisition) {
LOG.debug("Token acquisition will be delayed until this filter is executed to avoid blocking an IO thread");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import io.quarkiverse.openapi.generator.SpecItemConfig;

@ExtendWith(MockitoExtension.class)
abstract class AbstractAuthenticationProviderTest<T extends AbstractAuthProvider> {
abstract class AbstractOpenApiSpecProviderTest<T extends AbstractAuthProvider> {

protected static final String OPEN_API_FILE_SPEC_ID = "open_api_file_spec_id_json";
protected static final String AUTH_SCHEME_NAME = "auth_scheme_name";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

import io.quarkiverse.openapi.generator.AuthConfig;

class ApiKeyAuthenticationProviderTest extends AbstractAuthenticationProviderTest<ApiKeyAuthenticationProvider> {
class ApiKeyOpenApiSpecProviderTest extends AbstractOpenApiSpecProviderTest<ApiKeyAuthenticationProvider> {

private static final String API_KEY_NAME = "API_KEY_NAME";
private static final String API_KEY_VALUE = "API_KEY_VALUE";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

import io.quarkiverse.openapi.generator.AuthConfig;

class BasicAuthenticationProviderTest extends AbstractAuthenticationProviderTest<BasicAuthenticationProvider> {
class BasicOpenApiSpecProviderTest extends AbstractOpenApiSpecProviderTest<BasicAuthenticationProvider> {

private static final String USER = "USER";
private static final String PASSWORD = "PASSWORD";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import io.quarkiverse.openapi.generator.AuthConfig;

class BearerAuthenticationProviderTest extends AbstractAuthenticationProviderTest<BearerAuthenticationProvider> {
class BearerOpenApiSpecProviderTest extends AbstractOpenApiSpecProviderTest<BearerAuthenticationProvider> {

private static final String TOKEN = "TOKEN";
private static final String INCOMING_TOKEN = "INCOMING_TOKEN";
Expand Down

0 comments on commit 5e48fd9

Please sign in to comment.