diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php index 6e746fbfe0d1181b5d069737569c4eecdbcf00a1..e13128529cc4fa4ba26d8b3cc0f1d03c4d7bb489 100644 --- a/include/ajax.tickets.php +++ b/include/ajax.tickets.php @@ -150,23 +150,31 @@ class TicketsAjaxAPI extends AjaxController { function releaseLock($tid, $id=0) { global $thisstaff; - if($id && is_numeric($id)){ //Lock Id provided! + if (!($ticket = Ticket::lookup($tid))) { + return 0; + } - $lock = Lock::lookup($id); - //Already gone? - if(!$lock || !$lock->getStaffId() || $lock->isExpired()) //Said lock doesn't exist or is is expired + if ($id) { + // Fetch the lock from the ticket + if (!($lock = $ticket->getLock())) { return 1; - - //make sure the user actually owns the lock before releasing it. - return ($lock->getStaffId()==$thisstaff->getId() && $lock->release())?1:0; - - } elseif ($tid) { //release all the locks the user owns on the ticket. - if (!($ticket = Ticket::lookup($tid))) + } + // Identify the lock by the ID number + if ($lock->getId() != $id) { return 0; - return Lock::removeStaffLocks($thisstaff->getId(), $ticket)?1:0; + } + // You have to own the lock + if ($lock->getStaffId() != $thisstaff->getId()) { + return 0; + } + // Can't be expired + if ($lock->isExpired()) { + return 1; + } + return $lock->release() ? 1 : 0; } - return 0; + return Lock::removeStaffLocks($thisstaff->getId(), $ticket) ? 1 : 0; } function previewTicket ($tid) { diff --git a/include/class.auth.php b/include/class.auth.php index b115258952323bd069ece521c8643b7211f5fa45..192c3af7079265b5d99527390ca497db9bd45fe2 100644 --- a/include/class.auth.php +++ b/include/class.auth.php @@ -1050,8 +1050,10 @@ class AuthTokenAuthentication extends UserAuthenticationBackend { $user = null; switch ($matches['type']) { case 'c': //Collaborator - $criteria = array( 'userId' => $matches['id'], - 'ticketId' => $matches['tid']); + $criteria = array( + 'user_id' => $matches['id'], + 'thread__ticket__ticket_id' => $matches['tid'] + ); if (($c = Collaborator::lookup($criteria)) && ($c->getTicketId() == $matches['tid'])) $user = new ClientSession($c); @@ -1102,8 +1104,9 @@ class AccessLinkAuthentication extends UserAuthenticationBackend { $user = $ticket->getOwner(); // Collaborator? elseif (!($user = Collaborator::lookup(array( - 'userId' => $user->getId(), - 'ticketId' => $ticket->getId())))) + 'user_id' => $user->getId(), + 'thread__ticket__ticket_id' => $ticket->getId()) + ))) return false; //Bro, we don't know you! return $user; diff --git a/include/class.client.php b/include/class.client.php index 4932f4c400adfd6ab4d528fe3bb69853171e0aff..25efc2ca60132537015107d13d273b913bc13ee7 100644 --- a/include/class.client.php +++ b/include/class.client.php @@ -89,7 +89,7 @@ implements EmailContact, ITicketUser { } if (!$user - || !$user instanceof TicketUser + || !$user instanceof ITicketUser || strcasecmp($ticket->getAuthToken($user, $matches['algo']), $token)) return false; @@ -174,10 +174,13 @@ class EndUser extends BaseAuthenticatedUser { $u = $this; // Traverse the $user properties of all nested user objects to get // to the User instance with the custom data - while (isset($u->user)) + while (isset($u->user)) { $u = $u->user; - if (method_exists($u, 'getVar')) - return $u->getVar($tag); + if (method_exists($u, 'getVar')) { + if ($rv = $u->getVar($tag)) + return $rv; + } + } } function getId() { @@ -402,5 +405,7 @@ interface ITicketUser { function flagGuest(); function isGuest(); function getUserId(); + function getTicketId(); + function getTicket(); } ?> diff --git a/include/class.collaborator.php b/include/class.collaborator.php index 35e5ea0287185080469a3f947bf046359c1be48d..c457f1cd3cf4feac927e6076a428bc6a90ca4766 100644 --- a/include/class.collaborator.php +++ b/include/class.collaborator.php @@ -73,15 +73,12 @@ implements EmailContact, ITicketUser { function getName() { return $this->user->getName(); } - function sendAccessLink($ticket) { - return $this->user->sendAccessLink($ticket); - } // VariableReplacer interface function getVar($what) { global $cfg; - switch ($what) { + switch (strtolower($what)) { case 'ticket_link': return sprintf('%s/view.php?%s', $cfg->getBaseUrl(), diff --git a/include/class.ticket.php b/include/class.ticket.php index b7560b8a15f8da4d8b2e475595cc76e4fc3ab6e5..5df9f9a82de862e52128542f5907323e852ee41b 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -1042,6 +1042,31 @@ implements RestrictedAccess, Threadable { return $authtoken; } + function sendAccessLink($user) { + global $ost; + + if (!($email = $ost->getConfig()->getDefaultEmail()) + || !($content = Page::lookupByType('access-link'))) + return; + + $vars = array( + 'url' => $ost->getConfig()->getBaseUrl(), + 'ticket' => $this, + 'user' => $user, + 'recipient' => $user, + ); + + $lang = $user->getLanguage(UserAccount::LANG_MAILOUTS); + $msg = $ost->replaceTemplateVariables(array( + 'subj' => $content->getLocalName($lang), + 'body' => $content->getLocalBody($lang), + ), $vars); + + $email->send($user, Format::striptags($msg['subj']), + $msg['body']); + } + + /* -------------------- Setters --------------------- */ function setLastMsgId($msgid) { return $this->lastMsgId=$msgid; diff --git a/include/class.user.php b/include/class.user.php index 80b51163e90a3f1c7255e2ebdac9bc2cddf3f597..3a5fd1c29e205db10434a235315117b808de74c2 100644 --- a/include/class.user.php +++ b/include/class.user.php @@ -246,27 +246,9 @@ class User extends UserModel { $form->save(); } - function sendAccessLink($ticket) { - global $ost; - - if (!($email = $ost->getConfig()->getDefaultEmail()) - || !($content = Page::lookupByType('access-link'))) - return; - - $vars = array( - 'url' => $ost->getConfig()->getBaseUrl(), - 'ticket' => $ticket, - 'user' => $this, - 'recipient' => $this); - - $lang = $this->getLanguage(UserAccount::LANG_MAILOUTS); - $msg = $ost->replaceTemplateVariables(array( - 'subj' => $content->getLocalName($lang), - 'body' => $content->getLocalBody($lang), - ), $vars); - - $email->send($this->getEmail(), Format::striptags($msg['subj']), - $msg['body']); + function getLanguage($flags=false) { + if ($acct = $this->getAccount()) + return $acct->getLanguage($flags); } function to_json() { diff --git a/include/client/tickets.inc.php b/include/client/tickets.inc.php index d88ec62d51a78227497452396abf93111a0a9a10..76412f7e3b49e8921a432cc4f65369fcb46d1007 100644 --- a/include/client/tickets.inc.php +++ b/include/client/tickets.inc.php @@ -45,7 +45,7 @@ $$x=' class="'.strtolower($_REQUEST['order'] ?: 'desc').'" '; // Add visibility constraints $tickets->filter(Q::any(array( 'user_id' => $thisclient->getId(), - 'collaborators__user_id' => $thisclient->getId(), + 'thread__collaborators__user_id' => $thisclient->getId(), ))); // Perform basic search diff --git a/include/staff/templates/tickets.tmpl.php b/include/staff/templates/tickets.tmpl.php index 6e6b6cf5c383bfceaca595fa135c478b887bb862..ce48d471b659a6ae2b0cb2fb95bc9a646bd90066 100644 --- a/include/staff/templates/tickets.tmpl.php +++ b/include/staff/templates/tickets.tmpl.php @@ -49,8 +49,8 @@ if ($results) { .' LEFT JOIN '.THREAD_ENTRY_TABLE.' entry ON (entry.thread_id=thread.id) ' .' LEFT JOIN '.ATTACHMENT_TABLE.' attach ON (attach.object_id=entry.id AND attach.`type` = "H") ' - .' LEFT JOIN '.TICKET_COLLABORATOR_TABLE.' collab - ON ( ticket.ticket_id=collab.ticket_id) ' + .' LEFT JOIN '.THREAD_COLLABORATOR_TABLE.' collab + ON ( thread.id=collab.thread_id) ' .' WHERE ticket.ticket_id IN ('.implode(',', db_input(array_keys($results))).') GROUP BY ticket.ticket_id'; $ids_res = db_query($counts_sql); diff --git a/login.php b/login.php index d5df38be538ccb2641c2196a21e5a064cfb304f1..201f840c5b5cf6f4b31bf7e2922eb22d4263db78 100644 --- a/login.php +++ b/login.php @@ -72,11 +72,11 @@ elseif ($_POST && isset($_POST['lticket'])) { Http::redirect('tickets.php'); // This will succeed as it is checked in the authentication backend - $ticket = Ticket::lookup($_POST['lticket']); + $ticket = Ticket::lookupByNumber($_POST['lticket']); // We're using authentication backend so we can guard aganist brute // force attempts (which doesn't buy much since the link is emailed) - $user->sendAccessLink($ticket); + $ticket->sendAccessLink($user); $msg = sprintf(__("%s - access link sent to your email!"), Format::htmlchars($user->getName()->getFirst())); $_POST = null;