Skip to content
Snippets Groups Projects
Commit 91897809 authored by Jared Hancock's avatar Jared Hancock
Browse files

Make room for single sign on backends

Like HTTP authentication
parent a49b8c53
Branches
Tags
No related merge requests found
......@@ -43,48 +43,23 @@ class AuthenticationBackend {
}
/* static */
function process($username, $password=null, $backend=null, &$errors) {
global $ost;
function process($username, $password=null, &$errors) {
if (!$username)
return false;
$backend = static::_getAllowedBackends($username);
foreach (static::$registry as $bk) {
if ($backend && $bk->supportsAuthentication() && $bk::$id != $backend)
// User cannot be authenticated against this backend
continue;
// All backends are queried here, even if they don't support
// authentication so that extensions like lockouts and audits
// can be supported.
$result = $bk->authenticate($username, $password);
if ($result instanceof AuthenticatedUser) {
//Log debug info.
$ost->logDebug('Staff login',
sprintf("%s logged in [%s], via %s", $result->getUserName(),
$_SERVER['REMOTE_ADDR'], get_class($bk))); //Debug.
if ($result instanceof Staff) {
$sql='UPDATE '.STAFF_TABLE.' SET lastlogin=NOW() '
.' WHERE staff_id='.db_input($result->getId());
db_query($sql);
//Now set session crap and lets roll baby!
$_SESSION['_staff'] = array(); //clear.
$_SESSION['_staff']['userID'] = $username;
$result->refreshSession(); //set the hash.
$_SESSION['TZ_OFFSET'] = $result->getTZoffset();
$_SESSION['TZ_DST'] = $result->observeDaylight();
$_SESSION['_staff']['backend'] = $bk;
}
//Regenerate session id.
$sid = session_id(); //Current id
session_regenerate_id(true);
// Destroy old session ID - needed for PHP version < 5.1.0
// DELME: remove when we move to php 5.3 as min. requirement.
if(($session=$ost->getSession()) && is_object($session)
&& $sid!=session_id())
$session->destroy($sid);
Signal::send('auth.login.succeeded', $result);
$result->cancelResetTokens();
static::_login($result, $username, $bk);
$result->backend = $bk;
return $result;
}
// TODO: Handle permission denied, for instance
......@@ -97,6 +72,83 @@ class AuthenticationBackend {
Signal::send('auth.login.failed', null, $info);
}
function singleSignOn(&$errors) {
global $ost;
foreach (static::$registry as $bk) {
// All backends are queried here, even if they don't support
// authentication so that extensions like lockouts and audits
// can be supported.
$result = $bk->signOn();
if ($result instanceof AuthenticatedUser) {
// Ensure staff members are allowed to be authenticated
// against this backend
if ($result instanceof Staff
&& !static::_isBackendAllowed($result, $bk))
continue;
static::_login($result, $result->getUserName(), $bk);
$result->backend = $bk;
return $result;
}
// TODO: Handle permission denied, for instance
elseif ($result instanceof AccessDenied) {
$errors['err'] = $result->reason;
break;
}
}
}
function _isBackendAllowed($staff, $bk) {
$sql = 'SELECT backend FROM '.STAFF_TABLE
.' WHERE staff_id='.db_input($staff->getId());
$backend = db_result(db_query($sql));
return !$backend || strcasecmp($bk, $backend) === 0;
}
function _getAllowedBackends($username) {
$username = trim($_POST['userid']);
$sql = 'SELECT backend FROM '.STAFF_TABLE
.' WHERE username='.db_input($username)
.' OR email='.db_input($username);
return db_result(db_query($sql));
}
function _login($user, $username, $bk) {
global $ost;
if ($user instanceof Staff) {
//Log debug info.
$ost->logDebug('Staff login',
sprintf("%s logged in [%s], via %s", $user->getUserName(),
$_SERVER['REMOTE_ADDR'], get_class($bk))); //Debug.
$sql='UPDATE '.STAFF_TABLE.' SET lastlogin=NOW() '
.' WHERE staff_id='.db_input($user->getId());
db_query($sql);
//Now set session crap and lets roll baby!
$_SESSION['_staff'] = array(); //clear.
$_SESSION['_staff']['userID'] = $username;
$user->refreshSession(); //set the hash.
$_SESSION['TZ_OFFSET'] = $user->getTZoffset();
$_SESSION['TZ_DST'] = $user->observeDaylight();
}
//Regenerate session id.
$sid = session_id(); //Current id
session_regenerate_id(true);
// Destroy old session ID - needed for PHP version < 5.1.0
// DELME: remove when we move to php 5.3 as min. requirement.
if(($session=$ost->getSession()) && is_object($session)
&& $sid!=session_id())
$session->destroy($sid);
Signal::send('auth.login.succeeded', $user);
$user->cancelResetTokens();
}
/**
* Fetches the friendly name of the backend
*/
......@@ -144,6 +196,16 @@ class AuthenticationBackend {
function supportsPasswordReset() {
return false;
}
/* abstract */
function authenticate($username, $password) {
return false;
}
/* abstract */
function signOn() {
return false;
}
}
class RemoteAuthenticationBackend {
......
......@@ -22,17 +22,12 @@ require_once(INCLUDE_DIR.'class.csrf.php');
$dest = $_SESSION['_staff']['auth']['dest'];
$msg = $_SESSION['_staff']['auth']['msg'];
$msg = $msg?$msg:'Authentication Required';
$dest=($dest && (!strstr($dest,'login.php') && !strstr($dest,'ajax.php')))?$dest:'index.php';
if($_POST) {
// Lookup support backends for this staff
$username = trim($_POST['userid']);
$sql = 'SELECT backend FROM '.STAFF_TABLE
.' WHERE username='.db_input($username)
.' OR email='.db_input($username);
$backend = db_result(db_query($sql));
if ($user = AuthenticationBackend::process($username,
$_POST['passwd'], $backend, $errors)) {
$dest=($dest && (!strstr($dest,'login.php') && !strstr($dest,'ajax.php')))?$dest:'index.php';
$_POST['passwd'], $errors)) {
@header("Location: $dest");
require_once('index.php'); //Just incase header is messed up.
exit;
......@@ -40,6 +35,14 @@ if($_POST) {
$msg = $errors['err']?$errors['err']:'Invalid login';
}
// Consider single sign-on authentication backends
if (!$thisstaff->getId() || !$thisstaff->isValid()) {
if (($user = AuthenticationBackend::singleSignOn($errors))
&& ($user instanceof Staff))
@header("Location: $dest");
}
define("OSTSCPINC",TRUE); //Make includes happy!
include_once(INCLUDE_DIR.'staff/login.tpl.php');
?>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment