From 1626ac9867cd5406b83e73651080e33c11fb98d1 Mon Sep 17 00:00:00 2001 From: kstranacher_eGovL Date: Thu, 12 Jul 2012 11:27:13 +0000 Subject: Integration of STORK git-svn-id: https://joinup.ec.europa.eu/svn/moa-idspss/trunk@1285 d688527b-c9ab-4aba-bd8d-4036d912da1d --- .../validation/StorkAttributeValidator.java | 204 +++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 id/server/stork-saml-engine/src/main/java/eu/stork/vidp/messages/validation/StorkAttributeValidator.java (limited to 'id/server/stork-saml-engine/src/main/java/eu/stork/vidp/messages/validation/StorkAttributeValidator.java') diff --git a/id/server/stork-saml-engine/src/main/java/eu/stork/vidp/messages/validation/StorkAttributeValidator.java b/id/server/stork-saml-engine/src/main/java/eu/stork/vidp/messages/validation/StorkAttributeValidator.java new file mode 100644 index 000000000..6e37725d1 --- /dev/null +++ b/id/server/stork-saml-engine/src/main/java/eu/stork/vidp/messages/validation/StorkAttributeValidator.java @@ -0,0 +1,204 @@ +/* + * Copyright 2011 by Graz University of Technology, Austria + * The Austrian STORK Modules have been developed by the E-Government + * Innovation Center EGIZ, a joint initiative of the Federal Chancellery + * Austria 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 eu.stork.vidp.messages.validation; + +import java.util.regex.Pattern; + +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; +import org.opensaml.saml2.core.Attribute; +import org.opensaml.saml2.core.validator.AttributeSchemaValidator; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.schema.XSString; +import org.opensaml.xml.util.AttributeMap; +import org.opensaml.xml.validation.ValidationException; + +import eu.stork.vidp.messages.common.STORKConstants; +import eu.stork.vidp.messages.saml.STORKAttribute; + +public class StorkAttributeValidator extends AttributeSchemaValidator { + + private static final String PATTERN_EIDENTIFIER = "^[A-Z]{2}/[A-Z]{2}/[A-Za-z0-9+/=\r\n]+$"; + private static final String PATTERN_GENDER = "^[MF]{1}$"; + private static final String PATTERN_COUNTRYCODEOFBIRTH = "^[A-Z]{2}|[A-Z]{4}$"; + private static final String PATTERN_COUNTRYCODE = "^[A-Z]{2}$"; + private static final String PATTERN_MARTIALSTATUS = "^[SMPDW]{1}$"; + private static final String PATTERN_EMAIL = "^[-+.\\w]{1,64}@[-.\\w]{1,64}\\.[-.\\w]{2,6}$"; + private static final String PATTERN_AGE = "^[0-9]{1,3}$"; + private static final int MAX_AGE = 120; + private static final String PATTERN_ISAGEOVER = PATTERN_AGE; + private static final String PATTERN_CITIZENQAALEVEL = "^[1-4]{1}$"; + + + /** + * Constructor + * + */ + public StorkAttributeValidator() { + + super(); + } + + @Override + public void validate(Attribute attr) throws ValidationException { + + super.validate(attr); + + if(attr.getName() == null) { + + throw new ValidationException("Name is required."); + } + + if(attr.getNameFormat() == null) { + + throw new ValidationException("NameFormat is required."); + } + + + if(attr.getUnknownAttributes() != null) { + + AttributeMap map = attr.getUnknownAttributes(); + + String value = map.get(STORKAttribute.DEFAULT_STORK_ATTRIBUTE_QNAME); + + if (value == null || value.equals(STORKAttribute.ALLOWED_ATTRIBUTE_STATUS_AVAIL)) { + //if AttributeStatus not present, default is "Available" thus AttributeValue must be present + if (attr.getAttributeValues().isEmpty()) { + //isAgeOver can have no value + if (!attr.getName().equals(STORKConstants.STORK_ATTRIBUTE_ISAGEOVER)) { + throw new ValidationException("AttributeStatus indicates that attribute is available but no AttributeValue is present."); + } + } + + //throw new ValidationException("AttributeStatus not present."); + + } else if(!value.equals(STORKAttribute.ALLOWED_ATTRIBUTE_STATUS_AVAIL) && + !value.equals(STORKAttribute.ALLOWED_ATTRIBUTE_STATUS_NOT_AVAIL) && + !value.equals(STORKAttribute.ALLOWED_ATTRIBUTE_STATUS_WITHHELD)) { + + throw new ValidationException("AttributeStatus is invalid."); + } + + } + + if (!attr.getAttributeValues().isEmpty()) { + //validate individual attributes if present + XMLObject attrValueObject = attr.getAttributeValues().get(0); + + if (!(attrValueObject instanceof XSString)) { + //Only validate String attributes + return; + } + + String value = ((XSString) attr.getAttributeValues().get(0)).getValue(); + String attrName = attr.getName(); + + //only isAgeOver can be empty if provided + if (value == null) { + //only isAgeOver can be empty if provided + if (attrName.equals(STORKConstants.STORK_ATTRIBUTE_ISAGEOVER)) { + return; + } else { + throw new ValidationException("Provided AttributeValue is empty"); + } + } + + //validate eIdentifier + validateAttributeValueFormat(value, attrName, STORKConstants.STORK_ATTRIBUTE_EIDENTIFIER, PATTERN_EIDENTIFIER); + + //validate gender + validateAttributeValueFormat(value, attrName, STORKConstants.STORK_ATTRIBUTE_GENDER, PATTERN_GENDER); + + //validate dateOfBirth + if (attrName.equals(STORKConstants.STORK_ATTRIBUTE_DATEOFBIRTH)) { + verifyDate(value); + } + + //validate countryCode of birth + validateAttributeValueFormat(value, attrName, STORKConstants.STORK_ATTRIBUTE_COUNTRYCODEOFBIRTH, PATTERN_COUNTRYCODEOFBIRTH); + + //validate countryCode + validateAttributeValueFormat(value, attrName, STORKConstants.STORK_ATTRIBUTE_NATIONALITYCODE, PATTERN_COUNTRYCODE); + + //validate martialStatus + validateAttributeValueFormat(value, attrName, STORKConstants.STORK_ATTRIBUTE_MARTIALSTATUS, PATTERN_MARTIALSTATUS); + + //validate email + validateAttributeValueFormat(value, attrName, STORKConstants.STORK_ATTRIBUTE_EMAIL, PATTERN_EMAIL); + + //validate age and isAgeOver + validateAttributeValueFormat(value, attrName, STORKConstants.STORK_ATTRIBUTE_AGE, PATTERN_AGE); + validateAttributeValueFormat(value, attrName, STORKConstants.STORK_ATTRIBUTE_ISAGEOVER, PATTERN_ISAGEOVER); + if (attr.getName().equals(STORKConstants.STORK_ATTRIBUTE_AGE) || attr.getName().equals(STORKConstants.STORK_ATTRIBUTE_ISAGEOVER)) { + if (Integer.valueOf(((XSString) attr.getAttributeValues().get(0)).getValue()) > MAX_AGE) { + throw new ValidationException("Maximum age reached"); + } + } + + validateAttributeValueFormat(value, attrName, STORKConstants.STORK_ATTRIBUTE_CITIZENQAALEVEL, PATTERN_CITIZENQAALEVEL); + } + + } + + private void validateAttributeValueFormat(String value, String currentAttrName, String attrNameToTest, String pattern) throws ValidationException { + if (currentAttrName.equals(attrNameToTest)) { + if (!Pattern.matches(pattern, value)) { + throw new ValidationException(attrNameToTest + " has incorrect format."); + } + } + + } + + private static void verifyDate(String pepsDate) throws ValidationException { + DateTimeFormatter fmt = null; + + switch (pepsDate.length()) { + case 4: + fmt = DateTimeFormat.forPattern("yyyy"); + break; + case 6: + fmt = DateTimeFormat.forPattern("yyyyMM"); + break; + case 8: + fmt = DateTimeFormat.forPattern("yyyyMMdd"); + break; + default: + throw new ValidationException("Date has wrong format"); + } + + try { + fmt.parseDateTime(pepsDate); + } catch (IllegalArgumentException e) { + throw new ValidationException("Date has wrong format"); + } + + + } + + + + +} -- cgit v1.2.3