Skip to content

Commit e032776

Browse files
committed
Principal search: Take sharing settings into account
Signed-off-by: Georg Ehrke <developer@georgehrke.com>
1 parent dcdba08 commit e032776

File tree

6 files changed

+275
-35
lines changed

6 files changed

+275
-35
lines changed

apps/dav/appinfo/v1/caldav.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
$principalBackend = new Principal(
4545
\OC::$server->getUserManager(),
4646
\OC::$server->getGroupManager(),
47+
\OC::$server->getShareManager(),
48+
\OC::$server->getUserSession(),
4749
'principals/'
4850
);
4951
$db = \OC::$server->getDatabaseConnection();

apps/dav/appinfo/v1/carddav.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
$principalBackend = new Principal(
4646
\OC::$server->getUserManager(),
4747
\OC::$server->getGroupManager(),
48+
\OC::$server->getShareManager(),
49+
\OC::$server->getUserSession(),
4850
'principals/'
4951
);
5052
$db = \OC::$server->getDatabaseConnection();

apps/dav/lib/Command/CreateCalendar.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ protected function execute(InputInterface $input, OutputInterface $output) {
7575
}
7676
$principalBackend = new Principal(
7777
$this->userManager,
78-
$this->groupManager
78+
$this->groupManager,
79+
\OC::$server->getShareManager(),
80+
\OC::$server->getUserSession()
7981
);
8082
$random = \OC::$server->getSecureRandom();
8183
$logger = \OC::$server->getLogger();

apps/dav/lib/Connector/Sabre/Principal.php

Lines changed: 89 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
use OCP\IGroupManager;
3535
use OCP\IUser;
3636
use OCP\IUserManager;
37+
use OCP\IUserSession;
38+
use OCP\Share\IManager as IShareManager;
3739
use Sabre\DAV\Exception;
3840
use \Sabre\DAV\PropPatch;
3941
use Sabre\DAVACL\PrincipalBackend\BackendInterface;
@@ -47,6 +49,12 @@ class Principal implements BackendInterface {
4749
/** @var IGroupManager */
4850
private $groupManager;
4951

52+
/** @var IShareManager */
53+
private $shareManager;
54+
55+
/** @var IUserSession */
56+
private $userSession;
57+
5058
/** @var string */
5159
private $principalPrefix;
5260

@@ -56,13 +64,19 @@ class Principal implements BackendInterface {
5664
/**
5765
* @param IUserManager $userManager
5866
* @param IGroupManager $groupManager
67+
* @param IShareManager $shareManager
68+
* @param IUserSession $userSession
5969
* @param string $principalPrefix
6070
*/
6171
public function __construct(IUserManager $userManager,
6272
IGroupManager $groupManager,
73+
IShareManager $shareManager,
74+
IUserSession $userSession,
6375
$principalPrefix = 'principals/users/') {
6476
$this->userManager = $userManager;
6577
$this->groupManager = $groupManager;
78+
$this->shareManager = $shareManager;
79+
$this->userSession = $userSession;
6680
$this->principalPrefix = trim($principalPrefix, '/');
6781
$this->hasGroups = ($principalPrefix === 'principals/users/');
6882
}
@@ -106,7 +120,7 @@ public function getPrincipalByPath($path) {
106120
if ($prefix === $this->principalPrefix) {
107121
$user = $this->userManager->get($name);
108122

109-
if (!is_null($user)) {
123+
if ($user !== null) {
110124
return $this->userToPrincipal($user);
111125
}
112126
}
@@ -189,37 +203,65 @@ function updatePrincipal($path, PropPatch $propPatch) {
189203
* @param string $test
190204
* @return array
191205
*/
192-
function searchUserPrincipals(array $searchProperties, $test = 'allof') {
206+
protected function searchUserPrincipals(array $searchProperties, $test = 'allof') {
193207
$results = [];
194208

195-
//TODO: If more properties should be supported, hook this up to a db query
209+
// If sharing is disabled, return the empty array
210+
if (!$this->shareManager->shareApiEnabled()) {
211+
return [];
212+
}
213+
214+
// If sharing is restricted to group members only,
215+
// return only members that have groups in common
216+
$restrictGroups = false;
217+
if ($this->shareManager->shareWithGroupMembersOnly()) {
218+
$user = $this->userSession->getUser();
219+
if (!$user) {
220+
return [];
221+
}
222+
223+
$restrictGroups = $this->groupManager->getUserGroupIds($user);
224+
}
225+
196226
foreach ($searchProperties as $prop => $value) {
197227
switch ($prop) {
198228
case '{http://sabredav.org/ns}email-address':
199229
$users = $this->userManager->getByEmail($value);
200-
$results[] = array_map(function ($user) {
201-
return $this->principalPrefix . '/' . $user->getUID();
202-
}, $users);
230+
231+
$results[] = array_reduce($users, function(array $carry, IUser $user) use ($restrictGroups) {
232+
// is sharing restricted to groups only?
233+
if ($restrictGroups !== false) {
234+
$userGroups = $this->groupManager->getUserGroupIds($user);
235+
if (count(array_intersect($userGroups, $restrictGroups)) === 0) {
236+
return $carry;
237+
}
238+
}
239+
240+
$carry[] = $this->principalPrefix . '/' . $user->getUID();
241+
return $carry;
242+
}, []);
203243
break;
244+
204245
default:
205246
$results[] = [];
206247
break;
207248
}
208249
}
209250

210-
if (count($results) == 1) {
251+
// results is an array of arrays, so this is not the first search result
252+
// but the results of the first searchProperty
253+
if (count($results) === 1) {
211254
return $results[0];
212255
}
213256

214257
switch ($test) {
215-
case 'allof':
216-
217-
return array_intersect(...$results);
218258
case 'anyof':
219259
return array_unique(array_merge(...$results));
220-
}
221260

222-
return [];
261+
case 'allof':
262+
default:
263+
return array_intersect(...$results);
264+
}
223265
}
224266

225267
/**
@@ -229,13 +271,14 @@ function searchUserPrincipals(array $searchProperties, $test = 'allof') {
229271
* @return array
230272
*/
231273
function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') {
232-
if (count($searchProperties) == 0) {
274+
if (count($searchProperties) === 0) {
233275
return [];
234276
}
235277

236278
switch ($prefixPath) {
237279
case 'principals/users':
238280
return $this->searchUserPrincipals($searchProperties, $test);
281+
239282
default:
240283
return [];
241284
}
@@ -247,17 +290,43 @@ function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof')
247290
* @return string
248291
*/
249292
function findByUri($uri, $principalPrefix) {
250-
if (substr($uri, 0, 7) === 'mailto:') {
251-
if ($principalPrefix === principals/users) {
252-
$email = substr($uri, 7);
253-
$users = $this->userManager->getByEmail($email);
254-
if (count($users) === 1) {
255-
return $this->principalPrefix . '/' . $users[0]->getUID();
293+
// If sharing is disabled, return null as in user not found
294+
if (!$this->shareManager->shareApiEnabled()) {
295+
return null;
296+
}
297+
298+
// If sharing is restricted to group members only,
299+
// return only members that have groups in common
300+
$restrictGroups = false;
301+
if ($this->shareManager->shareWithGroupMembersOnly()) {
302+
$user = $this->userSession->getUser();
303+
if (!$user) {
304+
return null;
305+
}
306+
307+
$restrictGroups = $this->groupManager->getUserGroupIds($user);
308+
}
309+
310+
if (strpos($uri, 'mailto:') === 0) {
311+
if ($principalPrefix === 'principals/users') {
312+
$users = $this->userManager->getByEmail(substr($uri, 7));
313+
if (count($users) !== 1) {
314+
return null;
256315
}
316+
$user = $users[0];
317+
318+
if ($restrictGroups !== false) {
319+
$userGroups = $this->groupManager->getUserGroupIds($user);
320+
if (count(array_intersect($userGroups, $restrictGroups)) === 0) {
321+
return null;
322+
}
323+
}
324+
325+
return $this->principalPrefix . '/' . $user->getUID();
257326
}
258327
}
259328

260-
return '';
329+
return null;
261330
}
262331

263332
/**

apps/dav/lib/RootCollection.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,14 @@ public function __construct() {
4343
$logger = \OC::$server->getLogger();
4444
$userManager = \OC::$server->getUserManager();
4545
$groupManager = \OC::$server->getGroupManager();
46+
$shareManager = \OC::$server->getShareManager();
4647
$db = \OC::$server->getDatabaseConnection();
4748
$dispatcher = \OC::$server->getEventDispatcher();
4849
$userPrincipalBackend = new Principal(
4950
$userManager,
50-
$groupManager
51+
$groupManager,
52+
$shareManager,
53+
\OC::$server->getUserSession()
5154
);
5255
$groupPrincipalBackend = new GroupPrincipalBackend($groupManager);
5356
// as soon as debug mode is enabled we allow listing of principals

0 commit comments

Comments
 (0)