at.gv.egovernment.moa.id.auth.stork.STORKResponseProcessor.java Source code

Java tutorial

Introduction

Here is the source code for at.gv.egovernment.moa.id.auth.stork.STORKResponseProcessor.java

Source

/*******************************************************************************
 * Copyright 2014 Federal Chancellery Austria
 * MOA-ID has been developed in a cooperation between BRZ, the Federal
 * Chancellery Austria - ICT staff unit, and Graz University of Technology.
 * 
 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 * the European Commission - subsequent versions of the EUPL (the "Licence");
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at:
 * http://www.osor.eu/eupl/
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the Licence is distributed on an "AS IS" basis,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the Licence for the specific language governing permissions and
 * limitations under the Licence.
 * 
 * This product combines work with different licenses. See the "NOTICE" text
 * file for details on the various modules and licenses.
 * The "NOTICE" text file is part of the distribution. Any derivative works
 * that you distribute must include a readable copy of the "NOTICE" text file.
 ******************************************************************************/
/**
 * 
 */
package at.gv.egovernment.moa.id.auth.stork;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Vector;

import javax.activation.DataSource;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.stream.StreamSource;

import org.apache.commons.io.IOUtils;

import at.gv.egovernment.moa.id.auth.AuthenticationServer;
import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute;
import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttributeImpl;
import at.gv.egovernment.moa.id.auth.data.IdentityLink;
import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
import at.gv.egovernment.moa.id.auth.exception.ParseException;
import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser;
import at.gv.egovernment.moa.id.client.SZRGWClientException;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.Constants;
import at.gv.egovernment.moa.util.DateTimeUtils;
import at.gv.egovernment.moa.util.StringUtils;
import at.gv.util.xsd.srzgw.CreateIdentityLinkResponse;
import eu.stork.oasisdss.api.ApiUtils;
import eu.stork.oasisdss.api.LightweightSourceResolver;
import eu.stork.oasisdss.api.exceptions.ApiUtilsException;
import eu.stork.oasisdss.api.exceptions.UtilsException;
import eu.stork.oasisdss.profile.SignResponse;
import eu.stork.peps.auth.commons.IPersonalAttributeList;
import eu.stork.peps.auth.commons.PersonalAttribute;

/**
 * 
 * Handles all functionality for the processing of a STORK response
 * @author bzwattendorfer
 *
 */
public class STORKResponseProcessor {

    /** OASIS DSS Namespace */
    public static final String OASIS_DSS_NS = "urn:oasis:names:tc:dss:1.0:core:schema";

    /** OASIS DSS Success Message */
    public static final String OASIS_DSS_SUCCESS_MSG = "urn:oasis:names:tc:dss:1.0:resultmajor:Success";

    /**
     * Checks for attribute.
     *
     * @param attributeName the attribute name
     * @param attributeList the attribute list
     * @return true, if successful
     */
    public static boolean hasAttribute(String attributeName, IPersonalAttributeList attributeList) {
        try {
            getAttributeValue(attributeName, attributeList);
            return true;
        } catch (STORKException e) {
            return false;
        }
    }

    /**
     * helper for reading attributes. Handles logging and error handling.
     *
     * @param attributeName the attribute name
     * @param attributeList the attribute list
     * @return the attribute value
     * @throws STORKException the sTORK exception
     */
    private static String getAttributeValue(String attributeName, IPersonalAttributeList attributeList)
            throws STORKException {
        return getAttributeValue(attributeName, attributeList, true);
    }

    public static String getAttributeValue(String attributeName, IPersonalAttributeList attributeList,
            boolean throwException) throws STORKException {
        try {
            String result = attributeList.get(attributeName).getValue().get(0);
            Logger.trace(attributeName + " : " + result);
            return result;
        } catch (Exception e) {
            Logger.error(attributeName + " not found in response");
            if (throwException)
                throw new STORKException(attributeName + " not found in response");
            else
                return null;
        }
    }

    /**
     * Handels connection to SZR-GW and returns Identity Link on success.
     *
     * @param attributeList the attribute list
     * @param oaFriendlyName the oa friendly name
     * @param targetType the target type
     * @param targetValue the target value
     * @param filters the filters
     * @param citizenSignature2 
     * @return Identity Link
     * @throws STORKException the sTORK exception
     * @throws MOAIDException 
     */
    public static IdentityLink connectToSZRGateway(IPersonalAttributeList attributeList, String oaFriendlyName,
            String targetType, String targetValue, List<String> filters, String citizenSignature)
            throws STORKException, MOAIDException {
        Logger.trace("Calling SZR Gateway with the following attributes:");

        CreateIdentityLinkResponse identityLinkResponse = null;
        IdentityLink identityLink = null;
        try {
            Logger.trace("Starting call...");

            // if there is no signedDoc attribute, we cannot go on
            if (citizenSignature == null || citizenSignature.length() == 0) {
                String signResponseString = getAttributeValue("signedDoc", attributeList);

                //Extract signature from SIgnResponse
                Source response1 = new StreamSource(new java.io.StringReader(signResponseString));
                SignResponse dssSignResponse = ApiUtils.unmarshal(response1, SignResponse.class);
                citizenSignature = getCitizienSignatureFromSignResponse(dssSignResponse);
            }

            String fiscalNumber = getAttributeValue("fiscalNumber", attributeList, false);

            // if we have a signedDoc we test for a representation case
            // - according to stork samlengine and commons
            if (hasAttribute("mandate", attributeList)) {
                // we have a representation case
                String mandate = getAttributeValue("mandate", attributeList, false);

                if (!hasAttribute("dateOfBirth", attributeList)) {
                    // if we get here, we have a natural person representing a legal person
                    String organizationAddress = getAttributeValue("canonicalRegisteredAddress", attributeList,
                            false);
                    String organizationType = getAttributeValue("translateableType", attributeList, false);

                    identityLinkResponse = AuthenticationServer.getInstance().getIdentityLink(citizenSignature,
                            null, null, mandate, organizationAddress, organizationType, targetType, targetValue,
                            oaFriendlyName, filters, fiscalNumber);
                } else {
                    // if we get here, we have a natural person representing another natural person
                    String eIdentifier = getAttributeValue("eIdentifier", attributeList, false);
                    String givenName = getAttributeValue("givenName", attributeList, false);
                    String lastName = getAttributeValue("surname", attributeList, false);
                    String dateOfBirth = getAttributeValue("dateOfBirth", attributeList, false);

                    // gender attribute is mandatory here because of some legal stuff
                    String gender = getAttributeValue("gender", attributeList, false);

                    if (!StringUtils.isEmpty(dateOfBirth))
                        dateOfBirth = DateTimeUtils.formatPEPSDateToMOADate(dateOfBirth);

                    identityLinkResponse = AuthenticationServer.getInstance().getIdentityLink(eIdentifier,
                            givenName, lastName, dateOfBirth, gender, citizenSignature, null, null, mandate,
                            targetType, targetValue, oaFriendlyName, filters, fiscalNumber);
                }
            }
            // - according to stork spec
            else if (hasAttribute("mandateContent", attributeList) || hasAttribute("representative", attributeList)
                    || hasAttribute("represented", attributeList)) {
                // we have a representation case
                String representative = getAttributeValue("representative", attributeList, false);
                String represented = getAttributeValue("represented", attributeList, false);
                String mandate = getAttributeValue("mandateContent", attributeList, false);

                if (!hasAttribute("dateOfBirth", attributeList)) {
                    // if we get here, we have a natural person representing a legal person
                    String organizationAddress = getAttributeValue("canonicalRegisteredAddress", attributeList,
                            false);
                    String organizationType = getAttributeValue("translateableType", attributeList, false);

                    identityLinkResponse = AuthenticationServer.getInstance().getIdentityLink(citizenSignature,
                            representative, represented, mandate, organizationAddress, organizationType, targetType,
                            targetValue, oaFriendlyName, filters, fiscalNumber);
                } else {
                    // if we get here, we have a natural person representing another natural person
                    String eIdentifier = getAttributeValue("eIdentifier", attributeList, false);
                    String givenName = getAttributeValue("givenName", attributeList, false);
                    String lastName = getAttributeValue("surname", attributeList, false);
                    String dateOfBirth = getAttributeValue("dateOfBirth", attributeList, false);

                    // gender attribute is mandatory here because of some legal stuff
                    String gender = getAttributeValue("gender", attributeList, false);

                    if (!StringUtils.isEmpty(dateOfBirth))
                        dateOfBirth = DateTimeUtils.formatPEPSDateToMOADate(dateOfBirth);

                    identityLinkResponse = AuthenticationServer.getInstance().getIdentityLink(eIdentifier,
                            givenName, lastName, dateOfBirth, gender, citizenSignature, representative, represented,
                            mandate, targetType, targetValue, oaFriendlyName, filters, fiscalNumber);
                }
            } else {
                // we do not have a representation case
                String eIdentifier = getAttributeValue("eIdentifier", attributeList, false);
                String givenName = getAttributeValue("givenName", attributeList, false);
                String lastName = getAttributeValue("surname", attributeList, false);
                String dateOfBirth = getAttributeValue("dateOfBirth", attributeList, false);
                if (!StringUtils.isEmpty(dateOfBirth))
                    dateOfBirth = DateTimeUtils.formatPEPSDateToMOADate(dateOfBirth);
                identityLinkResponse = AuthenticationServer.getInstance().getIdentityLink(eIdentifier, givenName,
                        lastName, dateOfBirth, citizenSignature, fiscalNumber);
            }

            if (null != identityLinkResponse.getErrorResponse()) {
                throw new SZRGWClientException("service.08",
                        (String) identityLinkResponse.getErrorResponse().getErrorCode(),
                        (String) identityLinkResponse.getErrorResponse().getInfo());
            } else {
                IdentityLinkAssertionParser ilParser = new IdentityLinkAssertionParser(
                        new ByteArrayInputStream(identityLinkResponse.getIdentityLink()));
                identityLink = ilParser.parseIdentityLink();

                Logger.debug("Received Identity Link from SZR Gateway");
                //TODO: is this ok?
                //             if (StringUtils.isEmpty(identityLink.getDateOfBirth())) {
                //                identityLink.setDateOfBirth("9999-12-31");
                //            }

            }

        } catch (ParseException e) {
            Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e);
            throw new MOAIDException("auth.25", null, e);
        } catch (ApiUtilsException e) {
            Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e);
            throw new MOAIDException("auth.25", null, e);
        } catch (IllegalArgumentException e) {
            Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e);
            throw new MOAIDException("auth.25", null, e);
        } catch (TransformerConfigurationException e) {
            Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e);
            throw new MOAIDException("auth.25", null, e);
        } catch (UtilsException e) {
            Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e);
            throw new MOAIDException("auth.25", null, e);
        } catch (TransformerException e) {
            Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e);
            throw new MOAIDException("auth.25", null, e);
        } catch (TransformerFactoryConfigurationError e) {
            Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e);
            throw new MOAIDException("auth.25", null, e);
        } catch (IOException e) {
            Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e);
            throw new MOAIDException("auth.25", null, e);
        }

        return identityLink;

    }

    /**
     * Transforms additional STORK attributes to MOA Extended attributes
     * @param iPersonalAttributeList STORK attribute list
     * @return
     */
    public static List<ExtendedSAMLAttribute> addAdditionalSTORKAttributes(
            IPersonalAttributeList iPersonalAttributeList) {
        List<ExtendedSAMLAttribute> moaExtendedSAMLAttributeList = new Vector<ExtendedSAMLAttribute>();

        if (null == iPersonalAttributeList)
            return moaExtendedSAMLAttributeList;

        Logger.trace("Adding the following attributes to MOA assertion: ");
        int count = 0;

        for (PersonalAttribute attribute : iPersonalAttributeList) {
            Object attributeValue = attribute.getValue();
            if (null == attributeValue)
                attributeValue = attribute.getComplexValue();
            ExtendedSAMLAttribute extendedSAMLAttribute = new ExtendedSAMLAttributeImpl(attribute.getName(),
                    attributeValue, Constants.STORK_NS_URI, 0);
            moaExtendedSAMLAttributeList.add(extendedSAMLAttribute);
            count++;
            Logger.trace("Additional attribute: " + attribute.getName());
        }

        Logger.debug("Added " + count + " STORK attribute(s) to the MOA assertion.");

        return moaExtendedSAMLAttributeList;
    }

    private static String getCitizienSignatureFromSignResponse(SignResponse dssSignResponse)
            throws IllegalArgumentException, TransformerConfigurationException, UtilsException,
            TransformerException, TransformerFactoryConfigurationError, IOException, ApiUtilsException {
        // fetch signed doc
        DataSource ds = LightweightSourceResolver.getDataSource(dssSignResponse);
        if (ds == null) {
            throw new ApiUtilsException("No datasource found in response");
        }

        InputStream incoming = ds.getInputStream();
        String citizenSignature = IOUtils.toString(incoming);
        incoming.close();

        return citizenSignature;
    }

}