forked from extern/egroupware
* SAML/Shibboleth/SimpleSAMLphp authentication configurable through setup
This commit is contained in:
parent
b5dceda99c
commit
b1f79d1c40
@ -68,6 +68,9 @@ $setup_info['api']['hooks']['vfs_unlink'] = 'EGroupware\\Api\\Vfs\\Sharing::vfsU
|
|||||||
$setup_info['api']['hooks']['vfs_rename'] = 'EGroupware\\Api\\Vfs\\Sharing::vfsUpdate';
|
$setup_info['api']['hooks']['vfs_rename'] = 'EGroupware\\Api\\Vfs\\Sharing::vfsUpdate';
|
||||||
$setup_info['api']['hooks']['vfs_rmdir'] = 'EGroupware\\Api\\Vfs\\Sharing::vfsUpdate';
|
$setup_info['api']['hooks']['vfs_rmdir'] = 'EGroupware\\Api\\Vfs\\Sharing::vfsUpdate';
|
||||||
|
|
||||||
|
// hook to update SimpleSAMLphp config
|
||||||
|
$setup_info['api']['hooks']['setup_config'] = \EGroupware\Api\Auth\Saml::class.'::setupConfig';
|
||||||
|
|
||||||
// installation checks
|
// installation checks
|
||||||
$setup_info['api']['check_install'] = array(
|
$setup_info['api']['check_install'] = array(
|
||||||
'' => array(
|
'' => array(
|
||||||
|
@ -67,6 +67,12 @@ class Auth
|
|||||||
*/
|
*/
|
||||||
static function backend($type=null)
|
static function backend($type=null)
|
||||||
{
|
{
|
||||||
|
// do we have a hostname specific auth type set
|
||||||
|
if (is_null($type) && !empty($GLOBALS['egw_info']['server']['auth_type_host']) &&
|
||||||
|
Header\Http::host() === $GLOBALS['egw_info']['server']['auth_type_hostname'])
|
||||||
|
{
|
||||||
|
$type = $GLOBALS['egw_info']['server']['auth_type_host'];
|
||||||
|
}
|
||||||
if (is_null($type)) $type = $GLOBALS['egw_info']['server']['auth_type'];
|
if (is_null($type)) $type = $GLOBALS['egw_info']['server']['auth_type'];
|
||||||
|
|
||||||
$backend_class = __CLASS__.'\\'.ucfirst($type);
|
$backend_class = __CLASS__.'\\'.ucfirst($type);
|
||||||
|
@ -109,6 +109,14 @@ class Saml implements BackendSSO
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some urn:oid constants for common attributes
|
||||||
|
*/
|
||||||
|
const eduPersonPricipalName = 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6';
|
||||||
|
const emailAddress = 'urn:oid:0.9.2342.19200300.100.1.1';
|
||||||
|
const firstName = 'urn:oid:2.5.4.42';
|
||||||
|
const lastName = 'urn:oid:2.5.4.4';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt SSO login
|
* Attempt SSO login
|
||||||
*
|
*
|
||||||
@ -126,16 +134,24 @@ class Saml implements BackendSSO
|
|||||||
|
|
||||||
// get attributes for (automatic) account creation
|
// get attributes for (automatic) account creation
|
||||||
$attrs = $as->getAttributes();
|
$attrs = $as->getAttributes();
|
||||||
$user = $attrs['urn:oid:0.9.2342.19200300.100.1.1'][0];
|
$username = $attrs[self::usernameOid()][0];
|
||||||
$GLOBALS['egw_info']['server']['auto_create_acct'] = true;
|
|
||||||
$GLOBALS['auto_create_acct'] = [
|
|
||||||
'firstname' => $attrs['urn:oid:2.5.4.42'][0],
|
|
||||||
'lastname' => $attrs['urn:oid:2.5.4.4'][0],
|
|
||||||
'email' => $attrs['urn:oid:0.9.2342.19200300.100.1.3'][0],
|
|
||||||
];
|
|
||||||
|
|
||||||
|
// check if user already exists
|
||||||
|
if (!$GLOBALS['egw']->accounts->name2id($username, 'account_lid', 'u'))
|
||||||
|
{
|
||||||
|
// fail if auto-creation of authenticated users is NOT configured
|
||||||
|
if (empty($GLOBALS['egw_info']['server']['auto_create_acct']))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$GLOBALS['auto_create_acct'] = [
|
||||||
|
'firstname' => $attrs[self::firstName][0],
|
||||||
|
'lastname' => $attrs[self::lastName][0],
|
||||||
|
'email' => $attrs[self::emailAddress][0],
|
||||||
|
];
|
||||||
|
}
|
||||||
// return user session
|
// return user session
|
||||||
return $GLOBALS['egw']->session->create($user, null, null, false, false);
|
return $GLOBALS['egw']->session->create($username, null, null, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -159,31 +175,200 @@ class Saml implements BackendSSO
|
|||||||
{
|
{
|
||||||
return ['SimpleSAMLphp_SESSION'];
|
return ['SimpleSAMLphp_SESSION'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ASYNC_JOB_ID = 'saml_metadata_refresh';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook called when setup configuration is being stored:
|
||||||
|
* - updating SimpleSAMLphp config files
|
||||||
|
* - creating/removing cron job to refresh metadata
|
||||||
|
*
|
||||||
|
* @param array $location key "newsettings" with reference to changed settings from setup > configuration
|
||||||
|
* @throws \Exception for errors
|
||||||
|
*/
|
||||||
|
public static function setupConfig(array $location)
|
||||||
|
{
|
||||||
|
$config =& $location['newsettings'];
|
||||||
|
|
||||||
|
/*error_log(__METHOD__."() ".json_encode(array_filter($config, function($value, $key) {
|
||||||
|
return substr($key, 0, 5) === 'saml_' || $key === 'auth_type';
|
||||||
|
}, ARRAY_FILTER_USE_BOTH), JSON_UNESCAPED_SLASHES));*/
|
||||||
|
|
||||||
|
if ($newsettings['auth_type'] !== 'saml') return; // nothing to do
|
||||||
|
|
||||||
|
if (file_exists($config['files_dir'].'/saml/config.php'))
|
||||||
|
{
|
||||||
|
self::updateConfig($config);
|
||||||
|
}
|
||||||
|
self::checkDefaultConfig($config);
|
||||||
|
|
||||||
|
// install or remove async job to refresh metadata
|
||||||
|
static $freq2times = [
|
||||||
|
'hourly' => ['min' => 4], // hourly at minute 4
|
||||||
|
'daily' => ['min' => 4, 'hour' => 4], // daily at 4:04am
|
||||||
|
'weekly' => ['min' => 4, 'hour' => 4, 'dow' => 5], // Saturdays as 4:04am
|
||||||
|
];
|
||||||
|
$async = new Api\Asyncservice();
|
||||||
|
if (isset($freq2times[$config['saml_metadata_refresh']]) &&
|
||||||
|
preg_match('|^https://|', $config['saml_metadata']))
|
||||||
|
{
|
||||||
|
$async->set_timer($freq2times[$config['saml_metadata_refresh']], self::ASYNC_JOB_ID, self::class.'::refreshMetadata');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$async->cancel_timer(self::ASYNC_JOB_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($config['saml_metadata_refresh'] !== 'no')
|
||||||
|
{
|
||||||
|
self::refreshMetadata($config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh metadata
|
||||||
|
*
|
||||||
|
* @param array|null $config defaults to $GLOBALS['egw_info']['server']
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public static function refreshMetadata(array $config=null)
|
||||||
|
{
|
||||||
|
if (!isset($config)) $config = $GLOBALS['egw_info']['server'];
|
||||||
|
$old_config = Api\Config::read('phpgwapi');
|
||||||
|
|
||||||
|
$saml_config = $config['files_dir'].'/saml';
|
||||||
|
SimpleSAML\Configuration::setConfigDir($saml_config);
|
||||||
|
|
||||||
|
$source = [
|
||||||
|
'src' => $config['saml_metadata'],
|
||||||
|
'whitelist' => [$config['saml_idp']], // only ready our idp, the whole thing can be huge
|
||||||
|
];
|
||||||
|
if (!empty($config['saml_certificate']))
|
||||||
|
{
|
||||||
|
$cert = $saml_config.'/cert/'.basename(parse_url($config['saml_certificate'], PHP_URL_PATH));
|
||||||
|
if ((!file_exists($cert) || $config['saml_certificate'] !== $old_config['saml_certificate']) &&
|
||||||
|
(!($content = file_get_contents($config['saml_certificate'])) ||
|
||||||
|
!file_put_contents($cert, $content)))
|
||||||
|
{
|
||||||
|
throw new \Exception("Could not load certificate from $config[saml_certificate]!");
|
||||||
|
}
|
||||||
|
$source['certificate'] = $cert;
|
||||||
|
}
|
||||||
|
$metaloader = new SimpleSAML\Module\metarefresh\MetaLoader();
|
||||||
|
$metaloader->loadSource($source);
|
||||||
|
$metaloader->writeMetadataFiles($saml_config.'/metadata');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update config files
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
*/
|
||||||
|
public static function updateConfig(array $config)
|
||||||
|
{
|
||||||
|
// some Api classes require the config in $GLOBALS['egw_info']['server']
|
||||||
|
$GLOBALS['egw_info']['server']['webserver_url'] = $config['webserver_url'];
|
||||||
|
$GLOBALS['egw_info']['server']['usecookies'] = true;
|
||||||
|
$config['baseurlpath'] = Api\Framework::getUrl(Api\Egw::link('/saml/'));
|
||||||
|
$config['username_oid'] = [self::usernameOid($config)];
|
||||||
|
|
||||||
|
// update config.php and default-sp in authsources.php
|
||||||
|
foreach([
|
||||||
|
'authsources.php' => [
|
||||||
|
'saml_idp' => "/('default-sp' => *\\[.*?'idp' => *).*?$/ms",
|
||||||
|
'saml_sp' => "/('default-sp' => *\\[.*?'name' => *\\[.*?'en' => *).*?$/ms",
|
||||||
|
'username_oid' => "/('default-sp' => *\\[.*?'attributes.required' => *)\\[.*?\\],$/ms",
|
||||||
|
],
|
||||||
|
'config.php' => [
|
||||||
|
'baseurlpath' => "/('baseurlpath' => *).*?$/ms",
|
||||||
|
'saml_contact_name' => "/('technicalcontact_name' => *).*?$/ms",
|
||||||
|
'saml_contact_email' => "/('technicalcontact_email' => *).*?$/ms",
|
||||||
|
]
|
||||||
|
] as $file => $replacements)
|
||||||
|
{
|
||||||
|
if (file_exists($path = $config['files_dir'] . '/saml/'.$file) &&
|
||||||
|
($content = file_get_contents($path)))
|
||||||
|
{
|
||||||
|
foreach($replacements as $conf => $reg_exp)
|
||||||
|
{
|
||||||
|
$content = preg_replace($reg_exp, '$1' . (is_array($config[$conf]) ?
|
||||||
|
"[".implode(',', array_map(self::class.'::quote', $config[$conf]))."]" :
|
||||||
|
self::quote($config[$conf])) . ',', $content);
|
||||||
|
}
|
||||||
|
if (!file_put_contents($path, $content))
|
||||||
|
{
|
||||||
|
throw new \Exception("Failed to update '$path'!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|null $str
|
||||||
|
* @param string $empty=null default value, if $str is empty
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function quote($str, $empty=null)
|
||||||
|
{
|
||||||
|
return $str || isset($empty) ? "'".addslashes($str ?: $empty)."'" : 'null';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the urn:oid of the username
|
||||||
|
*
|
||||||
|
* @param array|null $config
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function usernameOid(array $config=null)
|
||||||
|
{
|
||||||
|
if (!isset($config)) $config = $GLOBALS['egw_info']['server'];
|
||||||
|
|
||||||
|
switch($config['saml_username'])
|
||||||
|
{
|
||||||
|
case 'eduPersonPrincipalName':
|
||||||
|
return self::eduPersonPricipalName;
|
||||||
|
case 'emailAddress':
|
||||||
|
return self::emailAddress;
|
||||||
|
case 'customOid':
|
||||||
|
return $config['saml_username_oid'] ?: self::emailAddress;
|
||||||
|
}
|
||||||
|
return self::emailAddress;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create simpleSAMLphp default configuration
|
* Create simpleSAMLphp default configuration
|
||||||
*
|
*
|
||||||
|
* @param array $config=null default $GLOBALS['egw_info']['server']
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function checkDefaultConfig()
|
public static function checkDefaultConfig(array $config=null)
|
||||||
{
|
{
|
||||||
|
if (!isset($config)) $config = $GLOBALS['egw_info']['server'];
|
||||||
|
|
||||||
|
// some Api classes require the config in $GLOBALS['egw_info']['server']
|
||||||
|
$GLOBALS['egw_info']['server']['webserver_url'] = $config['webserver_url'];
|
||||||
|
$GLOBALS['egw_info']['server']['usecookies'] = true;
|
||||||
|
|
||||||
// use "saml" subdirectory of EGroupware files directory as simpleSAMLphp config-directory
|
// use "saml" subdirectory of EGroupware files directory as simpleSAMLphp config-directory
|
||||||
$config_dir = $GLOBALS['egw_info']['server']['files_dir'].'/saml';
|
$config_dir = $config['files_dir'].'/saml';
|
||||||
if (!file_exists($config_dir) && !mkdir($config_dir))
|
if (!file_exists($config_dir) && !mkdir($config_dir))
|
||||||
{
|
{
|
||||||
throw new Exception("Can't create SAML config directory '$config_dir'!");
|
throw new Exception("Can't create SAML config directory '$config_dir'!");
|
||||||
}
|
}
|
||||||
SimpleSAML\Configuration::setConfigDir($config_dir);
|
SimpleSAML\Configuration::setConfigDir($config_dir);
|
||||||
|
|
||||||
// create a default configuration
|
// check if all necessary directories exist, if not create them
|
||||||
if ((!file_exists($config_dir.'/config.php') || filesize($config_dir.'/config.php') < 1000))
|
foreach(['cert', 'log', 'data', 'metadata', 'tmp'] as $dir)
|
||||||
{
|
{
|
||||||
foreach(['cert', 'log', 'data', 'metadata'] as $dir)
|
if (!file_exists($config_dir.'/'.$dir) && !mkdir($config_dir.'/'.$dir, 700, true))
|
||||||
{
|
{
|
||||||
if (!file_exists($config_dir.'/'.$dir) && !mkdir($config_dir.'/'.$dir, 700, true))
|
throw new Exception("Can't create $dir-directory '$config_dir/$dir'!");
|
||||||
{
|
|
||||||
throw new Exception("Can't create $dir-directory '$config_dir/$dir'!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a default configuration
|
||||||
|
if (!file_exists($config_dir.'/config.php') || filesize($config_dir.'/config.php') < 1000)
|
||||||
|
{
|
||||||
// create a key-pair
|
// create a key-pair
|
||||||
$cert_dir = $config_dir.'/cert';
|
$cert_dir = $config_dir.'/cert';
|
||||||
$private_key_path = $cert_dir.'/saml.pem';
|
$private_key_path = $cert_dir.'/saml.pem';
|
||||||
@ -229,44 +414,72 @@ class Saml implements BackendSSO
|
|||||||
{
|
{
|
||||||
case 'config.php':
|
case 'config.php':
|
||||||
$cookie_domain = Api\Session::getCookieDomain($cookie_path, $cookie_secure);
|
$cookie_domain = Api\Session::getCookieDomain($cookie_path, $cookie_secure);
|
||||||
if (!file_put_contents($config_dir.'/'.$file,
|
$replacements = [
|
||||||
$c=strtr($t=file_get_contents($path), [
|
"'baseurlpath' => 'simplesaml/'," => "'baseurlpath' => '".Api\Framework::getUrl(Api\Egw::link('/saml/'))."',",
|
||||||
"'baseurlpath' => 'simplesaml/'," => "'baseurlpath' => '".Api\Framework::getUrl(Api\Egw::link('/saml/'))."',",
|
"'timezone' => null," => "'timezone' => 'Europe/Berlin',", // ToDo: use default prefs
|
||||||
"'timezone' => null," => "'timezone' => 'Europe/Berlin',", // ToDo: use default prefs
|
"'secretsalt' => 'defaultsecretsalt'," => "'secretsalt' => '".Api\Auth::randomstring(32)."',",
|
||||||
"'secretsalt' => 'defaultsecretsalt'" => "'secretsalt' => '".Api\Auth::randomstring(32)."',",
|
"'auth.adminpassword' => '123'," => "'auth.adminpassword' => '".Api\Auth::randomstring(12)."',",
|
||||||
"'auth.adminpassword' => '123'," => "'auth.adminpassword' => '".Api\Auth::randomstring(12)."',",
|
"'admin.protectindexpage' => false," => "'admin.protectindexpage' => true,",
|
||||||
"'admin.protectindexpage' => false," => "'admin.protectindexpage' => true,",
|
"'certdir' => 'cert/'," => "'certdir' => __DIR__.'/cert/',",
|
||||||
"'certdir' => 'cert/'," => "'certdir' => __DIR__.'/cert/',",
|
"'loggingdir' => 'log/'," => "'loggingdir' => __DIR__.'/log/',",
|
||||||
"'loggingdir' => 'log/'," => "'loggingdir' => __DIR__.'/log/',",
|
"'datadir' => 'data/'," => "'datadir' => __DIR__.'/data/',",
|
||||||
"'datadir' => 'data/'," => "'datadir' => __DIR__.'/data/',",
|
"'tempdir' => '/tmp/simplesaml'," => "'tempdir' => __DIR__.'/tmp',",
|
||||||
"'tempdir' => '/tmp/simplesaml'," => "'tempdir' => \$GLOBALS['egw_info']['server']['temp_dir'],",
|
"'metadatadir' => 'metadata'," => "'metadatadir' => __DIR__.'/metadata',",
|
||||||
"'metadatadir' => 'metadata'," => "'metadatadir' => __DIR__.'/metadata',",
|
"'logging.handler' => 'syslog'," => "'logging.handler' => 'errorlog',",
|
||||||
"'logging.handler' => 'syslog'," => "'logging.handler' => 'errorlog',",
|
"'technicalcontact_name' => 'Administrator'" =>
|
||||||
"'metadata.sign.privatekey' => null," => "'metadata.sign.privatekey' => 'saml.pem',",
|
"'technicalcontact_name' => ".self::quote($config['saml_contact_name'], 'Administrator'),
|
||||||
//"'metadata.sign.privatekey_pass' => null," => "",
|
"'technicalcontact_email' => 'na@example.org'" =>
|
||||||
"'metadata.sign.certificate' => null," => "'metadata.sign.privatekey' => 'saml.crt',",
|
"'technicalcontact_email' => ".self::quote($config['saml_contact_email'], 'na@example.org'),
|
||||||
//"'metadata.sign.algorithm' => null," => "",
|
"'metadata.sign.privatekey' => null," => "'metadata.sign.privatekey' => 'saml.pem',",
|
||||||
// we have to use EGroupware session/cookie parameters
|
//"'metadata.sign.privatekey_pass' => null," => "",
|
||||||
"'session.cookie.name' => 'SimpleSAMLSessionID'," => "'session.cookie.name' => 'sessionid',",
|
"'metadata.sign.certificate' => null," => "'metadata.sign.certificate' => 'saml.crt',",
|
||||||
"'session.cookie.path' => '/'," => "'session.cookie.path' => '$cookie_path',",
|
//"'metadata.sign.algorithm' => null," => "",
|
||||||
"'session.cookie.domain' => null," => "'session.cookie.domain' => '$cookie_domain',",
|
// we have to use EGroupware session/cookie parameters
|
||||||
"'session.cookie.secure' => false," => "'session.cookie.secure' => ".($cookie_secure ? 'true' : 'false').',',
|
"'session.cookie.name' => 'SimpleSAMLSessionID'," => "'session.cookie.name' => 'sessionid',",
|
||||||
"'session.phpsession.cookiename' => 'SimpleSAML'," => "'session.phpsession.cookiename' => 'sessionid',",
|
"'session.cookie.path' => '/'," => "'session.cookie.path' => '$cookie_path',",
|
||||||
])))
|
"'session.cookie.domain' => null," => "'session.cookie.domain' => '.$cookie_domain',",
|
||||||
{
|
"'session.cookie.secure' => false," => "'session.cookie.secure' => ".($cookie_secure ? 'true' : 'false').',',
|
||||||
header('Content-Type: text/plain');
|
"'session.phpsession.cookiename' => 'SimpleSAML'," => "'session.phpsession.cookiename' => 'sessionid',",
|
||||||
echo "template:\n$t\n\nconfig:\n$c\n\n";
|
];
|
||||||
throw new Exception("Can't write SAML config file '$config_dir/config.php'!");
|
break;
|
||||||
}
|
|
||||||
|
case 'authsources.php':
|
||||||
|
$replacements = [
|
||||||
|
"'idp' => null," => "'idp' => ".self::quote($config['saml_idp']).',',
|
||||||
|
"'discoURL' => null," => "'discoURL' => null,\n\n".
|
||||||
|
// add our private and public keys
|
||||||
|
"\t'privatekey' => 'saml.pem',\n\n".
|
||||||
|
"\t// to include certificate in metadata\n".
|
||||||
|
"\t'certificate' => 'saml.crt',\n\n".
|
||||||
|
"\t'name' => [\n".
|
||||||
|
"\t\t'en' => ".self::quote($config['saml_sp'] ?: 'EGroupware').",\n".
|
||||||
|
"\t],\n\n".
|
||||||
|
"\t'attributes' => [\n".
|
||||||
|
"\t\t'eduPersonPricipalName' => '".self::eduPersonPricipalName."',\n".
|
||||||
|
"\t\t'emailAddress' => '".self::emailAddress."',\n".
|
||||||
|
"\t\t'firstName' => '".self::firstName."',\n".
|
||||||
|
"\t\t'lastName' => '".self::lastName."',\n".
|
||||||
|
"\t],\n".
|
||||||
|
"\t'attributes.required' => [".self::quote(self::usernameOid($config))."],",
|
||||||
|
];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
unset($replacements);
|
||||||
if (!copy($path, $config_dir.'/'.$file))
|
if (!copy($path, $config_dir.'/'.$file))
|
||||||
{
|
{
|
||||||
throw new Exception("Can't copy SAML config file '$config_dir/$file'!");
|
throw new Exception("Can't copy SAML config file '$config_dir/$file'!");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (isset($replacements) &&
|
||||||
|
!file_put_contents($config_dir.'/'.$file,
|
||||||
|
$c=strtr($t=file_get_contents($path), $replacements)))
|
||||||
|
{
|
||||||
|
header('Content-Type: text/plain');
|
||||||
|
echo "<pre>template:\n$t\n\nconfig:\n$c\n</pre>\n";
|
||||||
|
throw new Exception("Can't write SAML config file '$config_dir/config.php'!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
foreach(glob($simplesaml_dir.'/metadata-templates/*.php') as $path)
|
foreach(glob($simplesaml_dir.'/metadata-templates/*.php') as $path)
|
||||||
{
|
{
|
||||||
|
32
composer.lock
generated
32
composer.lock
generated
@ -852,12 +852,12 @@
|
|||||||
{
|
{
|
||||||
"name": "Chuck Hagenbuch",
|
"name": "Chuck Hagenbuch",
|
||||||
"email": "chuck@horde.org",
|
"email": "chuck@horde.org",
|
||||||
"role": "Lead"
|
"role": "lead"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Jan Schneider",
|
"name": "Jan Schneider",
|
||||||
"email": "jan@horde.org",
|
"email": "jan@horde.org",
|
||||||
"role": "Lead"
|
"role": "lead"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Michael J Rubinsky",
|
"name": "Michael J Rubinsky",
|
||||||
@ -904,7 +904,7 @@
|
|||||||
],
|
],
|
||||||
"description": "Compiled version of magicsuggest customized for EGroupware project.",
|
"description": "Compiled version of magicsuggest customized for EGroupware project.",
|
||||||
"homepage": "https://github.com/EGroupware/magicsuggest",
|
"homepage": "https://github.com/EGroupware/magicsuggest",
|
||||||
"time": "2018-06-21T13:36:37+00:00"
|
"time": "2018-06-21T10:14:03+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "egroupware/news_admin",
|
"name": "egroupware/news_admin",
|
||||||
@ -2046,7 +2046,7 @@
|
|||||||
"license": [
|
"license": [
|
||||||
"LGPL-2.1"
|
"LGPL-2.1"
|
||||||
],
|
],
|
||||||
"description": "A library to wrap various compression techniques."
|
"description": "An API for various compression techniques."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "pear-pear.horde.org/Horde_Crypt",
|
"name": "pear-pear.horde.org/Horde_Crypt",
|
||||||
@ -2112,7 +2112,7 @@
|
|||||||
"license": [
|
"license": [
|
||||||
"LGPL-2.1"
|
"LGPL-2.1"
|
||||||
],
|
],
|
||||||
"description": "A library that provides blowfish encryption/decryption for PHP string data."
|
"description": "Provides blowfish encryption/decryption for PHP string data."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "pear-pear.horde.org/Horde_Date",
|
"name": "pear-pear.horde.org/Horde_Date",
|
||||||
@ -2228,7 +2228,7 @@
|
|||||||
"license": [
|
"license": [
|
||||||
"BSD-2-Clause"
|
"BSD-2-Clause"
|
||||||
],
|
],
|
||||||
"description": "A library that wraps various backends providing IDNA (Internationalized Domain Names in Applications) support."
|
"description": "Normalized access to various backends providing IDNA (Internationalized Domain Names in Applications) support."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "pear-pear.horde.org/Horde_Imap_Client",
|
"name": "pear-pear.horde.org/Horde_Imap_Client",
|
||||||
@ -2266,7 +2266,7 @@
|
|||||||
"license": [
|
"license": [
|
||||||
"LGPL-2.1"
|
"LGPL-2.1"
|
||||||
],
|
],
|
||||||
"description": "A library to access IMAP4rev1 (RFC 3501) mail servers. Also supports connections to POP3 (STD 53/RFC 1939)."
|
"description": "Interface to access IMAP4rev1 (RFC 3501) mail servers. Also supports connections to POP3 (STD 53/RFC 1939)."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "pear-pear.horde.org/Horde_ListHeaders",
|
"name": "pear-pear.horde.org/Horde_ListHeaders",
|
||||||
@ -2546,7 +2546,7 @@
|
|||||||
"license": [
|
"license": [
|
||||||
"LGPL-2.1"
|
"LGPL-2.1"
|
||||||
],
|
],
|
||||||
"description": "A library that provides an abstract PHP network socket client."
|
"description": "Provides abstract class for use in creating PHP network socket clients."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "pear-pear.horde.org/Horde_Stream",
|
"name": "pear-pear.horde.org/Horde_Stream",
|
||||||
@ -2687,7 +2687,7 @@
|
|||||||
"license": [
|
"license": [
|
||||||
"LGPL-2.1"
|
"LGPL-2.1"
|
||||||
],
|
],
|
||||||
"description": "A library that provides a text-based diff engine and renderers for multiple diff output formats."
|
"description": "A text-based diff engine and renderers for multiple diff output formats."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "pear-pear.horde.org/Horde_Text_Flowed",
|
"name": "pear-pear.horde.org/Horde_Text_Flowed",
|
||||||
@ -2715,7 +2715,7 @@
|
|||||||
"license": [
|
"license": [
|
||||||
"LGPL-2.1"
|
"LGPL-2.1"
|
||||||
],
|
],
|
||||||
"description": "A library that provides common methods for manipulating text using the encoding described in RFC 3676 ('flowed' text)."
|
"description": "The Horde_Text_Flowed:: class provides common methods for manipulating text using the encoding described in RFC 3676 ('flowed' text)."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "pear-pear.horde.org/Horde_Translation",
|
"name": "pear-pear.horde.org/Horde_Translation",
|
||||||
@ -2798,7 +2798,7 @@
|
|||||||
"license": [
|
"license": [
|
||||||
"LGPL-2.1"
|
"LGPL-2.1"
|
||||||
],
|
],
|
||||||
"description": "A library that provides functionality useful for all kind of applications."
|
"description": "These classes provide functionality useful for all kind of applications."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "pear/archive_tar",
|
"name": "pear/archive_tar",
|
||||||
@ -4029,16 +4029,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "simplesamlphp/simplesamlphp",
|
"name": "simplesamlphp/simplesamlphp",
|
||||||
"version": "v1.18.6",
|
"version": "v1.18.7",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/simplesamlphp/simplesamlphp.git",
|
"url": "https://github.com/simplesamlphp/simplesamlphp.git",
|
||||||
"reference": "9fd1c3c5e5f9e6fed8de3c36e14ccdcce31e3dc7"
|
"reference": "c62e32c807d50ada1fd6f4792e2054a0471100ad"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/simplesamlphp/simplesamlphp/zipball/9fd1c3c5e5f9e6fed8de3c36e14ccdcce31e3dc7",
|
"url": "https://api.github.com/repos/simplesamlphp/simplesamlphp/zipball/c62e32c807d50ada1fd6f4792e2054a0471100ad",
|
||||||
"reference": "9fd1c3c5e5f9e6fed8de3c36e14ccdcce31e3dc7",
|
"reference": "c62e32c807d50ada1fd6f4792e2054a0471100ad",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -4150,7 +4150,7 @@
|
|||||||
"sp",
|
"sp",
|
||||||
"ws-federation"
|
"ws-federation"
|
||||||
],
|
],
|
||||||
"time": "2020-04-16T13:40:56+00:00"
|
"time": "2020-05-12T12:24:31+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "simplesamlphp/simplesamlphp-module-adfs",
|
"name": "simplesamlphp/simplesamlphp-module-adfs",
|
||||||
|
@ -60,6 +60,18 @@ if(@$_POST['submit'] && @$newsettings)
|
|||||||
/* Load hook file with functions to validate each config (one/none/all) */
|
/* Load hook file with functions to validate each config (one/none/all) */
|
||||||
$GLOBALS['egw_setup']->hook('config_validate','setup');
|
$GLOBALS['egw_setup']->hook('config_validate','setup');
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// allow apps to register hooks throwing Exceptions for errors
|
||||||
|
Api\Hooks::process([
|
||||||
|
'location' => 'setup_config',
|
||||||
|
'newsettings' => &$newsettings,
|
||||||
|
], [], true);
|
||||||
|
}
|
||||||
|
catch (\Exception $e) {
|
||||||
|
$GLOBALS['error'] .= '<b>'.$e->getMessage()."</b><br />\n";
|
||||||
|
}
|
||||||
|
|
||||||
$newsettings['tz_offset'] = date('Z')/3600;
|
$newsettings['tz_offset'] = date('Z')/3600;
|
||||||
|
|
||||||
$GLOBALS['egw_setup']->db->transaction_begin();
|
$GLOBALS['egw_setup']->db->transaction_begin();
|
||||||
|
@ -182,6 +182,10 @@ function auth_type_activesync($config)
|
|||||||
{
|
{
|
||||||
return _options_from(setup_cmd_config::auth_types(),$config['auth_type_activesync']);
|
return _options_from(setup_cmd_config::auth_types(),$config['auth_type_activesync']);
|
||||||
}
|
}
|
||||||
|
function auth_type_host($config)
|
||||||
|
{
|
||||||
|
return _options_from(setup_cmd_config::auth_types(),$config['auth_type_host']);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make account-repository-types from setup_cmd_config available
|
* Make account-repository-types from setup_cmd_config available
|
||||||
|
@ -123,7 +123,7 @@
|
|||||||
<td colspan="2"><b>{lang_Authentication_/_Accounts}</b></td>
|
<td colspan="2"><b>{lang_Authentication_/_Accounts}</b></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr class="row_off">
|
<tr class="row_on">
|
||||||
<td>{lang_Select_which_type_of_authentication_you_are_using}:</td>
|
<td>{lang_Select_which_type_of_authentication_you_are_using}:</td>
|
||||||
<td>
|
<td>
|
||||||
<select name="newsettings[auth_type]">
|
<select name="newsettings[auth_type]">
|
||||||
@ -132,7 +132,7 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr class="row_on">
|
<tr class="row_off">
|
||||||
<td>{lang_Authentication_type_for_application}: <b>CalDAV/CardDAV Sync</b></td>
|
<td>{lang_Authentication_type_for_application}: <b>CalDAV/CardDAV Sync</b></td>
|
||||||
<td>
|
<td>
|
||||||
<select name="newsettings[auth_type_groupdav]">
|
<select name="newsettings[auth_type_groupdav]">
|
||||||
@ -142,7 +142,7 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr class="row_off">
|
<tr class="row_on">
|
||||||
<td>{lang_Authentication_type_for_application}: <b>eSync (ActiveSync)</b></td>
|
<td>{lang_Authentication_type_for_application}: <b>eSync (ActiveSync)</b></td>
|
||||||
<td>
|
<td>
|
||||||
<select name="newsettings[auth_type_activesync]">
|
<select name="newsettings[auth_type_activesync]">
|
||||||
@ -152,6 +152,19 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr class="row_off">
|
||||||
|
<td>
|
||||||
|
{lang_Authentication_type_for_HTTP_Host}:
|
||||||
|
<input name="newsettings[auth_type_hostname]" value="{value_auth_type_hostname}" size="40"/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<select name="newsettings[auth_type_host]">
|
||||||
|
<option value="">{lang_Standard,_as_defined_above}</option>
|
||||||
|
{hook_auth_type_host}
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<tr class="row_on">
|
<tr class="row_on">
|
||||||
<td>{lang_HTTP_auth_types_(comma-separated)_to_use_without_login-page, eg. "NTLM"}:</td>
|
<td>{lang_HTTP_auth_types_(comma-separated)_to_use_without_login-page, eg. "NTLM"}:</td>
|
||||||
<td>
|
<td>
|
||||||
@ -461,6 +474,74 @@
|
|||||||
<td colspan="2"> </td>
|
<td colspan="2"> </td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr class="th">
|
||||||
|
<td colspan="2"><b>{lang_If_using_SAML_2.0 / Shibboleth / SimpleSAMLphp}:</b></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="row_on">
|
||||||
|
<td>{lang_Identity_Provider}:</td>
|
||||||
|
<td><input name="newsettings[saml_idp]" placeholder="https://idp.rhrk.uni-kl.de/idp/shibboleth" value="{value_saml_idp}" size="64" /></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="row_off">
|
||||||
|
<td>
|
||||||
|
{lang_Metadata}:
|
||||||
|
{lang_refresh}
|
||||||
|
<select name="newsettings[saml_metadata_refresh]">
|
||||||
|
<option value="daily"{selected_saml_metadata_refresh_daily}>{lang_daily}</option>
|
||||||
|
<option value="weekly"{selected_saml_metadata_refresh_weekly}>{lang_weekly}</option>
|
||||||
|
<option value="hourly"{selected_saml_metadata_refresh_hourly}>{lang_hourly}</option>
|
||||||
|
<option value="no"{selected_saml_metadata_refresh_no}>{lang_not_automatic}</option>
|
||||||
|
<option value="now"{selected_saml_metadata_refresh_now}>{lang_just_now}</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input name="newsettings[saml_metadata]" placeholder="https://www.aai.dfn.de/fileadmin/metadata/dfn-aai-metadata.xml" value="{value_saml_metadata}" size="64" /><br/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="row_on">
|
||||||
|
<td>{lang_Certificate_Metadata_is_signed_with}: ({lang_Will_be_downloaded_once,_unless_changed.})</td>
|
||||||
|
<td><input name="newsettings[saml_certificate]" placeholder="https://www.aai.dfn.de/fileadmin/metadata/dfn-aai.pem" value="{value_saml_certificate}" size="64" /></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="row_off">
|
||||||
|
<td>{lang_Result_data_to_use_as_username}:</td>
|
||||||
|
<td>
|
||||||
|
<select name="newsettings[saml_username]">
|
||||||
|
<option value="eduPersonPrincipalName"{selected_saml_username_eduPersonPrincipalName}>eduPersonPrincipalName</option>
|
||||||
|
<option value="emailAddress"{selected_saml_username_emailAddress}>emailAddress</option>
|
||||||
|
<option value="custom"{selected_saml_username_customOid}>{lang_custom_OID}</option>
|
||||||
|
</select>
|
||||||
|
<input name="newsettings[saml_username_oid]" value="{value_saml_username_oid}" placeholder="urn:oid:x.x.x.x" size="40" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="row_on" height="25">
|
||||||
|
<td>{lang_Some_information_for_the_own_Service_Provider_metadata}:</td>
|
||||||
|
<td><a href="{value_webserver_url}/saml/module.php/saml/sp/metadata.php/default-sp">{lang_Metadata_URL}</a></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="row_off">
|
||||||
|
<td>{lang_Name_for_Service_Provider}:</td>
|
||||||
|
<td><input name="newsettings[saml_sp]" placeholder="EGroupware" value="{value_saml_sp}" size="40" /></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="row_on">
|
||||||
|
<td>{lang_Technical_contact}:</td>
|
||||||
|
<td>
|
||||||
|
<input name="newsettings[saml_contact_name]" value="{value_saml_contact_name}" placeholder="{lang_Name}" size="24" />
|
||||||
|
<input name="newsettings[saml_contact_email]" value="{value_saml_contact_email}" placeholder="{lang_Email}" size="24" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="row_off">
|
||||||
|
<td colspan="2">{lang_The_used_SimpleSAMLphp_allows_a_lot_more_configuration_/_different_authentication_types_via_its_config_files in} {value_files_dir}/saml</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="row_off">
|
||||||
|
<td colspan="2"> </td>
|
||||||
|
</tr>
|
||||||
<tr class="th">
|
<tr class="th">
|
||||||
<td colspan="2"><b>{lang_If_using_CAS_(Central_Authentication_Service):}</b></td>
|
<td colspan="2"><b>{lang_If_using_CAS_(Central_Authentication_Service):}</b></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
Loading…
Reference in New Issue
Block a user