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

Shares are displayed to users with resharing rights #12105

Merged
merged 10 commits into from
Nov 4, 2018
84 changes: 80 additions & 4 deletions apps/files_sharing/lib/Controller/ShareAPIController.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
use OCP\AppFramework\OCSController;
use OCP\AppFramework\QueryException;
use OCP\Constants;
use OCP\Files\Folder;
use OCP\Files\Node;
use OCP\Files\NotFoundException;
use OCP\IConfig;
Expand Down Expand Up @@ -240,6 +239,9 @@ protected function formatShare(\OCP\Share\IShare $share, Node $recipientNode = n

$shareWithStart = ($hasCircleId? strrpos($share->getSharedWith(), '[') + 1: 0);
$shareWithLength = ($hasCircleId? -1: strpos($share->getSharedWith(), ' '));
if (is_bool($shareWithLength)) {
$shareWithLength = -1;
}
$result['share_with'] = substr($share->getSharedWith(), $shareWithStart, $shareWithLength);
} else if ($share->getShareType() === Share::SHARE_TYPE_ROOM) {
$result['share_with'] = $share->getSharedWith();
Expand Down Expand Up @@ -719,15 +721,29 @@ public function getShares(
$shares = array_merge($shares, $federatedShares);
}

$formatted = [];
$formatted = $miniFormatted = [];
$resharingRight = false;
foreach ($shares as $share) {
/** @var IShare $share */
try {
$formatted[] = $this->formatShare($share, $path);
} catch (NotFoundException $e) {
$format = $this->formatShare($share, $path);
$formatted[] = $format;
if ($share->getSharedBy() === $this->currentUser) {
$miniFormatted[] = $format;
}

if (!$resharingRight && $this->shareProviderResharingRights($this->currentUser, $share, $path)) {
$resharingRight = true;
}
} catch (\Exception $e) {
//Ignore share
}
}

if (!$resharingRight) {
$formatted = $miniFormatted;
}

if ($include_tags) {
$formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
}
Expand Down Expand Up @@ -1102,4 +1118,64 @@ private function getRoomShareHelper() {

return $this->serverContainer->query('\OCA\Spreed\Share\Helper\ShareAPIController');
}


/**
* Returns if we can find resharing rights in an IShare object for a specific user.
*
* @suppress PhanUndeclaredClassMethod
*
* @param string $userId
* @param IShare $share
* @param Node $node
* @return bool
* @throws NotFoundException
* @throws \OCP\Files\InvalidPathException
*/
private function shareProviderResharingRights(string $userId, IShare $share, $node): bool {

if ($share->getShareOwner() === $userId) {
return true;
}

// we check that current user have parent resharing rights on the current file
if ($node !== null && ($node->getPermissions() & \OCP\Constants::PERMISSION_SHARE) !== 0) {
return true;
}

if ((\OCP\Constants::PERMISSION_SHARE & $share->getPermissions()) === 0) {
return false;
}

if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER && $share->getSharedWith() === $userId) {
return true;
}

if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP && $this->groupManager->isInGroup($userId, $share->getSharedWith())) {
return true;
}

if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE && \OC::$server->getAppManager()->isEnabledForUser('circles') &&
class_exists('\OCA\Circles\Api\v1\Circles')) {
$hasCircleId = (substr($share->getSharedWith(), -1) === ']');
$shareWithStart = ($hasCircleId ? strrpos($share->getSharedWith(), '[') + 1 : 0);
$shareWithLength = ($hasCircleId ? -1 : strpos($share->getSharedWith(), ' '));
if (is_bool($shareWithLength)) {
$shareWithLength = -1;
}
$sharedWith = substr($share->getSharedWith(), $shareWithStart, $shareWithLength);
try {
$member = \OCA\Circles\Api\v1\Circles::getMember($sharedWith, $userId, 1);
if ($member->getLevel() >= 4) {
return true;
}
return false;
} catch (QueryException $e) {
return false;
}
}

return false;
}

}
4 changes: 4 additions & 0 deletions core/js/share/sharedialogshareelistview.handlebars
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<ul id="shareWithList" class="shareWithList">
{{#each sharees}}
{{#unless isShareWithCurrentUser}}
<li data-share-id="{{shareId}}" data-share-type="{{shareType}}" data-share-with="{{shareWith}}">
<div class="avatar {{#if modSeed}}imageplaceholderseed{{/if}}" data-username="{{shareWith}}" data-avatar="{{shareWithAvatar}}" data-displayname="{{shareWithDisplayName}}" {{#if modSeed}}data-seed="{{shareWith}} {{shareType}}"{{/if}}></div>
<span class="username" title="{{shareWithTitle}}">{{shareWithDisplayName}}</span>
{{#if canUpdateShareSettings }}
<span class="sharingOptionsGroup">
{{#if editPermissionPossible}}
<span>
Expand All @@ -14,7 +16,9 @@
{{{popoverMenu}}}
</div>
</span>
{{/if}}
</li>
{{/unless}}
{{/each}}
{{#each linkReshares}}
<li data-share-id="{{shareId}}" data-share-type="{{shareType}}">
Expand Down
6 changes: 6 additions & 0 deletions core/js/sharedialogshareelistview.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
var shareType = this.model.getShareType(shareIndex);
var sharedBy = this.model.getSharedBy(shareIndex);
var sharedByDisplayName = this.model.getSharedByDisplayName(shareIndex);
var fileOwnerUid = this.model.getFileOwnerUid(shareIndex);

var hasPermissionOverride = {};
if (shareType === OC.Share.SHARE_TYPE_GROUP) {
Expand Down Expand Up @@ -143,13 +144,18 @@
hasCreatePermission: this.model.hasCreatePermission(shareIndex),
hasUpdatePermission: this.model.hasUpdatePermission(shareIndex),
hasDeletePermission: this.model.hasDeletePermission(shareIndex),
sharedBy: sharedBy,
sharedByDisplayName: sharedByDisplayName,
shareWith: shareWith,
shareWithDisplayName: shareWithDisplayName,
shareWithAvatar: shareWithAvatar,
shareWithTitle: shareWithTitle,
shareType: shareType,
shareId: this.model.get('shares')[shareIndex].id,
modSeed: shareWithAvatar || (shareType !== OC.Share.SHARE_TYPE_USER && shareType !== OC.Share.SHARE_TYPE_CIRCLE && shareType !== OC.Share.SHARE_TYPE_ROOM),
owner: fileOwnerUid,
isShareWithCurrentUser: (shareType === OC.Share.SHARE_TYPE_USER && shareWith === oc_current_user),
canUpdateShareSettings: (sharedBy === oc_current_user || fileOwnerUid === oc_current_user),
isRemoteShare: shareType === OC.Share.SHARE_TYPE_REMOTE,
isRemoteGroupShare: shareType === OC.Share.SHARE_TYPE_REMOTE_GROUP,
isNoteAvailable: shareType !== OC.Share.SHARE_TYPE_REMOTE && shareType !== OC.Share.SHARE_TYPE_REMOTE_GROUP,
Expand Down
13 changes: 13 additions & 0 deletions core/js/shareitemmodel.js
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,19 @@
return share.displayname_owner;
},

/**
* @param shareIndex
* @returns {string}
*/
getFileOwnerUid: function(shareIndex) {
/** @type OC.Share.Types.ShareInfo **/
var share = this.get('shares')[shareIndex];
if(!_.isObject(share)) {
throw "Unknown Share";
}
return share.uid_file_owner;
},

/**
* returns the array index of a sharee for a provided shareId
*
Expand Down
34 changes: 22 additions & 12 deletions core/js/sharetemplates.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion core/js/tests/specs/sharedialogshareelistview.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ describe('OC.Share.ShareDialogShareeListView', function () {
share_type: OC.Share.SHARE_TYPE_USER,
share_with: 'user1',
share_with_displayname: 'User One',
uid_owner: oc_current_user,
itemType: 'folder'
}]);
shareModel.set('itemType', 'folder');
Expand All @@ -144,6 +145,7 @@ describe('OC.Share.ShareDialogShareeListView', function () {
share_type: OC.Share.SHARE_TYPE_USER,
share_with: 'user _.@-\'',
share_with_displayname: 'User One',
uid_owner: oc_current_user,
itemType: 'folder'
}]);
shareModel.set('itemType', 'folder');
Expand All @@ -159,6 +161,7 @@ describe('OC.Share.ShareDialogShareeListView', function () {
share_type: OC.Share.SHARE_TYPE_USER,
share_with: 'user1',
share_with_displayname: 'User One',
uid_owner: oc_current_user,
itemType: 'folder'
}]);
shareModel.set('itemType', 'folder');
Expand All @@ -174,6 +177,7 @@ describe('OC.Share.ShareDialogShareeListView', function () {
share_type: OC.Share.SHARE_TYPE_USER,
share_with: 'user _.@-\'',
share_with_displayname: 'User One',
uid_owner: oc_current_user,
itemType: 'folder'
}]);
shareModel.set('itemType', 'folder');
Expand All @@ -189,7 +193,8 @@ describe('OC.Share.ShareDialogShareeListView', function () {
permissions: 1,
share_type: OC.Share.SHARE_TYPE_USER,
share_with: 'user1',
share_with_displayname: 'User One'
share_with_displayname: 'User One',
uid_owner: oc_current_user,
}]);
shareModel.set('itemType', 'folder');
listView.render();
Expand All @@ -206,6 +211,7 @@ describe('OC.Share.ShareDialogShareeListView', function () {
share_type: OC.Share.SHARE_TYPE_USER,
share_with: 'user1',
share_with_displayname: 'User One',
uid_owner: oc_current_user,
itemType: 'folder'
}]);
shareModel.set('itemType', 'folder');
Expand All @@ -223,6 +229,7 @@ describe('OC.Share.ShareDialogShareeListView', function () {
share_type: OC.Share.SHARE_TYPE_USER,
share_with: 'user1',
share_with_displayname: 'User One',
uid_owner: oc_current_user,
itemType: 'folder'
}]);
shareModel.set('itemType', 'folder');
Expand Down
14 changes: 8 additions & 6 deletions lib/private/Share20/DefaultShareProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -620,12 +620,14 @@ public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offs
if ($reshares === false) {
$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
} else {
$qb->andWhere(
$qb->expr()->orX(
$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
)
);
if ($node === null) {
$qb->andWhere(
$qb->expr()->orX(
$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
)
);
}
}

if ($node !== null) {
Expand Down