Package org.apache.geronimo.j2ee.deployment.annotation

Source Code of org.apache.geronimo.j2ee.deployment.annotation.SecurityAnnotationHelper

/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/

package org.apache.geronimo.j2ee.deployment.annotation;

import java.util.List;

import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RunAs;
import javax.servlet.Servlet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.geronimo.common.DeploymentException;
import org.apache.geronimo.xbeans.javaee6.RoleNameType;
import org.apache.geronimo.xbeans.javaee6.RunAsType;
import org.apache.geronimo.xbeans.javaee6.SecurityRoleType;
import org.apache.geronimo.xbeans.javaee6.ServletType;
import org.apache.geronimo.xbeans.javaee6.ServletNameType;
import org.apache.geronimo.xbeans.javaee6.FullyQualifiedClassType;
import org.apache.geronimo.xbeans.javaee6.WebAppType;
import org.apache.xbean.finder.ClassFinder;


/**
* Static helper class used to encapsulate all the functions related to the translation of
* <strong>@DeclareRoles</strong> and <strong>@RunAs</strong> annotations to deployment
* descriptor tags. The SecurityAnnotationHelper class can be used as part of the deployment of a
* module into the Geronimo server. It performs the following major functions:
*
* <ol>
*      <li>Translates annotations into corresponding deployment descriptor elements (so that the
*          actual deployment descriptor in the module can be updated or even created if necessary)
* </ol>
*
* <p><strong>Note(s):</strong>
* <ul>
*      <li>Supports only servlets
*      <li>The user is responsible for invoking change to metadata-complete
*      <li>This helper class will validate any changes it makes to the deployment descriptor. An
*          exception will be thrown if it fails to parse
* </ul>
*
* @version $Rev $Date
* @since 04-2007
*/
public final class SecurityAnnotationHelper extends AnnotationHelper {

    // Private instance variables
    private static final Logger log = LoggerFactory.getLogger(SecurityAnnotationHelper.class);

    // Private constructor to prevent instantiation
    private SecurityAnnotationHelper() {
    }

    /**
     * Update the deployment descriptor from the DeclareRoles and RunAs annotations
     *
     * @param webApp Access to the spec dd
     * @param classFinder  Access to the classes of interest
     * @throws DeploymentException if parsing or validation error
     */
    public static void processAnnotations(WebAppType webApp, ClassFinder classFinder) throws DeploymentException {
        if (webApp != null && classFinder != null) {
            if (classFinder.isAnnotationPresent(DeclareRoles.class)) {
                processDeclareRoles(webApp, classFinder);
            }
            if (classFinder.isAnnotationPresent(RunAs.class)) {
                processRunAs(webApp, classFinder);
            }
        }
    }


    /**
     * Process @DeclareRole annotations (for servlets only)
     *
     * @param webApp Access to the spec dd
     * @param classFinder Access to the classes of interest
     * @throws DeploymentException if parsing or validation error
     */
    private static void processDeclareRoles(WebAppType webApp, ClassFinder classFinder) throws DeploymentException {
        log.debug("processDeclareRoles(): Entry: webApp: " + webApp.toString());

        List<Class> classesWithDeclareRoles = classFinder.findAnnotatedClasses(DeclareRoles.class);

        // Class-level annotation
        for (Class cls : classesWithDeclareRoles) {
            DeclareRoles declareRoles = (DeclareRoles) cls.getAnnotation(DeclareRoles.class);
            if (declareRoles != null && Servlet.class.isAssignableFrom(cls)) {
                addDeclareRoles(webApp, declareRoles, cls);
            }
        }

        // Validate deployment descriptor to ensure it's still okay
        validateDD(new AnnotatedWebApp(webApp));

        log.debug("processDeclareRoles(): Exit: webApp: " + webApp.toString());
    }


    /**
     * Process @RunAs annotations (for servlets only)
     *
     * @param webApp Access to the spec dd
     * @param classFinder Access to the classes of interest
     * @throws DeploymentException if parsing or validation error
     */
    private static void processRunAs(WebAppType webApp, ClassFinder classFinder) throws DeploymentException {
        log.debug("processRunAs(): Entry: webApp: " + webApp.toString());

        List<Class> classesWithRunAs = classFinder.findAnnotatedClasses(RunAs.class);

        // Class-level annotation
        for (Class cls : classesWithRunAs) {
            RunAs runAs = (RunAs) cls.getAnnotation(RunAs.class);
            if (runAs != null && Servlet.class.isAssignableFrom(cls)) {
                addRunAs(webApp, runAs, cls);
            }
        }

        // Validate deployment descriptor to ensure it's still okay
        validateDD(new AnnotatedWebApp(webApp));

        log.debug("processRunAs(): Exit: webApp: " + webApp.toString());
    }


    /**
     * Add @DeclareRoles annotations to the deployment descriptor. XMLBeans are used to read and
     * manipulate the deployment descriptor as necessary. The DeclareRoles annotation(s) will be
     * converted to one of the following deployment descriptors:
     *
     * <ol>
     *      <li><security-role> -- Describes a single security role
     * </ol>
     *
     * <p><strong>Note(s):</strong>
     * <ul>
     *      <li>The deployment descriptor is the authoritative source so this method ensures that
     *          existing elements in it are not overwritten by annoations
     * </ul>
     *
     * @param webApp  Access to the spec dd
     * @param annotation    @DeclareRoles annotation
     * @param cls           Class name with the @DeclareRoles annoation
     */
    private static void addDeclareRoles(WebAppType webApp, DeclareRoles annotation, Class cls) {
        log.debug("addDeclareRoles( [webApp] " + webApp.toString() + "," + '\n' +
                  "[annotation] " + annotation.toString() + "," + '\n' +
                  "[cls] " + (cls != null ? cls.getName() : null) + "): Entry");

        // Get all the <security-role> tags from the deployment descriptor
        SecurityRoleType[] securityRoles = webApp.getSecurityRoleArray();

        String[] annotationRoleNames = annotation.value();
        for (String annotationRoleName : annotationRoleNames) {
            if (!annotationRoleName.equals("")) {
                boolean exists = false;
                for (SecurityRoleType securityRole : securityRoles) {
                    if (securityRole.getRoleName().getStringValue().trim().equals(annotationRoleName)) {
                        exists = true;
                        break;
                    }
                }
                if (exists) {
                    log.debug("addDeclareRoles: <security-role> entry found: " + annotationRoleName);
                }
                else {
                    log.debug("addDeclareRoles: <security-role> entry NOT found: " + annotationRoleName);
                    SecurityRoleType securityRole = webApp.addNewSecurityRole();
                    RoleNameType roleName = securityRole.addNewRoleName();
                    roleName.setStringValue(annotationRoleName);
                }
            }
        }

        log.debug("addDeclareRoles(): Exit");
    }


    /**
     * Add @RunAs annotations to the deployment descriptor. XMLBeans are used to read and manipulate
     * the deployment descriptor as necessary. The DeclareRoles annotation(s) will be converted to
     * one of the following deployment descriptors:
     *
     * <ol>
     *      <li><run-as> -- Describes a run-as security identity to be used for the execution of a
     *      component
     * </ol>
     *
     * <p><strong>Note(s):</strong>
     * <ul>
     *      <li>The deployment descriptor is the authoritative source so this method ensures that
     *          existing elements in it are not overwritten by annoations
     * </ul>
     *
     * @param webApp Access to the spec dd
     * @param annotation    @RunAs annotation
     * @param cls           Class name with the @RunAs annoation
     */
    private static void addRunAs(WebAppType webApp, RunAs annotation, Class cls) {
        log.debug("addRunAs( [webApp] " + webApp.toString() + "," + '\n' +
                  "[annotation] " + annotation.toString() + "," + '\n' +
                  "[cls] " + (cls != null ? cls.getName() : null) + "): Entry");

        String annotationRunAs = annotation.value();
        if (!annotationRunAs.equals("")) {
            ServletType[] servlets = webApp.getServletArray();
            boolean exists = false;
            for (ServletType servlet : servlets) {
                if (servlet.getServletClass().getStringValue().trim().equals(cls.getName())) {
                    if (!servlet.isSetRunAs()) {
                        RunAsType runAsType = servlet.addNewRunAs();
                        RoleNameType roleName = runAsType.addNewRoleName();
                        roleName.setStringValue(annotationRunAs);
                    }
                    exists = true;
                    break;
                }
            }
            if (!exists) {
                log.warn("RunAs servlet not found in webApp: " + cls.getName());
            }
        }

        log.debug("addRunAs(): Exit");
    }

}
TOP

Related Classes of org.apache.geronimo.j2ee.deployment.annotation.SecurityAnnotationHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.