Skip to content

Commit

Permalink
Merge pull request #953 from arawa/backport/nextcloud-37677/exclude-s…
Browse files Browse the repository at this point in the history
…ome-groups-from-sharing-with-users/stable3.0

backport: Limit the search to members
  • Loading branch information
zak39 authored Apr 4, 2024
2 parents 537f344 + 5cf755d commit 86d3471
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 26 deletions.
43 changes: 17 additions & 26 deletions lib/Service/WorkspaceService.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@
use OCA\Workspace\Db\SpaceMapper;
use OCA\Workspace\Service\Group\UserGroup;
use OCA\Workspace\Service\Group\WorkspaceManagerGroup;
use OCA\Workspace\Share\Group\GroupMembersOnlyChecker;
use OCA\Workspace\Share\Group\ShareMembersOnlyFilter;
use OCP\IGroupManager;
use OCP\IUser;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\Share\IManager;
Expand All @@ -43,7 +44,9 @@ public function __construct(
private IUserSession $userSession,
private LoggerInterface $logger,
private SpaceMapper $spaceMapper,
private UserService $userService
private UserService $userService,
private ShareMembersOnlyFilter $shareMembersFilter,
private GroupMembersOnlyChecker $memberGroupOnlyChecker
) {
}

Expand Down Expand Up @@ -85,24 +88,6 @@ private function searchUsers(string $term): array {
return $users;
}

/**
* @param IUser[] $users
* @return IUser[]
*/
private function getUsersFromGroupsOnly(array $users): array {
$usersFromGroups = [];
$userSession = $this->userSession->getUser();
$groupsOfUserSession = $this->groupManager->getUserGroups($userSession);
foreach ($groupsOfUserSession as $group) {
$usersFromGroups = array_merge($usersFromGroups, $group->getUsers());
}

$usersFromGroups = array_filter($usersFromGroups, function ($user) use ($users) {
return in_array($user, $users);
});

return $usersFromGroups;
}

/**
* Returns a list of users whose name matches $term
Expand All @@ -123,8 +108,14 @@ public function autoComplete(string $term, array|string $space): array {
}
}

if ($this->shareManager->shareWithGroupMembersOnly()) {
$users = $this->getUsersFromGroupsOnly($users);
if ($this->memberGroupOnlyChecker->checkboxIsChecked()) {
$users = $this->shareMembersFilter->filterUsersGroupOnly($users);
}

if ($this->memberGroupOnlyChecker->groupsExcludeSelected()) {
if ($this->memberGroupOnlyChecker->checkMemberInGroupExcluded()) {
$users = $this->shareMembersFilter->excludeGroupsList($users);
}
}

// transform in a format suitable for the app
Expand Down Expand Up @@ -168,7 +159,7 @@ public function addUsersInfo(string|array $workspace): array {
// Caution: It is important to add users from the workspace's user group before adding the users
// from the workspace's manager group, as users may be members of both groups
$this->logger->debug('Adding users information to workspace');
$users = array();
$users = [];
$group = $this->groupManager->get(UserGroup::get($workspace['id']));
// TODO Handle is_null($group) better (remove workspace from list?)
if (!is_null($group)) {
Expand Down Expand Up @@ -197,13 +188,13 @@ public function addUsersInfo(string|array $workspace): array {
*
*/
public function addGroupsInfo(array|string $workspace): array {
$groups = array();
$groups = [];
foreach (array_keys($workspace['groups']) as $gid) {
$NCGroup = $this->groupManager->get($gid);
$groups[$gid] = array(
$groups[$gid] = [
'gid' => $NCGroup->getGID(),
'displayName' => $NCGroup->getDisplayName()
);
];
}
$workspace['groups'] = $groups;

Expand Down
49 changes: 49 additions & 0 deletions lib/Share/Group/GroupMembersOnlyChecker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace OCA\Workspace\Share\Group;

use OCP\IGroupManager;
use OCP\IUserSession;
use OCP\Share\IManager;

class GroupMembersOnlyChecker {
public function __construct(
private IGroupManager $groupManager,
private IManager $shareManager,
private IUserSession $userSession
) {
}

public function checkboxIsChecked(): bool {
return $this->shareManager->shareWithGroupMembersOnly();
}

public function groupsExcludeSelected(): bool {
if (
method_exists(
$this->shareManager,
"shareWithGroupMembersOnlyExcludeGroupsList"
)
) {
return $this->shareManager->shareWithGroupMembersOnly()
&& !empty($this->shareManager->shareWithGroupMembersOnlyExcludeGroupsList());
}

return false;
}

public function checkMemberInGroupExcluded(): bool {
$excludedGroups = $this->shareManager->shareWithGroupMembersOnlyExcludeGroupsList();

$userSession = $this->userSession->getUser();
$uid = $userSession->getUID();

foreach ($excludedGroups as $gid) {
if ($this->groupManager->isInGroup($uid, $gid)) {
return true;
}
}

return false;
}
}
70 changes: 70 additions & 0 deletions lib/Share/Group/ShareMembersOnlyFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace OCA\Workspace\Share\Group;

use OCP\IGroupManager;
use OCP\IUser;
use OCP\IUserSession;
use OCP\Share\IManager;

class ShareMembersOnlyFilter {
public function __construct(
private IGroupManager $groupManager,
private IManager $shareManager,
private IUserSession $userSession
) {
}

/**
* @param IUser[] $users
* @return IUser[]
* Return users with groups in common.
* Except some listed in the drop-down list
* (`Settings > Share > Restrict users to only share with users in their groups > Ingore the following groups when cheking group membership`).
*/
public function excludeGroupsList(array $users): array {
$usersNotExclude = [];

if (method_exists($this->shareManager, "shareWithGroupMembersOnlyExcludeGroupsList")) {
$excludedGroups = $this->shareManager->shareWithGroupMembersOnlyExcludeGroupsList();
$userSession = $this->userSession->getUser();
$groupsOfUserSession = $this->groupManager->getUserGroups($userSession);
$groupnamesOfUserSession = array_map(fn ($group) => $group->getGID(), $groupsOfUserSession);

if (!empty($excludedGroups)) {
$usersNotExclude = array_filter($users, function ($user) use ($excludedGroups, $groupnamesOfUserSession) {
$groups = $this->groupManager->getUserGroups($user);
$groupnames = array_values(array_map(fn ($group) => $group->getGID(), $groups));
$commonGroups = array_intersect($groupnamesOfUserSession, $groupnames);
return count(array_diff($commonGroups, $excludedGroups)) !== 0;
});
}

return $usersNotExclude;
}
}

/**
* @param IUser[] $users
*
* @return IUser[]
*/
public function filterUsersGroupOnly(array $users): array {
$usersInTheSameGroup = [];
$userSession = $this->userSession->getUser();
$groupsOfUserSession = $this->groupManager->getUserGroups($userSession);

foreach ($groupsOfUserSession as $group) {
$usersInTheSameGroup = array_merge($usersInTheSameGroup, $group->getUsers());
}

$usersInTheSameGroup = array_filter(
$users,
function ($user) use ($usersInTheSameGroup) {
$usernames = array_values(array_map(fn ($user) => $user->getUID(), $usersInTheSameGroup));
return in_array($user->getUID(), $usernames);
});

return $usersInTheSameGroup;
}
}

0 comments on commit 86d3471

Please sign in to comment.