diff --git a/classes/shibd_discofeed.class.php b/classes/shibd_discofeed.class.php new file mode 100644 index 0000000000000000000000000000000000000000..6323d812eaf36181ad04cfa82a5d2c8e9dda5336 --- /dev/null +++ b/classes/shibd_discofeed.class.php @@ -0,0 +1,101 @@ +<?php + +class shibd_discofeed +{ + protected string $SELFURL = ''; + protected string $listcache = 'discofeed.json'; + protected string $url_list = '/Shibboleth.sso/DiscoFeed'; + protected string $url_login = '/Shibboleth.sso/Login'; + protected int $ttlcache = 60*60; + + protected string $configfile = 'config.php'; + protected array $aConfig = []; + + // ---------------------------------------------------------------------- + + public function __construct(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->url_list = "$SELFURL$this->url_list"; + $this->url_login = "$SELFURL$this->url_login"; + + $this->listcache = dirname(__DIR__).'/'.$this->listcache; + $this->configfile = dirname(__DIR__).'/'.$this->configfile; + + // get the user config + if (!file_exists($this->configfile)) { + die("ERROR: config.php file does not exist yet."); + } + + $this->aConfig = require($this->configfile); + } + + /** + * 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->listcache) || filemtime($this->listcache) < time() - $this->ttlcache) { + // echo "DEBUG: IDP - reading from Shibboleth<br>"; + $aReturn = json_decode(file_get_contents($this->url_list), 1); + + if ($aReturn && is_array($aReturn)) { + // echo "DEBUG: IDP - storing cache<br>"; + file_put_contents($this->listcache, json_encode($aReturn)); + } + } else { + // echo "DEBUG: IDP - reading cache<br>"; + $aReturn = json_decode(file_get_contents($this->listcache), 1); + } + + return isset($aReturn) && is_array($aReturn) ? $aReturn : []; + } + + /** + * Get list of active IDPs + * @return mixed + */ + public function getIdps(): array + { + $aAllIdps = $this->getAllIdps(); + + $aReturn = []; + if (is_array($aAllIdps) && count($aAllIdps)) { + foreach ($aAllIdps as $aEntry) { + $sEntityId = $aEntry['entityID']; + + if (in_array($sEntityId, $this->aConfig['idps'])) { + + $sLabel = $aEntry['DisplayNames'][0]['value'] ?? parse_url($sEntityId, PHP_URL_HOST); + $sImage = $aEntry['Logos'][1]['value'] ?? ($aEntry['Logos'][0]['value'] ?? ''); + + $sUrl = $this->url_login + . '?entityID='. urlencode($sEntityId) + . "&target=" . urlencode($sEntityId) + . "&target=" . urlencode($this->SELFURL.($aConfig['return-url']??'')) + ; + + $aReturn[] = [ + 'label' => $sLabel, + 'image' => $sImage, + 'url' => $sUrl, + + // for debugging + '_entity' => $aEntry + ]; + } + } + } + return $aReturn; + } +} \ No newline at end of file