Select Git revision
shibd_discofeed.class.php
Hahn Axel (hahn) authored
shibd_discofeed.class.php 5.52 KiB
<?php
/**
* ======================================================================
*
* AAI LOGIN WITH SHIBBOLETH HANDLING MULTIPLE ORGANIZATIONS
*
* included functions
* License: GNU GPL 3.0
* Source: https://git-repo.iml.unibe.ch/iml-open-source/login-aai
* ======================================================================
*/
class shibd_discofeed
{
/**
* Url to the discofeed that returns a json with al idps
* @var string
*/
protected string $_sDiscofeedUrl = '/Shibboleth.sso/DiscoFeed';
/**
* Url to generate a static Shibboleth login url
* @var string
*/
protected string $_sShibLoginUrl = '/Shibboleth.sso/Login';
/**
* Language to search for in the discofeed; a 2 letter code
* @var string
*/
protected string $lang = 'en';
// caching of discofeed
/**
* Filename of the cache file for the Shibboleth discofeed
* @var string
*/
protected string $_sCachefile = 'discofeed.json';
/**
* Caching time for the discofeed cache in seconds
* @var int
*/
protected int $_iCacheTtl;
/**
* Self base URL of the current app tu build Shibboleth links
* @var string
*/
protected string $SELFURL = '';
// protected array $aConfig = [];
// ----------------------------------------------------------------------
/**
* Constructor
* @param array $aConfig config array; the following keys are required:
* idps array IDP poositive list
* return-url string return URL
* cache-ttl int caching time in seconds
* cachefile string caching filename
* @param string $SELFURL
*/
public function __construct(array $aConfig, string $SELFURL = '')
{
$SELFURL = $SELFURL ?: (
isset($_SERVER['SERVER_NAME']) ? "https://" . $_SERVER['SERVER_NAME'] : ''
);
if(!$SELFURL) {
die("ERROR: SELFURL is not set. \$_SERVER['SERVER_NAME'] is not available.");
}
$this->SELFURL = $SELFURL;
$this->_sDiscofeedUrl = "$SELFURL$this->_sDiscofeedUrl";
$this->_sShibLoginUrl = "$SELFURL$this->_sShibLoginUrl";
$this->_sCachefile = dirname(__DIR__).'/'
.($aConfig['cachefile']??'discofeed.json')
;
$this->_iCacheTtl = $aConfig['cachettl']??60*60;
$this->lang = $aConfig['lang']??'en';
$this->aConfig = $aConfig;
}
/**
* Get List if IDPs from cache file if possible
* or from Shibboleth Disco feed and write a cache file
* @return array
*/
function getAllIdps(): array
{
if (!file_exists($this->_sCachefile) || filemtime($this->_sCachefile) < time() - $this->_iCacheTtl) {
// echo "DEBUG: IDP - reading from Shibboleth<br>";
$aReturn = json_decode(file_get_contents($this->_sDiscofeedUrl), 1);
if ($aReturn && is_array($aReturn)) {
// echo "DEBUG: IDP - storing cache<br>";
file_put_contents($this->_sCachefile, json_encode($aReturn));
}
} else {
// echo "DEBUG: IDP - reading cache<br>";
$aReturn = json_decode(file_get_contents($this->_sCachefile), 1);
}
return isset($aReturn) && is_array($aReturn) ? $aReturn : [];
}
/**
* Get list of active IDPs
* @return array
*/
public function getIdps(): array
{
$aAllIdps = $this->getAllIdps();
$aReturn = [];
if (is_array($aAllIdps) && count($aAllIdps)) {
foreach ($aAllIdps as $aEntry) {
$sEntityId = $aEntry['entityID'];
$sIdpDomain = parse_url($sEntityId, PHP_URL_HOST);
$sIdpTld = preg_filter('/^.*?\.([^\.]+)$/', '$1', $sIdpDomain);
if (in_array($sEntityId, $this->aConfig['idps'])) {
$idxText=0;
foreach($aEntry['DisplayNames'] as $i=>$aLangitem){
if($aLangitem['lang']==$this->lang){
$idxText=$i;
}
}
$sLabel = $aEntry['DisplayNames'][$idxText]['value'] ?? parse_url($sEntityId, PHP_URL_HOST);
$sDescription = $aEntry['Descriptions'][$idxText]['value'] ?? '';
$sKeywords = $aEntry['Keywords'][$idxText]['value'] ?? '';
$sImage = $aEntry['Logos'][1]['value'] ?? ($aEntry['Logos'][0]['value'] ?? '');
// see also https://help.switch.ch/aai/guides/discovery/login-link-composer/
$sUrl = $this->_sShibLoginUrl
. '?entityID='. urlencode($sEntityId)
. "&target=" . urlencode($sEntityId)
. "&target=" . urlencode($this->SELFURL.($aConfig['return-url']??''))
;
$sKey=$sLabel;
$aReturn[$sKey] = array_merge([
'_label' => $sLabel,
'_description' => $sDescription,
'_keywords' => $sKeywords,
'_image' => $sImage,
'_url' => $sUrl,
'_idpdomain' => $sIdpDomain,
'_tld' => $sIdpTld,
],
$aEntry
);
}
}
}
ksort($aReturn);
return array_values($aReturn);
}
}