diff --git a/plugins/cas_auth_unl/README.txt b/plugins/cas_auth_unl/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..546350bb2ee8b6cd2cf9ea220d9bc034086d0316 --- /dev/null +++ b/plugins/cas_auth_unl/README.txt @@ -0,0 +1,32 @@ + + + + + + + +Built upon Xavier Roussel's cas_auth plugin +http://code.google.com/p/elgg-cas/ +His README below: + +************************* +Elgg is an open source social networking platform. + +CAS (Central Authentification Service) is an SSO. + +This project tries to allow CAS authentification in Elgg. The idea is to authenticate with CAS, then look up the user info in LDAP +and authenticate the user in Elgg. + +This plugin has been widely built on the ldap_auth plugin from Misja Hoebe and is inspired from the CAS authentification used in +Claroline : www.claroline.net + +You can edit the config in the Tool administration section by providing CAS host, port and URI. + +-- + +Xavier Roussel +Responsable technique - TICE +Direction des Systèmes d'Information - UVSQ +xavier.roussel@uvsq.fr +www.uvsq.fr +www.tice.uvsq.fr \ No newline at end of file diff --git a/plugins/cas_auth_unl/actions/login.php b/plugins/cas_auth_unl/actions/login.php new file mode 100644 index 0000000000000000000000000000000000000000..39eda913df660b8e12db71428b62508e069b28df --- /dev/null +++ b/plugins/cas_auth_unl/actions/login.php @@ -0,0 +1,104 @@ +<?php + /** + * Elgg UNL CAS authentication login action + * + * @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/ + * + * Builds upon the original login action at elgg/actions/login.php by Curverider Ltd + * + */ + + // Safety first + action_gatekeeper(); + + // Get $_GET inputs + + $username = get_input('username'); + $password = get_input("password"); + $persistent = get_input("persistent", false); + $usecas = get_input('usecas'); + + // 1. Do the regular elgg login if username and password are set + $result = false; + if (!empty($username) && !empty($password)) { + if ($user = authenticate($username,$password)) { + $result = login($user, $persistent); + } + } + + // 2. Otherwise try CAS if that button was clicked + if ($usecas == 'yes') { + $casObject = new elggSimpleCas(); + if (!$casObject->checkCas()) { + $ts = time(); + $token = generate_action_token($ts); + SimpleCAS::setURL('http://ucommrasmussen.unl.edu/workspace/UNL_Elgg/elgg/action/login?usecas=yes&__elgg_ts='.$ts.'&__elgg_token='.$token); + $casObject->forceCas(); + } + + $casObject->poopoo(); + } + + // Set the system_message as appropriate + + if ($result) { + system_message(elgg_echo('loginok')); + if ($_SESSION['last_forward_from']) + { + $forward_url = $_SESSION['last_forward_from']; + $_SESSION['last_forward_from'] = ""; + forward($forward_url); + } + else + { + if ( + (isadminloggedin()) && + (!datalist_get('first_admin_login')) + ) + { + system_message(elgg_echo('firstadminlogininstructions')); + + datalist_set('first_admin_login', time()); + + forward('pg/admin/plugins'); + } else { + /* here's the modifications we're making + forward("pg/dashboard/"); */ + + $lastlogin_date = $_SESSION['user']->last_login; + if (!$lastlogin_date){ + forward("mod/profile/edit.php?firstlogin=yes&username=$username"); + } + //forward("pg/profile/$username"); + forward("pg/dashboard/"); + } + } + } else { + $error_msg = elgg_echo('loginerror'); + // figure out why the login failed + if (!empty($username) && !empty($password)) { + // See if it exists and is disabled + $access_status = access_get_show_hidden_status(); + access_show_hidden_entities(true); + if (($user = get_user_by_username($username)) && !$user->validated) { + // give plugins a chance to respond + if (!trigger_plugin_hook('unvalidated_login_attempt','user',array('entity'=>$user))) { + // if plugins have not registered an action, the default action is to + // trigger the validation event again and assume that the validation + // event will display an appropriate message + trigger_elgg_event('validate', 'user', $user); + } + } else { + register_error(elgg_echo('loginerror')); + } + access_show_hidden_entities($access_status); + } else { + register_error(elgg_echo('loginerror')); + } + } + +?> \ No newline at end of file diff --git a/plugins/cas_auth_unl/manifest.xml b/plugins/cas_auth_unl/manifest.xml new file mode 100644 index 0000000000000000000000000000000000000000..0a60f2b2f1f3c4dc0d6451a6c4b848e1f881aa4f --- /dev/null +++ b/plugins/cas_auth_unl/manifest.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plugin_manifest> + <field key="author" value="University of Nebraska-Lincoln" /> + <field key="version" value="1.0" /> + <field key="description" value="CAS Authetication. Modified from the original LDAP plugin for use at UNL." ></field> + <field key="website" value="http://www.unl.edu/" /> + <field key="copyright" value="2010 Regents of the University of Nebraska " /> + <field key="licence" value="BSD http://www1.unl.edu/wdn/wiki/Software_License" /> +</plugin_manifest> diff --git a/plugins/cas_auth_unl/peoplefinder/include.php b/plugins/cas_auth_unl/peoplefinder/include.php new file mode 100644 index 0000000000000000000000000000000000000000..b50f08439874928049fae138a47b777b02cad0d0 --- /dev/null +++ b/plugins/cas_auth_unl/peoplefinder/include.php @@ -0,0 +1,98 @@ +<?php + require_once 'UNL/Services/Peoplefinder.php'; + + //In order to avoid a "__PHP_Incomplete_Class" problem when we unserialize the Peoplefinder data we need to set up the class here + //http://us2.php.net/manual/en/function.unserialize.php + class UNL_Peoplefinder_Record { + public $cn; + public $ou; + public $eduPersonNickname; + public $eduPersonPrimaryAffiliation; + public $givenName; + public $displayName; + public $mail; + public $postalAddress; + public $sn; + public $telephoneNumber; + public $title; + public $uid; + public $unlHRPrimaryDepartment; + public $unlHRAddress; + public $unlSISClassLevel; + public $unlSISCollege; + public $unlSISLocalAddr1; + public $unlSISLocalAddr2; + public $unlSISLocalCity; + public $unlSISLocalPhone; + public $unlSISLocalState; + public $unlSISLocalZip; + public $unlSISPermAddr1; + public $unlSISPermAddr2; + public $unlSISPermCity; + public $unlSISPermState; + public $unlSISPermZip; + public $unlSISMajor; + public $unlEmailAlias; + + /** + * Takes in a string from the LDAP directory, usually formatted like: + * ### ___ UNL 68588-#### + * Where ### is the room number, ___ = Building Abbreviation, #### zip extension + * + * @param string + * @return array Associative array. + */ + function formatPostalAddress() { + /* this is a faculty postal address + Currently of the form: + ### ___ UNL 68588-#### + Where ### is the room number, ___ = Building Abbreviation, #### zip extension + */ + /** + * We assumed that the address format is: ### ___ UNL 68588-####. + * Some 'fortunate' people have addresses not in this format. + */ + //RLIM + // treat UNL as the delimiter for the streetaddress and zip + if (strpos($this->postalAddress,'UNL')) { + $addressComponent = explode('UNL', $this->postalAddress); + } elseif (strpos($this->postalAddress,'UNO')) { + $addressComponent = explode('UNO', $this->postalAddress); + } elseif (strpos($this->postalAddress,'Omaha')) { + $addressComponent = explode('Omaha', $this->postalAddress); + } else { + $addressComponent = array($this->postalAddress); + } + $address['region'] = 'NE'; + $address['street-address'] = trim($addressComponent[0]); + if (isset($addressComponent[1])) { + $address['postal-code'] = trim($addressComponent[1]); + } else { + $address['postal-code'] = ''; + } + switch (substr($address['postal-code'],0,3)) { + case '681': + $address['locality'] = 'Omaha'; + break; + case '685': + default: + $address['locality'] = 'Lincoln'; + break; + } + + return $address; + } + } + + + + /** + * Gets a UNL SSO user's info from Peoplefinder Services + * + * @param string $username + * @return array of information from PF Services + */ + function peoplefinderServices($username){ + $pfrecord = unserialize(file_get_contents('http://peoplefinder.unl.edu/service.php?uid=' . $username . '&format=php')); + return $pfrecord; + } \ No newline at end of file diff --git a/plugins/cas_auth_unl/start.php b/plugins/cas_auth_unl/start.php new file mode 100644 index 0000000000000000000000000000000000000000..b1794220cf26309ce2fe2e9fa2c23ba758b3a31e --- /dev/null +++ b/plugins/cas_auth_unl/start.php @@ -0,0 +1,201 @@ +<?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 'peoplefinder/include.php'; + // http://code.google.com/p/simplecas/ + require_once 'SimpleCAS/Autoload.php'; + require_once 'HTTP/Request2.php'; + + + function cas_auth_unl_init() { + global $CONFIG; + + + + if ($_GET['loginwith'] == 'UNLlogin') { + if (checkCas()) { + $_SESSION['loggedWithCAS'] = true; + + $cas_user = getUserCas(); + if (casAuthenticate($cas_user)) { + system_message(elgg_echo('loginok')); + $cas_user = str_replace('-','_',$cas_user); + + //user is logged in now, this is the last step - forward based on whether they have logged in before + if (!$_SESSION['user']->last_login) + forward('mod/profile/edit.php?firstlogin=yes'); + else + forward("pg/profile/unl_" . $cas_user); + } else { + register_error(elgg_echo('loginerror')); + } + } else { + forceCas(); + } + } + + } + + //*************->Start + register_action("getemail",true,$CONFIG->pluginspath . "cas_auth_unl/views/default/actions/getemail.php"); + register_action("login",false,$CONFIG->pluginspath. "cas_auth_unl/actions/login.php"); + + // Fire up the plugin initialization using the elgg handler + register_elgg_event_handler('init','system','cas_auth_unl_init'); + + // Register CAS logout to main logout only if user logged with CAS + if (isset($_SESSION['loggedWithCAS']) && $_SESSION['loggedWithCAS']==true) { + // register_elgg_event_handler('logout', 'user', 'logoutCas'); + } + + // Set up login page, this creates the url /pg/login to be used as our login page + register_page_handler('login', 'login_page_handler'); + + function login_page_handler($page) { + // If we're not logged in, display the login page + if (!isloggedin()) { + page_draw(elgg_echo('login'), elgg_view("account/forms/login")); + // Otherwise, forward to the index page + } else { + forward(); + } + } + + + + + + +class elggSimpleCas { + + var $client; + var $casInitialized = false; + + function __construct() { + if (!$this->casInitialized) { + if ($ticket = get_input('ticket')) { + $_GET['ticket'] = $ticket; + } + $config = find_plugin_settings('cas_auth_unl'); + $options = array('hostname' => $config->casurl, + 'port' => $config->casport, + 'uri' => $config->casuri); + $protocol = new SimpleCAS_Protocol_Version2($options); + $request = $protocol->getRequest(); + $defaultClass = SimpleCAS_Protocol::DEFAULT_REQUEST_CLASS; + if ($request instanceof $defaultClass) { + $protocol->getRequest()->setConfig('ssl_verify_peer', false); + } + $this->client = SimpleCAS::client($protocol); + $this->casInitialized = true; + } + return true; + } + + function poopoo(){ + header('Location: http://google.com');exit(); + } + + function forceCas() { + $this->client->forceAuthentication(); + return true; + } + + function checkCas() { + if ($this->client->isAuthenticated()) { + return true; + } + else + return false; + } + + function logoutCas() { + global $CONFIG; + phpCAS::logout($CONFIG->url.'/action/logout'); + return true; + } + + /** + * Perform the CAS Authentication + * + * @param string $username + * @return boolean + */ + function casAuthenticate($username){ + + + if (empty($username)) + return false; + + // we're making this copy for use in the peoplefinderservices call later + // we dont want to call peoplefinderservices here since we dont need to every time a SSO user logs in + $casusername = $username; + + //We're going to make every UNL SSO user have an elgg profile name as such: unl_erasmussen2 + //and not allow friends of unl who register via elgg to pick names that begin with "unl_" + //This way, we won't have to deal with the case where someone registers erasmussen2 on elgg, then + //the real erasmussen2 signs in for the first time with UNL SSO and is logged in as the elgg user erasmussen2 + //rather then having a new account created. + $username = 'unl_' . $username; + //Replace the hyphen in a student's name with an underscore + $username = str_replace('-','_',$username); + + if ($user = get_user_by_username($username)) { + // User exists, login + return login($user); + } else { + // Valid login but user doesn't exist + $pf_user_info = peoplefinderServices($casusername); + + $name = $pf_user_info->cn; + + if (isset($_REQUEST['email'])) { + $email = $_REQUEST['email']; + } else { + if($pf_user_info->mail) + forward($CONFIG->url . 'mod/cas_auth/views/default/account/getemail.php?e=' . $pf_user_info->mail); + else + forward($CONFIG->url . 'mod/cas_auth/views/default/account/getemail.php'); + } + + try { + if ($user_guid = register_user($username, 'generic', $name, $email, false, 0, '', true)) { + $thisuser = get_user($user_guid); + + //pre-populate profile fields with data from Peoplefinder Services + $address = $pf_user_info->formatPostalAddress(); + $thisuser->profile_country = 'USA'; + $thisuser->profile_state = $address['region']; + $thisuser->profile_city = $address['locality']; + if($address['locality'] == 'Omaha') { + $thisuser->longitude = -95.9; + $thisuser->latitude = 41.25; + } else { //this is going to cover Lincoln and everyone else + $thisuser->longitude = -96.7; + $thisuser->latitude = 40.82; + } + + return login($thisuser); + } else { + register_error(elgg_echo("registerbad")); + } + } catch (RegistrationException $r) { + register_error($r->getMessage()); + } + + } + + } + + +} +?> \ No newline at end of file diff --git a/plugins/cas_auth_unl/views/default/account/forms/getemail.php b/plugins/cas_auth_unl/views/default/account/forms/getemail.php new file mode 100644 index 0000000000000000000000000000000000000000..7548872340fe8343499a62e3c77d903198f61534 --- /dev/null +++ b/plugins/cas_auth_unl/views/default/account/forms/getemail.php @@ -0,0 +1,39 @@ +<?php + + /** + * Elgg Get Email Only SSO register form + * + * @package Elgg + * @subpackage Core + * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 + * @author Curverider Ltd + * @copyright Curverider Ltd 2008-2009 + * @link http://elgg.org/ + */ + + // if we're returning from a failed email validation, we'll put the failed email in the email form field + if( isset($_REQUEST['e']) ) + { + $vars['unl_email'] = $_REQUEST['e']; + } + + $form_body = '<p class="required">Indicates a required field.</p>'; + $form_body .= '<fieldset> + <legend>Email Verification</legend> + <ol>'; + $form_body .= "<li class='required'><label class='element'>" . elgg_echo('email') . "</label><div class='element'>" . elgg_view('input/text' , array('internalname' => 'email', 'class' => "general-textarea", 'value' => $vars['unl_email'])) . "</div></li>"; + $form_body .= "</ol></fieldset>"; + $form_body .= '<p class="submit">' .elgg_view('input/submit', array('internalname' => 'submit', 'value' => 'Complete Registration and Login!')) . "</p>"; +?> + + <h2 class="sec_header">Email Verification</h2> + <div class="three_col left formCool"> + <p>We just want to make sure we have your correct e-mail and then we'll log you in.</p> + <?php echo elgg_view('input/form', array('action' => "{$vars['url']}action/getemail", 'body' => $form_body)) ?> + </div> + <div class="col right"> + <div class="zenbox cool"> + <h3>Email Address Usage</h3> + <p>Your email address is only used to send notifications from Planet Red.</p> + </div> + </div> \ No newline at end of file diff --git a/plugins/cas_auth_unl/views/default/account/forms/login.php b/plugins/cas_auth_unl/views/default/account/forms/login.php new file mode 100644 index 0000000000000000000000000000000000000000..406e6c2f191e663de92d6c6d2b6e72c0cbea23f4 --- /dev/null +++ b/plugins/cas_auth_unl/views/default/account/forms/login.php @@ -0,0 +1,41 @@ +<?php + /** + * Elgg UNL CAS authentication login form + * + * @package cas_auth_unl + * @license http://www1.unl.edu/wdn/wiki/Software_License + * @author University of Nebraska-Lincoln + * @copyright 2010 + * @link http://www.unl.edu/ + */ + + global $CONFIG; +?> + + <div id="login"> + <div class="two_col left"> + <h2 class="sec_main">Students, Faculty, Staff</h2> + + <p>If you are a student, faculty or staff member, you already have an account. Use your my.UNL credentials to begin.</p> + <?php + $form_body = '<p class="login-box">'; + $form_body .= '<label>' . elgg_view('input/hidden', array('internalname' => 'usecas', 'value' => 'yes')) . '</label>'; + $form_body .= elgg_view('input/submit', array('value' => elgg_echo('UNL Login'))) . '</p>'; + $ts = time(); + $token = generate_action_token($ts); + echo elgg_view('input/form', array('body' => $form_body, 'action' => "". $vars['url'] ."action/login")); + ?> + <p style="margin-top: 40px;"><a title="Find your my.UNL password" href="https://login.unl.edu/faq/account-resetpw.shtml">Lost your my.UNL password?</a></p> + + </div> + <div class="two_col right"> + <h2 class="sec_main">Huskers Worldwide</h2> + <?php + $form_body = '<p class="login-box"><label>' . elgg_echo('username') . '<br />' . elgg_view('input/text', array('internalname' => 'username', 'class' => 'login-textarea')) . '</label><br />'; + $form_body .= '<label>' . elgg_echo('password') . '<br />' . elgg_view('input/password', array('internalname' => 'password', 'class' => 'login-textarea')) . '</label><br />'; + $form_body .= elgg_view('input/submit', array('value' => elgg_echo('login'))) . '</p>'; + $form_body .= '<p><a href="'. $vars['url'] .'account/register.php">' . elgg_echo('register') . '</a> | <a href="'. $vars['url'] .'account/forgotten_password.php">' . elgg_echo('user:password:lost') . '</a></p>'; + echo elgg_view('input/form', array('body' => $form_body, 'action' => "". $vars['url'] ."action/login")); + ?> + </div> + </div> \ No newline at end of file diff --git a/plugins/cas_auth_unl/views/default/account/getemail.php b/plugins/cas_auth_unl/views/default/account/getemail.php new file mode 100644 index 0000000000000000000000000000000000000000..40d5666ea2bf02255cceb03296c98dc3a6a7cbda --- /dev/null +++ b/plugins/cas_auth_unl/views/default/account/getemail.php @@ -0,0 +1,22 @@ +<?php + + /** + * Get a UNL SSO user's email when they login the first time + * + * @package cas_auth + * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 + * @author Eric Rasmussen + * @copyright University of Nebraska-Lincoln 2009 + * @link http://www.unl.edu/ + */ + + /** + * Start the Elgg engine + */ + require_once(dirname(dirname(dirname(dirname(dirname(__FILE__))))) . "/elgg/engine/start.php"); + + + page_draw(elgg_echo('register'), elgg_view("account/forms/getemail")); + + +?> \ No newline at end of file diff --git a/plugins/cas_auth_unl/views/default/actions/getemail.php b/plugins/cas_auth_unl/views/default/actions/getemail.php new file mode 100644 index 0000000000000000000000000000000000000000..49147433620421073b2a20a4cb024dfc5564caff --- /dev/null +++ b/plugins/cas_auth_unl/views/default/actions/getemail.php @@ -0,0 +1,37 @@ +<?php + + /** + * Elgg UNL SSO get email registration action + * + * @package Elgg + * @subpackage Core + * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 + * @author Curverider Ltd + * @copyright Curverider Ltd 2008-2009 + * @link http://elgg.org/ + */ + + global $CONFIG; + + action_gatekeeper(); + + $email = get_input('email'); + $email = sanitise_string($email); + + if (is_email_address($email)) { + if (!get_user_by_email($email)) { + forward('?loginwith=UNLlogin&email=' . $email); + } else { + register_error(elgg_echo("Sorry, that email has already been registered. Please try again.")); + } + } else { + register_error(elgg_echo("Sorry, that is not a complete email address. Please try again.")); + } + + $qs = explode('?',$_SERVER['HTTP_REFERER']); + $qs = $qs[0]; + $qs .= "?e=" . urlencode($email); + + forward($CONFIG->url . 'mod/cas_auth/views/default/account/getemail.php?e=' . urlencode($email)); + +?> \ No newline at end of file diff --git a/plugins/cas_auth_unl/views/default/settings/cas_auth_unl/edit.php b/plugins/cas_auth_unl/views/default/settings/cas_auth_unl/edit.php new file mode 100644 index 0000000000000000000000000000000000000000..acd41d8d22fe5b82e3e89c79b81da19857160774 --- /dev/null +++ b/plugins/cas_auth_unl/views/default/settings/cas_auth_unl/edit.php @@ -0,0 +1,25 @@ +<?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/ + */ +?> +<p> + <fieldset style="border: 1px solid; padding: 15px; margin: 0 10px 0 10px"> + <legend><?php echo elgg_echo('CAS');?></legend> + + <label for="params[casurl]"><?php echo elgg_echo('CAS URL');?></label><br/> + <input type="text" name="params[casurl]" value="<?php echo $vars['entity']->casurl; ?>" /><br/> + + <label for="params[casport]"><?php echo elgg_echo('CAS PORT');?></label><br/> + <input type="text" name="params[casport]" value="<?php echo $vars['entity']->casport; ?>" /><br/> + + <label for="params[casuri]"><?php echo elgg_echo('CAS URI');?></label><br/> + <input type="text" name="params[casuri]" value="<?php echo $vars['entity']->casuri; ?>" /><br/> + </fieldset> +</p> \ No newline at end of file