namespace MiniOrange\IDPSaml\Helper\Saml2;
use MiniOrange\IDPSaml\Helper\Saml2\SAML2Utilities;
use MiniOrange\IDPSaml\Helper\IDPConstants;
use MiniOrange\IDPSaml\Helper\Exception\MissingIDException;
use MiniOrange\IDPSaml\Helper\Exception\InvalidRequestVersionException;
use MiniOrange\IDPSaml\Helper\Exception\MissingNameIdException;
use MiniOrange\IDPSaml\Helper\Exception\InvalidNumberOfNameIDsException;
class LogoutRequest
{
private $xml;
private $tagName;
private $id;
private $issuer;
private $destination;
private $issueInstant;
private $certificates;
private $validators;
private $notOnOrAfter;
private $encryptedNameId;
private $nameId;
private $sessionIndexes;
private $bindingType;
private $requestType = IDPConstants::LOGOUT_REQUEST;
public function __construct(\DOMElement $ov = NULL)
{
$this->xml = new \DOMDocument("1.0", "utf-8");
if (!($ov === NULL)) {
goto KE;
}
return;
KE:
$this->xml = $ov;
$this->tagName = "LogoutRequest";
$this->id = $this->generateUniqueID(40);
$this->issueInstant = time();
$this->certificates = array();
$this->validators = array();
$this->issueInstant = SAML2Utilities::xsDateTimeToTimestamp($ov->getAttribute("IssueInstant"));
$this->parseID($ov);
$this->checkSAMLVersion($ov);
if (!$ov->hasAttribute("Destination")) {
goto vk;
}
$this->destination = $ov->getAttribute("Destination");
vk:
$this->parseIssuer($ov);
$this->parseAndValidateSignature($ov);
if (!$ov->hasAttribute("NotOnOrAfter")) {
goto pb;
}
$this->notOnOrAfter = SAML2Utilities::xsDateTimeToTimestamp($ov->getAttribute("NotOnOrAfter"));
pb:
$this->parseNameId($ov);
$this->parseSessionIndexes($ov);
}
public function build()
{
$NO = $this->generateRequest();
if (!(empty($this->bindingType) || $this->bindingType == IDPConstants::HTTP_REDIRECT)) {
goto vf;
}
$LA = gzdeflate($NO);
$Ur = base64_encode($LA);
$wm = urlencode($Ur);
$NO = $wm;
vf:
return $NO;
}
private function generateRequest()
{
$y_ = $this->createSAMLLogoutRequest();
$this->xml->appendChild($y_);
$cZ = $this->buildIssuer();
$y_->appendChild($cZ);
$Ne = $this->buildNameId();
$y_->appendChild($Ne);
$Aq = $this->buildSessionIndex();
$y_->appendChild($Aq);
$vl = $this->xml->saveXML();
return $vl;
}
protected function createSAMLLogoutRequest()
{
$y_ = $this->xml->createElementNS("urn:oasis:names:tc:SAML:2.0:protocol", "samlp:LogoutRequest");
$y_->setAttribute("ID", $this->generateUniqueID(40));
$y_->setAttribute("Version", "2p");
$y_->setAttribute("IssueInstant", str_replace("+000", "Z", gmdate("c", time())));
$y_->setAttribute("Destination", $this->destination);
return $y_;
}
protected function buildIssuer()
{
return $this->xml->createElementNS("urn:oasis:names:tc:SAML:2.0:assertion", "saml:Issuer", $this->issuer);
}
protected function buildNameId()
{
return $this->xml->createElementNS("urn:oasis:names:tc:SAMLp:assertion", "saml:NameID", $this->nameId);
}
protected function buildSessionIndex()
{
return $this->xml->createElement("samlp:SessionIndex", is_array($this->sessionIndexes) ? $this->sessionIndexes[0] : $this->sessionIndexes);
}
protected function parseID($ov)
{
if ($ov->hasAttribute("ID")) {
goto xD;
}
throw new MissingIDException();
xD:
$this->id = $ov->getAttribute("ID");
}
protected function checkSAMLVersion($ov)
{
if (!($ov->getAttribute("Version") !== "2p")) {
goto Mx;
}
throw InvalidRequestVersionException();
Mx:
}
protected function parseIssuer($ov)
{
$cZ = SAML2Utilities::xpQuery($ov, "./saml_assertion:Issuer");
if (empty($cZ)) {
goto E5;
}
$this->issuer = trim($cZ[0]->textContent);
E5:
}
protected function parseSessionIndexes($ov)
{
$this->sessionIndexes = array();
$DT = SAML2Utilities::xpQuery($ov, "./saml_protocol:SessionIndex");
foreach ($DT as $Aq) {
$this->sessionIndexes[] = trim($Aq->textContent);
Lw:
}
Cc:
}
protected function parseAndValidateSignature($ov)
{
$hk = SAML2Utilities::validateElement($ov);
if (!($hk !== FALSE)) {
goto FM;
}
$this->certificates = $hk["Certificates"];
$this->validators[] = array("Function" => array("SAMLUtilities", "validateSignature"), "Data" => $hk);
FM:
}
protected function parseNameId($ov)
{
$Ne = SAML2Utilities::xpQuery($ov, "./saml_assertion:NameID | ./saml_assertion:EncryptedID/xenc:EncryptedData");
if (empty($Ne)) {
goto su;
}
if (count($Ne) > 1) {
goto xo;
}
goto nG;
su:
throw new MissingNameIdException();
goto nG;
xo:
throw new InvalidNumberOfNameIDsException();
nG:
$Ne = $Ne[0];
if ($Ne->localName === "EncryptedData") {
goto D9;
}
$this->nameId = SAML2Utilities::parseNameId($Ne);
goto oM;
D9:
$this->encryptedNameId = $Ne;
oM:
}
public function toUnsignedXML()
{
$L7 = toUnsignedXML();
if (!($this->notOnOrAfter !== NULL)) {
goto zT;
}
$L7->setAttribute("NotOnOrAfter", gmdate("Y-m-d\TH:i:s\Z", $this->notOnOrAfter));
zT:
if ($this->encryptedNameId === NULL) {
goto kH;
}
$mt = $L7->ownerDocument->createElementNS(SAML2_Const::NS_SAML, "saml:EncryptedID");
$L7->appendChild($mt);
$mt->appendChild($L7->ownerDocument->importNode($this->encryptedNameId, TRUE));
goto jd;
kH:
SAML2_Utils::addNameId($L7, $this->nameId);
jd:
foreach ($this->sessionIndexes as $Aq) {
SAML2_Utils::addString($L7, SAML2_Const::NS_SAMLP, "SessionIndex", $Aq);
DD:
}
Mm:
return $L7;
}
private function generateUniqueID($B5)
{
return SAML2Utilities::generateRandomAlphanumericValue($B5);
}
public function __toString()
{
$v5 = "LOGOUT REQUEST PARAMS [";
$v5 .= "TagName = " . $this->tagName;
$v5 .= ", validators = " . implode(",", $this->validators);
$v5 .= ", ID = " . $this->id;
$v5 .= ", Issuer = " . $this->issuer;
$v5 .= ", Not On Or After = " . $this->notOnOrAfter;
$v5 .= ", Destination = " . $this->destination;
$v5 .= ", Encrypted NameID = " . $this->encryptedNameId;
$v5 .= ", Issue Instant = " . $this->issueInstant;
$v5 .= ", Session Indexes = " . implode(",", $this->sessionIndexes);
$v5 .= "]";
return $v5;
}
public function getXml()
{
return $this->xml;
}
public function setXml($ov)
{
$this->xml = $ov;
return $this;
}
public function getTagName()
{
return $this->tagName;
}
public function setTagName($fD)
{
$this->tagName = $fD;
return $this;
}
public function getId()
{
return $this->id;
}
public function setId($ST)
{
$this->id = $ST;
return $this;
}
public function getIssuer()
{
return $this->issuer;
}
public function setIssuer($cZ)
{
$this->issuer = $cZ;
return $this;
}
public function getDestination()
{
return $this->destination;
}
public function setDestination($C4)
{
$this->destination = $C4;
return $this;
}
public function getIssueInstant()
{
return $this->issueInstant;
}
public function setIssueInstant($ih)
{
$this->issueInstant = $ih;
return $this;
}
public function getCertificates()
{
return $this->certificates;
}
public function setCertificates($CL)
{
$this->certificates = $CL;
return $this;
}
public function getValidators()
{
return $this->validators;
}
public function setValidators($Qf)
{
$this->validators = $Qf;
return $this;
}
public function getNotOnOrAfter()
{
return $this->notOnOrAfter;
}
public function setNotOnOrAfter($Bi)
{
$this->notOnOrAfter = $Bi;
return $this;
}
public function getEncryptedNameId()
{
return $this->encryptedNameId;
}
public function setEncryptedNameId($gd)
{
$this->encryptedNameId = $gd;
return $this;
}
public function getNameId()
{
return $this->nameId;
}
public function setNameId($Ne)
{
$this->nameId = $Ne;
return $this;
}
public function getSessionIndexes()
{
return $this->sessionIndexes;
}
public function setSessionIndexes($DT)
{
$this->sessionIndexes = $DT;
return $this;
}
public function getRequestType()
{
return $this->requestType;
}
public function setRequestType($nR)
{
$this->requestType = $nR;
return $this;
}
public function getBindingType()
{
return $this->bindingType;
}
public function setBindingType($ae)
{
$this->bindingType = $ae;
return $this;
}
}
© 2023 Quttera Ltd. All rights reserved.