This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
samlauth-elgg/start.php

150 lines
5.2 KiB
PHP

<?php
/**
* Elgg SAML v2.0 authentication
*
* @package ElggSAMLAuth
* @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
* @author Jerome Schneider <jschneider@entrouvert.com>
*/
require_once dirname(__FILE__) . '/simplesamlphp/lib/_autoload.php';
// Register the events
elgg_register_event_handler('init','system','saml_auth_init');
elgg_register_event_handler('logout','user','saml_logout');
/**
* SAML Authentication init
*
* These parameters are required for the event API, but we won't use them:
*/
function saml_auth_init()
{
global $CONFIG;
init_config();
$as = new SimpleSAML_Auth_Simple(elgg_get_plugin_setting('sp_name', 'saml_auth'));
$isAuth = $as->isAuthenticated();
$attributes = $as->getAttributes();
$elgg_user = none;
if ($isAuth && ! elgg_is_logged_in())
$elgg_user = saml_map_attributes($attributes);
if ($isAuth && ! elgg_is_logged_in() && $elgg_user)
{
$user = get_user_by_username($elgg_user['username']);
if ($user) {
trigger_error('SAMLAuth found user "' . $user->username, E_USER_NOTICE);
}
if (! $user)
{
try {
if (!register_user($elgg_user['username'], $elgg_user['password'],
$elgg_user['name'], $elgg_user['email']))
return 1;
} catch (RegistrationException $e) {
error_log('SAMLAuth cannot register username "' . $elgg_user['username'] . '", it exists already.');
register_error(elgg_echo('registration:dupeemail'));
return true;
}
$user = get_user_by_username($elgg_user['username']);
}
if ($user) {
saml_sync_user($user, $elgg_user);
$result = login($user);
$_SESSION['saml_user'] = TRUE;
return $result;
}
// XXX: else return an error ?
}
if (! $isAuth && elgg_is_logged_in() && $_SESSION['saml_user']) {
// unlogged from simplesamlphp but not from elgg
return logout();
}
}
function init_config()
{
$config = elgg_get_calling_plugin_entity('saml_auth');
if (! $config->sp_name)
elgg_set_plugin_setting('sp_name', 'default-sp', 'saml_auth');
if (! $config->username)
elgg_set_plugin_setting('username', 'NameID', 'saml_auth');
if (! $config->firstname)
elgg_set_plugin_setting('firstname', 'gn', 'saml_auth');
if (! $config->surname)
elgg_set_plugin_setting('surname', 'sn', 'saml_auth');
if (! $config->email)
elgg_set_plugin_setting('email', 'email', 'saml_auth');
if (! $config->classical_auth)
elgg_set_plugin_setting('classical_auth', 'yes', 'saml_auth');
}
function saml_sync_user($user, $elgg_user)
{
$user->name = $elgg_user['name'];
$user->email = $elgg_user['email'];
$user->save();
}
function gen_rand_pwd()
{
$password = "";
$chars = "0123456789_!@#$%&*()-=+/abcdfghjkmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_!@#$%&*()-=+/";
$i = 0;
while ($i < 18)
{
$char = substr($chars, rand(0, strlen($chars)-1), 1);
$password .= $char;
$i++;
}
return $password;
}
function saml_map_attributes($attributes)
{
$elgg_user = array();
$config = elgg_get_calling_plugin_entity('saml_auth');
# XXX: if not mail use mailForwardingAddress
if (! $attributes[$config->email] && $attributes['urn:oid:2.16.840.1.113730.3.1.17'])
$attributes[$config->email] = $attributes['urn:oid:2.16.840.1.113730.3.1.17'];
if (! $attributes[$config->username] or ! $attributes[$config->email])
{
error_log('SAMLAuth error : username or email not found');
register_error(elgg_echo('saml_auth:errorattrs'));
return false;
}
$elgg_user['username'] = $attributes[$config->username][0];
$elgg_user['password'] = gen_rand_pwd();
$elgg_user['name'] = '';
if ($attributes[$config->surname] || $attributes[$config->firstname])
{
if ($attributes[$config->firstname])
$elgg_user['name'] = $attributes[$config->firstname][0];
if ($attributes[$config->surname])
{
if (! empty($elgg_user['name']))
$elgg_user['name'] .= ' ';
$elgg_user['name'] .= $attributes[$config->surname][0];
}
}
else
$elgg_user['name'] = $elgg_user['username'];
$elgg_user['email'] = $attributes[$config->email][0];
return $elgg_user;
}
function saml_logout($page)
{
global $CONFIG;
$auth = new SimpleSAML_Auth_Simple(elgg_get_plugin_setting('sp_name', 'saml_auth'));
if ($auth->isAuthenticated()) {
$auth->logout(elgg_get_site_url());
}
}