Skip to content

Commit

Permalink
Merge pull request #1384 from nextcloud/backport/1357/1357-stable27
Browse files Browse the repository at this point in the history
[stable27] download permissions on share for internal/external members
  • Loading branch information
blizzz authored Sep 7, 2023
2 parents c202eb4 + 39d6f8f commit 575c444
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 23 deletions.
1 change: 1 addition & 0 deletions lib/Db/CoreRequestBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ class CoreRequestBuilder {
'file_source',
'file_target',
'permissions',
'attributes',
'stime',
'accepted',
'expiration',
Expand Down
67 changes: 49 additions & 18 deletions lib/Db/ShareWrapperRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,18 @@

namespace OCA\Circles\Db;

use JsonException;
use OCA\Circles\Exceptions\RequestBuilderException;
use OCA\Circles\Exceptions\ShareWrapperNotFoundException;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Membership;
use OCA\Circles\Model\Probes\CircleProbe;
use OCA\Circles\Model\ShareWrapper;
use OCP\Files\Folder;
use OCP\Files\NotFoundException;
use OCP\Share\Exceptions\IllegalIDChangeException;
use OCP\Share\IAttributes;
use OCP\Share\IShare;
use OCP\Files\Folder;

/**
* Class ShareWrapperRequest
Expand All @@ -62,18 +64,18 @@ public function save(IShare $share, int $parentId = 0): int {

$qb = $this->getShareInsertSql();
$qb->setValue('share_type', $qb->createNamedParameter($share->getShareType()))
->setValue('item_type', $qb->createNamedParameter($share->getNodeType()))
->setValue('item_source', $qb->createNamedParameter($share->getNodeId()))
->setValue('file_source', $qb->createNamedParameter($share->getNodeId()))
->setValue('file_target', $qb->createNamedParameter($share->getTarget()))
->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()))
->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
->setValue('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
->setValue('password', $qb->createNamedParameter($password))
->setValue('permissions', $qb->createNamedParameter($share->getPermissions()))
->setValue('token', $qb->createNamedParameter($share->getToken()))
->setValue('stime', $qb->createFunction('UNIX_TIMESTAMP()'));
->setValue('item_type', $qb->createNamedParameter($share->getNodeType()))
->setValue('item_source', $qb->createNamedParameter($share->getNodeId()))
->setValue('file_source', $qb->createNamedParameter($share->getNodeId()))
->setValue('file_target', $qb->createNamedParameter($share->getTarget()))
->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()))
->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
->setValue('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
->setValue('password', $qb->createNamedParameter($password))
->setValue('permissions', $qb->createNamedParameter($share->getPermissions()))
->setValue('token', $qb->createNamedParameter($share->getToken()))
->setValue('stime', $qb->createFunction('UNIX_TIMESTAMP()'));

if ($parentId > 0) {
$qb->setValue('parent', $qb->createNamedParameter($parentId));
Expand All @@ -95,12 +97,15 @@ public function save(IShare $share, int $parentId = 0): int {
*/
public function update(ShareWrapper $shareWrapper): void {
$qb = $this->getShareUpdateSql();
$shareAttributes = $this->formatShareAttributes($shareWrapper->getAttributes());

$qb->set('file_target', $qb->createNamedParameter($shareWrapper->getFileTarget()))
->set('share_with', $qb->createNamedParameter($shareWrapper->getSharedWith()))
->set('uid_owner', $qb->createNamedParameter($shareWrapper->getShareOwner()))
->set('uid_initiator', $qb->createNamedParameter($shareWrapper->getSharedBy()))
->set('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
->set('permissions', $qb->createNamedParameter($shareWrapper->getPermissions()));
->set('share_with', $qb->createNamedParameter($shareWrapper->getSharedWith()))
->set('uid_owner', $qb->createNamedParameter($shareWrapper->getShareOwner()))
->set('uid_initiator', $qb->createNamedParameter($shareWrapper->getSharedBy()))
->set('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
->set('permissions', $qb->createNamedParameter($shareWrapper->getPermissions()))
->set('attributes', $qb->createNamedParameter($shareAttributes));

$qb->limitToId((int)$shareWrapper->getId());

Expand Down Expand Up @@ -486,4 +491,30 @@ private function deleteSharesAndChild(array $ids): void {

$qb->execute();
}


/**
* Format IAttributes to database format (JSON string)
* based on OC\Share20\DefaultShareProvider::formatShareAttributes();
*/
private function formatShareAttributes(?IAttributes $attributes): ?string {
if (empty($attributes?->toArray())) {
return null;
}

$compressedAttributes = [];
foreach ($attributes->toArray() as $attribute) {
$compressedAttributes[] = [
$attribute['scope'],
$attribute['key'],
$attribute['enabled']
];
}

try {
return json_encode($compressedAttributes, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
return null;
}
}
}
58 changes: 57 additions & 1 deletion lib/Model/ShareWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
use OC;
use OC\Files\Cache\Cache;
use OC\Share20\Share;
use OC\Share20\ShareAttributes;
use OCA\Circles\AppInfo\Application;
use OCA\Circles\ShareByCircleProvider;
use OCA\Circles\Tools\Db\IQueryRow;
Expand All @@ -48,6 +49,7 @@
use OCP\IUserManager;
use OCP\L10N\IFactory;
use OCP\Share\Exceptions\IllegalIDChangeException;
use OCP\Share\IAttributes;
use OCP\Share\IShare;

/**
Expand Down Expand Up @@ -82,6 +84,8 @@ class ShareWrapper extends ManagedModel implements IDeserializable, IQueryRow, J
private ?Member $initiator = null;
private ?Member $owner = null;
private ?ShareToken $shareToken = null;
private ?IAttributes $attributes = null;
private bool $hideDownload = false;

public function __construct() {
$this->shareTime = new DateTime();
Expand Down Expand Up @@ -337,6 +341,27 @@ public function hasShareToken(): bool {
return !is_null($this->shareToken);
}

public function getAttributes(): ?IAttributes {
return $this->attributes;
}

public function setAttributes(?IAttributes $attributes): self {
$this->attributes = $attributes;

return $this;
}

public function getHideDownload(): bool {
return $this->hideDownload;
}

public function setHideDownload(bool $hideDownload): self {
$this->hideDownload = $hideDownload;

return $this;
}


/**
* @throws IllegalIDChangeException
*/
Expand All @@ -354,7 +379,8 @@ public function getShare(
$share->setTarget($this->getFileTarget());
$share->setProviderId($this->getProviderId());
$share->setStatus($this->getStatus());

$share->setHideDownload($this->getHideDownload());
$share->setAttributes($this->getAttributes());
if ($this->hasShareToken()) {
$password = $this->getShareToken()->getPassword();
if ($password !== '') {
Expand Down Expand Up @@ -456,6 +482,7 @@ public function import(array $data): IDeserializable {
$this->setId($this->get('id', $data))
->setShareType($this->getInt('shareType', $data))
->setPermissions($this->getInt('permissions', $data))
->setHideDownload($this->getBool('hideDownload', $data))
->setItemType($this->get('itemType', $data))
->setItemSource($this->getInt('itemSource', $data))
->setItemTarget($this->get('itemTarget', $data))
Expand Down Expand Up @@ -524,6 +551,8 @@ public function importFromDatabase(array $data, string $prefix = ''): IQueryRow
->setToken($this->get($prefix . 'token', $data))
->setShareTime($shareTime);

$this->importAttributesFromDatabase($this->get('attributes', $data));

// if (($password = $this->get('personal_password', $data, '')) !== '') {
// $share->setPassword($this->get('personal_password', $data, ''));
// } else if (($password = $this->get('password', $data, '')) !== '') {
Expand All @@ -541,12 +570,39 @@ public function importFromDatabase(array $data, string $prefix = ''): IQueryRow
return $this;
}


/**
* Load from database format (JSON string) to IAttributes
* based on \OC\Share20\DefaultShareProvider
*/
private function importAttributesFromDatabase(string $data): void {
if ($data === '') {
return;
}

$attributes = new ShareAttributes();
$compressedAttributes = json_decode($data, true);
if (!is_array($compressedAttributes)) {
return;
}

foreach ($compressedAttributes as $compressedAttribute) {
$attributes->setAttribute(...$compressedAttribute);
}

$this->setHideDownload(!($attributes->getAttribute('permissions', 'download') ?? true));
$this->setAttributes($attributes);
}


public function jsonSerialize(): array {
$arr = [
'id' => $this->getId(),
'shareType' => $this->getShareType(),
'providerId' => $this->getProviderId(),
'permissions' => $this->getPermissions(),
'attributes' => $this->getAttributes(),
'hideDownload' => $this->getHideDownload(),
'itemType' => $this->getItemType(),
'itemSource' => $this->getItemSource(),
'itemTarget' => $this->getItemTarget(),
Expand Down
2 changes: 1 addition & 1 deletion lib/Service/CircleService.php
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,7 @@ public function probeCircle(
* @param CircleProbe $circleProbe
* @param DataProbe|null $dataProbe
*
* @return array
* @return Circle[]
* @throws InitiatorNotFoundException
* @throws RequestBuilderException
*/
Expand Down
5 changes: 3 additions & 2 deletions lib/ShareByCircleProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,9 @@ public function create(IShare $share): IShare {
public function update(IShare $share): IShare {
$wrappedShare = $this->shareWrapperService->getShareById((int)$share->getId());
$wrappedShare->setPermissions($share->getPermissions())
->setShareOwner($share->getShareOwner())
->setSharedBy($share->getSharedBy());
->setShareOwner($share->getShareOwner())
->setAttributes($share->getAttributes())
->setSharedBy($share->getSharedBy());

$this->shareWrapperService->update($wrappedShare);

Expand Down
1 change: 1 addition & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<errorLevel type="suppress">
<referencedClass name="OC" />
<referencedClass name="Doctrine\DBAL\Schema\SchemaException" />
<referencedClass name="OC\Share20\ShareAttributes" />
</errorLevel>
</UndefinedClass>
<UndefinedDocblockClass>
Expand Down
3 changes: 2 additions & 1 deletion tests/psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,9 @@
</InvalidReturnType>
</file>
<file src="lib/Model/ShareWrapper.php">
<InvalidArgument occurrences="1">
<InvalidArgument occurrences="2">
<code>Cache::cacheEntryFromData($this-&gt;getFileCache()-&gt;toCache(), OC::$server-&gt;getMimeTypeLoader())</code>
<code>$this-&gt;setAttributes($attributes)</code>
</InvalidArgument>
<InvalidNullableReturnType occurrences="5">
<code>Circle</code>
Expand Down

0 comments on commit 575c444

Please sign in to comment.