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
Prev Previous commit
Next Next commit
Principal search: Take sharing settings into account
Signed-off-by: Georg Ehrke <[email protected]>
  • Loading branch information
georgehrke authored and rullzer committed Dec 11, 2017
commit 6802e2b59a8973b1e7b9c3aaafc5073df51677f9
2 changes: 2 additions & 0 deletions apps/dav/appinfo/v1/caldav.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
$principalBackend = new Principal(
\OC::$server->getUserManager(),
\OC::$server->getGroupManager(),
\OC::$server->getShareManager(),
\OC::$server->getUserSession(),
'principals/'
);
$db = \OC::$server->getDatabaseConnection();
Expand Down
2 changes: 2 additions & 0 deletions apps/dav/appinfo/v1/carddav.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
$principalBackend = new Principal(
\OC::$server->getUserManager(),
\OC::$server->getGroupManager(),
\OC::$server->getShareManager(),
\OC::$server->getUserSession(),
'principals/'
);
$db = \OC::$server->getDatabaseConnection();
Expand Down
4 changes: 3 additions & 1 deletion apps/dav/lib/Command/CreateCalendar.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ protected function execute(InputInterface $input, OutputInterface $output) {
}
$principalBackend = new Principal(
$this->userManager,
$this->groupManager
$this->groupManager,
\OC::$server->getShareManager(),
\OC::$server->getUserSession()
);
$random = \OC::$server->getSecureRandom();
$logger = \OC::$server->getLogger();
Expand Down
109 changes: 89 additions & 20 deletions apps/dav/lib/Connector/Sabre/Principal.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
use OCP\IGroupManager;
use OCP\IUser;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\Share\IManager as IShareManager;
use Sabre\DAV\Exception;
use \Sabre\DAV\PropPatch;
use Sabre\DAVACL\PrincipalBackend\BackendInterface;
Expand All @@ -47,6 +49,12 @@ class Principal implements BackendInterface {
/** @var IGroupManager */
private $groupManager;

/** @var IShareManager */
private $shareManager;

/** @var IUserSession */
private $userSession;

/** @var string */
private $principalPrefix;

Expand All @@ -56,13 +64,19 @@ class Principal implements BackendInterface {
/**
* @param IUserManager $userManager
* @param IGroupManager $groupManager
* @param IShareManager $shareManager
* @param IUserSession $userSession
* @param string $principalPrefix
*/
public function __construct(IUserManager $userManager,
IGroupManager $groupManager,
IShareManager $shareManager,
IUserSession $userSession,
$principalPrefix = 'principals/users/') {
$this->userManager = $userManager;
$this->groupManager = $groupManager;
$this->shareManager = $shareManager;
$this->userSession = $userSession;
$this->principalPrefix = trim($principalPrefix, '/');
$this->hasGroups = ($principalPrefix === 'principals/users/');
}
Expand Down Expand Up @@ -106,7 +120,7 @@ public function getPrincipalByPath($path) {
if ($prefix === $this->principalPrefix) {
$user = $this->userManager->get($name);

if (!is_null($user)) {
if ($user !== null) {
return $this->userToPrincipal($user);
}
}
Expand Down Expand Up @@ -189,37 +203,65 @@ function updatePrincipal($path, PropPatch $propPatch) {
* @param string $test
* @return array
*/
function searchUserPrincipals(array $searchProperties, $test = 'allof') {
protected function searchUserPrincipals(array $searchProperties, $test = 'allof') {
$results = [];

//TODO: If more properties should be supported, hook this up to a db query
// If sharing is disabled, return the empty array
if (!$this->shareManager->shareApiEnabled()) {
return [];
}

// If sharing is restricted to group members only,
// return only members that have groups in common
$restrictGroups = false;
if ($this->shareManager->shareWithGroupMembersOnly()) {
$user = $this->userSession->getUser();
if (!$user) {
return [];
}

$restrictGroups = $this->groupManager->getUserGroupIds($user);
}

foreach ($searchProperties as $prop => $value) {
switch ($prop) {
case '{http://sabredav.org/ns}email-address':
$users = $this->userManager->getByEmail($value);
$results[] = array_map(function ($user) {
return $this->principalPrefix . '/' . $user->getUID();
}, $users);

$results[] = array_reduce($users, function(array $carry, IUser $user) use ($restrictGroups) {
// is sharing restricted to groups only?
if ($restrictGroups !== false) {
$userGroups = $this->groupManager->getUserGroupIds($user);
if (count(array_intersect($userGroups, $restrictGroups)) === 0) {
return $carry;
}
}

$carry[] = $this->principalPrefix . '/' . $user->getUID();
return $carry;
}, []);
break;

default:
$results[] = [];
break;
}
}

if (count($results) == 1) {
// results is an array of arrays, so this is not the first search result
// but the results of the first searchProperty
if (count($results) === 1) {
return $results[0];
}

switch ($test) {
case 'allof':

return array_intersect(...$results);
case 'anyof':
return array_unique(array_merge(...$results));
}

return [];
case 'allof':
default:
return array_intersect(...$results);
}
}

/**
Expand All @@ -229,13 +271,14 @@ function searchUserPrincipals(array $searchProperties, $test = 'allof') {
* @return array
*/
function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') {
if (count($searchProperties) == 0) {
if (count($searchProperties) === 0) {
return [];
}

switch ($prefixPath) {
case 'principals/users':
return $this->searchUserPrincipals($searchProperties, $test);

default:
return [];
}
Expand All @@ -247,17 +290,43 @@ function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof')
* @return string
*/
function findByUri($uri, $principalPrefix) {
if (substr($uri, 0, 7) === 'mailto:') {
if ($principalPrefix === principals/users) {
$email = substr($uri, 7);
$users = $this->userManager->getByEmail($email);
if (count($users) === 1) {
return $this->principalPrefix . '/' . $users[0]->getUID();
// If sharing is disabled, return null as in user not found
if (!$this->shareManager->shareApiEnabled()) {
return null;
}

// If sharing is restricted to group members only,
// return only members that have groups in common
$restrictGroups = false;
if ($this->shareManager->shareWithGroupMembersOnly()) {
$user = $this->userSession->getUser();
if (!$user) {
return null;
}

$restrictGroups = $this->groupManager->getUserGroupIds($user);
}

if (strpos($uri, 'mailto:') === 0) {
if ($principalPrefix === 'principals/users') {
$users = $this->userManager->getByEmail(substr($uri, 7));
if (count($users) !== 1) {
return null;
}
$user = $users[0];

if ($restrictGroups !== false) {
$userGroups = $this->groupManager->getUserGroupIds($user);
if (count(array_intersect($userGroups, $restrictGroups)) === 0) {
return null;
}
}

return $this->principalPrefix . '/' . $user->getUID();
}
}

return '';
return null;
}

/**
Expand Down
5 changes: 4 additions & 1 deletion apps/dav/lib/RootCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,14 @@ public function __construct() {
$logger = \OC::$server->getLogger();
$userManager = \OC::$server->getUserManager();
$groupManager = \OC::$server->getGroupManager();
$shareManager = \OC::$server->getShareManager();
$db = \OC::$server->getDatabaseConnection();
$dispatcher = \OC::$server->getEventDispatcher();
$userPrincipalBackend = new Principal(
$userManager,
$groupManager
$groupManager,
$shareManager,
\OC::$server->getUserSession()
);
$groupPrincipalBackend = new GroupPrincipalBackend($groupManager);
// as soon as debug mode is enabled we allow listing of principals
Expand Down
Loading