diff --git a/bootstrap.php b/bootstrap.php index ef78830715a162dd91118d3edb8e600159adc8fd..4e2259cc3c86660bca8b49c888af6f73c6264a01 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -198,7 +198,6 @@ class Bootstrap { require(INCLUDE_DIR.'class.crypto.php'); require(INCLUDE_DIR.'class.timezone.php'); require_once(INCLUDE_DIR.'class.signal.php'); - require(INCLUDE_DIR.'class.nav.php'); require(INCLUDE_DIR.'class.page.php'); require_once(INCLUDE_DIR.'class.format.php'); //format helpers require_once(INCLUDE_DIR.'class.validator.php'); //Class to help with basic form input validation...please help improve it. diff --git a/client.inc.php b/client.inc.php index 0a572ed1cfb82278c620945c00d32fb60e712427..2ad4d4702139d68e589dd917acfcedd4ca28f30d 100644 --- a/client.inc.php +++ b/client.inc.php @@ -76,6 +76,7 @@ $ost->addExtraHeader('<meta name="csrf_token" content="'.$ost->getCSRFToken().'" /* Client specific defaults */ define('PAGE_LIMIT', DEFAULT_PAGE_LIMIT); +require(INCLUDE_DIR.'class.nav.php'); $nav = new UserNav($thisclient, 'home'); $exempt = in_array(basename($_SERVER['SCRIPT_NAME']), array('logout.php', 'ajax.php', 'logs.php', 'upgrade.php')); diff --git a/include/ajax.orgs.php b/include/ajax.orgs.php index 7c849e6db88bd31267ebd2ab67a9aabb0e1d6e09..c582b578060b8ba09151db6739cc49c6431809ad 100644 --- a/include/ajax.orgs.php +++ b/include/ajax.orgs.php @@ -54,6 +54,8 @@ class OrgsAjaxAPI extends AjaxController { if(!$thisstaff) Http::response(403, 'Login Required'); + elseif (!$thisstaff->getRole()->hasPerm(Organization::PERM_EDIT)) + Http::response(403, 'Permission Denied'); elseif(!($org = Organization::lookup($id))) Http::response(404, 'Unknown organization'); @@ -72,6 +74,8 @@ class OrgsAjaxAPI extends AjaxController { if(!$thisstaff) Http::response(403, 'Login Required'); + elseif (!$thisstaff->getRole()->hasPerm(Organization::PERM_EDIT)) + Http::response(403, 'Permission Denied'); elseif(!($org = Organization::lookup($id))) Http::response(404, 'Unknown organization'); @@ -97,6 +101,8 @@ class OrgsAjaxAPI extends AjaxController { if (!$thisstaff) Http::response(403, 'Login Required'); + elseif (!$thisstaff->getRole()->hasPerm(Organization::PERM_DELETE)) + Http::response(403, 'Permission Denied'); elseif (!($org = Organization::lookup($id))) Http::response(404, 'Unknown organization'); @@ -116,6 +122,8 @@ class OrgsAjaxAPI extends AjaxController { if (!$thisstaff) Http::response(403, 'Login Required'); + elseif (!$thisstaff->getRole()->hasPerm(User::PERM_EDIT)) + Http::response(403, 'Permission Denied'); elseif (!($org = Organization::lookup($id))) Http::response(404, 'Unknown organization'); @@ -137,7 +145,8 @@ class OrgsAjaxAPI extends AjaxController { Format::htmlchars($user->getName())); } else { //Creating new user $form = UserForm::getUserForm()->getForm($_POST); - if (!($user = User::fromForm($form))) + $can_create = $thisstaff->getRole()->hasPerm(User::PERM_CREATE); + if (!($user = User::fromForm($form, $can_create))) $info['error'] = __('Error adding user - try again!'); } @@ -175,6 +184,8 @@ class OrgsAjaxAPI extends AjaxController { if (!$thisstaff) Http::response(403, 'Login Required'); + elseif (!$thisstaff->getRole()->hasPerm(Organization::PERM_CREATE)) + Http::response(403, 'Permission Denied'); elseif (!($org = Organization::lookup($org_id))) Http::response(404, 'No such organization'); @@ -198,6 +209,10 @@ class OrgsAjaxAPI extends AjaxController { } function addOrg() { + global $thisstaff; + + if (!$thisstaff->getRole()->hasPerm(Organization::PERM_CREATE)) + Http::response(403, 'Permission Denied'); $info = array(); @@ -266,6 +281,8 @@ class OrgsAjaxAPI extends AjaxController { if (!$thisstaff) Http::response(403, "Login required"); + elseif (!$thisstaff->getRole()->hasPerm(Organization::PERM_EDIT)) + Http::response(403, 'Permission Denied'); elseif (!($org = Organization::lookup($org_id))) Http::response(404, "No such ticket"); elseif (!isset($_POST['forms'])) diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php index 721da44032dd29c96893016f5733564157732528..990ae735677c635ffbc7f1b78454e33df5282b82 100644 --- a/include/ajax.tickets.php +++ b/include/ajax.tickets.php @@ -181,7 +181,6 @@ class TicketsAjaxAPI extends AjaxController { } function previewTicket ($tid) { - global $thisstaff; if(!$thisstaff || !($ticket=Ticket::lookup($tid)) @@ -448,6 +447,7 @@ class TicketsAjaxAPI extends AjaxController { } function _userlookup($user, $form, $info) { + global $thisstaff; ob_start(); include(STAFFINC_DIR . 'templates/user-lookup.tmpl.php'); diff --git a/include/ajax.users.php b/include/ajax.users.php index cca1b11631263981e16c4f61b4ae6f5065878e45..f3b6c247a00fd57dc8379c077c6e07c1c0e084da 100644 --- a/include/ajax.users.php +++ b/include/ajax.users.php @@ -109,6 +109,8 @@ class UsersAjaxAPI extends AjaxController { if(!$thisstaff) Http::response(403, 'Login Required'); + elseif (!$thisstaff->getRole()->hasPerm(User::PERM_EDIT)) + Http::response(403, 'Permission Denied'); elseif(!($user = User::lookup($id))) Http::response(404, 'Unknown user'); @@ -125,6 +127,8 @@ class UsersAjaxAPI extends AjaxController { if(!$thisstaff) Http::response(403, 'Login Required'); + elseif (!$thisstaff->getRole()->hasPerm(User::PERM_EDIT)) + Http::response(403, 'Permission Denied'); elseif(!($user = User::lookup($id))) Http::response(404, 'Unknown user'); @@ -141,6 +145,8 @@ class UsersAjaxAPI extends AjaxController { if (!$thisstaff) Http::response(403, 'Login Required'); + elseif (!$thisstaff->getRole()->hasPerm(User::PERM_MANAGE)) + Http::response(403, 'Permission Denied'); elseif (!($user = User::lookup($id))) Http::response(404, 'Unknown user'); @@ -168,6 +174,8 @@ class UsersAjaxAPI extends AjaxController { if (!$thisstaff) Http::response(403, 'Login Required'); + elseif (!$thisstaff->getRole()->hasPerm(User::PERM_MANAGE)) + Http::response(403, 'Permission Denied'); elseif (!($user = User::lookup($id))) Http::response(404, 'Unknown user'); @@ -200,6 +208,8 @@ class UsersAjaxAPI extends AjaxController { if (!$thisstaff) Http::response(403, 'Login Required'); + elseif (!$thisstaff->getRole()->hasPerm(User::PERM_DELETE)) + Http::response(403, 'Permission Denied'); elseif (!($user = User::lookup($id))) Http::response(404, 'Unknown user'); @@ -240,6 +250,7 @@ class UsersAjaxAPI extends AjaxController { } function addUser() { + global $thisstaff; $info = array(); @@ -247,6 +258,9 @@ class UsersAjaxAPI extends AjaxController { $info['lookup'] = 'local'; if ($_POST) { + if (!$thisstaff->getRole()->hasPerm(User::PERM_CREATE)) + Http::response(403, 'Permission Denied'); + $info['title'] = __('Add New User'); $form = UserForm::getUserForm()->getForm($_POST); if (($user = User::fromForm($form))) @@ -263,6 +277,8 @@ class UsersAjaxAPI extends AjaxController { if (!$thisstaff) Http::response(403, 'Login Required'); + elseif (!$thisstaff->getRole()->hasPerm(User::PERM_CREATE)) + Http::response(403, 'Permission Denied'); elseif (!$bk || !$id) Http::response(422, 'Backend and user id required'); elseif (!($backend = AuthenticationBackend::getSearchDirectoryBackend($bk)) @@ -284,6 +300,8 @@ class UsersAjaxAPI extends AjaxController { if (!$thisstaff) Http::response(403, 'Login Required'); + elseif (!$thisstaff->getRole()->hasPerm(User::PERM_CREATE)) + Http::response(403, 'Permission Denied'); $info = array( 'title' => __('Import Users'), @@ -304,6 +322,7 @@ class UsersAjaxAPI extends AjaxController { } function selectUser($id) { + global $thisstaff; if ($id) $user = User::lookup($id); @@ -319,9 +338,14 @@ class UsersAjaxAPI extends AjaxController { } static function _lookupform($form=null, $info=array()) { + global $thisstaff; - if (!$info or !$info['title']) - $info += array('title' => __('Lookup or create a user')); + if (!$info or !$info['title']) { + if ($thisstaff->getRole()->hasPerm(User::PERM_CREATE)) + $info += array('title' => __('Lookup or create a user')); + else + $info += array('title' => __('Lookup a user')); + } ob_start(); include(STAFFINC_DIR . 'templates/user-lookup.tmpl.php'); @@ -422,6 +446,8 @@ class UsersAjaxAPI extends AjaxController { if (!$thisstaff) Http::response(403, "Login required"); + elseif (!$thisstaff->getRole()->hasPerm(User::PERM_EDIT)) + Http::response(403, 'Permission Denied'); elseif (!($user = User::lookup($user_id))) Http::response(404, "No such user"); elseif (!isset($_POST['forms'])) diff --git a/include/class.email.php b/include/class.email.php index 31c3dda775dd5f0b8aef0c6300e3a03f6f088add..2943192ef5c6734698829e874275c7574e590ed7 100644 --- a/include/class.email.php +++ b/include/class.email.php @@ -42,8 +42,9 @@ class EmailModel extends VerySimpleModel { 'title' => /* @trans */ 'Banlist', 'desc' => - /* @trans */ 'Ability to add/remove emails from banlist via ticket interface'), - ); + /* @trans */ 'Ability to add/remove emails from banlist via ticket interface', + 'primary' => true, + )); function getId() { return $this->email_id; diff --git a/include/class.faq.php b/include/class.faq.php index 9b95776031909bb948bacd74127e45182cca2135..a20060729ac804fe4284778fbe2424ba2002bffd 100644 --- a/include/class.faq.php +++ b/include/class.faq.php @@ -53,9 +53,9 @@ class FAQ extends VerySimpleModel { 'title' => /* @trans */ 'FAQ', 'desc' => - /* @trans */ 'Ability to add/update/disable/delete knowledgebase categories and FAQs'), - ); - + /* @trans */ 'Ability to add/update/disable/delete knowledgebase categories and FAQs', + 'primary' => true, + )); var $attachments; var $topics; diff --git a/include/class.nav.php b/include/class.nav.php index d3cbb943dfe2cd0e219060dea7802482f8d23585..92d08996a2bcd6d2076955021b36fc570c2e7dda 100644 --- a/include/class.nav.php +++ b/include/class.nav.php @@ -111,10 +111,18 @@ class StaffNav { function getTabs(){ + global $thisstaff; + if(!$this->tabs) { - $this->tabs=array(); - $this->tabs['dashboard'] = array('desc'=>__('Dashboard'),'href'=>'dashboard.php','title'=>__('Agent Dashboard')); - $this->tabs['users'] = array('desc' => __('Users'), 'href' => 'users.php', 'title' => __('User Directory')); + $this->tabs = array(); + $this->tabs['dashboard'] = array( + 'desc'=>__('Dashboard'),'href'=>'dashboard.php','title'=>__('Agent Dashboard') + ); + if ($thisstaff->getRole()->hasPerm(User::PERM_DIRECTORY)) { + $this->tabs['users'] = array( + 'desc' => __('Users'), 'href' => 'users.php', 'title' => __('User Directory') + ); + } $this->tabs['tickets'] = array('desc'=>__('Tickets'),'href'=>'tickets.php','title'=>__('Ticket Queue')); $this->tabs['kbase'] = array('desc'=>__('Knowledgebase'),'href'=>'kb.php','title'=>__('Knowledgebase')); if (count($this->getRegisteredApps())) diff --git a/include/class.organization.php b/include/class.organization.php index e13329507aba063361ad6cd834554f89b37f18cd..b5fed6c32115a366971834803f7f4f231771cdfc 100644 --- a/include/class.organization.php +++ b/include/class.organization.php @@ -35,6 +35,28 @@ class OrganizationModel extends VerySimpleModel { const COLLAB_PRIMARY_CONTACT = 0x0002; const ASSIGN_AGENT_MANAGER = 0x0004; + const PERM_CREATE = 'org.create'; + const PERM_EDIT = 'org.edit'; + const PERM_DELETE = 'org.delete'; + + static protected $perms = array( + self::PERM_CREATE => array( + 'title' => /* @trans */ 'Create', + 'desc' => /* @trans */ 'Ability to create new organizations', + 'primary' => true, + ), + self::PERM_EDIT => array( + 'title' => /* @trans */ 'Edit', + 'desc' => /* @trans */ 'Ability to manage organizations', + 'primary' => true, + ), + self::PERM_DELETE => array( + 'title' => /* @trans */ 'Delete', + 'desc' => /* @trans */ 'Ability to delete organizations', + 'primary' => true, + ), + ); + var $_manager; function getId() { @@ -101,7 +123,14 @@ class OrganizationModel extends VerySimpleModel { function allMembers() { return $this->users; } + + static function getPermissions() { + return self::$perms; + } } +include_once INCLUDE_DIR.'class.role.php'; +RolePermission::register(/* @trans */ 'Organizations', + OrganizationModel::getPermissions()); class OrganizationCdata extends VerySimpleModel { static $meta = array( diff --git a/include/class.report.php b/include/class.report.php index 0e8bae980f7af555cd743551655df3fbdb89e7e5..059325b3f44a69c1905582ba1826a8594ad93dc1 100644 --- a/include/class.report.php +++ b/include/class.report.php @@ -9,8 +9,9 @@ class ReportModel { 'title' => /* @trans */ 'Stats', 'desc' => - /* @trans */ 'Ability to view stats of other agents in allowed departments'), - ); + /* @trans */ 'Ability to view stats of other agents in allowed departments', + 'primary' => true, + )); static function getPermissions() { return self::$perms; diff --git a/include/class.role.php b/include/class.role.php index 476bd9a72b89721f1235a9f3b1dfdf65a2d89587..b2bcd2c97d0813d7cff5fd03d854bbf607cadeb1 100644 --- a/include/class.role.php +++ b/include/class.role.php @@ -266,6 +266,8 @@ class RolePermission { static protected $_permissions = array( /* @trans */ 'Tickets' => array(), /* @trans */ 'Tasks' => array(), + /* @trans */ 'Users' => array(), + /* @trans */ 'Organizations' => array(), /* @trans */ 'Knowledgebase' => array(), /* @trans */ 'Miscellaneous' => array(), ); diff --git a/include/class.search.php b/include/class.search.php index 5436ff519333b7ff3e578703fc13672cd194ed34..84d3bbbcdc7d4478be5d1af5e733eadda3e7a323 100644 --- a/include/class.search.php +++ b/include/class.search.php @@ -30,6 +30,16 @@ abstract class SearchBackend { const SORT_RECENT = 2; const SORT_OLDEST = 3; + const PERM_EVERYTHING = 'search.all'; + + static protected $perms = array( + self::PERM_EVERYTHING => array( + 'title' => /* @trans */ 'Search', + 'desc' => /* @trans */ 'See all tickets in search results, regardless of access', + 'primary' => true, + ), + ); + abstract function update($model, $id, $content, $new=false, $attrs=array()); abstract function find($query, QuerySet $criteria); @@ -48,7 +58,12 @@ abstract class SearchBackend { return new self::$registry[$id](); } + + static function getPermissions() { + return self::$perms; + } } +RolePermission::register(/* @trans */ 'Miscellaneous', SearchBackend::getPermissions()); // Register signals to intercept saving of various content throughout the // system diff --git a/include/class.staff.php b/include/class.staff.php index 44f7d6302e70558bbfe604b74050d825218836a7..6a7c06a260ddf63e0cdfda442c65cd74f7daa548 100644 --- a/include/class.staff.php +++ b/include/class.staff.php @@ -320,7 +320,7 @@ implements AuthenticatedUser, EmailContact { if (isset($this->_roles[$deptId])) return $this->_roles[$deptId]; - if (($role=$this->group->getRole($deptId))) + if (($role = $this->group->getRole($deptId))) return $this->_roles[$deptId] = $role; } // For the primary department, use the primary role @@ -329,6 +329,7 @@ implements AuthenticatedUser, EmailContact { function hasPerm($perm) { if (!isset($this->_perms)) { + $this->_perms = array(); foreach ($this->getDepartments() as $deptId) { if (($role = $this->getRole($deptId))) { foreach ($role->getPermission()->getInfo() as $perm=>$v) { @@ -337,7 +338,7 @@ implements AuthenticatedUser, EmailContact { } } } - return @$this->_perms[$perm]; + return @$this->_perms[$perm] ?: false; } function canManageTickets() { diff --git a/include/class.ticket.php b/include/class.ticket.php index 0505d9832bceb4ceda56ce80d52c462fd3b95e54..c5f364de9b756bbbb9e9db142ae1a4bbc3b3514e 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -2790,7 +2790,7 @@ implements RestrictedAccess, Threadable { */ static function create($vars, &$errors, $origin, $autorespond=true, $alertstaff=true) { - global $ost, $cfg, $thisclient, $_FILES; + global $ost, $cfg, $thisclient, $thisstaff; // Don't enforce form validation for email $field_filter = function($type) use ($origin) { @@ -2958,9 +2958,14 @@ implements RestrictedAccess, Threadable { } $user_form = UserForm::getUserForm()->getForm($vars); + $can_create = $thisstaff->getRole()->hasPerm(User::PERM_CREATE); if (!$user_form->isValid($field_filter('user')) - || !($user=User::fromVars($user_form->getClean()))) - $errors['user'] = __('Incomplete client information'); + || !($user=User::fromVars($user_form->getClean(), $can_create)) + ) { + $errors['user'] = $can_create + ? __('Incomplete client information') + : __('You do not have permission to create users.'); + } } } diff --git a/include/class.user.php b/include/class.user.php index 1bef5404b7eb68cec647d2e4864e296f85680b00..0ad21e055023ae751ebe044f54cb78068c1d9ad3 100644 --- a/include/class.user.php +++ b/include/class.user.php @@ -69,6 +69,40 @@ class UserModel extends VerySimpleModel { const PRIMARY_ORG_CONTACT = 0x0001; + const PERM_CREATE = 'user.create'; + const PERM_EDIT = 'user.edit'; + const PERM_DELETE = 'user.delete'; + const PERM_MANAGE = 'user.manage'; + const PERM_DIRECTORY = 'user.dir'; + + static protected $perms = array( + self::PERM_CREATE => array( + 'title' => /* @trans */ 'Create', + 'desc' => /* @trans */ 'Ability to add new users', + 'primary' => true, + ), + self::PERM_EDIT => array( + 'title' => /* @trans */ 'Edit', + 'desc' => /* @trans */ 'Ability to manage user information', + 'primary' => true, + ), + self::PERM_DELETE => array( + 'title' => /* @trans */ 'Delete', + 'desc' => /* @trans */ 'Ability to delete users', + 'primary' => true, + ), + self::PERM_MANAGE => array( + 'title' => /* @trans */ 'Manage Account', + 'desc' => /* @trans */ 'Ability to manage active user accounts', + 'primary' => true, + ), + self::PERM_DIRECTORY => array( + 'title' => /* @trans */ 'User Directory', + 'desc' => /* @trans */ 'Ability to access the user directory', + 'primary' => true, + ), + ); + function getId() { return $this->id; } @@ -125,7 +159,13 @@ class UserModel extends VerySimpleModel { else $this->clearStatus(User::PRIMARY_ORG_CONTACT); } + + static function getPermissions() { + return self::$perms; + } } +include_once INCLUDE_DIR.'class.role.php'; +RolePermission::register(/* @trans */ 'Users', UserModel::getPermissions()); class UserCdata extends VerySimpleModel { static $meta = array( @@ -146,10 +186,10 @@ class User extends UserModel { var $_entries; var $_forms; - static function fromVars($vars) { + static function fromVars($vars, $create=true) { // Try and lookup by email address $user = static::lookupByEmail($vars['email']); - if (!$user) { + if (!$user && $create) { $name = $vars['name']; if (!$name) list($name) = explode('@', $vars['email'], 2); @@ -184,7 +224,7 @@ class User extends UserModel { return $user; } - static function fromForm($form) { + static function fromForm($form, $create=true) { global $thisstaff; if(!$form) return null; @@ -205,7 +245,7 @@ class User extends UserModel { $valid = false; } - return $valid ? self::fromVars($form->getClean()) : null; + return $valid ? self::fromVars($form->getClean(), $create) : null; } function getEmail() { @@ -623,8 +663,14 @@ class PersonsName { elseif($cfg) $this->format = $cfg->getDefaultNameFormat(); - $this->parts = static::splitName($name); - $this->name = $name; + if (!is_array($name)) { + $this->parts = static::splitName($name); + $this->name = $name; + } + else { + $this->parts = $name; + $this->name = implode(' ', $name); + } } function getFirst() { diff --git a/include/i18n/en_US/role.yaml b/include/i18n/en_US/role.yaml index d83a60c2914848730123c02c623b52e7b210cd71..4e3a15e839dc06621146f12a3ca46e1f24ed2e3f 100644 --- a/include/i18n/en_US/role.yaml +++ b/include/i18n/en_US/role.yaml @@ -34,7 +34,15 @@ kb.premade, kb.faq, stats.agents, - emails.banlist] + emails.banlist, + user.edit, + user.delete, + user.manage, + user.dir, + org.create, + org.edit, + org.delete, + search.all] - id: 2 flags: 1 @@ -58,7 +66,14 @@ kb.premade, kb.faq, stats.agents, - emails.banlist] + emails.banlist, + user.edit, + user.delete, + user.manage, + user.dir, + org.create, + org.edit, + org.delete] - id: 3 flags: 1 @@ -74,4 +89,9 @@ task.create, task.assign, task.transfer, - task.reply] + task.reply, + user.edit, + user.manage, + user.dir, + org.create, + org.edit] diff --git a/include/staff/org-view.inc.php b/include/staff/org-view.inc.php index 112570e2e8c0f7679281b1d0a2cb88dbbfb31f06..492a5b86c51a9725f0a4a34de459afe66aa8cd7f 100644 --- a/include/staff/org-view.inc.php +++ b/include/staff/org-view.inc.php @@ -9,21 +9,27 @@ if(!defined('OSTSCPINC') || !$thisstaff || !is_object($org)) die('Invalid path') title="Reload"><i class="icon-refresh"></i> <?php echo $org->getName(); ?></a></h2> </td> <td width="50%" class="right_align has_bottom_border"> +<?php if ($thisstaff->getRole()->hasPerm(Organization::PERM_EDIT)) { ?> <span class="action-button pull-right" data-dropdown="#action-dropdown-more"> <i class="icon-caret-down pull-right"></i> <span ><i class="icon-cog"></i> <?php echo __('More'); ?></span> </span> +<?php } ?> +<?php if ($thisstaff->getRole()->hasPerm(Organization::PERM_DELETE)) { ?> <a id="org-delete" class="action-button pull-right org-action" href="#orgs/<?php echo $org->getId(); ?>/delete"><i class="icon-trash"></i> <?php echo __('Delete Organization'); ?></a> +<?php } ?> <div id="action-dropdown-more" class="action-dropdown anchor-right"> <ul> +<?php if ($thisstaff->getRole()->hasPerm(Organization::PERM_EDIT)) { ?> <li><a href="#ajax.php/orgs/<?php echo $org->getId(); ?>/forms/manage" onclick="javascript: $.dialog($(this).attr('href').substr(1), 201); return false" ><i class="icon-paste"></i> <?php echo __('Manage Forms'); ?></a></li> +<?php } ?> </ul> </div> </td> @@ -35,11 +41,17 @@ if(!defined('OSTSCPINC') || !$thisstaff || !is_object($org)) die('Invalid path') <table border="0" cellspacing="" cellpadding="4" width="100%"> <tr> <th width="150"><?php echo __('Name'); ?>:</th> - <td><b><a href="#orgs/<?php echo $org->getId(); + <td> +<?php if ($thisstaff->getRole()->hasPerm(Organization::PERM_EDIT)) { ?> + <b><a href="#orgs/<?php echo $org->getId(); ?>/edit" class="org-action"><i - class="icon-edit"></i> <?php echo - $org->getName(); - ?></a></td> + class="icon-edit"></i> +<?php } + echo $org->getName(); + if ($thisstaff->getRole()->hasPerm(Organization::PERM_EDIT)) { ?> + </a></b> +<?php } ?> + </td> </tr> <tr> <th><?php echo __('Account Manager'); ?>:</th> diff --git a/include/staff/orgs.inc.php b/include/staff/orgs.inc.php index f75f67f556d9e6fbf715ed374a1771e5b06c44d0..4973b0b6252933fc87a8106b3ad3f0fcbe79f6bf 100644 --- a/include/staff/orgs.inc.php +++ b/include/staff/orgs.inc.php @@ -86,9 +86,11 @@ $_SESSION['orgs_qs_'.$qhash] = $query; </table> </form> </div> +<?php if ($thisstaff->getRole()->hasPerm(Organization::PERM_CREATE)) { ?> <div class="pull-right flush-right"> <b><a href="#orgs/add" class="Icon newDepartment add-org"><?php echo __('Add New Organization'); ?></a></b></div> +<?php } ?> <div class="clear"></div> <?php $showing = $search ? __('Search Results').': ' : ''; diff --git a/include/staff/role.inc.php b/include/staff/role.inc.php index 25384cd39977d15950297605ec05bc11b3308db8..309d26d7bd86dfb74c6deb1fc8ffd020a0a3a92b 100644 --- a/include/staff/role.inc.php +++ b/include/staff/role.inc.php @@ -96,11 +96,15 @@ $info = Format::htmlchars(($errors && $_POST) ? array_merge($info, $_POST) : $in (isset($setting[$k]) && $setting[$k]) ? 'checked="checked"' : ''); ?> + <?php echo Format::htmlchars(__($v['title'])); ?> + — <?php - echo sprintf('%s - <em>%s</em>', - Format::htmlchars(__($v['title'])), - Format::htmlchars(__($v['desc']))); - ?> + if ($v['primary']) { ?> + <i class="icon-globe faded" title="<?php echo + __('This permission only applies to the staff primary role'); ?>"></i> +<?php } ?> + <em><?php echo Format::htmlchars(__($v['desc'])); + ?></em> </label> </td> </tr> diff --git a/include/staff/templates/tickets.tmpl.php b/include/staff/templates/tickets.tmpl.php index e70d3e29cd537338d5feb20b6f5f070acdf60de9..7fc45a41afd9328dc2b3300b16b935385e57fa76 100644 --- a/include/staff/templates/tickets.tmpl.php +++ b/include/staff/templates/tickets.tmpl.php @@ -1,63 +1,42 @@ <?php -$select ='SELECT ticket.ticket_id,ticket.`number`,ticket.dept_id,ticket.staff_id,ticket.team_id, ticket.user_id ' - .' ,dept.name as department, status.name as status,ticket.source,ticket.isoverdue,ticket.isanswered,ticket.created ' - .' ,CAST(GREATEST(IFNULL(ticket.lastmessage, 0), IFNULL(ticket.reopened, 0), ticket.created) as datetime) as effective_date ' - .' ,CONCAT_WS(" ", staff.firstname, staff.lastname) as staff, team.name as team ' - .' ,IF(staff.staff_id IS NULL,team.name,CONCAT_WS(" ", staff.lastname, staff.firstname)) as assigned ' - .' ,IF(ptopic.topic_pid IS NULL, topic.topic, CONCAT_WS(" / ", ptopic.topic, topic.topic)) as helptopic ' - .' ,cdata.priority as priority_id, cdata.subject, user.name, email.address as email'; +$tickets = TicketModel::objects(); -$from =' FROM '.TICKET_TABLE.' ticket ' - .' LEFT JOIN '.TICKET_STATUS_TABLE.' status - ON status.id = ticket.status_id ' - .' LEFT JOIN '.USER_TABLE.' user ON user.id = ticket.user_id ' - .' LEFT JOIN '.USER_EMAIL_TABLE.' email ON user.id = email.user_id ' - .' LEFT JOIN '.USER_ACCOUNT_TABLE.' account ON (ticket.user_id=account.user_id) ' - .' LEFT JOIN '.DEPT_TABLE.' dept ON ticket.dept_id=dept.id ' - .' LEFT JOIN '.STAFF_TABLE.' staff ON (ticket.staff_id=staff.staff_id) ' - .' LEFT JOIN '.TEAM_TABLE.' team ON (ticket.team_id=team.team_id) ' - .' LEFT JOIN '.TOPIC_TABLE.' topic ON (ticket.topic_id=topic.topic_id) ' - .' LEFT JOIN '.TOPIC_TABLE.' ptopic ON (ptopic.topic_id=topic.topic_pid) ' - .' LEFT JOIN '.TABLE_PREFIX.'ticket__cdata cdata ON (cdata.ticket_id = ticket.ticket_id) ' - .' LEFT JOIN '.PRIORITY_TABLE.' pri ON (pri.priority_id = cdata.priority)'; +if ($user) { + $tickets->filter(array('user_id' => $user->getId())); +} +elseif ($org) { + $tickets->filter(array('user__org' => $org)); +} + +if (!$thisstaff->getRole()->hasPerm(SearchBackend::PERM_EVERYTHING)) { + // -- Open and assigned to me + $visibility = array( + new Q(array('status__state'=>'open', 'staff_id' => $thisstaff->getId())) + ); + // -- Routed to a department of mine + if (!$thisstaff->showAssignedOnly() && ($depts=$thisstaff->getDepts())) + $visibility[] = new Q(array('dept_id__in' => $depts)); + // -- Open and assigned to a team of mine + if (($teams = $thisstaff->getTeams()) && count(array_filter($teams))) + $visibility[] = new Q(array( + 'team_id__in' => array_filter($teams), 'status__state'=>'open' + )); + $tickets->filter(Q::any($visibility)); +} -if ($user) - $where = 'WHERE ticket.user_id = '.db_input($user->getId()); -elseif ($org) - $where = 'WHERE user.org_id = '.db_input($org->getId()); +$tickets->annotate(array( + 'collab_count' => SqlAggregate::COUNT('thread__collaborators'), + 'attachment_count' => SqlAggregate::COUNT('thread__entries__attachments'), + 'thread_count' => SqlAggregate::COUNT('thread__entries'), +)); +$tickets->values('staff_id', 'staff__firstname', 'staff__lastname', 'team__name', 'team_id', 'lock__lock_id', 'lock__staff_id', 'isoverdue', 'status_id', 'status__name', 'status__state', 'number', 'cdata__subject', 'ticket_id', 'source', 'dept_id', 'dept__name', 'user_id', 'user__default_email__address', 'user__name'); TicketForm::ensureDynamicDataView(); -$query ="$select $from $where ORDER BY ticket.created DESC"; - // Fetch the results -$results = array(); -$res = db_query($query); -while ($row = db_fetch_array($res)) - $results[$row['ticket_id']] = $row; - -if ($results) { - $counts_sql = 'SELECT ticket.ticket_id, - count(DISTINCT attach.id) as attachments, - count(DISTINCT entry.id) as thread_count, - count(DISTINCT collab.id) as collaborators - FROM '.TICKET_TABLE.' ticket ' - .' LEFT JOIN '.THREAD_TABLE.' thread - ON (thread.object_id=ticket.ticket_id AND thread.object_type="T") ' - .' 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 '.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); - while ($row = db_fetch_array($ids_res)) { - $results[$row['ticket_id']] += $row; - } -} +$results = count($tickets); ?> <div style="width:700px;" class="pull-left"> <?php @@ -94,80 +73,91 @@ if ($results) { ?> <?php } ?> <th width="70"><?php echo __('Ticket'); ?></th> - <th width="100"><?php echo __('Date'); ?></th> - <th width="100"><?php echo __('Status'); ?></th> - <th width="300"><?php echo __('Subject'); ?></th> + <th width="120"><?php echo __('Date'); ?></th> + <th width="70"><?php echo __('Status'); ?></th> + <th width="380"><?php echo __('Subject'); ?></th> <?php if ($user) { ?> - <th width="100"><?php echo __('Department'); ?></th> - <th width="100"><?php echo __('Assignee'); ?></th> + <th width="150"><?php echo __('Department'); ?></th> + <th width="150"><?php echo __('Assignee'); ?></th> <?php } else { ?> - <th width="200"><?php echo __('User'); ?></th> + <th width="300"><?php echo __('User'); ?></th> <?php } ?> </tr> </thead> <tbody> <?php - foreach($results as $row) { + $subject_field = TicketForm::objects()->one()->getField('subject'); + foreach($tickets as $T) { $flag=null; - if ($row['lock_id']) + if ($T['lock__lock_id'] && $T['lock__staff_id'] != $thisstaff->getId()) $flag='locked'; - elseif ($row['isoverdue']) + elseif ($T['isoverdue']) $flag='overdue'; $assigned=''; - if ($row['staff_id']) - $assigned=sprintf('<span class="truncate Icon staffAssigned">%s</span>',$row['staff']); - elseif ($row['team_id']) - $assigned=sprintf('<span class="truncate Icon teamAssigned">%s</span>',$row['team']); + if ($T['staff_id']) + $assigned = new PersonsName(array( + 'first' => $row['staff__firstname'], + 'last' => $row['staff__lastname'] + )); + elseif ($T['team_id']) + $assigned = Team::getLocalById($T['team_id'], 'name', $T['team__name']); else $assigned=' '; - $status = ucfirst($row['status']); - $tid=$row['number']; - $subject = Format::htmlchars($row['subject']); - $threadcount=$row['thread_count']; + $status = TicketStatus::getLocalById($T['status_id'], 'value', $T['status__name']); + $tid = $T['number']; + $subject = $subject_field->display($subject_field->to_php($T['cdata__subject'])); + $threadcount = $T['thread_count']; ?> - <tr id="<?php echo $row['ticket_id']; ?>"> + <tr id="<?php echo $T['ticket_id']; ?>"> <?php //Implement mass action....if need be. if (0) { ?> <td align="center" class="nohover"> - <input class="ckb" type="checkbox" name="tids[]" value="<?php echo $row['ticket_id']; ?>" <?php echo $sel?'checked="checked"':''; ?>> + <input class="ckb" type="checkbox" name="tids[]" value="<?php echo $T['ticket_id']; ?>" <?php echo $sel?'checked="checked"':''; ?>> </td> <?php } ?> <td align="center" nowrap> <a class="Icon <?php - echo strtolower($row['source']); ?>Ticket preview" + echo strtolower($T['source']); ?>Ticket preview" title="<?php echo __('Preview Ticket'); ?>" - href="tickets.php?id=<?php echo $row['ticket_id']; ?>" - data-preview="#tickets/<?php echo $row['ticket_id']; ?>/preview"><?php echo $tid; ?></a></td> + href="tickets.php?id=<?php echo $T['ticket_id']; ?>" + data-preview="#tickets/<?php echo $T['ticket_id']; ?>/preview"><?php echo $tid; ?></a></td> <td align="center" nowrap><?php echo Format::datetime($row['effective_date']); ?></td> <td><?php echo $status; ?></td> - <td><a class="truncate <?php if ($flag) { ?> Icon <?php echo $flag; ?>Ticket" title="<?php echo ucfirst($flag); ?> Ticket<?php } ?>" - style="max-width: 80%; max-width: calc(100% - 86px);" - href="tickets.php?id=<?php echo $row['ticket_id']; ?>"><?php echo $subject; ?></a> + <td><a <?php if ($flag) { ?> class="Icon <?php echo $flag; ?>Ticket" title="<?php echo ucfirst($flag); ?> Ticket" <?php } ?> + href="tickets.php?id=<?php echo $T['ticket_id']; ?>"><span class="truncate" + style="max-width: 290px"><?php echo $subject; ?></span></a> <?php - if ($threadcount>1) - echo "<small>($threadcount)</small> ".'<i - class="icon-fixed-width icon-comments-alt"></i> '; - if ($row['collaborators']) - echo '<i class="icon-fixed-width icon-group faded"></i> '; + if ($threadcount > 1) { ?> + <span class="pull-right faded-more"><i class="icon-comments-alt"></i> + <small><?php echo $threadcount; ?></small> +<?php } if ($row['attachments']) - echo '<i class="icon-fixed-width icon-paperclip"></i> '; + echo '<i class="small icon-paperclip icon-flip-horizontal"></i>'; + if ($row['collaborators']) + echo '<i class="icon-group faded-more"></i>'; ?> </td> <?php - if ($user) { ?> - <td><span class="truncate"><?php echo $row['department']; ?></td> - <td> <?php echo $assigned; ?></td> + if ($user) { + $dept = Dept::getLocalById($T['dept_id'], 'name', $T['dept__name']); ?> + <td><span class="truncate" style="max-wdith:150px"><?php + echo Format::htmlchars($dept); ?></span></td> + <td><span class="truncate" style="max-width:150px"><?php + echo Format::htmlchars($assigned); ?></span></td> <?php } else { ?> - <td> <?php echo sprintf('<a href="users.php?id=%d">%s <em> <%s></em></a>', - $row['user_id'], $row['name'], $row['email']); ?></td> + <td><a class="truncate" style="max-width:250px" href="users.php?id="<?php + echo $T['user_id']; ?>><?php echo Format::htmlchars($T['user__name']); + ?> <em><<?php echo Format::htmlchars($T['user__default_email__address']); + ?>></em</a> + </td> <?php } ?> </tr> diff --git a/include/staff/templates/user-import.tmpl.php b/include/staff/templates/user-import.tmpl.php index b9ca02007d39bb21c5806edd74c79acbdd8216b8..413ed54e4bcbaeed35f4a2a234e4d78722b4a96d 100644 --- a/include/staff/templates/user-import.tmpl.php +++ b/include/staff/templates/user-import.tmpl.php @@ -22,12 +22,6 @@ if ($info['error']) { $(this).attr('action', '<?php echo $info['upload_url']; ?>'); $(document).unbind('submit.dialog'); }"> -<ul class="tabs"> - <li class="active"><a href="#copy-paste" - ><i class="icon-edit"></i> <?php echo __('Copy Paste'); ?></a></li> - <li><a href="#upload" - ><i class="icon-fixed-width icon-cloud-upload"></i> <?php echo __('Upload'); ?></a></li> -</ul> <?php echo csrf_token(); if ($org_id) { ?> <input type="hidden" name="id" value="<?php echo $org_id; ?>"/> diff --git a/include/staff/templates/user-lookup.tmpl.php b/include/staff/templates/user-lookup.tmpl.php index fa18f885888041d997c5e75e192d5644e7fd35b2..568df91f8d84ed4c4cb18fcf2745722e2e613a13 100644 --- a/include/staff/templates/user-lookup.tmpl.php +++ b/include/staff/templates/user-lookup.tmpl.php @@ -4,9 +4,11 @@ <hr/> <?php if (!isset($info['lookup']) || $info['lookup'] !== false) { ?> -<div><p id="msg_info"><i class="icon-info-sign"></i> <?php echo __( -'Search existing users or add a new user.' -); ?></p></div> +<div><p id="msg_info"><i class="icon-info-sign"></i> <?php echo + $thisstaff->getRole()->hasPerm(User::PERM_CREATE) + ? __('Search existing users or add a new user.') + : __('Search existing users.'); +?></p></div> <div style="margin-bottom:10px;"> <input type="text" class="search-input" style="width:100%;" placeholder="<?php echo __('Search by email, phone or name'); ?>" id="user-search" @@ -26,10 +28,12 @@ if ($info['error']) { <form method="post" class="user" action="<?php echo $info['action'] ? $info['action'] : '#users/lookup'; ?>"> <input type="hidden" id="user-id" name="id" value="<?php echo $user ? $user->getId() : 0; ?>"/> <i class="icon-user icon-4x pull-left icon-border"></i> +<?php if ($thisstaff->getRole()->hasPerm(User::PERM_CREATE)) { ?> <a class="action-button pull-right" style="overflow:inherit" id="unselect-user" href="#"><i class="icon-remove"></i> <?php echo __('Add New User'); ?></a> -<?php if ($user) { ?> +<?php } +if ($user) { ?> <div><strong id="user-name"><?php echo Format::htmlchars($user->getName()->getOriginal()); ?></strong></div> <div><<span id="user-email"><?php echo $user->getEmail(); ?></span>></div> <?php @@ -65,6 +69,7 @@ if ($info['error']) { </form> </div> <div id="new-user-form" style="display:<?php echo $user ? 'none' :'block'; ?>;"> +<?php if ($thisstaff->getRole()->hasPerm(User::PERM_CREATE)) { ?> <form method="post" class="user" action="<?php echo $info['action'] ?: '#users/lookup/form'; ?>"> <table width="100%" class="fixed"> <?php @@ -82,6 +87,15 @@ if ($info['error']) { </span> </p> </form> +<?php } +else { ?> + <hr/> + <p class="full-width"> + <span class="buttons pull-left"> + <input type="button" name="cancel" class="<?php echo $user ? 'cancel' : 'close' ?>" value="<?php echo __('Cancel'); ?>"> + </span> + </p> +<?php } ?> </div> <div class="clear"></div> </div> diff --git a/include/staff/templates/user.tmpl.php b/include/staff/templates/user.tmpl.php index 4737aaea25e1d0c5b923912c7d9dc1a67c197622..55538502017858db5a38abd5bf04f69e395cc620 100644 --- a/include/staff/templates/user.tmpl.php +++ b/include/staff/templates/user.tmpl.php @@ -50,9 +50,13 @@ if ($info['error']) { <div id="user_tabs_container"> <div class="tab_content" id="info-tab"> <div class="floating-options"> +<?php if ($thisstaff->getRole()->hasPerm(User::PERM_EDIT)) { ?> <a href="<?php echo $info['useredit'] ?: '#'; ?>" id="edituser" class="action" title="<?php echo __('Edit'); ?>"><i class="icon-edit"></i></a> +<?php } + if ($thisstaff->getRole()->hasPerm(User::PERM_DIRECTORY)) { ?> <a href="users.php?id=<?php echo $user->getId(); ?>" title="<?php echo __('Manage User'); ?>" class="action"><i class="icon-share"></i></a> +<?php } ?> </div> <table class="custom-info" width="100%"> <?php foreach ($user->getDynamicData() as $entry) { @@ -72,10 +76,12 @@ if ($info['error']) { <?php if ($org) { ?> <div class="hidden tab_content" id="org-tab"> +<?php if ($thisstaff->getRole()->hasPerm(User::PERM_DIRECTORY)) { ?> <div class="floating-options"> <a href="orgs.php?id=<?php echo $org->getId(); ?>" title="<?php echo __('Manage Organization'); ?>" class="action"><i class="icon-share"></i></a> </div> +<?php } ?> <table class="custom-info" width="100%"> <?php foreach ($org->getDynamicData() as $entry) { ?> diff --git a/include/staff/templates/users.tmpl.php b/include/staff/templates/users.tmpl.php index b95974d214cf17d57ef2062b1d26de4bd7106307..c8a262022a0d036d6127720354c77902ca59861d 100644 --- a/include/staff/templates/users.tmpl.php +++ b/include/staff/templates/users.tmpl.php @@ -57,6 +57,7 @@ else ?> <div style="width:700px;" class="pull-left"><b><?php echo $showing; ?></b></div> +<?php if ($thisstaff->getRole()->hasPerm(User::PERM_EDIT)) { ?> <div class="pull-right flush-right" style="padding-right:5px;"> <b><a href="#orgs/<?php echo $org->getId(); ?>/add-user" class="Icon newstaff add-user" ><?php echo __('Add User'); ?></a></b> @@ -65,6 +66,7 @@ else <i class="icon-cloud-upload icon-large"></i> <?php echo __('Import'); ?></a></b> </div> +<?php } ?> <div class="clear"></div> <br/> <?php diff --git a/include/staff/ticket-open.inc.php b/include/staff/ticket-open.inc.php index 9591f1794afe9ba08f62db40f9fafb073fb88954..a6fe4c26cce9173c1c1d30eaaa954e79de4a99e4 100644 --- a/include/staff/ticket-open.inc.php +++ b/include/staff/ticket-open.inc.php @@ -45,6 +45,7 @@ if ($_POST) <tr> <th colspan="2"> <em><strong><?php echo __('User Information'); ?></strong>: </em> + <div class="error"><?php echo $errors['user']; ?></div> </th> </tr> <?php @@ -84,7 +85,8 @@ if ($_POST) <span style="display:inline-block;"> <input type="text" size=45 name="email" id="user-email" autocomplete="off" autocorrect="off" value="<?php echo $info['email']; ?>" /> </span> - <font class="error">* <?php echo $errors['email']; ?></font> + <span class="error">*</span> + <div class="error"><?php echo $errors['email']; ?></div> </td> </tr> <tr> @@ -92,7 +94,8 @@ if ($_POST) <td> <span style="display:inline-block;"> <input type="text" size=45 name="name" id="user-name" value="<?php echo $info['name']; ?>" /> </span> - <font class="error">* <?php echo $errors['name']; ?></font> + <span class="error">*</span> + <div class="error"><?php echo $errors['name']; ?></div> </td> </tr> <?php diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php index 4b1a1ccef3d645dab29d9c93f1a5e41da187bbbe..a30454b50449800d35b9ddde351faa9ec0722dd1 100644 --- a/include/staff/ticket-view.inc.php +++ b/include/staff/ticket-view.inc.php @@ -224,14 +224,16 @@ if($ticket->isOverdue()) $user->getId(), sprintf(_N('%d Closed Ticket', '%d Closed Tickets', $closed), $closed)); ?> <li><a href="tickets.php?a=search&uid=<?php echo $ticket->getOwnerId(); ?>"><i class="icon-double-angle-right icon-fixed-width"></i> <?php echo __('All Tickets'); ?></a></li> +<?php if ($thisstaff->getRole()->hasPerm(User::PERM_DIRECTORY)) { ?> <li><a href="users.php?id=<?php echo $user->getId(); ?>"><i class="icon-user icon-fixed-width"></i> <?php echo __('Manage User'); ?></a></li> -<?php if ($user->getOrgId()) { ?> +<?php if ($user->getOrgId()) { ?> <li><a href="orgs.php?id=<?php echo $user->getOrgId(); ?>"><i class="icon-building icon-fixed-width"></i> <?php echo __('Manage Organization'); ?></a></li> -<?php } ?> +<?php } + } ?> </ul> </div> <?php diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php index 293acca9a4ee685d2608e3af19d0b7b34813a63f..ca01e03ddb0383ba6451abeeffcf2a85dba5f0b5 100644 --- a/include/staff/tickets.inc.php +++ b/include/staff/tickets.inc.php @@ -2,7 +2,7 @@ $search = SavedSearch::create(); $tickets = TicketModel::objects(); $clear_button = false; -$date_header = $date_col = false; +$view_all_tickets = $date_header = $date_col = false; // Figure out REFRESH url — which might not be accurate after posting a // response @@ -64,6 +64,7 @@ case 'search': $form = $search->getFormFromSession('advsearch'); $form->loadState($_SESSION['advsearch']); $tickets = $search->mangleQuerySet($tickets, $form); + $view_all_tickets = $thisstaff->getRole()->hasPerm(SearchBackend::PERM_EVERYTHING); $results_type=__('Advanced Search') . '<a class="action-button" href="?clear_filter"><i class="icon-ban-circle"></i> <em>' . __('clear') . '</em></a>'; break; @@ -94,19 +95,21 @@ if ($status) // Impose visibility constraints // ------------------------------------------------------------ -// -- Open and assigned to me -$visibility = array( - new Q(array('status__state'=>'open', 'staff_id' => $thisstaff->getId())) -); -// -- Routed to a department of mine -if (!$thisstaff->showAssignedOnly() && ($depts=$thisstaff->getDepts())) - $visibility[] = new Q(array('dept_id__in' => $depts)); -// -- Open and assigned to a team of mine -if (($teams = $thisstaff->getTeams()) && count(array_filter($teams))) - $visibility[] = new Q(array( - 'team_id__in' => array_filter($teams), 'status__state'=>'open' - )); -$tickets->filter(Q::any($visibility)); +if (!$view_all_tickets) { + // -- Open and assigned to me + $visibility = array( + new Q(array('status__state'=>'open', 'staff_id' => $thisstaff->getId())) + ); + // -- Routed to a department of mine + if (!$thisstaff->showAssignedOnly() && ($depts=$thisstaff->getDepts())) + $visibility[] = new Q(array('dept_id__in' => $depts)); + // -- Open and assigned to a team of mine + if (($teams = $thisstaff->getTeams()) && count(array_filter($teams))) + $visibility[] = new Q(array( + 'team_id__in' => array_filter($teams), 'status__state'=>'open' + )); + $tickets->filter(Q::any($visibility)); +} // Add in annotations $tickets->annotate(array( diff --git a/include/staff/user-view.inc.php b/include/staff/user-view.inc.php index 6d29d8b2492287165369760ba3ca7320eaaa9526..9e6fb90faf2f1aeac16daa97a53c5ca0d4325104 100644 --- a/include/staff/user-view.inc.php +++ b/include/staff/user-view.inc.php @@ -13,13 +13,19 @@ $org = $user->getOrganization(); title="Reload"><i class="icon-refresh"></i> <?php echo Format::htmlchars($user->getName()); ?></a></h2> </td> <td width="50%" class="right_align has_bottom_border"> +<?php if (($account && $account->isConfirmed()) + || $thisstaff->getRole()->hasPerm(User::PERM_EDIT)) { ?> <span class="action-button pull-right" data-dropdown="#action-dropdown-more"> <i class="icon-caret-down pull-right"></i> - <span ><i class="icon-cog"></i> <?php echo __('More'); ?></span> + <span><i class="icon-cog"></i> <?php echo __('More'); ?></span> </span> +<?php } + if ($thisstaff->getRole()->hasPerm(User::PERM_DELETE)) { ?> <a id="user-delete" class="action-button pull-right user-action" href="#users/<?php echo $user->getId(); ?>/delete"><i class="icon-trash"></i> <?php echo __('Delete User'); ?></a> +<?php } ?> +<?php if ($thisstaff->getRole()->hasPerm(User::PERM_MANAGE)) { ?> <?php if ($account) { ?> <a id="user-manage" class="action-button pull-right user-action" @@ -32,6 +38,7 @@ $org = $user->getOrganization(); <?php echo __('Register'); ?></a> <?php } ?> +<?php } ?> <div id="action-dropdown-more" class="action-dropdown anchor-right"> <ul> <?php @@ -48,19 +55,22 @@ $org = $user->getOrganization(); <?php echo __('Send Password Reset Email'); ?></a></li> <?php } ?> +<?php if ($thisstaff->getRole()->hasPerm(User::PERM_MANAGE)) { ?> <li><a class="user-action" href="#users/<?php echo $user->getId(); ?>/manage/access"><i class="icon-lock"></i> <?php echo __('Manage Account Access'); ?></a></li> <?php - +} } ?> +<?php if ($thisstaff->getRole()->hasPerm(User::PERM_EDIT)) { ?> <li><a href="#ajax.php/users/<?php echo $user->getId(); ?>/forms/manage" onclick="javascript: $.dialog($(this).attr('href').substr(1), 201); return false" ><i class="icon-paste"></i> <?php echo __('Manage Forms'); ?></a></li> +<?php } ?> </ul> </div> @@ -73,11 +83,18 @@ $org = $user->getOrganization(); <table border="0" cellspacing="" cellpadding="4" width="100%"> <tr> <th width="150"><?php echo __('Name'); ?>:</th> - <td><b><a href="#users/<?php echo $user->getId(); + <td> +<?php +if ($thisstaff->getRole()->hasPerm(User::PERM_EDIT)) { ?> + <b><a href="#users/<?php echo $user->getId(); ?>/edit" class="user-action"><i - class="icon-edit"></i> <?php echo - Format::htmlchars($user->getName()->getOriginal()); - ?></a></td> + class="icon-edit"></i> +<?php } + echo Format::htmlchars($user->getName()->getOriginal()); +if ($thisstaff->getRole()->hasPerm(User::PERM_EDIT)) { ?> + </a> +<?php } ?> +</td> </tr> <tr> <th><?php echo __('Email'); ?>:</th> @@ -93,10 +110,10 @@ $org = $user->getOrganization(); if ($org) echo sprintf('<a href="#users/%d/org" class="user-action">%s</a>', $user->getId(), $org->getName()); - else - echo sprintf('<a href="#users/%d/org" - class="user-action">Add Organization</a>', - $user->getId()); + elseif ($thisstaff->getRole()->hasPerm(User::PERM_EDIT)) { ?> + <a href="#users/<?php echo $user->getId(); ?>/org" + class="user-action"><?php echo __('Add Organization'); ?></a> +<?php } ?> </span> </td> diff --git a/include/staff/users.inc.php b/include/staff/users.inc.php index 763e121d4fec94ac4e6f1f4ee3b7c5b2c52940ac..7e9be8950c5cd1d9c5895018743c2ad79ecc51f7 100644 --- a/include/staff/users.inc.php +++ b/include/staff/users.inc.php @@ -71,12 +71,14 @@ $users->order_by($order . $order_column); </table> </form> </div> +<?php if ($thisstaff->getRole()->hasPerm(User::PERM_CREATE)) { ?> <div class="pull-right flush-right" style="padding-right:5px;"> <b><a href="#users/add" class="Icon newstaff popup-dialog"><?php echo __('Add User'); ?></a></b> | <b><a href="#users/import" class="popup-dialog"><i class="icon-cloud-upload icon-large"></i> <?php echo __('Import'); ?></a></b> </div> +<?php } ?> <div class="clear"></div> <?php $showing = $search ? __('Search Results').': ' : ''; diff --git a/scp/roles.php b/scp/roles.php index 2c9476e29b8cb7499b01f7d5e7d171fe980af980..824d13b14e285a4ae22d22283a9e988f36eaf0bf 100644 --- a/scp/roles.php +++ b/scp/roles.php @@ -15,6 +15,8 @@ **********************************************************************/ require 'admin.inc.php'; +include_once INCLUDE_DIR . 'class.user.php'; +include_once INCLUDE_DIR . 'class.organization.php'; include_once INCLUDE_DIR . 'class.canned.php'; include_once INCLUDE_DIR . 'class.faq.php'; include_once INCLUDE_DIR . 'class.email.php'; diff --git a/scp/staff.inc.php b/scp/staff.inc.php index 2ec1221e7f984044a7612302bcc1ed2c604c2378..e17314959df935b19883410b89a1a64353e44d65 100644 --- a/scp/staff.inc.php +++ b/scp/staff.inc.php @@ -36,7 +36,6 @@ define('KB_PREMADE_TABLE',TABLE_PREFIX.'kb_premade'); require_once(INCLUDE_DIR.'class.staff.php'); require_once(INCLUDE_DIR.'class.group.php'); -require_once(INCLUDE_DIR.'class.nav.php'); require_once(INCLUDE_DIR.'class.csrf.php'); /* First order of the day is see if the user is logged in and with a valid session. @@ -103,6 +102,9 @@ if ($_POST && !$ost->checkCSRFToken()) { //Add token to the header - used on ajax calls [DO NOT CHANGE THE NAME] $ost->addExtraHeader('<meta name="csrf_token" content="'.$ost->getCSRFToken().'" />'); +// Load the navigation after the user in case some things are hidden +require_once(INCLUDE_DIR.'class.nav.php'); + /******* SET STAFF DEFAULTS **********/ define('PAGE_LIMIT', $thisstaff->getPageLimit()?$thisstaff->getPageLimit():DEFAULT_PAGE_LIMIT); diff --git a/scp/users.php b/scp/users.php index ade2474137ff87dd793e9ebc01d9aad9dcd2a98c..a606ddca6adadd5aa34b520348d3ad9f760cd045 100644 --- a/scp/users.php +++ b/scp/users.php @@ -14,6 +14,9 @@ **********************************************************************/ require('staff.inc.php'); +if (!$thisstaff->getRole()->hasPerm(User::PERM_DIRECTORY)) + Http::redirect('index.php'); + require_once INCLUDE_DIR.'class.note.php'; $user = null; @@ -25,6 +28,8 @@ if ($_POST) { case 'update': if (!$user) { $errors['err']=sprintf(__('%s: Unknown or invalid'), _N('end user', 'end users', 1)); + } elseif (!$thisstaff->getRole()->hasPerm(User::PERM_EDIT)) { + $errors['err'] = __('Action denied. Contact admin for access'); } elseif(($acct = $user->getAccount()) && !$acct->update($_POST, $errors)) { $errors['err']=__('Unable to update user account information');