/** * Validation of a service ticket for Version 2 of the CAS protocol. * * @param string $data * The raw validation response data from CAS server. * * @return array * An array containing validation result data from the CAS server. * @throws CasValidateException */ private function validateVersion2($data) { $dom = new \DOMDocument(); $dom->preserveWhiteSpace = FALSE; $dom->encoding = "utf-8"; // Suppress errors from this function, as we intend to throw our own // exception. if (@$dom->loadXML($data) === FALSE) { throw new CasValidateException("XML from CAS server is not valid."); } $failure_elements = $dom->getElementsByTagName('authenticationFailure'); if ($failure_elements->length > 0) { // Failed validation, extract the message and toss exception. $failure_element = $failure_elements->item(0); $error_code = $failure_element->getAttribute('code'); $error_msg = $failure_element->nodeValue; throw new CasValidateException("Error Code " . trim($error_code) . ": " . trim($error_msg)); } $success_elements = $dom->getElementsByTagName("authenticationSuccess"); if ($success_elements->length === 0) { // All responses should have either an authenticationFailure // or authenticationSuccess node. throw new CasValidateException("XML from CAS server is not valid."); } // There should only be one success element, grab it and extract username. $success_element = $success_elements->item(0); $user_element = $success_element->getElementsByTagName("user"); if ($user_element->length == 0) { throw new CasValidateException("No user found in ticket validation response."); } $username = $user_element->item(0)->nodeValue; $this->casHelper->log("Extracted user: {$username}"); $property_bag = new CasPropertyBag($username); // If the server provided any attributes, parse them out into the property // bag. $attribute_elements = $dom->getElementsByTagName("attributes"); if ($attribute_elements->length > 0) { $property_bag->setAttributes($this->parseAttributes($attribute_elements)); } // Look for a proxy chain, and if it exists, validate it against config. $proxy_chain = $success_element->getElementsByTagName("proxy"); if ($this->casHelper->canBeProxied() && $proxy_chain->length > 0) { $this->verifyProxyChain($proxy_chain); } if ($this->casHelper->isProxy()) { // Extract the PGTIOU from the XML. $pgt_element = $success_element->getElementsByTagName("proxyGrantingTicket"); if ($pgt_element->length == 0) { throw new CasValidateException("Proxy initialized, but no PGTIOU provided in response."); } $pgt = $pgt_element->item(0)->nodeValue; $this->casHelper->log("Extracted PGT: {$pgt}"); $property_bag->setPgt($pgt); } return $property_bag; }
/** * Test getting the 'can be proxied' configuration. * * @covers ::canBeProxied * @covers ::__construct */ public function testCanBeProxied() { $config_factory = $this->getConfigFactoryStub(array('cas.settings' => array('server.hostname' => 'example.com', 'server.port' => 443, 'server.path' => '/cas', 'proxy.can_be_proxied' => TRUE))); $cas_helper = new CasHelper($config_factory, $this->urlGenerator, $this->connection, $this->loggerFactory, $this->session); $this->assertEquals(TRUE, $cas_helper->canBeProxied()); }