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

Add some framework for external authentication

DISABLE_SESSION define is changed so that existing session are continued
but new sessions are not saved. This allows external auth backends to
redirect to an external site and that site redirect back to a `/api` URL and
the user's session will be continued.
parent 1fba9fd1
Branches
Tags
No related merge requests found
......@@ -17,8 +17,6 @@ file_exists('../main.inc.php') or die('System Error');
// Disable sessions for the API. API should be considered stateless and
// shouldn't chew up database records to store sessions
if (!function_exists('noop')) { function noop() {} }
session_set_save_handler('noop','noop','noop','noop','noop','noop');
define('DISABLE_SESSION', true);
require_once('../main.inc.php');
......
......@@ -25,6 +25,8 @@ $dispatcher = patterns('',
))
);
Signal::send('api', $dispatcher);
# Call the respective function
print $dispatcher->resolve($ost->get_path_info());
?>
......@@ -308,8 +308,32 @@ abstract class AuthenticationBackend {
abstract static function signOut($user);
}
class RemoteAuthenticationBackend {
var $create_unknown_user = false;
/**
* ExternalAuthenticationBackend
*
* External authentication backends are backends such as Google+ which
* require a redirect to a remote site and a redirect back to osTicket in
* order for a user to be authenticated. For such backends, neither the
* username and password fields nor single sign on alone can be used to
* authenticate the user.
*/
interface ExternalAuthentication {
/**
* Requests the backend to render an external link box. When the user
* clicks this box, the backend will be prompted to redirect the user to
* the remote site for authentication there.
*/
function renderExternalLink();
/**
* Function: triggerAuth
*
* Called when a user clicks the button rendered in the
* ::renderExternalLink() function. This method should initiate the
* remote authentication mechanism.
*/
function triggerAuth();
}
abstract class StaffAuthenticationBackend extends AuthenticationBackend {
......@@ -454,6 +478,50 @@ abstract class StaffAuthenticationBackend extends AuthenticationBackend {
}
}
abstract class ExternalStaffAuthenticationBackend
extends StaffAuthenticationBackend
implements ExternalAuthentication {
static $fa_icon = "signin";
static $sign_in_image_url = false;
static $service_name = "External";
function renderExternalLink() { ?>
<a class="external-sign-in" title="Sign in with <?php echo static::$service_name; ?>"
href="login.php?do=ext&amp;bk=<?php echo urlencode(static::$id); ?>">
<?php if (static::$sign_in_image_url) { ?>
<img class="sign-in-image" src="<?php echo static::$sign_in_image_url;
?>" alt="Sign in with <?php echo static::$service_name; ?>"/>
<?php } else { ?>
<div class="external-auth-box">
<span class="external-auth-icon">
<i class="icon-<?php echo static::$fa_icon; ?> icon-large icon-fixed-with"></i>
</span>
<span class="external-auth-name">
Sign in with <?php echo static::$service_name; ?>
</span>
</div>
<?php } ?>
</a><?php
}
function triggerAuth() {
$_SESSION['ext:bk:class'] = get_class($this);
}
}
Signal::connect('api', function($dispatcher) {
$dispatcher->append(
url('^/auth/ext$', function() {
if ($class = $_SESSION['ext:bk:class']) {
$bk = StaffAuthenticationBackend::getBackend($class::$id)
?: UserAuthenticationBackend::getBackend($class::$id);
if ($bk instanceof ExternalAuthentication)
$bk->triggerAuth();
}
})
);
});
abstract class UserAuthenticationBackend extends AuthenticationBackend {
static private $_registry = array();
......@@ -580,6 +648,38 @@ abstract class UserAuthenticationBackend extends AuthenticationBackend {
}
}
abstract class ExternalUserAuthenticationBackend
extends UserAuthenticationBackend
implements ExternalAuthentication {
static $fa_icon = "signin";
static $sign_in_image_url = false;
static $service_name = "External";
function renderExternalLink() { ?>
<a class="external-sign-in" title="Sign in with <?php echo static::$service_name; ?>"
href="login.php?do=ext&amp;bk=<?php echo urlencode(static::$id); ?>">
<?php if (static::$sign_in_image_url) { ?>
<img class="sign-in-image" src="<?php echo static::$sign_in_image_url;
?>" alt="Sign in with <?php echo static::$service_name; ?>"/>
<?php } else { ?>
<div class="external-auth-box">
<span class="external-auth-icon">
<i class="icon-<?php echo static::$fa_icon; ?> icon-large icon-fixed-with"></i>
</span>
<span class="external-auth-name">
Sign in with <?php echo static::$service_name; ?>
</span>
</div>
<?php } ?>
</a><?php
}
function triggerAuth() {
$_SESSION['ext:bk:class'] = get_class($this);
}
}
/**
* This will be an exception in later versions of PHP
*/
......
......@@ -35,9 +35,6 @@ class osTicketSession {
if (OsticketConfig::getDBVersion())
return session_start();
elseif (defined('DISABLE_SESSION'))
return;
# Cookies
// Avoid setting a cookie domain without a dot, thanks
// http://stackoverflow.com/a/1188145
......@@ -80,6 +77,7 @@ class osTicketSession {
}
function read($id){
$this->isnew = true;
if (!$this->data || $this->id != $id) {
$sql='SELECT session_data FROM '.SESSION_TABLE
.' WHERE session_id='.db_input($id)
......@@ -91,6 +89,7 @@ class osTicketSession {
$this->id = $id;
}
$this->data_hash = md5($id.$this->data);
$this->isnew = false;
return $this->data;
}
......@@ -100,6 +99,9 @@ class osTicketSession {
if (md5($id.$data) == $this->data_hash)
return;
elseif (defined('DISABLE_SESSION') && $this->isnew)
return;
$ttl = ($this && get_class($this) == 'osTicketSession')
? $this->getTTL() : SESSION_TTL;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment