Skip to content

Commit

Permalink
Fix followups entities restriction (#17166)
Browse files Browse the repository at this point in the history
* Fix followups entities restriction

* Reduce code using loops

* Improve comments
  • Loading branch information
AdrienClairembault authored May 24, 2024
1 parent 319abc8 commit efc15b7
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 1 deletion.
37 changes: 36 additions & 1 deletion src/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -4573,8 +4573,24 @@ public static function addDefaultWhere($itemtype)
break;
}

// Build base condition using entity restrictions
// TODO 11.0: use $CFG_GLPI['itil_types']
$itil_types = [Ticket::class, Change::class, Problem::class];
$entity_restrictions = [];
foreach ($itil_types as $itil_itemtype) {
$entity_restrictions[] = getEntitiesRestrictRequest(
'',
$itil_itemtype::getTable() . '_items_id_' . self::computeComplexJoinID([
'condition' => "AND REFTABLE.`itemtype` = '$itil_itemtype'"
]),
'entities_id',
''
);
}
$condition = "(" . implode(" OR ", $entity_restrictions) . ")";

$in = "IN ('" . implode("','", $allowed_is_private) . "')";
$condition = "(`glpi_itilfollowups`.`is_private` $in ";
$condition .= " AND (`glpi_itilfollowups`.`is_private` $in ";

// Now filter on parent item visiblity
$condition .= "AND (";
Expand Down Expand Up @@ -5838,6 +5854,25 @@ public static function addDefaultJoin($itemtype, $ref_table, array &$already_lin
}
break;

case ITILFollowup::class:
// TODO 11.0: use $CFG_GLPI['itil_types']
$itil_types = [Ticket::class, Change::class, Problem::class];
foreach ($itil_types as $itil_itemtype) {
$out .= self::addLeftJoin(
$itemtype,
$ref_table,
$already_link_tables,
$itil_itemtype::getTable(),
'items_id',
false,
'',
[
'condition' => "AND REFTABLE.`itemtype` = '$itil_itemtype'"
]
);
}
break;

default:
// Plugin can override core definition for its type
if ($plug = isPluginItemType($itemtype)) {
Expand Down
70 changes: 70 additions & 0 deletions tests/functional/ITILFollowup.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,14 @@

namespace tests\units;

use Change;
use CommonITILActor;
use DbTestCase;
use Glpi\Toolbox\Sanitizer;
use ITILFollowup as CoreITILFollowup;
use Problem;
use QueryExpression;
use Search;
use Ticket;
use Ticket_User;
use User;
Expand Down Expand Up @@ -634,4 +638,70 @@ public function testIsParentAlreadyLoaded(
$this->callPrivateMethod($followup, 'isParentAlreadyLoaded')
)->isEqualTo($is_parent_loaded);
}

public function testAddDefaultWhereTakeEntitiesIntoAccount(): void
{
$this->login();
$this->setEntity('_test_child_2', false);

// Add followups in an entity our user can see
$number_of_visible_followups = $this->countVisibleFollowupsForLoggedInUser();
$this->createFollowupInEntityForType('_test_child_2', Ticket::class);
$this->createFollowupInEntityForType('_test_child_2', Problem::class);
$this->createFollowupInEntityForType('_test_child_2', Change::class);
$this->integer(
$this->countVisibleFollowupsForLoggedInUser()
)->isEqualTo($number_of_visible_followups + 3); // 3 new followup found

// Add followups in a visible that our user can't see
$number_of_visible_followups = $this->countVisibleFollowupsForLoggedInUser();
$this->createFollowupInEntityForType('_test_root_entity', Ticket::class);
$this->createFollowupInEntityForType('_test_root_entity', Problem::class);
$this->createFollowupInEntityForType('_test_root_entity', Change::class);
$this->integer(
$this->countVisibleFollowupsForLoggedInUser()
)->isEqualTo($number_of_visible_followups); // No new followups found
}

private function countVisibleFollowupsForLoggedInUser(): int
{
/** @var \DBMysql $DB */
global $DB;

$already_linked_tables = [];
$results = $DB->request([
'COUNT' => 'number_of_followups',
'FROM' => CoreITILFollowup::getTable(),
'JOIN' => [
new QueryExpression(
Search::addDefaultJoin(
CoreITILFollowup::class,
CoreITILFollowup::getTable(),
$already_linked_tables
)
)
],
'WHERE' => new QueryExpression(
Search::addDefaultWhere(CoreITILFollowup::class)
),
]);

return (int) iterator_to_array($results)[0]['number_of_followups'];
}

private function createFollowupInEntityForType(
string $entity_name,
string $itemtype
): void {
$itil = $this->createItem($itemtype, [
'entities_id' => getItemByTypeName('Entity', $entity_name, true),
'name' => 'Test ticket',
'content' => '',
]);
$this->createItem(CoreITILFollowup::class, [
'itemtype' => $itemtype,
'items_id' => $itil->getID(),
'content' => 'Test followup',
]);
}
}

0 comments on commit efc15b7

Please sign in to comment.