private function parseConditions(\DOMElement $xml)
{
$conditions = Utils::xpQuery($xml, './saml_assertion:Conditions');
if (empty($conditions)) {
/* No <saml:Conditions> node. */
return;
} elseif (count($conditions) > 1) {
throw new \Exception('More than one <saml:Conditions> in <saml:Assertion>.');
}
$conditions = $conditions[0];
if ($conditions->hasAttribute('NotBefore')) {
$notBefore = Utils::xsDateTimeToTimestamp($conditions->getAttribute('NotBefore'));
if ($this->notBefore === null || $this->notBefore < $notBefore) {
$this->notBefore = $notBefore;
}
}
if ($conditions->hasAttribute('NotOnOrAfter')) {
$notOnOrAfter = Utils::xsDateTimeToTimestamp($conditions->getAttribute('NotOnOrAfter'));
if ($this->notOnOrAfter === null || $this->notOnOrAfter > $notOnOrAfter) {
$this->notOnOrAfter = $notOnOrAfter;
}
}
for ($node = $conditions->firstChild; $node !== null; $node = $node->nextSibling) {
if ($node instanceof \DOMText) {
continue;
}
if ($node->namespaceURI !== Constants::NS_SAML) {
throw new \Exception('Unknown namespace of condition: ' . var_export($node->namespaceURI, true));
}
switch ($node->localName) {
case 'AudienceRestriction':
$audiences = Utils::extractStrings($node, Constants::NS_SAML, 'Audience');
if ($this->validAudiences === null) {
/* The first (and probably last) AudienceRestriction element. */
$this->validAudiences = $audiences;
} else {
/*
* The set of AudienceRestriction are ANDed together, so we need
* the subset that are present in all of them.
*/
$this->validAudiences = array_intersect($this->validAudiences, $audiences);
}
break;
case 'OneTimeUse':
/* Currently ignored. */
break;
case 'ProxyRestriction':
/* Currently ignored. */
break;
default:
throw new \Exception('Unknown condition: ' . var_export($node->localName, true));
}
}
}