diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php index 2d5ed570088cc5c710e15a3b4091d66fddbe55fc..6825556a98ad07028029130e195d7eaa3d7447d5 100644 --- a/include/ajax.tickets.php +++ b/include/ajax.tickets.php @@ -942,7 +942,7 @@ function refer($tid, $target=null) { || !$ticket->checkStaffPerm($thisstaff)) Http::response(404, 'Unknown ticket #'); - $role = $thisstaff->getRole($ticket->getDeptId()); + $role = $ticket->getRole($thisstaff); $info = array(); $state = null; @@ -995,7 +995,7 @@ function refer($tid, $target=null) { elseif ($status->getId() == $ticket->getStatusId()) $errors['err'] = sprintf(__('Ticket already set to %s status'), __($status->getName())); - elseif (($role = $thisstaff->getRole($ticket->getDeptId()))) { + elseif (($role = $ticket->getRole($thisstaff))) { // Make sure the agent has permission to set the status switch(mb_strtolower($status->getState())) { case 'open': diff --git a/include/class.staff.php b/include/class.staff.php index 8c943417b3a8cc0a04aaae8a2aba6278061807ad..d3676afb5d71a3783cb87a3332d2a30f28cfdca2 100644 --- a/include/class.staff.php +++ b/include/class.staff.php @@ -459,13 +459,21 @@ implements AuthenticatedUser, EmailContact, TemplateVariable, Searchable { return $this->_roles; } - function getRole($dept=null) { - $deptId = is_object($dept) ? $dept->getId() : $dept; + function getRole($dept=null, $assigned=false) { + + if (is_null($dept)) + return $this->role; + + if ((!$dept instanceof Dept) && !($dept=Dept::lookup($dept))) + return null; + + $deptId = $dept->getId(); $roles = $this->getRoles(); if (isset($roles[$deptId])) return $roles[$deptId]; - if ($this->usePrimaryRoleOnAssignment()) + // Default to primary role. + if ($assigned && $this->usePrimaryRoleOnAssignment()) return $this->role; // View only access @@ -534,8 +542,13 @@ implements AuthenticatedUser, EmailContact, TemplateVariable, Searchable { return ($teamId && in_array($teamId, $this->getTeams())); } - function canAccessDept($deptId) { - return ($deptId && in_array($deptId, $this->getDepts()) && !$this->isAccessLimited()); + function canAccessDept($dept) { + + if (!$dept instanceof Dept) + return false; + + return (!$this->isAccessLimited() + && in_array($dept->getId(), $this->getDepts())); } function getTeams() { diff --git a/include/class.task.php b/include/class.task.php index 1a5860b0b87595d6a045058a511f79a78c903ef6..1456272458d49d78463916f6c85f04ff00cc74cd 100644 --- a/include/class.task.php +++ b/include/class.task.php @@ -267,7 +267,7 @@ class Task extends TaskModel implements RestrictedAccess, Threadable { return false; // Check access based on department or assignment - if (!$staff->canAccessDept($this->getDeptId()) + if (!$staff->canAccessDept($this->getDept()) && $this->isOpen() && $staff->getId() != $this->getStaffId() && !$staff->isTeamMember($this->getTeamId())) @@ -279,7 +279,7 @@ class Task extends TaskModel implements RestrictedAccess, Threadable { return true; // Permission check requested -- get role. - if (!($role=$staff->getRole($this->getDeptId()))) + if (!($role=$staff->getRole($this->getDept))) return false; // Check permission based on the effective role @@ -1330,7 +1330,7 @@ class Task extends TaskModel implements RestrictedAccess, Threadable { $task->logEvent('created', null, $thisstaff); // Get role for the dept - $role = $thisstaff->getRole($task->dept_id); + $role = $thisstaff->getRole($task->getDept()); // Assignment $assignee = $vars['internal_formdata']['assignee']; if ($assignee diff --git a/include/class.thread.php b/include/class.thread.php index b06bd0432458f9e062c0a7877274da191d0fb26e..dd10d3a0d326235954f7be5066ccdb5ec182e8c3 100644 --- a/include/class.thread.php +++ b/include/class.thread.php @@ -284,7 +284,7 @@ implements Searchable { function isReferred($to=null, $strict=false) { - if (is_null($to)) + if (is_null($to) || !$this->referrals) return ($this->referrals); switch (true) { @@ -299,12 +299,12 @@ implements Searchable { return false; // Referred to staff's department - if ($this->referrals->findFirst(array( + if ($to->getDepts() && $this->referrals->findFirst(array( 'object_id__in' => $to->getDepts(), 'object_type' => ObjectModel::OBJECT_TYPE_DEPT))) return true; // Referred to staff's team - if ($this->referrals->findFirst(array( + if ($to->getTeams() && $this->referrals->findFirst(array( 'object_id__in' => $to->getTeams(), 'object_type' => ObjectModel::OBJECT_TYPE_TEAM))) return true; diff --git a/include/class.thread_actions.php b/include/class.thread_actions.php index 8cc2d785d2f2c29ab1274e4e349a9c3936e40784..ee0c8b16d9b98868144375ad96a78d60c89503f9 100644 --- a/include/class.thread_actions.php +++ b/include/class.thread_actions.php @@ -135,7 +135,7 @@ class TEA_EditThreadEntry extends ThreadEntryAction { && $T->getDept()->getManagerId() == $thisstaff->getId() ) || ($T instanceof Ticket - && ($role = $thisstaff->getRole($T->getDeptId(), $T->isAssigned($thisstaff))) + && ($role = $T->getRole($thisstaff)) && $role->hasPerm(ThreadEntry::PERM_EDIT) ) ); diff --git a/include/class.ticket.php b/include/class.ticket.php index a6c4d78671420a2cab00eeef80622e9f339c761f..cbfa765800763b6e6c6ea8a7c5a0d9633e4dcc0c 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -248,7 +248,7 @@ implements RestrictedAccess, Threadable, Searchable { if (!$this->isOpen()) return false; - if (!$to) + if (is_null($to)) return ($this->getStaffId() || $this->getTeamId()); switch (true) { @@ -276,30 +276,36 @@ implements RestrictedAccess, Threadable, Searchable { return null !== $this->getLock(); } + function getRole($staff) { + if (!$staff instanceof Staff) + return null; + + return $staff->getRole($this->getDept(), $this->isAssigned($staff)); + } + function checkStaffPerm($staff, $perm=null) { + // Must be a valid staff - if (!$staff instanceof Staff && !($staff=Staff::lookup($staff))) + if ((!$staff instanceof Staff) && !($staff=Staff::lookup($staff))) return false; - // Check access based on department or assignment - if (($staff->showAssignedOnly() - || !$staff->canAccessDept($this->getDeptId())) - // only open tickets can be considered assigned - && $this->isOpen() - && $staff->getId() != $this->getStaffId() - && !$staff->isTeamMember($this->getTeamId()) - && !$this->thread->isReferred($staff) - ) { + // check department access first + if (!$staff->canAccessDept($this->getDept()) + // no restrictions + && !$staff->isAccessLimited() + // check assignment + && !$this->isAssigned($staff) + // check referral + && !$this->thread->isReferred($staff)) return false; - } // At this point staff has view access unless a specific permission is // requested if ($perm === null) return true; - // Permission check requested -- get role. - if (!($role=$staff->getRole($this->getDeptId()))) + // Permission check requested -- get role if any + if (!($role=$this->getRole($staff))) return false; // Check permission based on the effective role @@ -1243,7 +1249,7 @@ implements RestrictedAccess, Threadable, Searchable { function setStatus($status, $comments='', &$errors=array(), $set_closing_agent=true) { global $thisstaff; - if ($thisstaff && !($role = $thisstaff->getRole($this->getDeptId()))) + if ($thisstaff && !($role=$this->getRole($thisstaff))) return false; if ($status && is_numeric($status)) @@ -1682,7 +1688,7 @@ implements RestrictedAccess, Threadable, Searchable { // Is agent on vacation ? && $staff->isAvailable() // Does the agent have access to dept? - && $staff->canAccessDept($dept->getId())) + && $staff->canAccessDept($dept)) $this->setStaffId($staff->getId()); else $this->setStaffId(0); // Clear assignment @@ -3955,7 +3961,8 @@ implements RestrictedAccess, Threadable, Searchable { return false; if ($vars['deptId'] - && ($role = $thisstaff->getRole($vars['deptId'])) + && ($dept=Dept::lookup($vars['deptId'])) + && ($role = $thisstaff->getRole($dept)) && !$role->hasPerm(Ticket::PERM_CREATE) ) { $errors['err'] = sprintf(__('You do not have permission to create a ticket in %s'), __('this department')); @@ -4030,7 +4037,7 @@ implements RestrictedAccess, Threadable, Searchable { $vars['msgId']=$ticket->getLastMsgId(); // Effective role for the department - $role = $thisstaff->getRole($ticket->getDeptId()); + $role = $ticket->getRole($thisstaff); // post response - if any $response = null; diff --git a/include/staff/templates/status-options.tmpl.php b/include/staff/templates/status-options.tmpl.php index c8cff18a94cc8b06535f0ecd017a2b87df9fd841..16d0f885bf3bb4813865d8ebbdc3171cf5be49b1 100644 --- a/include/staff/templates/status-options.tmpl.php +++ b/include/staff/templates/status-options.tmpl.php @@ -1,5 +1,10 @@ <?php global $thisstaff, $ticket; + +$role = $ticket ? $ticket->getRole($thisstaff) : $thisstaff->getRole(); +if ($role && !$role->hasPerm(Ticket::PERM_CLOSE)) + return; + // Map states to actions $actions= array( 'closed' => array( @@ -14,9 +19,8 @@ $actions= array( ); $states = array('open'); -if ($thisstaff->getRole($ticket ? $ticket->getDeptId() : null)->hasPerm(Ticket::PERM_CLOSE) - && (!$ticket || !Ticket::getMissingRequiredFields($ticket))) - $states = array_merge($states, array('closed')); +if (!$ticket || $ticket->isCloseable()) + $states[] = 'closed'; $statusId = $ticket ? $ticket->getStatusId() : 0; $nextStatuses = array(); diff --git a/include/staff/templates/task-view.tmpl.php b/include/staff/templates/task-view.tmpl.php index 0f6d44adf483efa54507354218d700bdb1c9b1eb..adb250728e1ae3bd19c355e78974120bc39237a5 100644 --- a/include/staff/templates/task-view.tmpl.php +++ b/include/staff/templates/task-view.tmpl.php @@ -1,7 +1,7 @@ <?php if (!defined('OSTSCPINC') || !$thisstaff || !$task - || !($role = $thisstaff->getRole($task->getDeptId()))) + || !($role = $thisstaff->getRole($task->getDept()))) die('Invalid path'); global $cfg; diff --git a/include/staff/templates/ticket-preview.tmpl.php b/include/staff/templates/ticket-preview.tmpl.php index b615e37971f7fe9b7f4be23bc547192f752f2893..2431b038471221c6d121f74fc44917dadf034c75 100644 --- a/include/staff/templates/ticket-preview.tmpl.php +++ b/include/staff/templates/ticket-preview.tmpl.php @@ -6,7 +6,7 @@ $staff=$ticket->getStaff(); $lock=$ticket->getLock(); -$role=$thisstaff->getRole($ticket->getDeptId()); +$role=$ticket->getRole($thistaff); $error=$msg=$warn=null; $thread = $ticket->getThread(); diff --git a/include/staff/ticket-tasks.inc.php b/include/staff/ticket-tasks.inc.php index a260f0f05b07e2427b973ccfd68f44ea9ce0e30c..aa765aef5cd39eebf3f68f53f4d02227f5ca4641 100644 --- a/include/staff/ticket-tasks.inc.php +++ b/include/staff/ticket-tasks.inc.php @@ -1,7 +1,7 @@ <?php global $thisstaff; -$role = $thisstaff->getRole($ticket->getDeptId()); +$role = $ticket->getRole($thisstaff); $tasks = Task::objects() ->select_related('dept', 'staff', 'team') diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php index c31d946607c5e6040722de4dad3c3882aebf4524..0767f5ebcd6f5624742965fd34babb0ac1603966 100644 --- a/include/staff/ticket-view.inc.php +++ b/include/staff/ticket-view.inc.php @@ -10,7 +10,7 @@ $info=($_POST && $errors)?Format::input($_POST):array(); //Get the goodies. $dept = $ticket->getDept(); //Dept -$role = $thisstaff->getRole($dept, $ticket->isAssigned($thisstaff)); +$role = $ticket->getRole($thisstaff); $staff = $ticket->getStaff(); //Assigned or closed by.. $user = $ticket->getOwner(); //Ticket User (EndUser) $team = $ticket->getTeam(); //Assigned team. @@ -186,8 +186,10 @@ if($ticket->isOverdue()) return false" ><i class="icon-paste"></i> <?php echo __('Manage Forms'); ?></a></li> <?php - } ?> + } + if ($role->hasPerm(Ticket::PERM_REPLY)) { + ?> <li> <?php @@ -199,9 +201,12 @@ if($ticket->isOverdue()) $recipients); ?> </li> + <?php + } ?> -<?php if ($thisstaff->hasPerm(Email::PERM_BANLIST)) { +<?php if ($thisstaff->hasPerm(Email::PERM_BANLIST) + && $role->hasPerm(Ticket::PERM_REPLY)) { if(!$emailBanned) {?> <li><a class="confirm-action" id="ticket-banemail" href="#banemail"><i class="icon-ban-circle"></i> <?php echo sprintf( diff --git a/scp/tasks.php b/scp/tasks.php index 5cd77777f3714b6ff592878ab25ca6ee35a212a1..63e4b87ca1b35831e54f6bfcde6ce0efe07620db 100644 --- a/scp/tasks.php +++ b/scp/tasks.php @@ -44,7 +44,7 @@ if($_POST && !$errors): if ($task) { //More coffee please. $errors=array(); - $role = $thisstaff->getRole($task->getDeptId()); + $role = $thisstaff->getRole($task->getDept()); switch(strtolower($_POST['a'])): case 'postnote': /* Post Internal Note */ $vars = $_POST; diff --git a/scp/tickets.php b/scp/tickets.php index 112a7f7d581212a1c16ccaab830468af560e6164..773744a69f47513a5febf1451c4820ce9f3826dd 100644 --- a/scp/tickets.php +++ b/scp/tickets.php @@ -139,7 +139,7 @@ if($_POST && !$errors): //More coffee please. $errors=array(); $lock = $ticket->getLock(); //Ticket lock if any - $role = $thisstaff->getRole($ticket->getDeptId()); + $role = $ticket->getRole($thisstaff); switch(strtolower($_POST['a'])): case 'reply': if (!$role || !$role->hasPerm(Ticket::PERM_REPLY)) {