Skip to content

Commit

Permalink
Give OWN rights when groups matches
Browse files Browse the repository at this point in the history
  • Loading branch information
cedric-anne committed May 6, 2024
1 parent e25d7ba commit bb3bb66
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 38 deletions.
40 changes: 27 additions & 13 deletions src/Features/AssignableAsset.php
Expand Up @@ -53,7 +53,8 @@ public function canViewItem()

$is_assigned = $this->fields['users_id_tech'] === $_SESSION['glpiID'] ||
in_array((int) ($this->fields['groups_id_tech'] ?? 0), $_SESSION['glpigroups'] ?? [], true);
$is_owned = isset($this->fields['users_id']) && $this->fields['users_id'] === $_SESSION['glpiID'];
$is_owned = isset($this->fields['users_id']) && $this->fields['users_id'] === $_SESSION['glpiID'] ||
in_array((int) ($this->fields['groups_id'] ?? 0), $_SESSION['glpigroups'] ?? [], true);

if (!Session::haveRight(static::$rightname, READ)) {
return ($is_assigned && Session::haveRight(static::$rightname, READ_ASSIGNED))
Expand All @@ -77,7 +78,8 @@ public function canUpdateItem()

$is_assigned = $this->fields['users_id_tech'] === $_SESSION['glpiID'] ||
in_array((int) ($this->fields['groups_id_tech'] ?? 0), $_SESSION['glpigroups'] ?? [], true);
$is_owned = isset($this->fields['users_id']) && $this->fields['users_id'] === $_SESSION['glpiID'];
$is_owned = isset($this->fields['users_id']) && $this->fields['users_id'] === $_SESSION['glpiID'] ||
in_array((int) ($this->fields['groups_id'] ?? 0), $_SESSION['glpigroups'] ?? [], true);

if (!Session::haveRight(static::$rightname, UPDATE)) {
return ($is_assigned && Session::haveRight(static::$rightname, UPDATE_ASSIGNED))
Expand All @@ -90,28 +92,40 @@ public function canUpdateItem()

public static function getAssignableVisiblityCriteria()
{
if (!Session::haveRightsOr(static::$rightname, [READ, READ_ASSIGNED, READ_OWNED])) {
return [new QueryExpression('0')];
}
if (Session::haveRight(static::$rightname, READ)) {
return [new QueryExpression('1')];
}

$or = [];
if (Session::haveRight(static::$rightname, READ_ASSIGNED)) {
$criteria = [
'OR' => [
'users_id_tech' => $_SESSION['glpiID'],
],
$or[] = [
'users_id_tech' => $_SESSION['glpiID'],
];
if (count($_SESSION['glpigroups'])) {
$criteria['OR']['groups_id_tech'] = $_SESSION['glpigroups'];
$or[] = [
'groups_id_tech' => $_SESSION['glpigroups'],
];
}
return [$criteria];
}
if (Session::haveRight(static::$rightname, READ_OWNED)) {
return [
'OR' => [
'users_id' => $_SESSION['glpiID'],
],
$or[] = [
'users_id' => $_SESSION['glpiID'],
];
if (count($_SESSION['glpigroups'])) {
$or[] = [
'groups_id' => $_SESSION['glpigroups'],
];
}
}
return [new QueryExpression('0')];

// 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;
}

/**
Expand Down
115 changes: 90 additions & 25 deletions tests/functional/CommonDBTM.php
Expand Up @@ -1798,47 +1798,74 @@ public function testCanViewItemAssignableAssets($itemtype)
{
$this->login();

// Add the user to a test group
$group = new \Group();
$this->integer($groups_id = $group->add([
'name' => __FUNCTION__,
'entities_id' => $this->getTestRootEntity(true),
'is_recursive' => 1
]))->isGreaterThan(0);
$group_user = new \Group_User();
$this->integer($group_user->add(['groups_id' => $groups_id, 'users_id' => $_SESSION['glpiID']]))->isGreaterThan(0);
\Session::loadGroups();

// Create the item
/** @var \CommonDBTM $item */
$item = new $itemtype();
$this->integer($item->add([
'name' => 'test',
'entities_id' => getItemByTypeName('Entity', '_test_root_entity', true),
]))->isGreaterThan(0);

// User cannot access the item without any right
$_SESSION['glpiactiveprofile'][$itemtype::$rightname] = 0;
$this->boolean($item->canViewItem())->isFalse();

// User can access the item with the global right, even if not own/assigned
$_SESSION['glpiactiveprofile'][$itemtype::$rightname] = READ;
$this->boolean($item->canViewItem())->isTrue();

// User can access the item with the assigned right, but only if item is assigned to himself or one of its groups
$_SESSION['glpiactiveprofile'][$itemtype::$rightname] = READ_ASSIGNED;
$this->boolean($item->canViewItem())->isFalse();

$this->boolean($item->update([
'id' => $item->getID(),
'users_id_tech' => $_SESSION['glpiID'],
]));
$this->boolean($item->canViewItem())->isTrue();

$this->boolean($item->update([
'id' => $item->getID(),
'users_id_tech' => 0,
]));
$this->boolean($item->canViewItem())->isFalse();

$this->boolean($item->update([
'id' => $item->getID(),
'groups_id_tech' => $groups_id,
]));
$this->boolean($item->canViewItem())->isTrue();

// User can access the item with the own right, but only if item is owned by himself or one of its groups
$_SESSION['glpiactiveprofile'][$itemtype::$rightname] = READ_OWNED;
$this->boolean($item->canViewItem())->isFalse();

$this->boolean($item->update([
'id' => $item->getID(),
'users_id' => $_SESSION['glpiID'],
]));
$this->boolean($item->canViewItem())->isTrue();

// Create group for the user
$group = new \Group();
$this->integer($groups_id = $group->add([
'name' => __FUNCTION__,
'entities_id' => $this->getTestRootEntity(true),
'is_recursive' => 1
]))->isGreaterThan(0);
// Add user to group
$group_user = new \Group_User();
$this->integer($group_user->add(['groups_id' => $groups_id, 'users_id' => $_SESSION['glpiID']]))->isGreaterThan(0);
\Session::loadGroups();
$this->boolean($item->update([
'id' => $item->getID(),
'users_id' => 0,
]));
$this->boolean($item->canViewItem())->isFalse();

$this->boolean($item->update([
'id' => $item->getID(),
'users_id_tech' => 0,
'groups_id_tech' => $groups_id,
'groups_id' => $groups_id,
]));
$this->boolean($item->canViewItem())->isTrue();
}
Expand All @@ -1853,6 +1880,8 @@ public function testCanUpdateAssignableAssets($itemtype)
$this->boolean($itemtype::canUpdate())->isTrue();
$_SESSION['glpiactiveprofile'][$itemtype::$rightname] = UPDATE_ASSIGNED;
$this->boolean($itemtype::canUpdate())->isTrue();
$_SESSION['glpiactiveprofile'][$itemtype::$rightname] = UPDATE_OWNED;
$this->boolean($itemtype::canUpdate())->isTrue();
$_SESSION['glpiactiveprofile'][$itemtype::$rightname] = ALLSTANDARDRIGHT & ~UPDATE;
$this->boolean($itemtype::canUpdate())->isFalse();
}
Expand All @@ -1864,39 +1893,75 @@ public function testCanUpdateItemAssignableAssets($itemtype)
{
$this->login();

// Add the user to a test group
$group = new \Group();
$this->integer($groups_id = $group->add([
'name' => __FUNCTION__,
'entities_id' => $this->getTestRootEntity(true),
'is_recursive' => 1
]))->isGreaterThan(0);
$group_user = new \Group_User();
$this->integer($group_user->add(['groups_id' => $groups_id, 'users_id' => $_SESSION['glpiID']]))->isGreaterThan(0);
\Session::loadGroups();

// Create the item
/** @var \CommonDBTM $item */
$item = new $itemtype();
$this->integer($item->add([
'name' => 'test',
'entities_id' => getItemByTypeName('Entity', '_test_root_entity', true),
]))->isGreaterThan(0);

// User cannot update the item without any right
$_SESSION['glpiactiveprofile'][$itemtype::$rightname] = 0;
$this->boolean($item->canUpdateItem())->isFalse();

// User can update the item with the global right, even if not own/assigned
$_SESSION['glpiactiveprofile'][$itemtype::$rightname] = UPDATE;
$this->boolean($item->canUpdateItem())->isTrue();

// User can update the item with the assigned right, but only if item is assigned to himself or one of its groups
$_SESSION['glpiactiveprofile'][$itemtype::$rightname] = UPDATE_ASSIGNED;
$this->boolean($item->canUpdateItem())->isFalse();

$this->boolean($item->update([
'id' => $item->getID(),
'users_id_tech' => $_SESSION['glpiID'],
]));
$this->boolean($item->canUpdateItem())->isTrue();

// Create group for the user
$group = new \Group();
$this->integer($groups_id = $group->add([
'name' => __FUNCTION__,
'entities_id' => $this->getTestRootEntity(true),
'is_recursive' => 1
]))->isGreaterThan(0);
// Add user to group
$group_user = new \Group_User();
$this->integer($group_user->add(['groups_id' => $groups_id, 'users_id' => $_SESSION['glpiID']]))->isGreaterThan(0);
\Session::loadGroups();

$this->boolean($item->update([
'id' => $item->getID(),
'users_id_tech' => 0,
]));
$this->boolean($item->canUpdateItem())->isFalse();

$this->boolean($item->update([
'id' => $item->getID(),
'groups_id_tech' => $groups_id,
]));
$this->boolean($item->canUpdateItem())->isTrue();

// User can update the item with the own right, but only if item is owned by himself or one of its groups
$_SESSION['glpiactiveprofile'][$itemtype::$rightname] = UPDATE_OWNED;
$this->boolean($item->canUpdateItem())->isFalse();

$this->boolean($item->update([
'id' => $item->getID(),
'users_id' => $_SESSION['glpiID'],
]));
$this->boolean($item->canUpdateItem())->isTrue();

$this->boolean($item->update([
'id' => $item->getID(),
'users_id' => 0,
]));
$this->boolean($item->canUpdateItem())->isFalse();

$this->boolean($item->update([
'id' => $item->getID(),
'groups_id' => $groups_id,
]));
$this->boolean($item->canUpdateItem())->isTrue();
}
}

0 comments on commit bb3bb66

Please sign in to comment.