/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2009 Sun Microsystems Inc. All Rights Reserved
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* https://opensso.dev.java.net/public/CDDLv1.0.html or
* opensso/legal/CDDLv1.0.txt
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at opensso/legal/CDDLv1.0.txt
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* $Id: XACMLPrivilegeUtils.java,v 1.4 2010/01/10 06:39:42 dillidorai Exp $
*
* Portions Copyrighted 2011-2016 ForgeRock AS.
* Portions Copyrighted 2014 Nomura Research Institute, Ltd
*/
package com.sun.identity.entitlement.xacml3;
import static com.sun.identity.entitlement.EntitlementException.INVALID_VALUE;
import static org.forgerock.openam.utils.Time.currentTimeMillis;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import org.forgerock.util.annotations.VisibleForTesting;
import org.json.JSONException;
import org.json.JSONObject;
import org.xml.sax.InputSource;
import com.sun.identity.entitlement.Entitlement;
import com.sun.identity.entitlement.EntitlementCondition;
import com.sun.identity.entitlement.EntitlementException;
import com.sun.identity.entitlement.EntitlementSubject;
import com.sun.identity.entitlement.Privilege;
import com.sun.identity.entitlement.PrivilegeManager;
import com.sun.identity.entitlement.ReferralPrivilege;
import com.sun.identity.entitlement.ResourceAttribute;
import com.sun.identity.entitlement.UserSubject;
import com.sun.identity.entitlement.opensso.XACMLOpenSSOPrivilege;
import com.sun.identity.entitlement.xacml3.core.AdviceExpressions;
import com.sun.identity.entitlement.xacml3.core.AllOf;
import com.sun.identity.entitlement.xacml3.core.AnyOf;
import com.sun.identity.entitlement.xacml3.core.Apply;
import com.sun.identity.entitlement.xacml3.core.AttributeDesignator;
import com.sun.identity.entitlement.xacml3.core.AttributeValue;
import com.sun.identity.entitlement.xacml3.core.Condition;
import com.sun.identity.entitlement.xacml3.core.EffectType;
import com.sun.identity.entitlement.xacml3.core.Match;
import com.sun.identity.entitlement.xacml3.core.ObjectFactory;
import com.sun.identity.entitlement.xacml3.core.Policy;
import com.sun.identity.entitlement.xacml3.core.PolicySet;
import com.sun.identity.entitlement.xacml3.core.Rule;
import com.sun.identity.entitlement.xacml3.core.Target;
import com.sun.identity.entitlement.xacml3.core.VariableDefinition;
import com.sun.identity.entitlement.xacml3.core.Version;
import com.sun.identity.entitlement.xacml3.validation.PrivilegeValidator;
import com.sun.identity.shared.JSONUtils;
import com.sun.identity.shared.xml.XMLUtils;
/**
* Class with utility methods to map from
* <code>com.sun.identity.entity.Privilege</code>
* to
* </code>com.sun.identity.entitlement.xacml3.core.Policy</code>
*/
public class XACMLPrivilegeUtils {
private static final ObjectFactory objectFactory = new ObjectFactory();
// Used in ResourceAttribute serialisation.
private static final ResourceAttributeUtil resourceAttributeUtil = new ResourceAttributeUtil();
private static final XACMLSchemaFactory schemaFactory = new XACMLSchemaFactory();
/**
* Constructs XACMLPrivilegeUtils
*/
private XACMLPrivilegeUtils() {
}
public static String toXACML(Privilege privilege) {
if (privilege == null) {
return "";
}
Policy policy = privilegeToPolicy(privilege);
return toXML(policy);
}
public static String toXML(Policy policy) {
if (policy == null) {
return "";
}
StringWriter stringWriter = new StringWriter();
try {
JAXBContext jaxbContext = JAXBContext.newInstance(
XACMLConstants.XACML3_CORE_PKG);
JAXBElement<Policy> policyElement = objectFactory.createPolicy(policy);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(policyElement, stringWriter);
} catch (JAXBException je) {
//TOODO: handle, propogate exception
PrivilegeManager.debug.error(
"JAXBException while mapping privilege to policy:", je);
}
return stringWriter.toString();
}
public static String toXML(PolicySet policySet) throws EntitlementException {
if (policySet == null) {
return "";
}
StringWriter stringWriter = new StringWriter();
try {
JAXBContext jaxbContext = JAXBContext.newInstance(XACMLConstants.XACML3_CORE_PKG);
JAXBElement<PolicySet> policySetElement = objectFactory.createPolicySet(policySet);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(policySetElement, stringWriter);
} catch (JAXBException je) {
PrivilegeManager.debug.error("JAXBException while mapping privilege to policy:", je);
throw new EntitlementException(EntitlementException.UNABLE_TO_SERIALIZE_OBJECT, je);
}
return stringWriter.toString();
}
public static void writeXMLToStream(PolicySet policySet, OutputStream outputStream) throws EntitlementException {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(XACMLConstants.XACML3_CORE_PKG);
JAXBElement<PolicySet> policySetElement = objectFactory.createPolicySet(policySet);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(policySetElement, outputStream);
} catch (JAXBException je) {
PrivilegeManager.debug.error("JAXBException while mapping privilege to policy:", je);
throw new EntitlementException(EntitlementException.UNABLE_TO_SERIALIZE_OBJECT, je);
}
}
public static Policy privilegeToPolicy(Privilege privilege) {
Policy policy = null;
try {
policy = privilegeToPolicyInternal(privilege);
} catch (JAXBException je) {
PrivilegeManager.debug.error("Caught JAXBException while converting Privilege to Policy", je);
} catch (EntitlementException ee) {
PrivilegeManager.debug.error("Caught EntitlementException while converting Privilege to Policy", ee);
}
return policy;
}
private static Policy privilegeToPolicyInternal(Privilege privilege) throws JAXBException, EntitlementException {
/*
* See entitelement meeting minutes - 22apr09
*
* privilege name would map to policy id
*
* application name would map to application category attribute
*
* entitlement resource names would map to xacml policy target
*
* entitlement excluded resource names would map to xacml rule target
*
* simple one level entitlement subjects (without or, and etc)
* would map to policy target
*
* all entitlement subjects would also map to xacml rule condition
*
* entitlement conditions would map to xacml rule condition
*
* entitlement resource attributes would map to rule advice expression
*
* at present xacml obligation support is out of scope
*/
if (privilege == null) {
return null;
}
Policy policy = new Policy();
String privilegeName = privilege.getName();
String applicationName = null;
String entitlementName = null;
Entitlement entitlement = privilege.getEntitlement();
if (entitlement != null) {
applicationName = entitlement.getApplicationName();
entitlementName = entitlement.getName();
}
String policyId = privilegeNameToPolicyId(privilegeName, applicationName);
policy.setPolicyId(policyId);
String description = privilege.getDescription();
policy.setDescription(description);
List<Object> vrList = policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition();
JAXBContext jaxbContext = JAXBContext.newInstance(XACMLConstants.XACML3_CORE_PKG);
if (applicationName != null) {
VariableDefinition appName = new VariableDefinition();
vrList.add(appName);
appName.setVariableId(XACMLConstants.APPLICATION_NAME);
AttributeValue cbv = new AttributeValue();
cbv.setDataType(XACMLConstants.XS_STRING);
cbv.getContent().add(applicationName);
JAXBElement<AttributeValue> cbve = objectFactory.createAttributeValue(cbv);
appName.setExpression(cbve);
}
if (entitlementName != null) {
VariableDefinition entName = new VariableDefinition();
vrList.add(entName);
entName.setVariableId(XACMLConstants.ENTITLEMENT_NAME);
AttributeValue cbv = new AttributeValue();
cbv.setDataType(XACMLConstants.XS_STRING);
cbv.getContent().add(entitlementName);
JAXBElement<AttributeValue> cbve = objectFactory.createAttributeValue(cbv);
entName.setExpression(cbve);
}
VariableDefinition createdBy = new VariableDefinition();
vrList.add(createdBy);
createdBy.setVariableId(XACMLConstants.PRIVILEGE_CREATED_BY);
AttributeValue cbv = new AttributeValue();
cbv.setDataType(XACMLConstants.XS_STRING);
cbv.getContent().add(privilege.getCreatedBy());
JAXBElement<AttributeValue> cbve = objectFactory.createAttributeValue(cbv);
createdBy.setExpression(cbve);
VariableDefinition lastModifiedBy = new VariableDefinition();
vrList.add(lastModifiedBy);
lastModifiedBy.setVariableId(XACMLConstants.PRIVILEGE_LAST_MODIFIED_BY);
AttributeValue lmbv = new AttributeValue();
lmbv.setDataType(XACMLConstants.XS_STRING);
lmbv.getContent().add(privilege.getLastModifiedBy());
JAXBElement<AttributeValue> lmbve = objectFactory.createAttributeValue(lmbv);
lastModifiedBy.setExpression(lmbve);
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm:ss.SSS");
SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss.SSS");
sdf1.setTimeZone(TimeZone.getTimeZone("GMT"));
sdf2.setTimeZone(TimeZone.getTimeZone("GMT"));
sdf3.setTimeZone(TimeZone.getTimeZone("GMT"));
VariableDefinition creationDate = new VariableDefinition();
vrList.add(creationDate);
creationDate.setVariableId(XACMLConstants.PRIVILEGE_CREATION_DATE);
AttributeValue cdv = new AttributeValue();
cdv.setDataType(XACMLConstants.XS_DATE_TIME);
cdv.getContent().add(
sdf1.format(privilege.getCreationDate())
+ "T"
+ sdf2.format(privilege.getCreationDate()));
JAXBElement<AttributeValue> cdve = objectFactory.createAttributeValue(cdv);
creationDate.setExpression(cdve);
VariableDefinition lastModifiedDate = new VariableDefinition();
vrList.add(lastModifiedDate);
lastModifiedDate.setVariableId(XACMLConstants.PRIVILEGE_LAST_MODIFIED_DATE);
AttributeValue lmdv = new AttributeValue();
lmdv.setDataType(XACMLConstants.XS_DATE_TIME);
lmdv.getContent().add(
sdf1.format(privilege.getLastModifiedDate())
+ "T"
+ sdf2.format(privilege.getLastModifiedDate()));
JAXBElement<AttributeValue> lmdve = objectFactory.createAttributeValue(lmdv);
lastModifiedDate.setExpression(lmdve);
// PolicyIssuer policyIssuer = null; // optional, TODO
Version version = new Version();
// TODO: use privilege version in future
version.setValue(sdf3.format(privilege.getLastModifiedDate()));
policy.setVersion(version);
// Defaults policyDefaults = null; // optional, TODO
String rca = getRuleCombiningAlgId(applicationName);
policy.setRuleCombiningAlgId(rca);
// String ruleCombiningAlgId = "rca"; // required
// XACML Target contains a list of AnyOf(s)
// XACML AnyOf contains a list of AllOf(s)
// XACML AllOf contains a list of Match(s)
Target target = new Target();
policy.setTarget(target);
List<AnyOf> targetAnyOfList = target.getAnyOf();
EntitlementSubject es = privilege.getSubject();
/* TODO: detect simple subjects and set attribute value and designator
List<AnyOf> anyOfSubjectList = entitlementSubjectToAnyOfList(es);
if (anyOfSubjectList != null) {
targetAnyOfList.addAll(anyOfSubjectList);
}
*/
AnyOf anyOfSubject = entitlementSubjectToAnyOf(es);
if (anyOfSubject != null) {
targetAnyOfList.add(anyOfSubject);
}
Set<String> resources = entitlement.getResourceNames();
List<AnyOf> anyOfResourceList = resourceNamesToAnyOfList(resources, applicationName);
if (anyOfResourceList != null) {
targetAnyOfList.addAll(anyOfResourceList);
}
AnyOf anyOfApplication = applicationNameToAnyOf(applicationName);
if (anyOfApplication != null) {
targetAnyOfList.add(anyOfApplication);
}
Map<String, Boolean> actionValues = entitlement.getActionValues();
List<AnyOf> anyOfActionList
= actionNamesToAnyOfList(actionValues.keySet(),
applicationName);
if (anyOfActionList != null) {
targetAnyOfList.addAll(anyOfActionList);
}
// PermitRule, DenyRule
Set<String> permitActions = new HashSet<String>();
Set<String> denyActions = new HashSet<String>();
if (actionValues != null) {
Set<String> actionNames = actionValues.keySet();
for(String actionName : actionNames) {
if (Boolean.TRUE.equals(actionValues.get(actionName))) {
permitActions.add(actionName);
} else {
denyActions.add(actionName);
}
}
}
Condition condition = eSubjectConditionToXCondition(privilege.getSubject(), privilege.getCondition());
// Include resource attributes (ResourceProvider) as AdviceExpressions
Set<ResourceAttribute> ra = privilege.getResourceAttributes();
if (ra != null && !ra.isEmpty()) {
AdviceExpressions adviceExpressions = schemaFactory.resourceAttributesToAdviceExpressions(ra);
policy.setAdviceExpressions(adviceExpressions);
}
if (!permitActions.isEmpty()) {
Rule permitRule = new Rule();
vrList.add(permitRule);
permitRule.setRuleId(entitlement.getName() + ":" + XACMLConstants.PREMIT_RULE_SUFFIX);
permitRule.setDescription(XACMLConstants.PERMIT_RULE_DESCRIPTION);
permitRule.setEffect(EffectType.PERMIT);
Target permitTarget = new Target();
permitRule.setTarget(permitTarget);
List<AnyOf> permitTargetAnyOfList = permitTarget.getAnyOf();
List<AnyOf> anyOfPermitActionList = actionNamesToAnyOfList(permitActions, applicationName);
if (anyOfPermitActionList != null) {
permitTargetAnyOfList.addAll(anyOfPermitActionList);
}
if (condition != null) {
permitRule.setCondition(condition);
}
}
if (!denyActions.isEmpty()) {
Rule denyRule = new Rule();
vrList.add(denyRule);
denyRule.setRuleId(entitlement.getName() + ":" + XACMLConstants.DENY_RULE_SUFFIX);
denyRule.setDescription(XACMLConstants.DENY_RULE_DESCRIPTION);
denyRule.setEffect(EffectType.DENY);
Target denyTarget = new Target();
denyRule.setTarget(denyTarget);
List<AnyOf> denyTargetAnyOfList = denyTarget.getAnyOf();
List<AnyOf> anyOfDenyActionList = actionNamesToAnyOfList(denyActions, applicationName);
if (anyOfDenyActionList != null) {
denyTargetAnyOfList.addAll(anyOfDenyActionList);
}
if (condition != null) {
denyRule.setCondition(condition);
}
}
return policy;
}
public static String privilegeNameToPolicyId(String privilegeName,
String applicationName) {
//TODO: implement privilegeNameToPolicyId() correctly
return privilegeName;
}
// TODO: not used now, use, test, fix and verify
public static List<AnyOf> entitlementSubjectToAnyOfList(
EntitlementSubject es) {
if (es == null) {
return null;
}
List<AnyOf> anyOfList = new ArrayList<AnyOf>();
AnyOf anyOf = new AnyOf();
anyOfList.add(anyOf);
List<AllOf> allOfList = anyOf.getAllOf();
AllOf allOf = new AllOf();
allOfList.add(allOf);
List<Match> matchList = allOf.getMatch();
if (es instanceof UserSubject) {
UserSubject us = (UserSubject)es;
String userId = us.getID();
Match match = new Match();
matchList.add(match);
match.setMatchId("user-subject-match");
AttributeValue attributeValue = new AttributeValue();
String dataType = "datatype";
attributeValue.setDataType(dataType);
attributeValue.getContent().add(userId);
AttributeDesignator attributeDesignator = new AttributeDesignator();
String category = "subject-category";
attributeDesignator.setCategory(category);
String attributeId = "user-subject:user-id";
attributeDesignator.setAttributeId(attributeId);
String dt = "xs;string";
attributeDesignator.setDataType(dt);
String issuer = "subject:issuer";
// attributeDesignator.setIssuer(issuer); TODO: verify and fix
boolean mustBePresent = true;
attributeDesignator.setMustBePresent(mustBePresent);
match.setAttributeValue(attributeValue);
match.setAttributeDesignator(attributeDesignator);
}
return anyOfList;
}
public static AnyOf entitlementSubjectToAnyOf(
EntitlementSubject es) throws JAXBException {
if (es == null) {
return null;
}
AnyOf anyOf = new AnyOf();
List<AllOf> allOfList = anyOf.getAllOf();
AllOf allOf = new AllOf();
allOfList.add(allOf);
List<Match> matchList = allOf.getMatch();
Match match = new Match();
matchList.add(match);
match.setMatchId(XACMLConstants.JSON_SUBJECT_MATCH);
AttributeValue attributeValue = new AttributeValue();
String dataType = XACMLConstants.JSON_SUBJECT_DATATYPE + ":"
+ es.getClass().getName();
attributeValue.setDataType(dataType);
String esString = es.getState();
attributeValue.getContent().add(esString);
AttributeDesignator attributeDesignator = new AttributeDesignator();
String category = XACMLConstants.XACML_ACCESS_SUBJECT_CATEGORY;
attributeDesignator.setCategory(category);
String attributeId = XACMLConstants.JSON_SUBJECT_ID;
attributeDesignator.setAttributeId(attributeId);
String dt = XACMLConstants.JSON_SUBJECT_DATATYPE + ":"
+ es.getClass().getName();
attributeDesignator.setDataType(dt);
String issuer = XACMLConstants.SUBJECT_ISSUER; // TODO: not a constant?
//attributeDesignator.setIssuer(issuer); //TODO: verify and fix
boolean mustBePresent = true;
attributeDesignator.setMustBePresent(mustBePresent);
match.setAttributeValue(attributeValue);
match.setAttributeDesignator(attributeDesignator);
return anyOf;
}
public static List<AnyOf> resourceNamesToAnyOfList(
Set<String> resourceNames, String applicationName) {
if (resourceNames == null || resourceNames.isEmpty()) {
return null;
}
List<AnyOf> anyOfList = new ArrayList<AnyOf>();
AnyOf anyOf = new AnyOf();
anyOfList.add(anyOf);
List<AllOf> allOfList = anyOf.getAllOf();
for (String resourceName : resourceNames) {
AllOf allOf = new AllOf();
List<Match> matchList = allOf.getMatch();
matchList.add(resourceNameToMatch(resourceName, applicationName));
allOfList.add(allOf);
}
return anyOfList;
}
public static AnyOf applicationNameToAnyOf(String applicationName) {
AnyOf anyOf = new AnyOf();
List<AllOf> allOfList = anyOf.getAllOf();
AllOf allOf = new AllOf();
List<Match> matchList = allOf.getMatch();
matchList.add(applicationNameToMatch(applicationName));
allOfList.add(allOf);
return anyOf;
}
public static List<AnyOf> actionNamesToAnyOfList(
Set<String> actionNames, String applicationName) {
if (actionNames == null || actionNames.isEmpty()) {
return null;
}
List<AnyOf> anyOfList = new ArrayList<AnyOf>();
AnyOf anyOf = new AnyOf();
anyOfList.add(anyOf);
List<AllOf> allOfList = anyOf.getAllOf();
for (String actionName : actionNames) {
AllOf allOf = new AllOf();
List<Match> matchList = allOf.getMatch();
matchList.add(actionNameToMatch(actionName, applicationName));
allOfList.add(allOf);
}
return anyOfList;
}
public static Match resourceNameToMatch(String resourceName,
String applicationName) {
if (resourceName == null || resourceName.length() == 0) {
return null;
}
Match match = new Match();
String matchId = XACMLConstants.ENTITLEMENT_RESOURCE_MATCH + ":"
+ applicationName;
match.setMatchId(matchId);
AttributeValue attributeValue = new AttributeValue();
String dataType = XACMLConstants.XS_STRING;
attributeValue.setDataType(dataType);
attributeValue.getContent().add(resourceName);
AttributeDesignator attributeDesignator = new AttributeDesignator();
String category = XACMLConstants.XACML_RESOURCE_CATEGORY;
attributeDesignator.setCategory(category);
String attributeId = XACMLConstants.XACML_RESOURCE_ID;
attributeDesignator.setAttributeId(attributeId);
String dt = XACMLConstants.XS_STRING;
attributeDesignator.setDataType(dt);
String issuer = XACMLConstants.RESOURCE_ISSUER; // TOOD: not a constant?
// attributeDesignator.setIssuer(issuer); TODO: verify and fix
boolean mustBePresent = true;
attributeDesignator.setMustBePresent(mustBePresent);
match.setAttributeValue(attributeValue);
match.setAttributeDesignator(attributeDesignator);
return match;
}
public static Match resourceNameToNotMatch(String resourceName,
String applicationName) {
if (resourceName == null || resourceName.length() == 0) {
return null;
}
Match match = new Match();
String matchId = XACMLConstants.ENTITLEMENT_RESOURCE_NO_MATCH + ":"
+ applicationName;
match.setMatchId(matchId);
AttributeValue attributeValue = new AttributeValue();
String dataType = XACMLConstants.XS_STRING;
attributeValue.setDataType(dataType);
attributeValue.getContent().add(resourceName);
AttributeDesignator attributeDesignator = new AttributeDesignator();
String category = XACMLConstants.XACML_RESOURCE_CATEGORY;
attributeDesignator.setCategory(category);
String attributeId = XACMLConstants.XACML_RESOURCE_ID;
attributeDesignator.setAttributeId(attributeId);
String dt = XACMLConstants.XS_STRING;
attributeDesignator.setDataType(dt);
String issuer = XACMLConstants.RESOURCE_ISSUER; // TODO: not a constant?
// attributeDesignator.setIssuer(issuer); TODO: verify and fix
boolean mustBePresent = true;
attributeDesignator.setMustBePresent(mustBePresent);
match.setAttributeValue(attributeValue);
match.setAttributeDesignator(attributeDesignator);
return match;
}
public static Match actionNameToMatch(String actionName,
String applicationName) {
if (actionName == null || actionName.length() == 0) {
return null;
}
Match match = new Match();
String matchId = XACMLConstants.ENTITLEMENT_ACTION_MATCH + ":"
+ applicationName;
match.setMatchId(matchId);
AttributeValue attributeValue = new AttributeValue();
String dataType = XACMLConstants.XS_STRING;
attributeValue.setDataType(dataType);
attributeValue.getContent().add(actionName);
AttributeDesignator attributeDesignator = new AttributeDesignator();
String category = XACMLConstants.XACML_ACTION_CATEGORY;
attributeDesignator.setCategory(category);
String attributeId = XACMLConstants.XACML_ACTION_ID;
attributeDesignator.setAttributeId(attributeId);
String dt = XACMLConstants.XS_STRING;
attributeDesignator.setDataType(dt);
String issuer = XACMLConstants.ACTION_ISSUER; // TODO: not a constant?
// attributeDesignator.setIssuer(issuer); // TODO: verify and fix
boolean mustBePresent = true;
attributeDesignator.setMustBePresent(mustBePresent);
match.setAttributeValue(attributeValue);
match.setAttributeDesignator(attributeDesignator);
return match;
}
public static Match applicationNameToMatch(String applicationName) {
if (applicationName == null || applicationName.length() == 0) {
return null;
}
Match match = new Match();
String matchId = XACMLConstants.APPLICATION_MATCH;
match.setMatchId(matchId);
AttributeValue attributeValue = new AttributeValue();
String dataType = XACMLConstants.XS_STRING;
attributeValue.setDataType(dataType);
attributeValue.getContent().add(applicationName);
AttributeDesignator attributeDesignator = new AttributeDesignator();
String category = XACMLConstants.APPLICATION_CATEGORY;
attributeDesignator.setCategory(category);
String attributeId = XACMLConstants.APPLICATION_ID;
attributeDesignator.setAttributeId(attributeId);
String dt = XACMLConstants.XS_STRING;
attributeDesignator.setDataType(dt);
String issuer = XACMLConstants.APPLICATION_ISSUER; // TODO: not a constant?
// attributeDesignator.setIssuer(issuer); // TODO: verify and fix
boolean mustBePresent = false;
attributeDesignator.setMustBePresent(mustBePresent);
match.setAttributeValue(attributeValue);
match.setAttributeDesignator(attributeDesignator);
return match;
}
public static Condition eSubjectConditionToXCondition(
EntitlementSubject es, EntitlementCondition ec)
throws JAXBException {
Condition condition = null;
if (es != null || ec != null) {
condition = new Condition();
JAXBContext jaxbContext = JAXBContext.newInstance(
XACMLConstants.XACML3_CORE_PKG);
Apply apply = new Apply();
apply.setFunctionId(
XACMLConstants.JSON_SUBJECT_AND_CONDITION_SATISFIED);
List applyExpressions = apply.getExpression();
if (es != null) {
String esString = es.getState();
// TODO: add custom xml attribute to idenity as privilge subject
AttributeValue esv = new AttributeValue();
Map<QName, String> otherAttrs = esv.getOtherAttributes();
QName qn = new QName("privilegeComponent");
otherAttrs.put(qn, "entitlementSubject");
String dataType = XACMLConstants.JSON_SUBJECT_DATATYPE + ":"
+ es.getClass().getName();
esv.setDataType(dataType);
esv.getContent().add(esString);
JAXBElement esve = objectFactory.createAttributeValue(esv);
applyExpressions.add(esve);
}
if (ec != null) {
String ecString = ec.getState();
// TODO: add custom xml attribute to idenity as privilge condition
AttributeValue ecv = new AttributeValue();
Map<QName, String> otherAttrs = ecv.getOtherAttributes();
QName qn = new QName("privilegeComponent");
otherAttrs.put(qn, "entitlementCondition");
String dataType = XACMLConstants.JSON_CONDITION_DATATYPE + ":"
+ ec.getClass().getName();
ecv.setDataType(dataType);
ecv.getContent().add(ecString);
JAXBElement ecve = objectFactory.createAttributeValue(ecv);
applyExpressions.add(ecve);
}
JAXBElement applyElement = objectFactory.createApply(apply);
condition.setExpression(applyElement);
}
return condition;
}
public static String getRuleCombiningAlgId(String applicationName) {
// TODO: return the correct algorithm id based on application
return XACMLConstants.XACML_RULE_DENY_OVERRIDES;
}
public static Set<Privilege> policySetToPrivileges(PolicySet policySet)
throws EntitlementException {
if (policySet == null) {
return null;
}
Set<Privilege> privileges = new HashSet<Privilege>();
Set<Policy> policies = getPoliciesFromPolicySet(policySet);
if (policies != null) {
for (Policy policy : policies) {
Privilege p = policyToPrivilege(policy);
privileges.add(p);
}
}
return privileges;
}
public static Privilege policyToPrivilege(Policy policy) throws EntitlementException {
String policyId = policy.getPolicyId();
String privilegeName = policyIdToPrivilegeName(policyId);
String description = policy.getDescription();
String createdBy = getVariableById(policy, XACMLConstants.PRIVILEGE_CREATED_BY);
long createdAt = dateStringToLong(getVariableById(policy, XACMLConstants.PRIVILEGE_CREATION_DATE));
String lastModifiedBy = getVariableById(policy, XACMLConstants.PRIVILEGE_LAST_MODIFIED_BY);
long lastModifiedAt = dateStringToLong(getVariableById(policy, XACMLConstants.PRIVILEGE_LAST_MODIFIED_DATE));
String entitlementName = getVariableById(policy, XACMLConstants.ENTITLEMENT_NAME);
String applicationName = getApplicationNameFromPolicy(policy);
Set<String> resourceNames = getResourceNamesFromPolicy(policy);
Map<String, Boolean> actionValues = getActionValuesFromPolicy(policy);
EntitlementSubject es = getEntitlementSubjectFromPolicy(policy);
EntitlementCondition ec = getEntitlementConditionFromPolicy(policy);
/*
* Construct entitlement from Rule target
* Get resource names, excluded resource names, action names from Rule Match element
* One Match for Action
* One Rule per value
*/
Entitlement entitlement = new Entitlement(applicationName, resourceNames, actionValues);
if (entitlementName != null) {
entitlement.setName(entitlementName);
}
// Process AdviceExpressions from Export into ResourceAttributes
Set<ResourceAttribute> ras = schemaFactory.adviceExpressionsToResourceAttributes(policy.getAdviceExpressions());
Privilege privilege = new XACMLOpenSSOPrivilege();
privilege.setName(privilegeName);
privilege.setDescription(description);
privilege.setCreatedBy(createdBy);
privilege.setCreationDate(createdAt);
privilege.setLastModifiedBy(lastModifiedBy);
privilege.setLastModifiedDate(lastModifiedAt);
privilege.setEntitlement(entitlement);
privilege.setSubject(es);
privilege.setCondition(ec);
privilege.setResourceAttributes(ras);
return privilege;
}
/**
* Gets the name of the application to which this policy belongs.
*
* @param policy read from XACML import stream.
*
* @return application name.
*/
public static String getApplicationNameFromPolicy(Policy policy) {
return getVariableById(policy, XACMLConstants.APPLICATION_NAME);
}
/**
* Gets the resource names from the policy.
*
* @param policy read from XACML import stream.
*
* @return resource names.
*/
public static Set<String> getResourceNamesFromPolicy(Policy policy) {
List<Match> policyMatches = getAllMatchesFromTarget(policy.getTarget());
return getResourceNamesFromMatches(policyMatches);
}
public static String policyIdToPrivilegeName(String policyId) {
// FIXME: do some transform, not required at this time
return policyId;
}
public static String getVariableById(Policy policy, String id) {
String val = null;
List<Object> vrList = policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition();
for (Object obj : vrList) {
if (obj instanceof VariableDefinition) {
VariableDefinition vd = (VariableDefinition) obj;
if (vd.getVariableId().equals(id)) {
JAXBElement<AttributeValue> jav = (JAXBElement<AttributeValue>) vd.getExpression();
AttributeValue attributeValue = (AttributeValue) jav.getValue();
val = attributeValue.getContent().get(0).toString();
}
}
}
return val;
}
private static long dateStringToLong(String dateString) {
if ((dateString) == null || (dateString.length() == 0)) {
return 0;
}
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd:HH:mm:ss.SSSS");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
dateString = dateString.replace("T", ":");
long time = 0;
try {
time = sdf.parse(dateString).getTime();
} catch (java.text.ParseException pe) {
//TODO: log debug warning
}
return time;
}
public static PolicySet privilegesToPolicySet(String realm, Collection<Privilege> privileges) {
PolicySet policySet = null;
try {
policySet = privilegesToPolicySetInternal(realm, privileges);
} catch (JAXBException je) {
//TODO: log error, jaxbexception
}
return policySet;
}
private static PolicySet privilegesToPolicySetInternal(String realm,
Collection<Privilege> privileges) throws JAXBException {
if (privileges == null) {
return null;
}
Set<Policy> policies = new HashSet<Policy>();
for (Privilege privilege : privileges) {
Policy policy = privilegeToPolicy(privilege);
policies.add(policy);
}
PolicySet policySet = policiesToPolicySetInternal(realm, policies);
return policySet;
}
public static PolicySet newPolicySet(String realm)
throws JAXBException {
PolicySet policySet = new PolicySet();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss.SSS");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String currentTime = sdf.format(currentTimeMillis());
String policySetId = realm + ":" + currentTime;
policySet.setPolicySetId(policySetId);
Version version = new Version();
version.setValue(sdf.format(currentTimeMillis()));
policySet.setVersion(version);
// FIXME: is there a better choice?
// policySet could contain policies for different applications
policySet.setPolicyCombiningAlgId(XACMLConstants.XACML_RULE_DENY_OVERRIDES);
Target target = new Target();
policySet.setVersion(version);
policySet.setTarget(target);
return policySet;
}
private static PolicySet policiesToPolicySetInternal(String realm, Set<Policy> policies)
throws JAXBException {
PolicySet policySet = new PolicySet();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss.SSS");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String currentTime = sdf.format(currentTimeMillis());
String policySetId = realm + ":" + currentTime;
policySet.setPolicySetId(policySetId);
Version version = new Version();
version.setValue(sdf.format(currentTimeMillis()));
policySet.setVersion(version);
// FIXME: is there a better choice?
// policySet could contain policies for different applications
policySet.setPolicyCombiningAlgId(XACMLConstants.XACML_RULE_DENY_OVERRIDES);
Target target = new Target();
policySet.setVersion(version);
policySet.setTarget(target);
JAXBContext jaxbContext = JAXBContext.newInstance(
XACMLConstants.XACML3_CORE_PKG);
List<JAXBElement<?>> pList
= policySet.getPolicySetOrPolicyOrPolicySetIdReference();
if (policies != null) {
for (Policy policy : policies) {
JAXBElement<Policy> policyElement
= objectFactory.createPolicy(policy);
pList.add(policyElement);
}
}
return policySet;
}
public static PolicySet addPolicyToPolicySet(Policy policy,
PolicySet policySet)
throws JAXBException {
if (policySet == null || policy == null) {
return policySet;
}
JAXBContext jaxbContext = JAXBContext.newInstance(
XACMLConstants.XACML3_CORE_PKG);
List<JAXBElement<?>> pList
= policySet.getPolicySetOrPolicyOrPolicySetIdReference();
JAXBElement<Policy> policyElement = objectFactory.createPolicy(policy);
pList.add(policyElement);
return policySet;
}
static List<Match> getAllMatchesFromTarget(Target target) {
List<Match> matches = new ArrayList<Match>();
if (target != null) {
List<AnyOf> anyOfList = target.getAnyOf();
for (AnyOf anyOf : anyOfList) {
List<AllOf> allOfList = anyOf.getAllOf();
for (AllOf allOf : allOfList) {
List<Match> matchList = allOf.getMatch();
matches.addAll(matchList);
}
}
}
return matches;
}
static Set<String> getResourceNamesFromMatches(List<Match> matches) {
if (matches == null) {
return null;
}
Set<String> resourceNames = new HashSet<String>();
for (Match match : matches) {
String matchId = match.getMatchId();
if ((matchId != null) && matchId.indexOf(":resource-match:") != -1) {
AttributeValue attributeValue = match.getAttributeValue();
if (attributeValue != null) {
List<Object> contentList = attributeValue.getContent();
if ((contentList != null) && !contentList.isEmpty()) {
// FIXME: log a warning if more than one element
Object obj = contentList.get(0);
resourceNames.add(obj.toString());
}
}
}
}
return resourceNames;
}
static Set<String> getActionNamesFromMatches(List<Match> matches) {
if (matches == null) {
return null;
}
Set<String> actionNames = new HashSet<String>();
for (Match match : matches) {
String matchId = match.getMatchId();
if ((matchId != null) && matchId.indexOf(":action-match:") != -1) {
AttributeValue attributeValue = match.getAttributeValue();
if (attributeValue != null) {
List<Object> contentList = attributeValue.getContent();
if ((contentList != null) && !contentList.isEmpty()) {
// FIXME: log a warning if more than one element
Object obj = contentList.get(0);
actionNames.add(obj.toString());
}
}
}
}
return actionNames;
}
static JSONObject getRealmsAppsResources(List<Match> matches)
throws JSONException {
if (matches == null) {
return null;
}
JSONObject jo = null;
String jsonString = null;
for (Match match : matches) {
String matchId = match.getMatchId();
if ((matchId != null) && matchId.equals(
XACMLConstants.JSON_REALMS_APPS_RESOURCES_MATCH)) {
AttributeValue attributeValue = match.getAttributeValue();
if (attributeValue != null) {
List<Object> contentList = attributeValue.getContent();
if ((contentList != null) && !contentList.isEmpty()) {
Object obj = contentList.get(0);
jsonString =obj.toString();
break;
}
}
}
}
if (jsonString != null) {
jo = new JSONObject(jsonString);
}
return jo;
}
static List<Rule> getRules(Policy policy) {
if (policy == null) {
return null;
}
List<Rule> ruleList = new ArrayList<Rule>();
List<Object> obList = policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition();
for (Object ob : obList) {
if (ob instanceof Rule) {
ruleList.add((Rule)ob);
}
}
return ruleList;
}
/**
* Gets the action values from the policy.
*
* @param policy instance read from the XACML input stream.
*
* @return action values.
*/
public static Map<String, Boolean> getActionValuesFromPolicy(Policy policy) {
if (policy == null) {
return null;
}
List<Rule> rules = getRules(policy);
if (rules == null) {
return null;
}
Map<String, Boolean> actionValues = new HashMap<String, Boolean>();
for (Rule rule : rules) {
Target target = rule.getTarget();
List<Match> matches = getAllMatchesFromTarget(target);
Set<String> actions = getActionNamesFromMatches(matches);
EffectType effectType = rule.getEffect();
for (String action : actions) {
actionValues.put(action,
(EffectType.PERMIT == effectType) ? Boolean.TRUE : Boolean.FALSE);
}
}
return actionValues;
}
/**
* Constructs EntitlementSubject from policy.
*
* @param policy
* from which the EntitlementSubject is created.
*
* @return EntitlementSubject created from the policy instance.
*/
public static EntitlementSubject getEntitlementSubjectFromPolicy(Policy policy) {
if (policy == null) {
return null;
}
List<Rule> rules = getRules(policy);
if (rules == null) {
return null;
}
EntitlementSubject es = null;
for (Rule rule : rules) {
Condition condition = rule.getCondition();
JAXBElement jaxbElement = condition.getExpression();
if (jaxbElement.getDeclaredType().equals(Apply.class)) {
Apply apply = (Apply)jaxbElement.getValue();
String functionId = apply.getFunctionId();
if (XACMLConstants.JSON_SUBJECT_AND_CONDITION_SATISFIED.equals(
functionId)) {
List<JAXBElement<?>> expressionList = apply.getExpression();
for (JAXBElement jaxe : expressionList) {
if (jaxe.getDeclaredType().equals(AttributeValue.class)) {
AttributeValue av = (AttributeValue)jaxe.getValue();
String dataType = av.getDataType();
if (dataType.startsWith(
XACMLConstants.JSON_SUBJECT_DATATYPE)) {
List<Object> valueList = av.getContent();
String value = null;
if (valueList != null) {
for (Object ob : valueList) {
if (ob instanceof String) {
value = (String)ob;
break;
}
}
}
if (value != null) {
es = createEntitlementSubject(dataType, value);
}
}
}
}
}
}
if (es != null) {
break;
}
}
return es;
}
/**
* Constructs EntitlementCondition from the policy.
*
* @param policy
* from which EntitlementCondition is constructed.
*
* @return EntitlementCondition instance created from the policy instance.
*
* @throws EntitlementException
* when any error occurs during construction.
*/
public static EntitlementCondition getEntitlementConditionFromPolicy(Policy policy) throws EntitlementException {
if (policy == null) {
return null;
}
List<Rule> rules = getRules(policy);
if (rules == null) {
return null;
}
EntitlementCondition ec = null;
for (Rule rule : rules) {
Condition condition = rule.getCondition();
JAXBElement jaxbElement = condition.getExpression();
if (jaxbElement.getDeclaredType().equals(Apply.class)) {
Apply apply = (Apply)jaxbElement.getValue();
String functionId = apply.getFunctionId();
if (XACMLConstants.JSON_SUBJECT_AND_CONDITION_SATISFIED.equals(
functionId)) {
List<JAXBElement<?>> expressionList = apply.getExpression();
for (JAXBElement jaxe : expressionList) {
if (jaxe.getDeclaredType().equals(AttributeValue.class)) {
AttributeValue av = (AttributeValue)jaxe.getValue();
String dataType = av.getDataType();
if (dataType.startsWith(
XACMLConstants.JSON_CONDITION_DATATYPE)) {
List<Object> valueList = av.getContent();
String value = null;
if (valueList != null) {
for (Object ob : valueList) {
if (ob instanceof String) {
value = (String)ob;
break;
}
}
}
if (value != null) {
ec = createEntitlementCondition(dataType, value);
}
}
}
}
}
if (ec != null) {
break;
}
}
}
return ec;
}
public static PolicySet streamToPolicySet(InputStream stream) throws JAXBException {
//FIXME: remove
PrivilegeManager.debug.error(
"XACMLProvilegeUtils.streamToPolicySet(), core_pkg:"
+ XACMLConstants.XACML3_CORE_PKG);
if (stream == null) {
return null;
}
JAXBContext jc = JAXBContext.newInstance(
XACMLConstants.XACML3_CORE_PKG);
Unmarshaller um = jc.createUnmarshaller();
JAXBElement je = (JAXBElement)um.unmarshal(XMLUtils.createSAXSource(new InputSource(stream)));
PolicySet ps = (PolicySet)je.getValue();
return ps;
}
public static Set<Policy> getPoliciesFromPolicySet(PolicySet policySet) {
if (policySet == null) {
return null;
}
Set<Policy> policies = new HashSet<Policy>();
List<JAXBElement<?>> choiceList = policySet.getPolicySetOrPolicyOrPolicySetIdReference();
for (JAXBElement jaxe : choiceList) {
if (jaxe.getDeclaredType().equals(Policy.class)) {
Policy p = (Policy)jaxe.getValue();
policies.add(p);
}
}
return policies;
}
static EntitlementSubject createEntitlementSubject(String dataType, String value) {
if (dataType == null || value == null) {
return null;
}
EntitlementSubject es = null;
int i = dataType.indexOf(XACMLConstants.JSON_SUBJECT_DATATYPE);
if (i != 0) {
return null;
}
String className = null;
if (dataType.length()
> XACMLConstants.JSON_SUBJECT_DATATYPE.length()) {
className = dataType.substring(
XACMLConstants.JSON_SUBJECT_DATATYPE.length() + 1);
Object ob = createDefaultObject(className);
if (ob != null && ob instanceof EntitlementSubject) {
es = (EntitlementSubject)ob;
} else {
PrivilegeManager.debug.error("XACMLPrivilegeUtils."
+ "createEntitlementSubject()"
+ "not an EntitlementSubject");
}
}
if (es != null) {
es.setState(value);
}
return es;
}
static EntitlementCondition createEntitlementCondition(String dataType, String value) throws EntitlementException {
if (dataType == null || value == null) {
return null;
}
EntitlementCondition ec = null;
int i = dataType.indexOf(XACMLConstants.JSON_CONDITION_DATATYPE);
if (i != 0) {
return null;
}
String className = null;
if (dataType.length()
> XACMLConstants.JSON_CONDITION_DATATYPE.length()) {
className = dataType.substring(
XACMLConstants.JSON_CONDITION_DATATYPE.length() + 1);
Object ob = createDefaultObject(className);
if (ob != null && ob instanceof EntitlementCondition) {
ec = (EntitlementCondition)ob;
} else {
PrivilegeManager.debug.error("XACMLPrivilegeUtils."
+ "createEntitlementCondition()"
+ "not an EntitlementCondition");
}
}
if (ec != null) {
ec.setState(value);
ec.validate();
}
return ec;
}
static Object createDefaultObject(String className) {
if (className == null) {
return null;
}
Object ob = null;
try {
Class cla = Class.forName(className.trim());
ob = cla.newInstance();
} catch (ClassNotFoundException e) {
PrivilegeManager.debug.error("XACMLPrivilegeUtils.createDefaultObject(),"
+ "hit exception", e);
} catch (IllegalAccessException e) {
PrivilegeManager.debug.error("XACMLPrivilegeUtils.createDefaultObject(),"
+ "hit exception", e);
} catch (InstantiationException e) {
PrivilegeManager.debug.error("XACMLPrivilegeUtils.createDefaultObject(),"
+ "hit exception", e);
}
return ob;
}
public static Policy referralToPolicy(ReferralPrivilege privilege) throws JSONException {
Policy policy = null;
try {
policy = referralToPolicyInternal(privilege);
} catch (JAXBException je) {
PrivilegeManager.debug.error(
"JAXBException while mapping referral to policy:", je);
}
return policy;
}
public static Policy referralToPolicyInternal(ReferralPrivilege privilege) throws JAXBException, JSONException {
if (privilege == null) {
return null;
}
Policy policy = new Policy();
String privilegeName = privilege.getName();
String policyId = privilegeNameToPolicyId(privilegeName, null);
policy.setPolicyId(policyId);
String description = privilege.getDescription();
policy.setDescription(description);
List<Object> vrList = policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition();
JAXBContext jaxbContext = JAXBContext.newInstance(XACMLConstants.XACML3_CORE_PKG);
VariableDefinition createdBy = new VariableDefinition();
vrList.add(createdBy);
createdBy.setVariableId(XACMLConstants.PRIVILEGE_CREATED_BY);
AttributeValue cbv = new AttributeValue();
cbv.setDataType(XACMLConstants.XS_STRING);
cbv.getContent().add(privilege.getCreatedBy());
JAXBElement<AttributeValue> cbve = objectFactory.createAttributeValue(cbv);
createdBy.setExpression(cbve);
VariableDefinition lastModifiedBy = new VariableDefinition();
vrList.add(lastModifiedBy);
lastModifiedBy.setVariableId(XACMLConstants.PRIVILEGE_LAST_MODIFIED_BY);
AttributeValue lmbv = new AttributeValue();
lmbv.setDataType(XACMLConstants.XS_STRING);
lmbv.getContent().add(privilege.getLastModifiedBy());
JAXBElement<AttributeValue> lmbve = objectFactory.createAttributeValue(lmbv);
lastModifiedBy.setExpression(lmbve);
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm:ss.SSS");
SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss.SSS");
sdf1.setTimeZone(TimeZone.getTimeZone("GMT"));
sdf2.setTimeZone(TimeZone.getTimeZone("GMT"));
sdf3.setTimeZone(TimeZone.getTimeZone("GMT"));
VariableDefinition creationDate = new VariableDefinition();
vrList.add(creationDate);
creationDate.setVariableId(XACMLConstants.PRIVILEGE_CREATION_DATE);
AttributeValue cdv = new AttributeValue();
cdv.setDataType(XACMLConstants.XS_DATE_TIME);
cdv.getContent().add(
sdf1.format(privilege.getCreationDate())
+ "T"
+ sdf2.format(privilege.getCreationDate()));
JAXBElement<AttributeValue> cdve = objectFactory.createAttributeValue(cdv);
creationDate.setExpression(cdve);
VariableDefinition lastModifiedDate = new VariableDefinition();
vrList.add(lastModifiedDate);
lastModifiedDate.setVariableId(XACMLConstants.PRIVILEGE_LAST_MODIFIED_DATE);
AttributeValue lmdv = new AttributeValue();
lmdv.setDataType(XACMLConstants.XS_DATE_TIME);
lmdv.getContent().add(
sdf1.format(privilege.getLastModifiedDate())
+ "T"
+ sdf2.format(privilege.getLastModifiedDate()));
JAXBElement<AttributeValue> lmdve = objectFactory.createAttributeValue(lmdv);
lastModifiedDate.setExpression(lmdve);
VariableDefinition isReferralPolicy = new VariableDefinition();
vrList.add(isReferralPolicy);
isReferralPolicy.setVariableId(XACMLConstants.IS_REFERRAL_POLICY);
AttributeValue irdv = new AttributeValue();
irdv.setDataType(XACMLConstants.XS_BOOLEAN_TYPE);
irdv.getContent().add(XACMLConstants.XS_BOOLEAN_TRUE);
JAXBElement<AttributeValue> irdve = objectFactory.createAttributeValue(irdv);
isReferralPolicy.setExpression(irdve);
// PolicyIssuer policyIssuer = null; // optional, TODO
Version version = new Version();
// TODO: use privilege version in future
version.setValue(sdf3.format(privilege.getLastModifiedDate()));
policy.setVersion(version);
// Defaults policyDefaults = null; // optional, TODO
policy.setRuleCombiningAlgId(XACMLConstants.XACML_RULE_DENY_OVERRIDES);
// XACML Target contains a list of AnyOf(s)
// XACML AnyOf contains a list of AllOf(s)
// XACML AllOf contains a list of Match(s)
Target target = new Target();
policy.setTarget(target);
List<AnyOf> targetAnyOfList = target.getAnyOf();
Set<String> realms = privilege.getRealms();
Map<String, Set<String>> appsResources = privilege.getOriginalMapApplNameToResources();
AnyOf anyOfRealmsAppsResources = realmsAppsResourcesToAnyOf(realms, appsResources);
if (anyOfRealmsAppsResources != null) {
targetAnyOfList.add(anyOfRealmsAppsResources);
}
Rule permitRule = new Rule();
vrList.add(permitRule);
permitRule.setRuleId(privilegeName + ":" + XACMLConstants.PREMIT_RULE_SUFFIX);
permitRule.setDescription(XACMLConstants.PERMIT_RULE_DESCRIPTION);
permitRule.setEffect(EffectType.PERMIT);
Target permitTarget = new Target();
permitRule.setTarget(permitTarget);
return policy;
}
public static boolean isReferralPolicy(Policy policy) {
String s = getVariableById(policy, XACMLConstants.IS_REFERRAL_POLICY);
return XACMLConstants.XS_BOOLEAN_TRUE.equalsIgnoreCase(s);
}
public static ReferralPrivilege policyToReferral(Policy policy) throws EntitlementException, JSONException {
String policyId = policy.getPolicyId();
String privilegeName = policyIdToPrivilegeName(policyId);
String description = policy.getDescription();
String createdBy = getVariableById(policy, XACMLConstants.PRIVILEGE_CREATED_BY);
long createdAt = dateStringToLong(getVariableById(policy, XACMLConstants.PRIVILEGE_CREATION_DATE));
String lastModifiedBy = getVariableById(policy, XACMLConstants.PRIVILEGE_LAST_MODIFIED_BY);
long lastModifiedAt = dateStringToLong(getVariableById(policy, XACMLConstants.PRIVILEGE_LAST_MODIFIED_DATE));
List<Match> policyMatches = getAllMatchesFromTarget(policy.getTarget());
JSONObject jo = getRealmsAppsResources(policyMatches);
Set<String> realms = JSONUtils.getSet(jo, "realms");
Map<String, Set<String>> appsResources = JSONUtils.getMapStringSetString(jo, "appsResources");
ReferralPrivilege referral = new ReferralPrivilege(privilegeName, appsResources, realms);
referral.setDescription(description);
referral.setCreatedBy(createdBy);
referral.setCreationDate(createdAt);
referral.setLastModifiedBy(lastModifiedBy);
referral.setLastModifiedDate(lastModifiedAt);
return referral;
}
public static AnyOf realmsAppsResourcesToAnyOf(Set<String> realms,
Map<String, Set<String>> appsResources) throws JSONException {
AnyOf anyOf = new AnyOf();
List<AllOf> allOfList = anyOf.getAllOf();
AllOf allOf = new AllOf();
allOfList.add(allOf);
List<Match> matchList = allOf.getMatch();
Match match = new Match();
matchList.add(match);
match.setMatchId(XACMLConstants.JSON_REALMS_APPS_RESOURCES_MATCH); //FIXME
AttributeValue attributeValue = new AttributeValue();
String dataType = XACMLConstants.JSON_REALMS_APPS_RESOURCES_DATATYPE; //FIXME
attributeValue.setDataType(dataType);
JSONObject jo = new JSONObject();
jo.put("realms", realms);
jo.put("appsResources", appsResources);
attributeValue.getContent().add(jo.toString());
AttributeDesignator attributeDesignator = new AttributeDesignator();
String category = XACMLConstants.REALMS_APPS_RESOURCES_CATEGORY;
attributeDesignator.setCategory(category);
String attributeId = XACMLConstants.JSON_REALMS_APPS_RESOURCES_ID;
attributeDesignator.setAttributeId(attributeId);
attributeDesignator.setDataType(dataType);
boolean mustBePresent = false;
attributeDesignator.setMustBePresent(mustBePresent);
match.setAttributeValue(attributeValue);
match.setAttributeDesignator(attributeDesignator);
return anyOf;
}
/**
* Validates the privilege instance.
*
* @param privilege
* instance to be validated.
* @param privilegeValidator
* the validator for privilege.
*
* @throws EntitlementException
* if the privilege is invalid.
*/
public static void validate(Privilege privilege, PrivilegeValidator privilegeValidator) throws EntitlementException {
// OPENAM-5031
// For the moment, fail the whole import if any single referral is found to have a name which doesn't
// suit LDAP.
if (containsUndesiredCharacters(privilege.getName())) {
throw new EntitlementException(INVALID_VALUE,
new Object[] { "privilege name " + privilege.getName() });
}
privilegeValidator.validatePrivilege(privilege);
}
/**
* OPENAM-5031: We would have used DN.escapeAttributeValue to encode the incoming string and compare with the
* original string - if there are differences then the incoming string contains characters which LDAP requires
* quoted. However ssoadm doesn't include the jar that the DN class ends up in. In order to avoid the
* overhead of adding a whole jar just for one function in one class, this is provided here. Thus, this
* function returns true if the incoming string contains any character which LDAP requires to be quoted.
*
* @param s The specified string.
* @return true if the string contains characters which require quotation for LDAP to work, false otherwise
*/
@VisibleForTesting
public static boolean containsUndesiredCharacters(String s) {
// This is done with strings rather than characters because the initialisation of the set is much easier.
// Otherwise we end up with a Set<Character> being initialised from a List<char>
final String[] DODGY_LDAP_CHARS = { ",", "+", "\"", "\\", "<", ">", ";" };
Set<String> dodgyChars = new HashSet<>(Arrays.asList(DODGY_LDAP_CHARS));
for(int i = 0; i < s.length(); i++) {
String sub = s.substring(i, i + 1);
if (dodgyChars.contains(sub)) {
return true;
}
}
return false;
}
}