Skip to content

Commit aa4ad2c

Browse files
authored
fix ticket list ignoring validation role
1 parent 6d9f81b commit aa4ad2c

File tree

2 files changed

+224
-95
lines changed

2 files changed

+224
-95
lines changed

src/Ticket.php

Lines changed: 157 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -5395,6 +5395,7 @@ public static function showListForItem(CommonDBTM $item, $withtemplate = 0)
53955395
self::$rightname,
53965396
[self::READALL, self::READMY, self::READASSIGN, CREATE]
53975397
)
5398+
&& !Session::haveRightsOr(TicketValidation::$rightname, TicketValidation::getValidateRights())
53985399
) {
53995400
return false;
54005401
}
@@ -5404,65 +5405,23 @@ public static function showListForItem(CommonDBTM $item, $withtemplate = 0)
54045405
}
54055406

54065407
$criteria = self::getCommonCriteria();
5407-
$restrict = [];
5408-
$options = [
5409-
'criteria' => [],
5410-
'reset' => 'reset',
5411-
];
5408+
$restrict = self::getListForItemRestrict($item);
5409+
$criteria['WHERE'] = $restrict + getEntitiesRestrictCriteria(self::getTable());
5410+
$criteria['WHERE']['glpi_tickets.is_deleted'] = 0;
5411+
$criteria['LIMIT'] = (int)$_SESSION['glpilist_limit'];
54125412

54135413
switch (get_class($item)) {
5414-
case User::class:
5415-
$restrict['glpi_tickets_users.users_id'] = $item->getID();
5416-
$restrict['glpi_tickets_users.type'] = CommonITILActor::REQUESTER;
5417-
5418-
$options['criteria'][0]['field'] = 4; // status
5419-
$options['criteria'][0]['searchtype'] = 'equals';
5420-
$options['criteria'][0]['value'] = $item->getID();
5421-
$options['criteria'][0]['link'] = 'AND';
5422-
break;
5423-
54245414
case SLA::class:
5425-
$restrict[] = [
5426-
'OR' => [
5427-
'slas_id_tto' => $item->getID(),
5428-
'slas_id_ttr' => $item->getID()
5429-
]
5430-
];
54315415
$criteria['ORDERBY'] = 'glpi_tickets.time_to_resolve DESC';
5432-
5433-
$options['criteria'][0]['field'] = 30;
5434-
$options['criteria'][0]['searchtype'] = 'equals';
5435-
$options['criteria'][0]['value'] = $item->getID();
5436-
$options['criteria'][0]['link'] = 'AND';
54375416
break;
54385417

54395418
case OLA::class:
5440-
$restrict[] = [
5441-
'OR' => [
5442-
'olas_id_tto' => $item->getID(),
5443-
'olas_id_ttr' => $item->getID()
5444-
]
5445-
];
54465419
$criteria['ORDERBY'] = 'glpi_tickets.internal_time_to_resolve DESC';
5447-
5448-
$options['criteria'][0]['field'] = 30;
5449-
$options['criteria'][0]['searchtype'] = 'equals';
5450-
$options['criteria'][0]['value'] = $item->getID();
5451-
$options['criteria'][0]['link'] = 'AND';
5452-
break;
5453-
5454-
case Supplier::class:
5455-
$restrict['glpi_suppliers_tickets.suppliers_id'] = $item->getID();
5456-
$restrict['glpi_suppliers_tickets.type'] = CommonITILActor::ASSIGN;
5457-
5458-
$options['criteria'][0]['field'] = 6;
5459-
$options['criteria'][0]['searchtype'] = 'equals';
5460-
$options['criteria'][0]['value'] = $item->getID();
5461-
$options['criteria'][0]['link'] = 'AND';
54625420
break;
54635421

54645422
case Group::class:
5465-
// Mini search engine
5423+
// Mini search engine
5424+
/** @var Group $item */
54665425
if ($item->haveChildren()) {
54675426
$tree = Session::getSavedOption(__CLASS__, 'tree', 0);
54685427
echo "<table class='tab_cadre_fixe'>";
@@ -5479,56 +5438,10 @@ public static function showListForItem(CommonDBTM $item, $withtemplate = 0)
54795438
$tree = 0;
54805439
}
54815440
echo "</td></tr></table>";
5482-
5483-
$restrict['glpi_groups_tickets.groups_id'] = ($tree ? getSonsOf('glpi_groups', $item->getID()) : $item->getID());
5484-
$restrict['glpi_groups_tickets.type'] = CommonITILActor::REQUESTER;
5485-
5486-
$options['criteria'][0]['field'] = 71;
5487-
$options['criteria'][0]['searchtype'] = ($tree ? 'under' : 'equals');
5488-
$options['criteria'][0]['value'] = $item->getID();
5489-
$options['criteria'][0]['link'] = 'AND';
5490-
break;
5491-
5492-
default:
5493-
$restrict['glpi_items_tickets.items_id'] = $item->getID();
5494-
$restrict['glpi_items_tickets.itemtype'] = $item->getType();
5495-
5496-
// you can only see your tickets
5497-
if (!Session::haveRight(self::$rightname, self::READALL)) {
5498-
$or = [
5499-
'glpi_tickets.users_id_recipient' => Session::getLoginUserID(),
5500-
[
5501-
'AND' => [
5502-
'glpi_tickets_users.tickets_id' => new \QueryExpression('glpi_tickets.id'),
5503-
'glpi_tickets_users.users_id' => Session::getLoginUserID()
5504-
]
5505-
]
5506-
];
5507-
if (count($_SESSION['glpigroups'])) {
5508-
$or['glpi_groups_tickets.groups_id'] = $_SESSION['glpigroups'];
5509-
}
5510-
$restrict[] = ['OR' => $or];
5511-
}
5512-
5513-
$options['criteria'][0]['field'] = 12;
5514-
$options['criteria'][0]['searchtype'] = 'equals';
5515-
$options['criteria'][0]['value'] = 'all';
5516-
$options['criteria'][0]['link'] = 'AND';
5517-
5518-
$options['metacriteria'][0]['itemtype'] = $item->getType();
5519-
$options['metacriteria'][0]['field'] = Search::getOptionNumber(
5520-
$item->getType(),
5521-
'id'
5522-
);
5523-
$options['metacriteria'][0]['searchtype'] = 'equals';
5524-
$options['metacriteria'][0]['value'] = $item->getID();
5525-
$options['metacriteria'][0]['link'] = 'AND';
5441+
/** @var CommonDBTM $item */
55265442
break;
55275443
}
55285444

5529-
$criteria['WHERE'] = $restrict + getEntitiesRestrictCriteria(self::getTable());
5530-
$criteria['WHERE']['glpi_tickets.is_deleted'] = 0;
5531-
$criteria['LIMIT'] = (int)$_SESSION['glpilist_limit'];
55325445
$iterator = $DB->request($criteria);
55335446
$number = count($iterator);
55345447

@@ -5590,6 +5503,7 @@ public static function showListForItem(CommonDBTM $item, $withtemplate = 0)
55905503
)
55915504
);
55925505

5506+
$options = self::getListForItemSearchOptionsCriteria($item);
55935507
echo "<tr class='noHover'><th colspan='$colspan'>";
55945508
$title = sprintf(_n('Last %d ticket', 'Last %d tickets', $number), $number);
55955509
$link = "<a href='" . Ticket::getSearchURL() . "?" .
@@ -5786,6 +5700,13 @@ public static function getCommonCriteria()
57865700
]
57875701
];
57885702

5703+
$criteria['LEFT JOIN']['glpi_ticketvalidations'] = [
5704+
'ON' => [
5705+
self::getTable() => 'id',
5706+
'glpi_ticketvalidations' => 'tickets_id'
5707+
]
5708+
];
5709+
57895710
return $criteria;
57905711
}
57915712

@@ -7077,4 +6998,145 @@ public static function getContentTemplatesParametersClass(): string
70776998
{
70786999
return TicketParameters::class;
70797000
}
7001+
7002+
public static function getListForItemRestrict(CommonDBTM $item)
7003+
{
7004+
$restrict = [];
7005+
7006+
switch (get_class($item)) {
7007+
case User::class:
7008+
$restrict['glpi_tickets_users.users_id'] = $item->getID();
7009+
$restrict['glpi_tickets_users.type'] = CommonITILActor::REQUESTER;
7010+
break;
7011+
7012+
case SLA::class:
7013+
$restrict[] = [
7014+
'OR' => [
7015+
'slas_id_tto' => $item->getID(),
7016+
'slas_id_ttr' => $item->getID()
7017+
]
7018+
];
7019+
break;
7020+
7021+
case OLA::class:
7022+
$restrict[] = [
7023+
'OR' => [
7024+
'olas_id_tto' => $item->getID(),
7025+
'olas_id_ttr' => $item->getID()
7026+
]
7027+
];
7028+
break;
7029+
7030+
case Supplier::class:
7031+
$restrict['glpi_suppliers_tickets.suppliers_id'] = $item->getID();
7032+
$restrict['glpi_suppliers_tickets.type'] = CommonITILActor::ASSIGN;
7033+
break;
7034+
7035+
case Group::class:
7036+
/** @var Group $item */
7037+
if ($item->haveChildren()) {
7038+
$tree = Session::getSavedOption(__CLASS__, 'tree', 0);
7039+
} else {
7040+
$tree = 0;
7041+
}
7042+
$restrict['glpi_groups_tickets.groups_id'] = ($tree ? getSonsOf('glpi_groups', $item->getID()) : $item->getID());
7043+
$restrict['glpi_groups_tickets.type'] = CommonITILActor::REQUESTER;
7044+
/** @var CommonDBTM $item */
7045+
break;
7046+
7047+
default:
7048+
$restrict['glpi_items_tickets.items_id'] = $item->getID();
7049+
$restrict['glpi_items_tickets.itemtype'] = $item->getType();
7050+
// you can only see your tickets
7051+
if (!Session::haveRight(self::$rightname, self::READALL)) {
7052+
$or = [
7053+
'glpi_tickets.users_id_recipient' => Session::getLoginUserID(),
7054+
[
7055+
'AND' => [
7056+
'glpi_tickets_users.tickets_id' => new \QueryExpression('glpi_tickets.id'),
7057+
'glpi_tickets_users.users_id' => Session::getLoginUserID()
7058+
]
7059+
]
7060+
];
7061+
if (Session::haveRightsOr(TicketValidation::$rightname, [TicketValidation::VALIDATEINCIDENT, TicketValidation::VALIDATEREQUEST])) {
7062+
$or[] = [
7063+
'AND' => [
7064+
'glpi_ticketvalidations.tickets_id' => new \QueryExpression('glpi_tickets.id'),
7065+
'glpi_ticketvalidations.users_id_validate' => Session::getLoginUserID(),
7066+
]
7067+
];
7068+
}
7069+
if (count($_SESSION['glpigroups'])) {
7070+
$or['glpi_groups_tickets.groups_id'] = $_SESSION['glpigroups'];
7071+
}
7072+
$restrict[] = ['OR' => $or];
7073+
}
7074+
}
7075+
7076+
return $restrict;
7077+
}
7078+
7079+
private static function getListForItemSearchOptionsCriteria(CommonDBTM $item): array
7080+
{
7081+
$options = [
7082+
'criteria' => [],
7083+
'reset' => 'reset',
7084+
];
7085+
7086+
switch (get_class($item)) {
7087+
case User::class:
7088+
$options['criteria'][0]['field'] = 4; // status
7089+
$options['criteria'][0]['searchtype'] = 'equals';
7090+
$options['criteria'][0]['value'] = $item->getID();
7091+
$options['criteria'][0]['link'] = 'AND';
7092+
break;
7093+
7094+
case SLA::class:
7095+
case OLA::class:
7096+
$options['criteria'][0]['field'] = 30;
7097+
$options['criteria'][0]['searchtype'] = 'equals';
7098+
$options['criteria'][0]['value'] = $item->getID();
7099+
$options['criteria'][0]['link'] = 'AND';
7100+
break;
7101+
7102+
case Supplier::class:
7103+
$options['criteria'][0]['field'] = 6;
7104+
$options['criteria'][0]['searchtype'] = 'equals';
7105+
$options['criteria'][0]['value'] = $item->getID();
7106+
$options['criteria'][0]['link'] = 'AND';
7107+
break;
7108+
7109+
case Group::class:
7110+
/** @var Group $item */
7111+
if ($item->haveChildren()) {
7112+
$tree = Session::getSavedOption(__CLASS__, 'tree', 0);
7113+
} else {
7114+
$tree = 0;
7115+
}
7116+
$options['criteria'][0]['field'] = 71;
7117+
$options['criteria'][0]['searchtype'] = ($tree ? 'under' : 'equals');
7118+
$options['criteria'][0]['value'] = $item->getID();
7119+
$options['criteria'][0]['link'] = 'AND';
7120+
/** @var CommonDBTM $item */
7121+
break;
7122+
7123+
default:
7124+
$options['criteria'][0]['field'] = 12;
7125+
$options['criteria'][0]['searchtype'] = 'equals';
7126+
$options['criteria'][0]['value'] = 'all';
7127+
$options['criteria'][0]['link'] = 'AND';
7128+
7129+
$options['metacriteria'][0]['itemtype'] = $item->getType();
7130+
$options['metacriteria'][0]['field'] = Search::getOptionNumber(
7131+
$item->getType(),
7132+
'id'
7133+
);
7134+
$options['metacriteria'][0]['searchtype'] = 'equals';
7135+
$options['metacriteria'][0]['value'] = $item->getID();
7136+
$options['metacriteria'][0]['link'] = 'AND';
7137+
break;
7138+
}
7139+
7140+
return $options;
7141+
}
70807142
}

tests/functional/Ticket.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
use Ticket_User;
5555
use TicketValidation;
5656
use User;
57+
use Session;
5758

5859
/* Test for inc/ticket.class.php */
5960

@@ -6984,4 +6985,70 @@ public function testRestrictedDropdownValues()
69846985
$this->array($values['results'])->size->isGreaterThan(1);
69856986
$this->boolean($fn_dropdown_has_id($values['results'], $not_my_tickets_id))->isTrue();
69866987
}
6988+
6989+
public function testGetCommonCriteria()
6990+
{
6991+
global $DB;
6992+
6993+
$this->login('tech', 'tech');
6994+
6995+
$item = new \Project();
6996+
$item->add([
6997+
'name' => $this->getUniqueString(),
6998+
]);
6999+
$this->boolean($item->isNewItem())->isFalse();
7000+
7001+
// Find tickets already in the entity
7002+
$request = \Ticket::getCommonCriteria();
7003+
$request['WHERE'] = $this->callPrivateMethod(new \Ticket(), 'getListForItemRestrict', $item);
7004+
$request['WHERE'] = $request['WHERE'] + getEntitiesRestrictCriteria(\Ticket::getTable());
7005+
$result = $DB->request($request);
7006+
$existing_tickets = $result->count();
7007+
7008+
// Create a ticket with no actor and a valdiator
7009+
$ticket = new \Ticket();
7010+
$ticket->add([
7011+
'name' => __FUNCTION__,
7012+
'content' => __FUNCTION__,
7013+
'entities_id' => $this->getTestRootEntity(true),
7014+
'users_id_recipient' => getItemByTypeName(User::class, 'tech', true),
7015+
]);
7016+
$this->boolean($ticket->isNewItem())->isFalse();
7017+
7018+
$item_ticket = new \Item_Ticket();
7019+
$item_ticket->add([
7020+
'tickets_id' => $ticket->getID(),
7021+
'itemtype' => $item->getType(),
7022+
'items_id' => $item->getID(),
7023+
]);
7024+
$this->boolean($item_ticket->isNewItem())->isFalse();
7025+
7026+
$user = new \Ticket_User();
7027+
$users = $user->find([
7028+
'tickets_id' => $ticket->getID(),
7029+
]);
7030+
$this->integer(count($users))->IsEqualTo(0);
7031+
7032+
$this->login('post-only', 'postonly');
7033+
$_SESSION['glpiactiveprofile'][\TicketValidation::$rightname] = \TicketValidation::VALIDATEINCIDENT + \TicketValidation::VALIDATEREQUEST;
7034+
7035+
// Check the ticket is not found
7036+
$request['WHERE'] = $this->callPrivateMethod(new \Ticket(), 'getListForItemRestrict', $item);
7037+
$request['WHERE'] = $request['WHERE'] + getEntitiesRestrictCriteria(\Ticket::getTable());
7038+
$result = $DB->request($request);
7039+
$this->integer($result->count())->isEqualTo($existing_tickets);
7040+
7041+
$ticket_valdiation = new TicketValidation();
7042+
$ticket_valdiation->add([
7043+
'tickets_id' => $ticket->getID(),
7044+
'entities_id' => $ticket->fields['entities_id'],
7045+
'users_id_validate' => Session::getLoginUserID(),
7046+
'timeline_position' => 1,
7047+
]);
7048+
$this->boolean($ticket_valdiation->isNewItem())->isFalse();
7049+
7050+
// Check the ticket under valdiation is found
7051+
$result = $DB->request($request);
7052+
$this->integer($result->count())->isEqualTo($existing_tickets + 1);
7053+
}
69877054
}

0 commit comments

Comments
 (0)