<?php
###############################################################################
# OneLogin.php
#
# @author Anil Kumar <akumar@codepunch.com>
# @link   https://codepunch.com
#
############################################################################### 

namespace 	CodePunch\Config\SAML;

use 		CodePunch\Base\Util as UTIL;
use			CodePunch\Base\Text as TEXT;
use			CodePunch\DB\Audit as AUDIT;
use 		Exception;

###############################################################################

class OneLogin Extends SAML {
	
	###########################################################################
	
	public function logout()
	{
		$returnTo = null;
		$parameters = array();
		$nameId = null;
		$sessionIndex = null;
		$nameIdFormat = null;
		
		parent::logout();

		if (isset($_SESSION['samlNameId'])) {
			$nameId = $_SESSION['samlNameId'];
		}
		if (isset($_SESSION['samlSessionIndex'])) {
			$sessionIndex = $_SESSION['samlSessionIndex'];
		}
		if (isset($_SESSION['samlNameIdFormat'])) {
			$nameIdFormat = $_SESSION['samlNameIdFormat'];
		}

		if($this->getSAMLAuth()) 
			$this->getSAMLAuth()->logout($returnTo, $parameters, $nameId, $sessionIndex, false, $nameIdFormat);

		# If LogoutRequest ID need to be saved in order to later validate it, do instead
		# $sloBuiltUrl = $this->getSAMLAuth()->logout(null, $paramters, $nameId, $sessionIndex, true);
		# $_SESSION['LogoutRequestID'] = $this->getSAMLAuth()->getLastRequestID();
		# header('Pragma: no-cache');
		# header('Cache-Control: no-cache, must-revalidate');
		# header('Location: ' . $sloBuiltUrl);
		# exit();
	}
	
	###########################################################################
	
	public function ACS()
	{
		if (isset($_SESSION) && isset($_SESSION['AuthNRequestID'])) 
			$requestID = $_SESSION['AuthNRequestID'];
		else 
			$requestID = null;

		try {
			$this->getSAMLAuth()->processResponse($requestID);
			$errors = $this->getSAMLAuth()->getErrors();
			if (!$this->getSAMLAuth()->isAuthenticated()) {
				$errmsg = "";
				if(!empty($errors))
					$errmsg = implode(', ', $errors);
				throw new Exception(sprintf(TEXT::get("format_saml_auth_error_S"), $errmsg));
			}
			$_SESSION['samlUserdata'] = $this->getSAMLAuth()->getAttributes();
			$_SESSION['samlNameId'] = $this->getSAMLAuth()->getNameId();
			$_SESSION['samlNameIdFormat'] = $this->getSAMLAuth()->getNameIdFormat();
			$_SESSION['samlSessionIndex'] = $this->getSAMLAuth()->getSessionIndex();
			unset($_SESSION['AuthNRequestID']);
			if (isset($_POST['RelayState']) && \OneLogin_Saml2_Utils::getSelfURL() != $_POST['RelayState']) {
				$this->getSAMLAuth()->redirectTo($_POST['RelayState']);
			}
		}
		catch (Exception $e) {
			throw $e;
		}
	}
	
	###########################################################################
	
	public function SLS()
	{
		if (isset($_SESSION) && isset($_SESSION['LogoutRequestID'])) 
			$requestID = $_SESSION['LogoutRequestID'];
		else 
			$requestID = null;

		$this->getSAMLAuth()->processSLO(false, $requestID);
		$errors = $this->getSAMLAuth()->getErrors();
		if (empty($errors)) {
			echo '<p>Sucessfully logged out</p>';
		} 
		else {
			echo '<p>', implode(', ', $errors), '</p>';
		}
	}
	
	###########################################################################
	
	public function hasSettings()
	{
		$settings = $this->getSettings();
		if(isset($settings['sp']) && isset($settings['idp'])) {
			if(count($settings['sp']) && count($settings['idp']))
				return true;
		}
		return false;
	}
	
	###########################################################################
	
	public function isLoggedIn()
	{
		if (isset($_SESSION['samlUserdata'])) {
			if (!empty($_SESSION['samlUserdata'])) {
				return true;
			}
		}
		return false;
	}
	
	###########################################################################
	
	public function process()
	{
		if (isset($_SESSION['samlUserdata'])) {
			if (!empty($_SESSION['samlUserdata'])) {
				$attributes = $_SESSION['samlUserdata'];
				$oneloginuser = "";
				if(isset($_SESSION['samlNameId']))
					$oneloginuser = $_SESSION['samlNameId'];
				/*
				else if(isset($attributes['User.email']))
					$oneloginuser = $attributes['User.email'][0];
				else if(isset($attributes['PersonImmutableID']))
					$oneloginuser = $attributes['PersonImmutableID'][0];
				else if(isset($attributes['email']))
					$oneloginuser = $attributes['email'][0];
				else if(isset($attributes['EmailAddress']))
					$oneloginuser = $attributes['EmailAddress'][0]; */
				$oneloginname = UTIL::get_from_array($attributes['User.FirstName'][0], "") . " " . UTIL::get_from_array($attributes['User.LastName'][0], "");
				$samldata = array('idp'=>'OneLogin', 'name'=>$oneloginname, 'user'=>$oneloginuser);
				$mappeduser = $this->get_valid_user_name($oneloginuser, $oneloginname);
				$this->processUser($mappeduser, $samldata);
			} 
			else {
				// Error
			}
		} 
		else {
			$url = UTIL::get_root_url() . "saml.php?sso";
			header("Location: $url");
			exit;
		}

	}
	
	###########################################################################
	
	public function getOptions()
	{
		return array (
			'idp-entityId' => array('string', 'ID Provider', 'Entity ID (Issuer URL)'),
			'idp-singleSignOnService' => array('string', 'ID Provider', 'SignOn URL (SAML 2.0 Endpoint)'),
			'idp-singleLogoutService' => array('string', 'ID Provider', 'Logout URL (SLO Endpoint)'),
			'idp-x509cert' => array('text', 'ID Provider', 'x509 Certificate'),
			'idp-strictMode' => array('boolean', 'Strict Mode', 'SAML Strict Mode')
		);
	}
	
	###########################################################################
	
	public function getName()
	{
		return "OneLogin";
	}

	###########################################################################

	public function getSettings()
	{
		$setup = new \CodePunch\Config\Settings($this->getAuth());
		
		$settingsInfo = array('sp'=>array(), 'idp'=>array());
		$settingsInfo['sp']['entityId'] = UTIL::get_root_url() . "metadata.php";
		$settingsInfo['sp']['assertionConsumerService'] = array('url'=>UTIL::get_root_url() . "saml.php?acs");
		$settingsInfo['sp']['singleLogoutService'] = array('url'=>UTIL::get_root_url() . "saml.php?sls");
		$settingsInfo['sp']['NameIDFormat'] = 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress';

		$settingsInfo['idp']['entityId'] = $setup->getEncryptedOption("onelogin_idp_entityid", "");
		$settingsInfo['idp']['singleSignOnService'] = array('url' => $setup->getEncryptedOption("onelogin_idp_singlesignonservice", ""));
		$settingsInfo['idp']['singleLogoutService'] = array('url' => $setup->getEncryptedOption("onelogin_idp_singlelogoutservice", ""));
		$cert = $setup->getText("onelogin_idp_x509cert", "");
		$settingsInfo['idp']['x509cert'] = $this->getAuth()->decrypt($cert);
		
		$settingsInfo['strict'] = UTIL::str_to_bool($setup->getEncryptedOption("onelogin_idp_strictmode", "yes"), true);
		$settingsInfo['security'] = array();
		$settingsInfo['security']['signatureAlgorithm'] = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256';
		$settingsInfo['security']['digestAlgorithm'] = 'http://www.w3.org/2001/04/xmlenc#sha256';

		return $settingsInfo;
	}
	
}

###############################################################################
