Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create infrastructure to allow files to be shared with circles #6959

4 changes: 4 additions & 0 deletions apps/dav/lib/CalDAV/CalDavBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
* @author Thomas Citharel <tcit@tcit.fr>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Georg Ehrke <oc.list@georgehrke.com>
* @author Vinicius Cubas Brand <vinicius@eita.org.br>
* @author Daniel Tygel <dtygel@eita.org.br>
*
* @license AGPL-3.0
*
Expand Down Expand Up @@ -280,6 +282,8 @@ function getCalendarsForUser($principalUri) {

// query for shared calendars
$principals = $this->principalBackend->getGroupMembership($principalUriOriginal, true);
$principals = array_merge($principals, $this->principalBackend->getCircleMembership($principalUriOriginal));

$principals = array_map(function($principal) {
return urldecode($principal);
}, $principals);
Expand Down
38 changes: 38 additions & 0 deletions apps/dav/lib/Connector/Sabre/FilesReportPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class FilesReportPlugin extends ServerPlugin {
const NS_OWNCLOUD = 'http://owncloud.org/ns';
const REPORT_NAME = '{http://owncloud.org/ns}filter-files';
const SYSTEMTAG_PROPERTYNAME = '{http://owncloud.org/ns}systemtag';
const CIRCLE_PROPERTYNAME = '{http://owncloud.org/ns}circle';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be {http:/nextcloud.com/ns}circle

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, adding hooks in dav app would be more elegant. But since system tags are already core factored in dav, we thought a first approach would be to have both system tags and circles working similarly.

We would be happy to collaborate to implement hooks in dav in the future, and then migrate both circles and system tags to the hooks approach.

Maybe, for NC13, we could start the way we've implemented now... What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is another difference ;)
systemtags are shipped (therefor the code is not missing etc) while circles are totally optional


/**
* Reference to main server object
Expand Down Expand Up @@ -255,14 +256,19 @@ protected function processFilterRules($filterRules) {
$ns = '{' . $this::NS_OWNCLOUD . '}';
$resultFileIds = null;
$systemTagIds = [];
$circlesIds = [];
$favoriteFilter = null;
foreach ($filterRules as $filterRule) {
if ($filterRule['name'] === $ns . 'systemtag') {
$systemTagIds[] = $filterRule['value'];
}
if ($filterRule['name'] === $ns . 'circle') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's CIRCLE_PROPERTYNAME now

$circlesIds[] = $filterRule['value'];
}
if ($filterRule['name'] === $ns . 'favorite') {
$favoriteFilter = true;
}

}

if ($favoriteFilter !== null) {
Expand All @@ -281,6 +287,15 @@ protected function processFilterRules($filterRules) {
}
}

if (!empty($circlesIds)) {
$fileIds = $this->getCirclesFileIds($circlesIds);
if (empty($resultFileIds)) {
$resultFileIds = $fileIds;
} else {
$resultFileIds = array_intersect($fileIds, $resultFileIds);
}
}

return $resultFileIds;
}

Expand Down Expand Up @@ -327,6 +342,29 @@ private function getSystemTagFileIds($systemTagIds) {
return $resultFileIds;
}

private function getCirclesFileIds($circlesIds) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PHPDocs on the function parameters and the return value would be awesome.

Also is $circlesIds an array? If so you can typehint it with array $circleIds.


// check user permissions, if applicable
/*
if (!$this->isAdmin()) {
// check visibility/permission
$tags = $this->tagManager->getTagsByIds($circlesIds);
$unknownTagIds = [];
foreach ($tags as $tag) {
if (!$tag->isUserVisible()) {
$unknownTagIds[] = $tag->getId();
}
}

if (!empty($unknownTagIds)) {
throw new TagNotFoundException('Tag with ids ' . implode(', ', $unknownTagIds) . ' not found');
}
}
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe cleaning those commented line


return \OCA\Circles\Api\v1\Circles::getFilesForCircles($circlesIds);
}

/**
* Prepare propfind response for the given nodes
*
Expand Down
71 changes: 70 additions & 1 deletion apps/dav/lib/Connector/Sabre/Principal.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Thomas Tanghus <thomas@tanghus.net>
* @author Vincent Petry <pvince81@owncloud.com>
* @author Vinicius Cubas Brand <vinicius@eita.org.br>
* @author Daniel Tygel <dtygel@eita.org.br>
*
* @license AGPL-3.0
*
Expand Down Expand Up @@ -52,6 +54,9 @@ class Principal implements BackendInterface {
/** @var bool */
private $hasGroups;

/** @var bool */
private $hasCircles;

/**
* @param IUserManager $userManager
* @param IGroupManager $groupManager
Expand All @@ -63,7 +68,7 @@ public function __construct(IUserManager $userManager,
$this->userManager = $userManager;
$this->groupManager = $groupManager;
$this->principalPrefix = trim($principalPrefix, '/');
$this->hasGroups = ($principalPrefix === 'principals/users/');
$this->hasGroups = $this->hasCircles = ($principalPrefix === 'principals/users/');
}

/**
Expand Down Expand Up @@ -108,6 +113,8 @@ public function getPrincipalByPath($path) {
if (!is_null($user)) {
return $this->userToPrincipal($user);
}
} else if ($prefix === 'principals/circles') {
return $this->circleToPrincipal($name);
}
return null;
}
Expand Down Expand Up @@ -232,4 +239,66 @@ public function getPrincipalPrefix() {
return $this->principalPrefix;
}

/**
* @param string $circleUniqueId
* @return array|null
*/
protected function circleToPrincipal($circleUniqueId) {
if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) {
return null;
}

$circle = \OCA\Circles\Api\v1\Circles::detailsCircle($circleUniqueId);

if (!$circle) {
return null;
}

$principal = [
'uri' => 'principals/circles/' . $circleUniqueId,
'{DAV:}displayname' => $circle->getName(),
];

return $principal;
}

/**
* Returns the list of circles a principal is a member of
*
* @param string $principal
* @param bool $needGroups
* @return array
* @throws Exception
*/
public function getCircleMembership($principal) {
if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) {
return [];
}

list($prefix, $name) = URLUtil::splitPath($principal);

if ($this->hasCircles && $prefix === $this->principalPrefix) {
$user = $this->userManager->get($name);
if (!$user) {
throw new Exception('Principal not found');
}

$userSession = \OC::$server->getUserSession();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we inject the current user in the constructor instead?

$currentUser = $userSession->getUser();

$userSession->setUser($user);
$circles = \OCA\Circles\Api\v1\Circles::joinedCircles();
$userSession->setUser($currentUser);

$circles = array_map(function($circle) {
/** @var \OCA\Circles\Model\Circle $group */
return 'principals/circles/' . urlencode($circle->getUniqueId());
}, $circles);

return $circles;

}
return [];
}

}
1 change: 1 addition & 0 deletions apps/dav/lib/Connector/Sabre/SharesPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ private function getShareTypes(\OCP\Files\Node $node) {
\OCP\Share::SHARE_TYPE_LINK,
\OCP\Share::SHARE_TYPE_REMOTE,
\OCP\Share::SHARE_TYPE_EMAIL,
\OCP\Share::SHARE_TYPE_CIRCLE,
];
foreach ($requestedShareTypes as $requestedShareType) {
// one of each type is enough to find out about the types
Expand Down
8 changes: 6 additions & 2 deletions core/js/files/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@

/**
* Fetches a flat list of files filtered by a given filter criteria.
* (currently only system tags is supported)
* (currently system tags and circles are supported)
*
* @param {Object} filter filter criteria
* @param {Object} [filter.systemTagIds] list of system tag ids to filter by
Expand All @@ -476,7 +476,8 @@
properties = options.properties;
}

if (!filter || (!filter.systemTagIds && _.isUndefined(filter.favorite))) {
if (!filter ||
(!filter.systemTagIds && _.isUndefined(filter.favorite) && !filter.circlesIds) ) {
throw 'Missing filter argument';
}

Expand All @@ -502,6 +503,9 @@
_.each(filter.systemTagIds, function(systemTagIds) {
body += ' <oc:systemtag>' + escapeHTML(systemTagIds) + '</oc:systemtag>\n';
});
_.each(filter.circlesIds, function(circlesIds) {
body += ' <oc:circle>' + escapeHTML(circlesIds) + '</oc:circle>\n';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nc?

});
if (filter.favorite) {
body += ' <oc:favorite>' + (filter.favorite ? '1': '0') + '</oc:favorite>\n';
}
Expand Down