Skip to content

Commit 987193d

Browse files
committed
fix(issue): access to tickets
if several tickets are under validation by a user under service catalog, but without acess to the form answer also change the initial status of the issue as it is set as accepted and leads the issue to be counted in closed issues instead of an other (waiting is better)
1 parent 41c3477 commit 987193d

File tree

1 file changed

+185
-76
lines changed

1 file changed

+185
-76
lines changed

inc/formanswer.class.php

Lines changed: 185 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,6 @@ public static function canView() {
100100
}
101101

102102
public function canViewItem() {
103-
global $DB;
104-
105103
if (Plugin::isPluginActive(PLUGIN_FORMCREATOR_ADVANCED_VALIDATION)) {
106104
$advFormAnswer = new PluginAdvformFormanswer();
107105
$advFormAnswer->getFromDB($this->getID());
@@ -115,93 +113,30 @@ public function canViewItem() {
115113
}
116114

117115
if (Session::haveRight('entity', UPDATE)) {
116+
// user has administration power
118117
return true;
119118
}
120119

120+
// Is the user the requester of the formanswer ?
121121
if ($currentUser == $this->fields['requester_id']) {
122122
return true;
123123
}
124124

125+
// Is the user a valodator of the formanswer ?
125126
if ($currentUser == $this->fields['users_id_validator']) {
126127
return true;
127128
}
128129

129-
$groupUser = new Group_User();
130-
$groups = $groupUser->getUserGroups($currentUser);
131-
foreach ($groups as $group) {
132-
if ($this->fields['groups_id_validator'] == $group['id']) {
133-
return true;
134-
}
130+
// Is the user a member of a validator group ?
131+
if ($this->userIsMemberOfValidatorGroup($currentUser)) {
132+
return true;
135133
}
136134

137-
$request = [
138-
'SELECT' => PluginFormcreatorForm_Validator::getTable() . '.*',
139-
'FROM' => $this::getTable(),
140-
'INNER JOIN' => [
141-
PluginFormcreatorForm::getTable() => [
142-
'FKEY' => [
143-
PluginFormcreatorForm::getTable() => PluginFormcreatorForm::getIndexName(),
144-
$this::getTable() => PluginFormcreatorForm::getForeignKeyField(),
145-
],
146-
],
147-
PluginFormcreatorForm_Validator::getTable() => [
148-
'FKEY' => [
149-
PluginFormcreatorForm::getTable() => PluginFormcreatorForm::getIndexName(),
150-
PluginFormcreatorForm_Validator::getTable() => PluginFormcreatorForm::getForeignKeyField()
151-
]
152-
]
153-
],
154-
'WHERE' => [$this::getTable() . '.id' => $this->getID()],
155-
];
156-
foreach ($DB->request($request) as $row) {
157-
if ($row['itemtype'] == User::class) {
158-
if ($currentUser == $row['items_id']) {
159-
return true;
160-
}
161-
} else {
162-
foreach ($groups as $group) {
163-
if ($group['id'] == $row['items_id']) {
164-
return true;
165-
}
166-
}
167-
}
135+
if ($this->userIsTicketActor($currentUser)) {
136+
return true;
168137
}
169138

170-
// Check if the current user is a requester of a ticket linked to a form answer typed
171-
// Matches search option 42, 43 and 44 of PluginFormcreatorIssue (requester, watcher, assigned)
172-
$ticket_table = Ticket::getTable();
173-
$ticket_user_table = Ticket_User::getTable();
174-
$item_ticket_table = Item_Ticket::getTable();
175-
$request = [
176-
'SELECT' => [
177-
Ticket_User::getTableField(User::getForeignKeyField()),
178-
Ticket::getTableField('id'),
179-
],
180-
'FROM' => $ticket_user_table,
181-
'INNER JOIN' => [
182-
$ticket_table => [
183-
'FKEY' => [
184-
$ticket_table => 'id',
185-
$ticket_user_table => 'tickets_id',
186-
['AND' => [
187-
Ticket_User::getTableField(User::getForeignKeyField()) => $currentUser,
188-
]],
189-
],
190-
],
191-
$item_ticket_table => [
192-
'FKEY' => [
193-
$item_ticket_table => 'tickets_id',
194-
$ticket_table => 'id',
195-
['AND' => [
196-
Item_Ticket::getTableField('itemtype') => self::getType(),
197-
Item_Ticket::getTableField('items_id') => $this->getID(),
198-
]],
199-
],
200-
],
201-
]
202-
];
203-
204-
if ($DB->request($request)->count() > 0) {
139+
if ($this->userIsTicketValidator($currentUser)) {
205140
return true;
206141
}
207142

@@ -581,6 +516,32 @@ public function showForm($ID, $options = []) {
581516
if (!isset($ID) || !$this->getFromDB($ID)) {
582517
Html::displayNotFoundError();
583518
}
519+
520+
// Check access right
521+
// shightly differs from self::canViewItem() as viewing the main tab requires to be an actor or an admin
522+
$currentUser = Session::getLoginUserID();
523+
if ($currentUser === false) {
524+
return false;
525+
}
526+
527+
if (!(
528+
Session::haveRight('entity', UPDATE)
529+
|| $currentUser == $this->fields['requester_id']
530+
|| $currentUser == $this->fields['users_id_validator']
531+
|| $this->userIsMemberOfValidatorGroup($currentUser)
532+
)) {
533+
// Find issue linked to the formanswer
534+
$issue = new PluginFormcreatorIssue();
535+
$issue->getFromDBByCrit([
536+
'itemtype' => self::class,
537+
'items_id' => $this->getID(),
538+
]);
539+
Html::redirect(PluginFormcreatorIssue::getFormURLWithID($issue->getID())
540+
. '&' . PluginFormcreatorFormAnswer::class . '=' . $this->getID()
541+
. '&forcetab=' . PluginFormcreatorIssue::class . '$1');
542+
return false;
543+
}
544+
584545
$options['canedit'] = false;
585546

586547
// Print css media
@@ -2005,8 +1966,8 @@ public function getAggregatedStatus(): ?int {
20051966
continue;
20061967
}
20071968
$ticketStatus = PluginFormcreatorCommon::getTicketStatusForIssue($generatedTarget);
2008-
if ($ticketStatus >= PluginFormcreatorFormAnswer::STATUS_WAITING) {
2009-
// Ignore tickets refused or pending for validation
1969+
if ($ticketStatus == PluginFormcreatorFormAnswer::STATUS_REFUSED) {
1970+
// Ignore tickets refused for validation
20101971
// getTicketStatusForIssue() does not returns STATUS_ACCEPTED
20111972
continue;
20121973
}
@@ -2147,4 +2108,152 @@ public function getFromDbByTicket($item) {
21472108
])
21482109
]);
21492110
}
2111+
2112+
/**
2113+
* Is the user a member of a validator group ?
2114+
*
2115+
* @param int $user_id
2116+
* @return boolean
2117+
*/
2118+
protected function userIsMemberOfValidatorGroup($user_id): bool {
2119+
global $DB;
2120+
2121+
$groupUser = new Group_User();
2122+
$groups = $groupUser->getUserGroups($user_id);
2123+
foreach ($groups as $group) {
2124+
if ($this->fields['groups_id_validator'] == $group['id']) {
2125+
return true;
2126+
}
2127+
}
2128+
2129+
$request = [
2130+
'SELECT' => PluginFormcreatorForm_Validator::getTable() . '.*',
2131+
'FROM' => $this::getTable(),
2132+
'INNER JOIN' => [
2133+
PluginFormcreatorForm::getTable() => [
2134+
'FKEY' => [
2135+
PluginFormcreatorForm::getTable() => PluginFormcreatorForm::getIndexName(),
2136+
$this::getTable() => PluginFormcreatorForm::getForeignKeyField(),
2137+
],
2138+
],
2139+
PluginFormcreatorForm_Validator::getTable() => [
2140+
'FKEY' => [
2141+
PluginFormcreatorForm::getTable() => PluginFormcreatorForm::getIndexName(),
2142+
PluginFormcreatorForm_Validator::getTable() => PluginFormcreatorForm::getForeignKeyField()
2143+
]
2144+
]
2145+
],
2146+
'WHERE' => [$this::getTable() . '.id' => $this->getID()],
2147+
];
2148+
foreach ($DB->request($request) as $row) {
2149+
if ($row['itemtype'] == User::class) {
2150+
if ($user_id == $row['items_id']) {
2151+
return true;
2152+
}
2153+
} else {
2154+
foreach ($groups as $group) {
2155+
if ($group['id'] == $row['items_id']) {
2156+
return true;
2157+
}
2158+
}
2159+
}
2160+
}
2161+
2162+
return false;
2163+
}
2164+
2165+
/**
2166+
* Check if the current user is an actor of a ticket linked to a form answer typed
2167+
* Matches search option 42, 43 and 44 of PluginFormcreatorIssue (requester, watcher, assigned)
2168+
*
2169+
* @param int $user_id
2170+
* @return boolean
2171+
*/
2172+
protected function userIsTicketActor($user_id): bool {
2173+
global $DB;
2174+
2175+
$ticket_table = Ticket::getTable();
2176+
$ticket_user_table = Ticket_User::getTable();
2177+
$item_ticket_table = Item_Ticket::getTable();
2178+
$request = [
2179+
'SELECT' => [
2180+
Ticket_User::getTableField(User::getForeignKeyField()),
2181+
Ticket::getTableField('id'),
2182+
],
2183+
'FROM' => $ticket_user_table,
2184+
'INNER JOIN' => [
2185+
$ticket_table => [
2186+
'FKEY' => [
2187+
$ticket_table => 'id',
2188+
$ticket_user_table => 'tickets_id',
2189+
['AND' => [
2190+
Ticket_User::getTableField(User::getForeignKeyField()) => $user_id,
2191+
]],
2192+
],
2193+
],
2194+
$item_ticket_table => [
2195+
'FKEY' => [
2196+
$item_ticket_table => 'tickets_id',
2197+
$ticket_table => 'id',
2198+
['AND' => [
2199+
Item_Ticket::getTableField('itemtype') => self::getType(),
2200+
Item_Ticket::getTableField('items_id') => $this->getID(),
2201+
]],
2202+
],
2203+
],
2204+
]
2205+
];
2206+
2207+
if ($DB->request($request)->count() > 0) {
2208+
return true;
2209+
}
2210+
2211+
return false;
2212+
}
2213+
2214+
/**
2215+
* Check if the current user is a validator of a ticket linked to a form answer typed
2216+
* Matches search option 11 of PluginFormcreatorIssue
2217+
*
2218+
* @param int $user_id
2219+
* @return boolean
2220+
*/
2221+
protected function userIsTicketValidator($user_id): bool {
2222+
global $DB;
2223+
2224+
$ticket_table = Ticket::getTable();
2225+
$item_ticket_table = Item_Ticket::getTable();
2226+
2227+
$ticket_validation_table = TicketValidation::getTable();
2228+
$request = [
2229+
'SELECT' => TicketValidation::getTableField('id'),
2230+
'FROM' => $ticket_validation_table,
2231+
'INNER JOIN' => [
2232+
$ticket_table => [
2233+
'FKEY' => [
2234+
$ticket_table => 'id',
2235+
$ticket_validation_table => 'tickets_id',
2236+
],
2237+
],
2238+
$item_ticket_table => [
2239+
'FKEY' => [
2240+
$item_ticket_table => 'tickets_id',
2241+
$ticket_table => 'id',
2242+
['AND' => [
2243+
Item_Ticket::getTableField('itemtype') => self::getType(),
2244+
Item_Ticket::getTableField('items_id') => $this->getID(),
2245+
]],
2246+
],
2247+
],
2248+
],
2249+
'WHERE' => [
2250+
'users_id_validate' => $user_id,
2251+
],
2252+
];
2253+
if ($DB->request($request)->count() > 0) {
2254+
return true;
2255+
}
2256+
2257+
return false;
2258+
}
21502259
}

0 commit comments

Comments
 (0)