org.italiangrid.voms.aa.x509.ACServlet.java Source code

Java tutorial

Introduction

Here is the source code for org.italiangrid.voms.aa.x509.ACServlet.java

Source

/**
 * Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2006-2016
 *
 * Licensed 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.italiangrid.voms.aa.x509;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.glite.security.voms.admin.configuration.VOMSConfiguration;
import org.glite.security.voms.admin.configuration.VOMSConfigurationConstants;
import org.glite.security.voms.admin.operations.CurrentAdmin;
import org.italiangrid.utils.voms.CurrentSecurityContext;
import org.italiangrid.utils.voms.SecurityContextImpl;
import org.italiangrid.utils.voms.VOMSSecurityContext;
import org.italiangrid.voms.aa.AttributeAuthority;
import org.italiangrid.voms.aa.AttributeAuthorityFactory;
import org.italiangrid.voms.aa.RequestContext;
import org.italiangrid.voms.aa.RequestContextFactory;
import org.italiangrid.voms.aa.VOMSError;
import org.italiangrid.voms.aa.VOMSErrorMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ACServlet extends HttpServlet {

    /**
      * 
      */
    private static final long serialVersionUID = 1L;

    public static final String LEGACY_REQUEST_HEADER = "X-VOMS-Legacy";

    public static final Logger log = LoggerFactory.getLogger(ACServlet.class);

    private VOMSResponseBuilder responseBuilder;
    private ACGenerator acGenerator;
    private ACRequestLogger acRequestLogger;

    /**
     * 
     * @param response
     * @param context
     */
    protected void addDebugHeaders(HttpServletResponse response, RequestContext context) {

        response.addHeader("X-VOMS-FQANs", StringUtils.join(context.getResponse().getIssuedFQANs(), ","));

        response.addHeader("X-VOMS-GAs", StringUtils.join(context.getResponse().getIssuedGAs(), ","));
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        RequestContext context = newRequestContext(request);
        boolean isLegacyRequest = isLegacyRequest(request);

        prepareResponse(response);

        if (!isACEndpointEnabled()) {
            VOMSErrorMessage em = VOMSErrorMessage.endpointDisabled();

            logFailure(context, em.getMessage());

            writeErrorResponse(request, response, em, isLegacyRequest);

            return;
        }

        if (CurrentAdmin.instance().isUnauthenticated()) {
            logFailure(context, VOMSError.UnauthenticatedClient.getDefaultMessage());

            writeErrorResponse(request, response, VOMSErrorMessage.unauthenticatedClient(), isLegacyRequest);

            return;
        }

        populateRequest(request, context);

        AttributeAuthority aa = newAttributeAuthority();

        if (!aa.getAttributes(context)) {

            VOMSErrorMessage em = context.getResponse().getErrorMessages().get(0);

            logFailure(context, em.getMessage());

            writeErrorResponse(request, response, em, isLegacyRequest);

            return;

        } else {

            try {

                byte[] acBytes = acGenerator.generateVOMSAC(context);

                addDebugHeaders(response, context);
                writeResponse(response, acBytes, context);
                logSuccess(context);
                return;

            } catch (Throwable t) {

                log.error("Error encoding user attribute certificate: " + t.getMessage(), t);

                logFailure(context, VOMSError.InternalError.getDefaultMessage());

                writeErrorResponse(request, response, VOMSErrorMessage.internalError(t.getMessage()),
                        isLegacyRequest);
            }
        }
    }

    @Override
    public void init() throws ServletException {

        super.init();
        responseBuilder = ResponseBuilderFactory.newResponseBuilder();
        acGenerator = ACGeneratorFactory.newACGenerator();
        acRequestLogger = ACRequestLoggerFactory.newRequestLogger();
    }

    /**
     * 
     * @return
     */
    protected boolean isACEndpointEnabled() {

        return VOMSConfiguration.instance().getBoolean(VOMSConfigurationConstants.VOMS_AA_X509_ACTIVATE_ENDPOINT,
                true);
    }

    /**
     * 
     * @param request
     * @return
     */
    protected boolean isLegacyRequest(HttpServletRequest request) {

        return request.getHeader(LEGACY_REQUEST_HEADER) != null;
    }

    /**
     * 
     * @param context
     * @param errorMessage
     */
    public void logFailure(RequestContext context, String errorMessage) {

        acRequestLogger.logFailure(context, errorMessage);
    }

    /**
     * 
     * @param context
     */
    public void logSuccess(RequestContext context) {

        acRequestLogger.logSuccess(context);
    }

    /**
     * 
     * @return
     */
    protected AttributeAuthority newAttributeAuthority() {

        long maximumValidity = VOMSConfiguration.instance()
                .getLong(VOMSConfigurationConstants.VOMS_AA_X509_MAX_AC_VALIDITY, TimeUnit.HOURS.toSeconds(12));

        boolean legacyFQANEncoding = VOMSConfiguration.instance()
                .getBoolean(VOMSConfigurationConstants.VOMS_AA_X509_LEGACY_FQAN_ENCODING, true);

        return AttributeAuthorityFactory.newAttributeAuthority(maximumValidity, legacyFQANEncoding);
    }

    /**
     * 
     * @param request
     * @return
     */
    protected RequestContext newRequestContext(HttpServletRequest request) {

        RequestContext context = RequestContextFactory.newContext();

        String subject = CurrentAdmin.instance().getRealSubject();

        String issuer = CurrentAdmin.instance().getRealIssuer();

        context.getRequest().setRequesterSubject(subject);
        context.getRequest().setRequesterIssuer(issuer);
        context.getRequest().setHolderSubject(subject);
        context.getRequest().setHolderIssuer(issuer);

        context.setVOName(VOMSConfiguration.instance().getVOName());
        context.setHost(VOMSConfiguration.instance().getHostname());
        context.setPort(request.getServerPort());

        return context;
    }

    /**
     * 
     * @param request
     * @return
     */
    protected List<String> parseRequestedFQANs(HttpServletRequest request) {

        String fqansString = request.getParameter("fqans");

        if (fqansString == null)
            return Collections.emptyList();

        List<String> requestedFQANs = new ArrayList<String>();

        if (fqansString.contains(",")) {

            for (String s : StringUtils.split(fqansString, ","))
                requestedFQANs.add(s);
        } else
            requestedFQANs.add(fqansString);

        return requestedFQANs;

    }

    /**
     * 
     * @param request
     * @return
     */
    private List<String> parseTargetsFromRequest(HttpServletRequest request) {

        String targets = request.getParameter("targets");
        if (targets == null)
            return Collections.emptyList();

        List<String> targetList = new ArrayList<String>();

        if (targets.contains(",")) {

            String targetTokens[] = targets.split(",");

            for (String t : targetTokens)
                targetList.add(t);

        } else {

            targetList = Collections.singletonList(targets);

        }

        return targetList;

    }

    /**
     * Parse
     * 
     * @param request
     * @return
     */
    private long parseValidityFromRequest(HttpServletRequest request) {

        long lifetime = -1;

        try {
            String lifetimeString = request.getParameter("lifetime");

            if (lifetimeString != null)
                lifetime = Long.parseLong(request.getParameter("lifetime"));

        } catch (NumberFormatException e) {
            // Ignore strange things in lifetime parameter
        }
        return lifetime;
    }

    /**
     * 
     * @param request
     * @param context
     */
    private void populateRequest(HttpServletRequest request, RequestContext context) {

        VOMSSecurityContext ctxt = (VOMSSecurityContext) CurrentSecurityContext.get();

        context.getRequest().setHolderCert(ctxt.getClientCert());

        context.getRequest().setRequestedFQANs(parseRequestedFQANs(request));
        context.getRequest().setRequestedValidity(parseValidityFromRequest(request));
        context.getRequest().setTargets(parseTargetsFromRequest(request));

        context.getRequest().setOwnedAttributes(ctxt.getVOMSAttributes());

    }

    /**
     * 
     * @param response
     */
    protected void prepareResponse(HttpServletResponse response) {

        response.setContentType("text/xml");
        response.setCharacterEncoding("UTF-8");
    }

    /**
     * 
     * @param request
     * @param response
     * @param errorMessage
     * @param isLegacyClient
     * @throws ServletException
     * @throws IOException
     */
    protected void writeErrorResponse(HttpServletRequest request, HttpServletResponse response,
            VOMSErrorMessage errorMessage, boolean isLegacyClient) throws ServletException, IOException {

        response.setStatus(errorMessage.getError().getHttpStatus());

        String responseString = null;

        if (isLegacyClient) {
            responseString = responseBuilder.createLegacyErrorResponse(errorMessage);
        } else
            responseString = responseBuilder.createErrorResponse(errorMessage);

        response.getOutputStream().write(responseString.getBytes());
    }

    /**
     * 
     * @param response
     * @param ac
     * @param context
     * @throws ServletException
     * @throws IOException
     */
    protected void writeResponse(HttpServletResponse response, byte[] ac, RequestContext context)
            throws ServletException, IOException {

        String responseString = responseBuilder.createResponse(ac, context.getResponse().getWarnings());

        response.getOutputStream().write(responseString.getBytes());
    }

}