Select Git revision
Forked from
Digital Experience Group / PlanetRed
630 commits behind, 146 commits ahead of the upstream repository.
-
Jeff Sturek authoredJeff Sturek authored
start.php 9.08 KiB
<?php
/**
* Elgg UNL CAS authentication
*
* @package cas_auth_unl
* @license BSD http://www1.unl.edu/wdn/wiki/Software_License
* @author University of Nebraska-Lincoln
* @copyright 2010 Regents of the University of Nebraska
* @link http://www.unl.edu/
*/
global $CONFIG;
require_once __DIR__ . '/vendor/autoload.php';
function cas_auth_unl_init() {
global $CONFIG;
$auth = new UnlCAS();
$auth->autoLogin();
$auth->singleLogOut();
// Set up login page, this creates the url /login to be used as our login page
elgg_register_page_handler('login', 'cas_auth_unl_login_page_handler');
elgg_register_page_handler('logout', 'cas_auth_unl_logout_page_handler');
elgg_register_page_handler('register', 'cas_auth_unl_registration_page_handler');
/* set up getemail page */
elgg_register_page_handler('getemail', 'cas_auth_unl_getemail_page_handler');
elgg_register_action('getemail', $CONFIG->pluginspath . 'cas_auth_unl/actions/getemail.php', 'public');
elgg_register_action('logout', $CONFIG->pluginspath . 'cas_auth_unl/actions/logout.php', 'public');
}
// Fire up the plugin initialization using the elgg handler
elgg_register_event_handler('init','system','cas_auth_unl_init');
function cas_auth_unl_login_page_handler($page = NULL) {
// If we're not logged in, display the login page
if (!elgg_is_logged_in()) {
$auth = new UnlCAS();
$auth->forceLogin();
}
// Otherwise, forward to the index page
forward();
}
function cas_auth_unl_logout_page_handler($page = NULL) {
if (elgg_is_logged_in()) {
// If we're not logged in, display the login page
$auth = new UnlCAS();
$auth->forceLogout();
}
// Otherwise, forward to the index page
forward();
}
function cas_auth_unl_registration_page_handler($page = NULL) {
if (elgg_is_logged_in()) {
// Otherwise, forward to the index page
forward();
}
if (!isset($_SESSION['cas_auth_unl']['register']['uid'])) {
//They are not already in the registration process
forward();
}
if (!isset($_POST['email'])) {
forward();
}
// If we're not logged in, display the login page
$auth = new UnlCAS();
$unl_uid = $_SESSION['cas_auth_unl']['register']['uid'];
$auth->register($unl_uid, $_POST['email']);
$auth->login($unl_uid);
forward();
}
function cas_auth_unl_getemail_page_handler($page = NULL) {
if (!elgg_get_logged_in_user_entity()) {
echo elgg_view_page(elgg_echo('Your Email'), elgg_view("account/forms/getemail"));
} else {
forward();
}
}
class UnlCAS {
var $client;
var $casInitialized = false;
const DIRECTORY_URL = 'https://directory.unl.edu/';
public static $cert_path = '/etc/pki/tls/cert.pem';
function __construct() {
if (!\phpCAS::isInitialized()) {
\phpCAS::client(CAS_VERSION_2_0, 'shib.unl.edu', 443, 'idp/profile/cas');
\phpCAS::setCasServerCACert(self::$cert_path);
\phpCAS::setPostAuthenticateCallback(function($logoutTicket) {
$auth = new UnlCAS();
$auth->loginOrRegister(\phpCAS::getUser());
$session = elgg_get_session();
$pool = $auth->getSessionMapPool();
$item = $pool->getItem($logoutTicket);
$item->set(array(
'session_id' => $session->getId(),
'date_created' => time()
));
});
\phpCAS::setSingleSignoutCallback(function ($logoutTicket) {
$auth = new UnlCAS();
$pool = $auth->getSessionMapPool();
$item = $pool->getItem($logoutTicket);
if ($item->isMiss()) {
return null;
}
$data = $item->get();
$handler = new Elgg\Http\DatabaseSessionHandler(_elgg_services()->db);
if (!$handler->destroy($data['session_id'])) {
throw new \Exception('unable to destroy session on single sign out');
}
//Remove the cached item
$item->clear();
});
}
}
public function getSessionMapPool()
{
// Setting a custom path is done by passing an options array to the constructor.
$options = array('path' => __DIR__ .'/../../tmp/elgg_session_map');
$driver = new Stash\Driver\FileSystem($options);
$pool = new Stash\Pool($driver);
return $pool;
}
public function singleLogOut()
{
\phpCAS::handleLogoutRequests(false);
}
public function autoLogin()
{
if ('pg' == elgg_get_context() && false !== strpos($_SERVER['REQUEST_URI'], '/pg/icon/')) {
//Don't auto-login on profile icon view
return;
}
if (false !== strpos($_SERVER['REQUEST_URI'], '/mod/profile/icondirect.php')) {
//prevent auto-login for the icondirect.php endpoint too
return;
}
if (!array_key_exists('unl_sso', $_COOKIE)) {
//No unl_sso cookie was found, no need to auto-login.
return;
}
if (elgg_get_logged_in_user_entity()) {
//We are already logged in, no need to auto-login
return;
}
//Everything looks good. Log in!
$result = \phpCAS::checkAuthentication();
if ($result) {
//Make sure we are still authenticated with CAS
//setPostAuthenticateCallback() will actually do the work
\phpCAS::renewAuthentication();
}
}
protected function loginOrRegister($unl_uid)
{
$elgg_uid = $this->toElggUID($unl_uid);
$user = get_user_by_username($elgg_uid);
if (!$user) {
$this->register($unl_uid);
$this->login($unl_uid);
} else {
$this->login($unl_uid);
}
}
public function login($unl_uid)
{
$user = get_user_by_username($this->toElggUID($unl_uid));
//Log the user into elgg
login($user);
}
public function register($unl_uid, $student_email = false)
{
$elgg_uid = $this->toElggUID($unl_uid);
$directory_info = $this->getDirectoryInfo($unl_uid);
$name = 'unknown';
$email = false;
if ($student_email) {
$email = $student_email;
}
if (isset($directory_info['name'])) {
$name = $directory_info['name'];
}
if (isset($directory_info['email'])) {
//Override the student email with the one from the directory
$email = $directory_info['email'];
}
if (false === $email) {
$_SESSION['cas_auth_unl']['register']['uid'] = $unl_uid;
forward('getemail');
}
$password = generate_random_cleartext_password();
try {
$user_guid = register_user($elgg_uid, $password, $name, $email, false);
} catch (RegistrationException $e) {
//Looks like we had an invalid email address... ask for it again.
register_error(elgg_echo($e->getMessage()));
forward('getemail');
}
if (!$user_guid) {
register_error(elgg_echo("registerbad"));
}
//Make sure that this gets unset
unset($_SESSION['cas_auth_unl']);
return true;
}
protected function getDirectoryInfo($uid)
{
$info = array();
if (!$json = @file_get_contents(self::DIRECTORY_URL . '?uid=' . $uid . '&format=json')) {
return $info;
}
if (!$json = json_decode($json, true)) {
return $info;
}
$map = array(
'givenName' => 'first_name',
'sn' => 'last_name',
'mail' => 'email'
);
foreach ($map as $from => $to) {
if (isset($json[$from][0])) {
$info[$to] = $json[$from][0];
}
}
$info['name'] = $info['first_name'] . ' ' . $info['last_name'];
return $info;
}
protected function toElggUID($unl_uid)
{
$unl_uid = str_replace('-','_',$unl_uid);
return 'unl_' . $unl_uid;
}
public function forceLogin() {
//Due to the weirdness of phpCAS, it might think we are still logged in (when we are not)
$_SESSION['phpCAS'] = array();
\phpCAS::forceAuthentication();
}
public function forceLogout()
{
//log out of elgg
logout();
//log out of CAS
\phpCAS::logout();
}
}