<?php /********************************************************************* class.client.php Handles everything about EndUser Peter Rotich <peter@osticket.com> Copyright (c) 2006-2013 osTicket http://www.osticket.com Released under the GNU General Public License WITHOUT ANY WARRANTY. See LICENSE.TXT for details. vim: expandtab sw=4 ts=4 sts=4: **********************************************************************/ abstract class TicketUser { static private $token_regex = '/^(?P<type>\w{1})(?P<id>\d+)t(?P<tid>\d+)x(?P<algo>\d+)h(?P<hash>.*)$/i'; protected $user; function __construct($user) { $this->user = $user; } function __call($name, $args) { global $cfg; if($this->user && is_callable(array($this->user, $name))) return $args ? call_user_func_array(array($this->user, $name), $args) : call_user_func(array($this->user, $name)); $tag = substr($name, 3); switch (strtolower($tag)) { case 'ticket_link': return sprintf('%s/view.php?auth=%s', $cfg->getBaseUrl(), urlencode($this->getAuthToken())); break; } return false; } protected function getAuthToken($type=1) { //Format: // c<id>x<algo id used>h<hash for algo> $authtoken = ''; switch($type) { case 1: $authtoken = sprintf('%s%dt%dx%dh%s', ($this->isOwner() ? 'o' : 'c'), $this->getId(), $this->getTicketId(), $type, substr(base64_encode(md5($this->getId().$this->getTicket()->getCreateDate().$this->getTicketId().SECRET_SALT, true)), 16)); break; } //TODO: Throw an exception if (!$authtoken) return false; return $authtoken; } static function lookupByToken($token) { //Expecting well formatted token see getAuthToken routine for details. $matches = array(); if (!preg_match(static::$token_regex, $token, $matches)) return null; $user = null; switch ($matches['type']) { case 'c': //Collaborator c if (($user = Collaborator::lookup($matches['id'])) && $user->getTicketId() != $matches['tid']) $user = null; break; case 'o': //Ticket owner if (($ticket = Ticket::lookup($matches['tid']))) { if (($user = $ticket->getOwner()) && $user->getId() != $matches['id']) $user = null; } break; } if (!$user || !$user instanceof TicketUser || strcasecmp($user->getAuthToken($matches['algo']), $token)) return false; var_dump($user); return $user; } function isOwner() { return ($this->user && $this->user->getId() == $this->getTicket()->getOwnerId()); } abstract function getTicketId(); abstract function getTicket(); } class TicketOwner extends TicketUser { protected $ticket; function __construct($user, $ticket) { parent::__construct($user); $this->ticket = $ticket; } function getTicket() { return $this->ticket; } function getTicketId() { return $this->ticket->getId(); } } /* * Decorator class for authenticated user * */ class EndUser extends AuthenticatedUser { protected $user; function __construct($user) { $this->user = $user; } /* * Delegate calls to the user */ function __call($name, $args) { if(!$this->user || !is_callable(array($this->user, $name))) return false; return $args ? call_user_func_array(array($this->user, $name), $args) : call_user_func(array($this->user, $name)); } function getId() { //We ONLY care about user ID at the ticket level if ($this->user instanceof Collaborator) return $this->user->getUserId(); return $this->user->getId(); } function getUserName() { //XXX: Revisit when real usernames are introduced or when email // requirement is removed. return $this->user->getEmail(); } function getRole() { return $this->isOwner() ? 'owner' : 'collaborator'; } function logOut() { return UserAuthenticationBackend::signOut($this); } function getTicketStats() { if (!isset($this->ht['stats'])) $this->ht['stats'] = $this->getStats(); return $this->ht['stats']; } function getNumTickets() { return ($stats=$this->getTicketStats())?($stats['open']+$stats['closed']):0; } function getNumOpenTickets() { return ($stats=$this->getTicketStats())?$stats['open']:0; } function getNumClosedTickets() { return ($stats=$this->getTicketStats())?$stats['closed']:0; } private function getStats() { $sql='SELECT count(open.ticket_id) as open, count(closed.ticket_id) as closed ' .' FROM '.TICKET_TABLE.' ticket ' .' LEFT JOIN '.TICKET_TABLE.' open ON (open.ticket_id=ticket.ticket_id AND open.status=\'open\') ' .' LEFT JOIN '.TICKET_TABLE.' closed ON (closed.ticket_id=ticket.ticket_id AND closed.status=\'closed\')' .' LEFT JOIN '.TICKET_COLLABORATOR_TABLE.' collab ON (collab.ticket_id=ticket.ticket_id AND collab.user_id = '.db_input($this->getId()).' )' .' WHERE ticket.user_id = '.db_input($this->getId()) .' OR collab.user_id = '.db_input($this->getId()); return db_fetch_array(db_query($sql)); } } ?>