<?php
/*
* Wizard for configuring shibboleth login (lightdm greeter)
*/
const SHIB_SESSION_DATA = 'shibiddata';
class ShibAuth_Start extends AddModule_Base
{
protected function renderInternal()
{
/* Load or initialise session data */
if (Request::get('back', 'false', 'string') !== 'false') {
/* If coming via the back button, load the session data */
$session_data = Session::get(SHIB_SESSION_DATA);
if (!is_array($session_data)) {
$session_data = ['userlogin' => true];
}
} elseif ($this->edit !== null) {
$session_data = $this->edit->getData(null)
+ ['title' => $this->edit->title()];
Session::set(SHIB_SESSION_DATA, $session_data);
} else {
$session_data = ['userlogin' => true];
Session::set(SHIB_SESSION_DATA, $session_data);
}
Render::addDialog(Dictionary::translateFile('config-module', 'shibauth_title'), false, 'shibauth-start', [
'next' => 'ShibAuth_Orgs',
'edit' => $this->edit !== null ? $this->edit->id() : 0,
] + $session_data);
}
protected function ajaxInternal()
{
$ret = Shib::refreshIdpSuffixMap();
if (!$ret) {
Message::addError('shib-list-update-failed');
}
}
}
class Shibauth_Orgs extends AddModule_Base
{
private $session_data;
protected function preprocessInternal()
{
$title = trim(Request::post('title', '', 'string'));
if (empty($title)) {
Util::redirect('?do=sysconfig&action=addmodule&step=ShibAuth_Start&back=true');
}
$this->session_data = Session::get(SHIB_SESSION_DATA);
if (!is_array($this->session_data)) {
$this->session_data = [];
}
$this->session_data['title'] = $title;
$this->session_data['browser'] = !empty(Request::post('browser', '', 'string'));
$this->session_data['qrcode'] = !empty(Request::post('qrcode', '', 'string'));
$this->session_data['userlogin'] = !empty(Request::post('userlogin', '', 'string'));
Session::set(SHIB_SESSION_DATA, $this->session_data);
}
protected function renderInternal()
{
$list = array_values(Shib::getListByRegistrar());
$selected = [];
if (is_array($this->session_data['regs'])) {
$selected += array_flip(Shib::explodeRegistrars($this->session_data['regs']));
}
if (is_array($this->session_data['idp'])) {
$selected += array_flip($this->session_data['idp']);
}
foreach ($list as &$reg) {
$reg['reghash'] = substr(md5($reg['registrar']), 0, 7);
foreach ($reg['list'] as &$idp) {
$idp['idphash'] = substr(md5($idp['id']), 0, 7);
if (isset($selected[$idp['id']])) {
$idp['checked'] = 'checked';
}
}
unset($idp);
ArrayUtil::sortByColumn($reg['list'], 'name');
}
Render::addDialog(Dictionary::translateFile('config-module', 'shibauth_title'), false, 'shibauth-orgs', [
'next' => 'ShibAuth_Finish',
'edit' => $this->edit !== null ? $this->edit->id() : 0,
'list' => $list,
]);
}
}
class ShibAuth_Finish extends AddModule_Base
{
protected function preprocessInternal()
{
$userIdpList = Request::post('idp', [], 'array');
if (empty($userIdpList)) {
Message::addError('no-organization-selected');
Util::redirect('?do=sysconfig&action=addmodule&step=ShibAuth_Orgs');
}
$session_data = Session::get(SHIB_SESSION_DATA);
if (!is_array($session_data)) {
$session_data = ['idp' => $userIdpList];
Session::set(SHIB_SESSION_DATA, $session_data);
Message::addError('no-session-data');
Util::redirect('?do=sysconfig&action=addmodule&step=ShibAuth_Start&back=true');
}
/* Only create an instance if it's a new one */
if ($this->edit !== null) {
$module = $this->edit;
} else {
$module = ConfigModule::getInstance('ShibAuth');
}
// Now figure out which registrars were selected in its entirety.
// In those cases, add thr registrar instead.
$regLookup = Shib::getIdp2SuffixList();
$byReg = [];
$entireRegs = [];
// Collect by reg
foreach ($userIdpList as $idp) {
$reg = $regLookup[$idp]['regauth'] ?? 'none';
if (!isset($byReg[$reg])) {
$byReg[$reg] = [];
}
$byReg[$reg][] = $idp;
}
// Check which one matches all
$regList = Shib::getListByRegistrar();
foreach (array_keys($byReg) as $reg) {
if (!isset($regList[$reg]))
continue;
if (count ($regList[$reg]['list']) === count($byReg[$reg])) {
$entireRegs[] = $reg;
unset ($byReg[$reg]);
error_log("Entire registrar $reg");
}
}
// Build final IDP list by combining the remaining ones again
$userIdpList = [];
foreach ($byReg as $idps) {
$userIdpList = array_merge($userIdpList, $idps);
}
/* Set all the data to the module instance */
$module->setData('browser', $session_data['browser']);
$module->setData('qrcode', $session_data['qrcode']);
$module->setData('userlogin', $session_data['userlogin']);
$module->setData('idp', $userIdpList);
$module->setData('regs', $entireRegs);
/* Insert or update database entries */
if ($this->edit !== null) {
$module->update($session_data['title']);
} else {
$module->insert($session_data['title']);
}
$task = $module->generate($this->edit === null);
// Yay
Session::set(SHIB_SESSION_DATA, false);
if ($task !== false && $this->edit !== null) {
Message::addSuccess('module-edited');
} elseif ($task !== false) {
Message::addSuccess('module-added');
AddModule_Base::setStep('AddModule_Assign', $module->id());
return;
}
Util::redirect('?do=SysConfig');
}
protected function renderInternal()
{
}
}