Search in sources :

Example 11 with MethodInfo

use of org.jboss.jandex.MethodInfo in project wildfly-swarm by wildfly-swarm.

the class OpenApiAnnotationScanner method parameterIn.

/**
 * Determines where an @Parameter can be found (examples include Query, Path,
 * Header, Cookie, etc).
 * @param target
 */
private In parameterIn(MethodParameterInfo paramInfo) {
    MethodInfo method = paramInfo.method();
    short paramPosition = paramInfo.position();
    List<AnnotationInstance> annotations = JandexUtil.getParameterAnnotations(method, paramPosition);
    for (AnnotationInstance annotation : annotations) {
        if (annotation.name().equals(OpenApiConstants.DOTNAME_QUERY_PARAM)) {
            return In.QUERY;
        }
        if (annotation.name().equals(OpenApiConstants.DOTNAME_PATH_PARAM)) {
            return In.PATH;
        }
        if (annotation.name().equals(OpenApiConstants.DOTNAME_HEADER_PARAM)) {
            return In.HEADER;
        }
        if (annotation.name().equals(OpenApiConstants.DOTNAME_COOKIE_PARAM)) {
            return In.COOKIE;
        }
    }
    return null;
}
Also used : MethodInfo(org.jboss.jandex.MethodInfo) AnnotationInstance(org.jboss.jandex.AnnotationInstance)

Example 12 with MethodInfo

use of org.jboss.jandex.MethodInfo in project wildfly-swarm by wildfly-swarm.

the class OpenApiAnnotationScanner method processJaxRsResourceClass.

/**
 * Processing a single JAX-RS resource class (annotated with @Path).
 * @param openApi
 * @param resourceClass
 */
private void processJaxRsResourceClass(OpenAPIImpl openApi, ClassInfo resourceClass) {
    LOG.debug("Processing a JAX-RS resource class: " + resourceClass.simpleName());
    // Set the current resource path.
    AnnotationInstance pathAnno = JandexUtil.getClassAnnotation(resourceClass, OpenApiConstants.DOTNAME_PATH);
    this.currentResourcePath = pathAnno.value().asString();
    // TODO handle the use-case where the resource class extends a base class, and the base class has jax-rs relevant methods and annotations
    // Process @SecurityScheme annotations
    // //////////////////////////////////////
    List<AnnotationInstance> securitySchemeAnnotations = JandexUtil.getRepeatableAnnotation(resourceClass, OpenApiConstants.DOTNAME_SECURITY_SCHEME, OpenApiConstants.DOTNAME_SECURITY_SCHEMES);
    for (AnnotationInstance annotation : securitySchemeAnnotations) {
        String name = JandexUtil.stringValue(annotation, OpenApiConstants.PROP_SECURITY_SCHEME_NAME);
        if (name == null && JandexUtil.isRef(annotation)) {
            name = JandexUtil.nameFromRef(annotation);
        }
        if (name != null) {
            SecurityScheme securityScheme = readSecurityScheme(annotation);
            Components components = ModelUtil.components(openApi);
            components.addSecurityScheme(name, securityScheme);
        }
    }
    // Process tags (both declarations and references)
    // //////////////////////////////////////
    Set<String> tagRefs = new HashSet<>();
    AnnotationInstance tagAnno = JandexUtil.getClassAnnotation(resourceClass, OpenApiConstants.DOTNAME_TAG);
    if (tagAnno != null) {
        if (JandexUtil.isRef(tagAnno)) {
            String tagRef = JandexUtil.stringValue(tagAnno, OpenApiConstants.PROP_REF);
            tagRefs.add(tagRef);
        } else {
            Tag tag = readTag(tagAnno);
            if (tag.getName() != null) {
                openApi.addTag(tag);
                tagRefs.add(tag.getName());
            }
        }
    }
    AnnotationInstance tagsAnno = JandexUtil.getClassAnnotation(resourceClass, OpenApiConstants.DOTNAME_TAGS);
    if (tagsAnno != null) {
        AnnotationValue tagsArrayVal = tagsAnno.value();
        if (tagsArrayVal != null) {
            AnnotationInstance[] tagsArray = tagsArrayVal.asNestedArray();
            for (AnnotationInstance ta : tagsArray) {
                if (JandexUtil.isRef(ta)) {
                    String tagRef = JandexUtil.stringValue(ta, OpenApiConstants.PROP_REF);
                    tagRefs.add(tagRef);
                } else {
                    Tag tag = readTag(ta);
                    if (tag.getName() != null) {
                        openApi.addTag(tag);
                        tagRefs.add(tag.getName());
                    }
                }
            }
        }
        List<String> listValue = JandexUtil.stringListValue(tagsAnno, OpenApiConstants.PROP_REFS);
        if (listValue != null) {
            tagRefs.addAll(listValue);
        }
    }
    // //////////////////////////////////////
    for (MethodInfo methodInfo : resourceClass.methods()) {
        AnnotationInstance get = methodInfo.annotation(OpenApiConstants.DOTNAME_GET);
        if (get != null) {
            processJaxRsMethod(openApi, resourceClass, methodInfo, get, HttpMethod.GET, tagRefs);
        }
        AnnotationInstance put = methodInfo.annotation(OpenApiConstants.DOTNAME_PUT);
        if (put != null) {
            processJaxRsMethod(openApi, resourceClass, methodInfo, put, HttpMethod.PUT, tagRefs);
        }
        AnnotationInstance post = methodInfo.annotation(OpenApiConstants.DOTNAME_POST);
        if (post != null) {
            processJaxRsMethod(openApi, resourceClass, methodInfo, post, HttpMethod.POST, tagRefs);
        }
        AnnotationInstance delete = methodInfo.annotation(OpenApiConstants.DOTNAME_DELETE);
        if (delete != null) {
            processJaxRsMethod(openApi, resourceClass, methodInfo, delete, HttpMethod.DELETE, tagRefs);
        }
        AnnotationInstance head = methodInfo.annotation(OpenApiConstants.DOTNAME_HEAD);
        if (head != null) {
            processJaxRsMethod(openApi, resourceClass, methodInfo, head, HttpMethod.HEAD, tagRefs);
        }
        AnnotationInstance options = methodInfo.annotation(OpenApiConstants.DOTNAME_OPTIONS);
        if (options != null) {
            processJaxRsMethod(openApi, resourceClass, methodInfo, options, HttpMethod.OPTIONS, tagRefs);
        }
    }
}
Also used : Components(org.eclipse.microprofile.openapi.models.Components) AnnotationValue(org.jboss.jandex.AnnotationValue) MethodInfo(org.jboss.jandex.MethodInfo) Tag(org.eclipse.microprofile.openapi.models.tags.Tag) SecurityScheme(org.eclipse.microprofile.openapi.models.security.SecurityScheme) AnnotationInstance(org.jboss.jandex.AnnotationInstance) HashSet(java.util.HashSet)

Example 13 with MethodInfo

use of org.jboss.jandex.MethodInfo in project wildfly-swarm by wildfly-swarm.

the class HealthAnnotationProcessor method process.

@Override
public void process() throws NamingException {
    // first pass: jboss-web context root
    Optional<String> jbossWebContext = Optional.empty();
    // if (archive instanceof JBossWebContainer) {
    if (archive.getName().endsWith(".war")) {
        JBossWebContainer war = archive.as(WARArchive.class);
        if (war.getContextRoot() != null) {
            jbossWebContext = Optional.of(war.getContextRoot());
        }
    }
    // second pass: JAX-RS applications
    Optional<String> appPath = Optional.empty();
    Collection<AnnotationInstance> appPathAnnotations = index.getAnnotations(APP_PATH);
    for (AnnotationInstance annotation : appPathAnnotations) {
        if (annotation.target().kind() == AnnotationTarget.Kind.CLASS) {
            appPath = Optional.of(annotation.value().asString());
        }
    }
    // third pass: JAX-RS resources
    Collection<AnnotationInstance> pathAnnotations = index.getAnnotations(PATH);
    for (AnnotationInstance annotation : pathAnnotations) {
        if (annotation.target().kind() == AnnotationTarget.Kind.CLASS) {
            ClassInfo classInfo = annotation.target().asClass();
            for (MethodInfo methodInfo : classInfo.methods()) {
                if (methodInfo.hasAnnotation(HEALTH) || methodInfo.hasAnnotation(MP_HEALTH)) {
                    StringBuilder sb = new StringBuilder();
                    boolean isSecure = false;
                    // prepend the jboss-web cntext if given
                    if (jbossWebContext.isPresent() && !jbossWebContext.get().equals("/")) {
                        safeAppend(sb, jbossWebContext.get());
                    }
                    // prepend the appPath if given
                    if (appPath.isPresent() && !appPath.get().equals("/")) {
                        safeAppend(sb, appPath.get());
                    }
                    // the class level @Path
                    for (AnnotationInstance classAnnotation : classInfo.classAnnotations()) {
                        if (classAnnotation.name().equals(PATH)) {
                            String methodPathValue = classAnnotation.value().asString();
                            if (!methodPathValue.equals("/")) {
                                safeAppend(sb, methodPathValue);
                            }
                        }
                    }
                    if (methodInfo.hasAnnotation(PATH)) {
                        // the method level @Path
                        safeAppend(sb, methodInfo.annotation(PATH).value().asString());
                        // the method level @Health either MP or regular Swarm
                        AnnotationInstance healthAnnotation = methodInfo.annotation(HEALTH);
                        if (null == healthAnnotation) {
                            healthAnnotation = methodInfo.annotation(MP_HEALTH);
                        }
                        isSecure = healthAnnotation.value("inheritSecurity") != null ? healthAnnotation.value("inheritSecurity").asBoolean() : true;
                    } else {
                        throw new RuntimeException("@Health requires an explicit @Path annotation");
                    }
                    HealthMetaData metaData = new HealthMetaData(sb.toString(), isSecure);
                    Monitor.lookup().registerHealth(metaData);
                }
            }
        }
    }
}
Also used : HealthMetaData(org.wildfly.swarm.microprofile.health.HealthMetaData) JBossWebContainer(org.wildfly.swarm.undertow.descriptors.JBossWebContainer) MethodInfo(org.jboss.jandex.MethodInfo) AnnotationInstance(org.jboss.jandex.AnnotationInstance) ClassInfo(org.jboss.jandex.ClassInfo)

Example 14 with MethodInfo

use of org.jboss.jandex.MethodInfo in project wildfly-swarm by wildfly-swarm.

the class MPJWTAuthExtensionArchivePreparer method generateSecurityConstraints.

/**
 * Generate security constraints for a resource root class.
 *
 * @param webXml - the deployment web.xml metadata to add the security constraints to
 * @param classInfo - the class to scan for security constraints
 * @param roles - class level roles if any
 * @param appPath - the @ApplicationPath if any
 */
private void generateSecurityConstraints(WebXmlAsset webXml, ClassInfo classInfo, String[] roles, final String appPath) {
    // This includes both class level and method level @Path instances
    List<AnnotationInstance> paths = classInfo.annotations().get(PATH);
    if (paths == null || paths.size() == 0) {
        // Not a resource root
        return;
    }
    StringBuilder fullAppPath = new StringBuilder(appPath);
    if (fullAppPath.charAt(fullAppPath.length() - 1) != '/') {
        fullAppPath.append('/');
    }
    List<SecurityConstraint> newConstraints = new ArrayList<>();
    HashSet<String> allRoles = new HashSet<>();
    allRoles.addAll(Arrays.asList(roles));
    // Get the root @Path annotation if it exists
    ListIterator<AnnotationInstance> pathsIter = paths.listIterator();
    while (pathsIter.hasNext()) {
        AnnotationInstance ann = pathsIter.next();
        if (ann.target().kind() == AnnotationTarget.Kind.CLASS) {
            String subpath = ann.value().asString();
            if (subpath.charAt(0) == '/') {
                fullAppPath.append(subpath.substring(1));
            } else {
                fullAppPath.append(subpath);
            }
            if (fullAppPath.charAt(fullAppPath.length() - 1) != '/') {
                fullAppPath.append('/');
            }
            pathsIter.remove();
            break;
        }
    }
    // Check for a class level @DenyAll
    boolean classIsDenyAll = false;
    boolean classIsPermitAll = false;
    List<AnnotationInstance> classDenyAll = classInfo.annotations().get(DENY_ALL);
    if (classDenyAll != null) {
        for (AnnotationInstance ann : classDenyAll) {
            if (ann.target() == classInfo) {
                // Create a security constraint that denies all access to subresources by default
                SecurityConstraint sc = webXml.protect(fullAppPath.toString() + "*").withRole("");
                newConstraints.add(sc);
                classIsDenyAll = true;
            }
        }
    }
    // Check for class level @PermitAll
    List<AnnotationInstance> classPermitAll = classInfo.annotations().get(PERMIT_ALL);
    if (classPermitAll != null) {
        for (AnnotationInstance ann : classPermitAll) {
            if (ann.target() == classInfo) {
                // Create a security constraint that permits all access to subresources by default
                SecurityConstraint sc = webXml.protect(fullAppPath.toString() + "*").permitAll();
                newConstraints.add(sc);
                classIsPermitAll = true;
            }
        }
    }
    // Process the method level @Path and security annotations into security constraints
    for (AnnotationInstance path : paths) {
        if (path.target().kind() == AnnotationTarget.Kind.METHOD) {
            // For each method determine the endpoint path and roles
            String subpath = path.value().asString();
            MethodInfo methodInfo = path.target().asMethod();
            AnnotationInstance rolesAllowed = methodInfo.annotation(ROLES_ALLOWED);
            AnnotationInstance denyAll = methodInfo.annotation(DENY_ALL);
            AnnotationInstance permitAll = methodInfo.annotation(PERMIT_ALL);
            // Start with the class level @RolesAllowed
            HashSet<String> localRoles = new HashSet<>(allRoles);
            if (denyAll != null) {
                // To deny access we need a security constraint with an empty roles which we indicate by a null
                localRoles = null;
            } else if (permitAll != null) {
                // To permit all access we need a security contraint with no auth contraint which we indicate by an empty roles
                localRoles.clear();
            } else if (rolesAllowed != null) {
                // Override the class level roles
                localRoles.clear();
                localRoles.addAll(Arrays.asList(rolesAllowed.value().asStringArray()));
            } else if (classIsDenyAll) {
                localRoles = null;
            } else if (classIsPermitAll) {
                localRoles.clear();
            }
            String uriPath;
            if (subpath.charAt(0) == '/') {
                uriPath = fullAppPath.toString() + subpath.substring(1);
            } else {
                uriPath = fullAppPath.toString() + subpath;
            }
            // If this uri includes a path param, truncate and add a wildcard
            int pathParamStart = uriPath.indexOf('{');
            if (pathParamStart >= 0) {
                uriPath = uriPath.substring(0, pathParamStart);
                if (uriPath.charAt(uriPath.length() - 1) != '/') {
                    uriPath += '/';
                }
                uriPath += "*";
            }
            SecurityConstraint sc = webXml.protect(uriPath);
            // No roles == @DenyAll
            if (localRoles == null) {
                sc.withRole("");
            // Empy roles == @PermitAll
            } else if (localRoles.isEmpty()) {
                sc.permitAll();
            } else {
                localRoles.forEach(sc::withRole);
            }
            newConstraints.add(sc);
        }
    }
    if (log.isDebugEnabled()) {
        log.debugf("SecurityConstraints introduced by class: %s", classInfo.name());
        for (SecurityConstraint sc : newConstraints) {
            log.debugf("SecurityConstraint(%s), roles=%s, isPermitAll=%s", sc.urlPattern(), sc.roles(), sc.isPermitAll());
        }
    }
    scannedClasses.add(classInfo.name());
}
Also used : ArrayList(java.util.ArrayList) SecurityConstraint(org.wildfly.swarm.undertow.descriptors.SecurityConstraint) SecurityConstraint(org.wildfly.swarm.undertow.descriptors.SecurityConstraint) MethodInfo(org.jboss.jandex.MethodInfo) AnnotationInstance(org.jboss.jandex.AnnotationInstance) HashSet(java.util.HashSet)

Example 15 with MethodInfo

use of org.jboss.jandex.MethodInfo in project wildfly-swarm by wildfly-swarm.

the class MPJWTAuthExtensionArchivePreparer method process.

@Override
public void process() throws Exception {
    WARArchive war = archive.as(WARArchive.class);
    // Check for LoginConfig annotation
    Collection<AnnotationInstance> lcAnnotations = index.getAnnotations(LOGIN_CONFIG);
    for (AnnotationInstance lc : lcAnnotations) {
        AnnotationValue authMethod = lc.value("authMethod");
        AnnotationValue realmName = lc.value("realmName");
        String realm = realmName != null ? realmName.asString() : "";
        // Set the web.xml login-config auth-method and jboss-web.xml security domain
        if (authMethod != null) {
            WebXmlAsset webXml = war.findWebXmlAsset();
            webXml.setLoginConfig(authMethod.asString(), realm);
        }
        if (realm.length() > 0) {
            JBossWebAsset jBossWeb = war.findJbossWebAsset();
            jBossWeb.setSecurityDomain(realm);
        }
    }
    // Get the @ApplicationPath setting
    WebXmlAsset webXml = war.findWebXmlAsset();
    String appPath = "/";
    Collection<AnnotationInstance> appPaths = index.getAnnotations(APP_PATH);
    if (!appPaths.isEmpty()) {
        appPath = appPaths.iterator().next().value().asString();
    }
    // Process the @RolesAllowed, @PermitAll and @DenyAll annotations
    Collection<AnnotationInstance> rolesAnnotations = index.getAnnotations(ROLES_ALLOWED);
    for (AnnotationInstance annotation : rolesAnnotations) {
        if (annotation.target().kind() == AnnotationTarget.Kind.CLASS) {
            // Process the root resource
            String[] roles = annotation.value().asStringArray();
            ClassInfo classInfo = annotation.target().asClass();
            if (!scannedClasses.contains(classInfo.name())) {
                generateSecurityConstraints(webXml, classInfo, roles, appPath);
            }
        } else if (annotation.target().kind() == AnnotationTarget.Kind.METHOD) {
            // Process the containing root resource if it has not been already
            MethodInfo methodInfo = annotation.target().asMethod();
            ClassInfo classInfo = methodInfo.declaringClass();
            if (!scannedClasses.contains(classInfo.name())) {
                String[] roles = {};
                generateSecurityConstraints(webXml, classInfo, roles, appPath);
            }
        }
    }
    // Handle the verification configuration on the fraction
    if (fraction.getTokenIssuer().isPresent()) {
        log.debugf("Issuer: %s", fraction.getTokenIssuer().get());
        war.addAsManifestResource(new StringAsset(fraction.getTokenIssuer().get()), "MP-JWT-ISSUER");
    }
    if (fraction.getPublicKey() != null) {
        log.debugf("PublicKey: %s", fraction.getPublicKey());
        war.addAsManifestResource(new StringAsset(fraction.getPublicKey()), "MP-JWT-SIGNER");
    }
    if (log.isTraceEnabled()) {
        log.trace("war: " + war.toString(true));
    }
}
Also used : JBossWebAsset(org.wildfly.swarm.undertow.descriptors.JBossWebAsset) StringAsset(org.jboss.shrinkwrap.api.asset.StringAsset) WebXmlAsset(org.wildfly.swarm.undertow.descriptors.WebXmlAsset) AnnotationValue(org.jboss.jandex.AnnotationValue) MethodInfo(org.jboss.jandex.MethodInfo) WARArchive(org.wildfly.swarm.undertow.WARArchive) AnnotationInstance(org.jboss.jandex.AnnotationInstance) ClassInfo(org.jboss.jandex.ClassInfo)

Aggregations

MethodInfo (org.jboss.jandex.MethodInfo)24 AnnotationInstance (org.jboss.jandex.AnnotationInstance)18 ClassInfo (org.jboss.jandex.ClassInfo)18 EEModuleClassDescription (org.jboss.as.ee.component.EEModuleClassDescription)7 FieldInfo (org.jboss.jandex.FieldInfo)7 AnnotationTarget (org.jboss.jandex.AnnotationTarget)6 ArrayList (java.util.ArrayList)5 HashSet (java.util.HashSet)5 InterceptorClassDescription (org.jboss.as.ee.component.interceptors.InterceptorClassDescription)5 InvocationContext (javax.interceptor.InvocationContext)4 AnnotationValue (org.jboss.jandex.AnnotationValue)4 Type (org.jboss.jandex.Type)4 DeploymentUnit (org.jboss.as.server.deployment.DeploymentUnit)3 CompositeIndex (org.jboss.as.server.deployment.annotation.CompositeIndex)3 MethodIdentifier (org.jboss.invocation.proxy.MethodIdentifier)3 EEModuleDescription (org.jboss.as.ee.component.EEModuleDescription)2 DotName (org.jboss.jandex.DotName)2 MethodParameterInfo (org.jboss.jandex.MethodParameterInfo)2 PropertyReplacer (org.jboss.metadata.property.PropertyReplacer)2 JBossWebContainer (org.wildfly.swarm.undertow.descriptors.JBossWebContainer)2