Newer
Older
function signOn() {
if ($_GET['auth']) {
if (($u = TicketUser::lookupByToken($_GET['auth'])))
$user = new ClientSession($u);
}
// Support old ticket based tokens.
elseif ($_GET['t'] && $_GET['e'] && $_GET['a']) {
if (($ticket = Ticket::lookupByNumber($_GET['t'], $_GET['e']))
// Using old ticket auth code algo - hardcoded here because it
// will be removed in ticket class in the upcoming rewrite
&& !strcasecmp($_GET['a'], md5($ticket->getId() . $_GET['e'] . SECRET_SALT))
&& ($owner = $ticket->getOwner()))
$user = new ClientSession($owner);
}
return $user;
}
function supportsInteractiveAuthentication() {
return false;
}
protected function getAuthKey($user) {
return null;
//Generate authkey based the type of ticket user
// It's required to validate users going forward.
$authkey = sprintf('%s%dt%dh%s', //XXX: Placeholder
($user->isOwner() ? 'o':'c'),
$user->getTicketId(),
md5($user->getId().$this->id));
protected function validate($authkey) {
$regex = '/^(?P<type>\w{1})(?P<id>\d+)t(?P<tid>\d+)h(?P<hash>.*)$/i';
$matches = array();
if (!preg_match($regex, $authkey, $matches))
return false;
$user = null;
switch ($matches['type']) {
case 'c': //Collaborator
$criteria = array( 'userId' => $matches['id'],
'ticketId' => $matches['tid']);
if (($c = Collaborator::lookup($criteria))
&& ($c->getTicketId() == $matches['tid']))
$user = new ClientSession($c);
break;
case 'o': //Ticket owner
if (($ticket = Ticket::lookup($matches['tid']))
&& ($o = $ticket->getOwner())
&& ($o->getId() == $matches['id']))
$user = new ClientSession($o);
break;
}
//Make sure the authkey matches.
if (!$user || strcmp($this->getAuthKey($user), $authkey))
return null;
UserAuthenticationBackend::register('AuthTokenAuthentication');
//Simple ticket lookup backend used to recover ticket access link.
// We're using authentication backend so we can guard aganist brute force
// attempts (which doesn't buy much since the link is emailed)
class AccessLinkAuthentication extends UserAuthenticationBackend {
static $name = "Ticket Access Link Authentication";
static $id = "authlink";
function authenticate($email, $number) {
if (!($ticket = Ticket::lookupByNumber($number))
|| !($user=User::lookup(array('emails__address' => $email))))
if (!($user = $this->_getTicketUser($ticket, $user)))
return false;
$_SESSION['_auth']['user-ticket'] = $number;
return new ClientSession($user);
}
function _getTicketUser($ticket, $user) {
if ($ticket->getUserId() == $user->getId())
$user = $ticket->getOwner();
// Collaborator?
elseif (!($user = Collaborator::lookup(array(
'userId' => $user->getId(),
'ticketId' => $ticket->getId()))))
return false; //Bro, we don't know you!
// We are not actually logging in the user....
global $cfg;
if (!$cfg->isClientEmailVerificationRequired()) {
return parent::login($user, $bk);
}
protected function validate($userid) {
$number = $_SESSION['_auth']['user-ticket'];
if (!($ticket = Ticket::lookupByNumber($number)))
return false;
if (!($user = User::lookup($userid)))
return false;
if (!($user = $this->_getTicketUser($ticket, $user)))
return false;
$user = new ClientSession($user);
$user->flagGuest();
return $user;
}
function supportsInteractiveAuthentication() {
return false;
}
}
UserAuthenticationBackend::register('AccessLinkAuthentication');
class osTicketClientAuthentication extends UserAuthenticationBackend {
static $name = "Local Client Authentication";
static $id = "client";
function authenticate($username, $password) {
if (!($acct = ClientAccount::lookupByUsername($username)))
if (($client = new ClientSession(new EndUser($acct->getUser())))
&& !$client->getId())
return false;
elseif (!$acct->checkPassword($password))
return false;
else
return $client;
}
}
UserAuthenticationBackend::register('osTicketClientAuthentication');
class ClientPasswordResetTokenBackend extends UserAuthenticationBackend {
static $id = "pwreset.client";
function supportsInteractiveAuthentication() {
return false;
}
function signOn($errors=array()) {
global $ost;
if (!isset($_POST['userid']) || !isset($_POST['token']))
return false;
elseif (!($_config = new Config('pwreset')))
return false;
elseif (!($acct = ClientAccount::lookupByUsername($_POST['userid']))
|| !$acct->getId()
|| !($client = new ClientSession(new EndUser($acct->getUser()))))
$errors['msg'] = __('Invalid user-id given');
elseif (!($id = $_config->get($_POST['token']))
|| $id != $client->getId())
$errors['msg'] = __('Invalid reset token');
elseif (!($ts = $_config->lastModified($_POST['token']))
&& ($ost->getConfig()->getPwResetWindow() < (time() - strtotime($ts))))
$errors['msg'] = __('Invalid reset token');
elseif (!$acct->forcePasswdReset())
$errors['msg'] = __('Unable to reset password');
function login($client, $bk) {
$_SESSION['_client']['reset-token'] = $_POST['token'];
Signal::send('auth.pwreset.login', $client);
return parent::login($client, $bk);
}
UserAuthenticationBackend::register('ClientPasswordResetTokenBackend');
class ClientAcctConfirmationTokenBackend extends UserAuthenticationBackend {
static $id = "confirm.client";
function supportsInteractiveAuthentication() {
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
return false;
}
function signOn($errors=array()) {
global $ost;
if (!isset($_GET['token']))
return false;
elseif (!($_config = new Config('pwreset')))
return false;
elseif (!($id = $_config->get($_GET['token'])))
return false;
elseif (!($acct = ClientAccount::lookup(array('user_id'=>$id)))
|| !$acct->getId()
|| $id != $acct->getUserId()
|| !($client = new ClientSession(new EndUser($acct->getUser()))))
return false;
else
return $client;
}
}
UserAuthenticationBackend::register('ClientAcctConfirmationTokenBackend');