Skip to content

Commit

Permalink
Merge pull request quarkusio#44306 from michalvavrik/feature/security…
Browse files Browse the repository at this point in the history
…-extension-refactoring

Replace deprecated methods and classes in Quarkus Security and tiny bit of refactoring
  • Loading branch information
sberyozkin authored Nov 5, 2024
2 parents d13c7d9 + 7a710f0 commit 92e09b9
Show file tree
Hide file tree
Showing 11 changed files with 111 additions and 111 deletions.
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
package io.quarkus.security.deployment;

import static io.quarkus.security.deployment.SecurityProcessor.createMethodDescription;
import static io.quarkus.security.spi.SecurityTransformerUtils.DENY_ALL;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;

import org.jboss.jandex.AnnotationTarget;
import jakarta.annotation.security.DenyAll;

import org.jboss.jandex.AnnotationTransformation;
import org.jboss.jandex.MethodInfo;

import io.quarkus.arc.processor.AnnotationsTransformer;
import io.quarkus.security.spi.runtime.MethodDescription;

public class AdditionalDenyingUnannotatedTransformer implements AnnotationsTransformer {
final class AdditionalDenyingUnannotatedTransformer
implements Predicate<MethodInfo>, Consumer<AnnotationTransformation.TransformationContext> {

private final Set<MethodDescription> methods;

public AdditionalDenyingUnannotatedTransformer(Collection<MethodDescription> methods) {
this.methods = new HashSet<>(methods);
AdditionalDenyingUnannotatedTransformer(Collection<MethodDescription> methods) {
this.methods = Set.copyOf(methods);
}

@Override
public boolean appliesTo(AnnotationTarget.Kind kind) {
return kind == AnnotationTarget.Kind.METHOD;
public void accept(AnnotationTransformation.TransformationContext ctx) {
ctx.add(DenyAll.class);
}

@Override
public void transform(TransformationContext context) {
MethodDescription methodDescription = createMethodDescription(context.getTarget().asMethod());
if (methods.contains(methodDescription)) {
context.transform().add(DENY_ALL).done();
}
public boolean test(MethodInfo methodInfo) {
MethodDescription methodDescription = createMethodDescription(methodInfo);
return methods.contains(methodDescription);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,44 @@
import static io.quarkus.security.deployment.SecurityProcessor.createMethodDescription;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;

import jakarta.annotation.security.RolesAllowed;

import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTransformation;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.DotName;
import org.jboss.jandex.MethodInfo;

import io.quarkus.arc.processor.AnnotationsTransformer;
import io.quarkus.security.spi.runtime.MethodDescription;

public class AdditionalRolesAllowedTransformer implements AnnotationsTransformer {
final class AdditionalRolesAllowedTransformer
implements Predicate<MethodInfo>, Consumer<AnnotationTransformation.TransformationContext> {

private static final DotName ROLES_ALLOWED = DotName.createSimple(RolesAllowed.class.getName());
private final Set<MethodDescription> methods;
private final AnnotationValue[] rolesAllowed;

public AdditionalRolesAllowedTransformer(Collection<MethodDescription> methods, List<String> rolesAllowed) {
this.methods = new HashSet<>(methods);
AdditionalRolesAllowedTransformer(Collection<MethodDescription> methods, List<String> rolesAllowed) {
this.methods = Set.copyOf(methods);
this.rolesAllowed = rolesAllowed.stream().map(s -> AnnotationValue.createStringValue("", s))
.toArray(AnnotationValue[]::new);
}

@Override
public boolean appliesTo(AnnotationTarget.Kind kind) {
return kind == AnnotationTarget.Kind.METHOD;
public boolean test(MethodInfo methodInfo) {
MethodDescription method = createMethodDescription(methodInfo);
return methods.contains(method);
}

@Override
public void transform(TransformationContext context) {
MethodDescription method = createMethodDescription(context.getTarget().asMethod());
if (methods.contains(method)) {
context.transform().add(ROLES_ALLOWED, AnnotationValue.createArrayValue("value", rolesAllowed)).done();
}
public void accept(AnnotationTransformation.TransformationContext ctx) {
AnnotationInstance rolesAllowedInstance = AnnotationInstance.create(ROLES_ALLOWED, ctx.declaration().asMethod(),
new AnnotationValue[] { AnnotationValue.createArrayValue("value", rolesAllowed) });
ctx.add(rolesAllowedInstance);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.quarkus.security.deployment;

import java.util.List;
import java.util.function.Predicate;

import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.MethodInfo;

import io.quarkus.security.spi.SecurityTransformerUtils;

final class DenyUnannotatedPredicate implements Predicate<ClassInfo> {

@Override
public boolean test(ClassInfo classInfo) {
List<MethodInfo> methods = classInfo.methods();
return !SecurityTransformerUtils.hasSecurityAnnotation(classInfo)
&& methods.stream().anyMatch(SecurityTransformerUtils::hasSecurityAnnotation);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import java.util.function.Predicate;
import java.util.stream.Collectors;

import jakarta.annotation.security.DenyAll;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.Dependent;
import jakarta.inject.Singleton;
Expand Down Expand Up @@ -90,8 +91,8 @@
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem;
import io.quarkus.deployment.execannotations.ExecutionModelAnnotationsAllowedBuildItem;
import io.quarkus.deployment.pkg.NativeConfig;
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
import io.quarkus.gizmo.CatchBlockCreator;
import io.quarkus.gizmo.ClassCreator;
import io.quarkus.gizmo.ClassOutput;
Expand Down Expand Up @@ -313,16 +314,18 @@ void recordBouncyCastleProviders(SecurityProviderRecorder recorder,
}
}

@BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
NativeImageFeatureBuildItem bouncyCastleFeature(
@BuildStep
NativeImageFeatureBuildItem bouncyCastleFeature(NativeConfig nativeConfig,
List<BouncyCastleProviderBuildItem> bouncyCastleProviders,
List<BouncyCastleJsseProviderBuildItem> bouncyCastleJsseProviders) {

Optional<BouncyCastleJsseProviderBuildItem> bouncyCastleJsseProvider = getOne(bouncyCastleJsseProviders);
Optional<BouncyCastleProviderBuildItem> bouncyCastleProvider = getOne(bouncyCastleProviders);
if (nativeConfig.enabled()) {
Optional<BouncyCastleJsseProviderBuildItem> bouncyCastleJsseProvider = getOne(bouncyCastleJsseProviders);
Optional<BouncyCastleProviderBuildItem> bouncyCastleProvider = getOne(bouncyCastleProviders);

if (bouncyCastleJsseProvider.isPresent() || bouncyCastleProvider.isPresent()) {
return new NativeImageFeatureBuildItem("io.quarkus.security.BouncyCastleFeature");
if (bouncyCastleJsseProvider.isPresent() || bouncyCastleProvider.isPresent()) {
return new NativeImageFeatureBuildItem("io.quarkus.security.BouncyCastleFeature");
}
}
return null;
}
Expand Down Expand Up @@ -549,7 +552,10 @@ void transformSecurityAnnotations(BuildProducer<AnnotationsTransformerBuildItem>
List<AdditionalSecuredMethodsBuildItem> additionalSecuredMethods,
SecurityBuildTimeConfig config) {
if (config.denyUnannotated()) {
transformers.produce(new AnnotationsTransformerBuildItem(new DenyingUnannotatedTransformer()));
transformers.produce(new AnnotationsTransformerBuildItem(AnnotationTransformation
.forClasses()
.whenClass(new DenyUnannotatedPredicate())
.transform(ctx -> ctx.add(DenyAll.class))));
}
if (!additionalSecuredMethods.isEmpty()) {
for (AdditionalSecuredMethodsBuildItem securedMethods : additionalSecuredMethods) {
Expand All @@ -558,13 +564,19 @@ void transformSecurityAnnotations(BuildProducer<AnnotationsTransformerBuildItem>
additionalSecured.add(createMethodDescription(additionalSecuredMethod));
}
if (securedMethods.rolesAllowed.isPresent()) {
transformers.produce(
new AnnotationsTransformerBuildItem(new AdditionalRolesAllowedTransformer(additionalSecured,
securedMethods.rolesAllowed.get())));
var additionalRolesAllowedTransformer = new AdditionalRolesAllowedTransformer(additionalSecured,
securedMethods.rolesAllowed.get());
transformers.produce(new AnnotationsTransformerBuildItem(AnnotationTransformation
.forMethods()
.whenMethod(additionalRolesAllowedTransformer)
.transform(additionalRolesAllowedTransformer)));
} else {
transformers.produce(
new AnnotationsTransformerBuildItem(
new AdditionalDenyingUnannotatedTransformer(additionalSecured)));
var additionalDenyingUnannotatedTransformer = new AdditionalDenyingUnannotatedTransformer(
additionalSecured);
transformers.produce(new AnnotationsTransformerBuildItem(AnnotationTransformation
.forMethods()
.whenMethod(additionalDenyingUnannotatedTransformer)
.transform(additionalDenyingUnannotatedTransformer)));
}
}
}
Expand Down Expand Up @@ -799,17 +811,12 @@ void createSecurityCheckStorage(BuildProducer<SyntheticBeanBuildItem> syntheticB
recorder.registerDefaultSecurityCheck(builder, recorder.rolesAllowed(roles.toArray(new String[0])));
}
}
recorder.create(builder);

syntheticBeans.produce(
SyntheticBeanBuildItem.configure(SecurityCheckStorage.class)
.scope(ApplicationScoped.class)
.unremovable()
.creator(creator -> {
ResultHandle ret = creator.invokeStaticMethod(MethodDescriptor.ofMethod(SecurityCheckRecorder.class,
"getStorage", SecurityCheckStorage.class));
creator.returnValue(ret);
}).done());
.runtimeProxy(recorder.create(builder))
.done());
}

@Consume(RuntimeConfigSetupCompleteBuildItem.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@

public class AnonymousIdentityProvider implements IdentityProvider<AnonymousAuthenticationRequest> {

private static final Principal principal = new Principal() {
private static final Principal PRINCIPAL = new Principal() {
@Override
public String getName() {
return "";
}
};

private static final SecurityIdentity instance = new SecurityIdentity() {
private static final SecurityIdentity INSTANCE = new SecurityIdentity() {
@Override
public Principal getPrincipal() {
return principal;
return PRINCIPAL;
}

@Override
Expand Down Expand Up @@ -77,6 +77,6 @@ public Class<AnonymousAuthenticationRequest> getRequestType() {
@Override
public Uni<SecurityIdentity> authenticate(AnonymousAuthenticationRequest request,
AuthenticationRequestContext context) {
return Uni.createFrom().item(instance);
return Uni.createFrom().item(INSTANCE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public Executor get() {
public IdentityProviderManager ipm() {
boolean customAnon = false;
QuarkusIdentityProviderManagerImpl.Builder builder = QuarkusIdentityProviderManagerImpl.builder();
for (IdentityProvider i : identityProviders) {
for (var i : identityProviders) {
builder.addProvider(i);
if (i.getRequestType() == AnonymousAuthenticationRequest.class) {
customAnon = true;
Expand Down
Loading

0 comments on commit 92e09b9

Please sign in to comment.