Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 59 additions & 18 deletions src/Glpi/Features/AssignableItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,22 @@ public function canUpdateItem(): bool
* @return array[]|QueryExpression[]
* @see AssignableItemInterface::getAssignableVisiblityCriteria()
*/
public static function getAssignableVisiblityCriteria(?string $item_table_reference = null): array
{
public static function getAssignableVisiblityCriteria(
?string $item_table_reference = null
): array {
return Session::getCurrentInterface() === "central"
? self::getAssignableVisiblityCriteriaForCentral($item_table_reference)
: self::getAssignableVisiblityCriteriaForHelpdesk($item_table_reference)
;
}

/**
* @param string|null $item_table_reference
* @return array[]|QueryExpression[]
*/
private static function getAssignableVisiblityCriteriaForCentral(
?string $item_table_reference = null
): array {
if (!Session::haveRightsOr(static::$rightname, [READ, READ_ASSIGNED, READ_OWNED])) {
return [new QueryExpression('0')];
}
Expand Down Expand Up @@ -138,22 +152,7 @@ public static function getAssignableVisiblityCriteria(?string $item_table_refere
}
}
if (Session::haveRight(static::$rightname, READ_OWNED)) {
$or[] = [
$item_table . '.users_id' => $_SESSION['glpiID'],
];
if (count($_SESSION['glpigroups']) > 0) {
$or[] = [
$item_table . '.id' => new QuerySubQuery([
'SELECT' => $relation_table . '.items_id',
'FROM' => $relation_table,
'WHERE' => [
'itemtype' => static::class,
'groups_id' => $_SESSION['glpigroups'],
'type' => Group_Item::GROUP_TYPE_NORMAL,
],
]),
];
}
$or += self::getOwnAssetsCriteria($item_table, $relation_table);
}

// Add another layer to the array to prevent losing duplicates keys if the
Expand All @@ -163,6 +162,48 @@ public static function getAssignableVisiblityCriteria(?string $item_table_refere
return $criteria;
}

/**
* @param string|null $item_table_reference
* @return array[]|QueryExpression[]
*/
private static function getAssignableVisiblityCriteriaForHelpdesk(
?string $item_table_reference = null
): array {
// Helpdesk doesn't support READ, READ_ASSIGNED, READ_OWNED rights.
// Instead, we assume the user can only see his own assets.
$item_table = $item_table_reference ?? static::getTable();
$relation_table = Group_Item::getTable();
$or = self::getOwnAssetsCriteria($item_table, $relation_table);

// Add another layer to the array to prevent losing duplicates keys if the
// result of the function is merged with another array
$criteria = [crc32(serialize($or)) => ['OR' => $or]];

return $criteria;
}

private static function getOwnAssetsCriteria(
string $item_table,
string $relation_table,
): array {
$or = [$item_table . '.users_id' => $_SESSION['glpiID']];
if (count($_SESSION['glpigroups']) > 0) {
$or[] = [
$item_table . '.id' => new QuerySubQuery([
'SELECT' => $relation_table . '.items_id',
'FROM' => $relation_table,
'WHERE' => [
'itemtype' => static::class,
'groups_id' => $_SESSION['glpigroups'],
'type' => Group_Item::GROUP_TYPE_NORMAL,
],
]),
];
}

return $or;
}

/** @see AssignableItemInterface::getRights() */
public function getRights($interface = 'central')
{
Expand Down
29 changes: 29 additions & 0 deletions tests/functional/DropdownTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2736,4 +2736,33 @@ public function testGetDropdownMyDevices()
// Test that count is accurate
$this->assertGreaterThan(0, $result['count']);
}

public function testSelfServiceCanSeeHisOwnAssets(): void
{
// Arrange: assign a computer to a self-service user
$this->createItem(Computer::class, [
'name' => 'My computer',
'entities_id' => $this->getTestRootEntity(only_id: true),
'users_id' => getItemByTypeName(User::class, "post-only", true),
]);
$this->createItem(Computer::class, [
'name' => 'Not my computer',
'entities_id' => $this->getTestRootEntity(only_id: true),
]);

// Act: get dropdown values for this user
$this->login('post-only');
$params = [
'itemtype' => Computer::class,
];
$params['_idor_token'] = Session::getNewIDORToken(Computer::class, $params);
$results = \Dropdown::getDropdownValue($params, false);

// Assert: only one computer should be count
$this->assertEquals(1, $results["count"]);
$this->assertEquals(
"My computer",
$results["results"][1]["children"][0]["text"]
);
}
}