diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 03e2738b6..7dba407b1 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -55,7 +55,7 @@ jobs: uses: actions/checkout@v4.2.2 with: repository: nextcloud/server - ref: ${{ matrix.server-versions }} + ref: 'feature/54562/files-sharing-authoritative' submodules: true - name: Checkout app diff --git a/composer.lock b/composer.lock index b2d385960..4506e9333 100644 --- a/composer.lock +++ b/composer.lock @@ -65,26 +65,26 @@ }, { "name": "justinrainbow/json-schema", - "version": "6.4.2", + "version": "6.6.4", "source": { "type": "git", "url": "https://github.com/jsonrainbow/json-schema.git", - "reference": "ce1fd2d47799bb60668643bc6220f6278a4c1d02" + "reference": "2eeb75d21cf73211335888e7f5e6fd7440723ec7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/ce1fd2d47799bb60668643bc6220f6278a4c1d02", - "reference": "ce1fd2d47799bb60668643bc6220f6278a4c1d02", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/2eeb75d21cf73211335888e7f5e6fd7440723ec7", + "reference": "2eeb75d21cf73211335888e7f5e6fd7440723ec7", "shasum": "" }, "require": { "ext-json": "*", - "marc-mabe/php-enum": "^4.0", + "marc-mabe/php-enum": "^4.4", "php": "^7.2 || ^8.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "3.3.0", - "json-schema/json-schema-test-suite": "1.2.0", + "json-schema/json-schema-test-suite": "^23.2", "marc-mabe/php-enum-phpstan": "^2.0", "phpspec/prophecy": "^1.19", "phpstan/phpstan": "^1.12", @@ -134,9 +134,9 @@ ], "support": { "issues": "https://github.com/jsonrainbow/json-schema/issues", - "source": "https://github.com/jsonrainbow/json-schema/tree/6.4.2" + "source": "https://github.com/jsonrainbow/json-schema/tree/6.6.4" }, - "time": "2025-06-03T18:27:04+00:00" + "time": "2025-12-19T15:01:32+00:00" }, { "name": "marc-mabe/php-enum", @@ -437,12 +437,12 @@ "source": { "type": "git", "url": "https://github.com/nextcloud-deps/ocp.git", - "reference": "d42bd36d0413b881b7459b220e1328bc57e48b38" + "reference": "6c1e5686d00c40f57abd83e8ad268e9ab34825bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/d42bd36d0413b881b7459b220e1328bc57e48b38", - "reference": "d42bd36d0413b881b7459b220e1328bc57e48b38", + "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/6c1e5686d00c40f57abd83e8ad268e9ab34825bb", + "reference": "6c1e5686d00c40f57abd83e8ad268e9ab34825bb", "shasum": "" }, "require": { @@ -478,7 +478,7 @@ "issues": "https://github.com/nextcloud-deps/ocp/issues", "source": "https://github.com/nextcloud-deps/ocp/tree/master" }, - "time": "2025-12-11T00:55:32+00:00" + "time": "2026-01-09T00:57:54+00:00" }, { "name": "nikic/php-parser", diff --git a/lib/Controller/CardApiController.php b/lib/Controller/CardApiController.php index bc1359250..4a3187e01 100644 --- a/lib/Controller/CardApiController.php +++ b/lib/Controller/CardApiController.php @@ -72,11 +72,11 @@ public function create($title, $type = 'plain', $order = 999, $description = '', $card = $this->cardService->create($title, $this->request->getParam('stackId'), $type, $order, $this->userId, $description, $duedate); foreach ($labels as $labelId) { - $this->cardService->assignLabel($card->id, $labelId); + $this->cardService->assignLabel($card->getId(), $labelId); } foreach ($users as $user) { - $this->assignmentService->assignUser($card->id, $user['id'], $user['type']); + $this->assignmentService->assignUser($card->getId(), $user['id'], $user['type']); } return new DataResponse($card, HTTP::STATUS_OK); diff --git a/lib/Db/Assignment.php b/lib/Db/Assignment.php index 6c273240a..4160aed12 100644 --- a/lib/Db/Assignment.php +++ b/lib/Db/Assignment.php @@ -10,7 +10,6 @@ use JsonSerializable; class Assignment extends RelationalEntity implements JsonSerializable { - public $id; protected $participant; protected $cardId; protected $type; diff --git a/lib/Db/Session.php b/lib/Db/Session.php index 7f65f8839..886fdfb4c 100644 --- a/lib/Db/Session.php +++ b/lib/Db/Session.php @@ -12,7 +12,6 @@ use OCP\AppFramework\Db\Entity; class Session extends Entity implements \JsonSerializable { - public $id; protected $userId; protected $token; protected $lastContact; diff --git a/lib/Service/FilesAppService.php b/lib/Service/FilesAppService.php index 38f3cf373..dda58be0f 100644 --- a/lib/Service/FilesAppService.php +++ b/lib/Service/FilesAppService.php @@ -312,7 +312,7 @@ public function markAsDeleted(Attachment $attachment) { */ private function getShareForAttachment(Attachment $attachment): IShare { try { - $share = $this->shareProvider->getShareById($attachment->getId()); + $share = $this->shareProvider->getShareById((string)$attachment->getId()); } catch (ShareNotFound $e) { throw new NoPermissionException('No permission to access the attachment from the card'); } diff --git a/lib/Sharing/DeckShareProvider.php b/lib/Sharing/DeckShareProvider.php index ca0dbc5e7..f841fe3c8 100644 --- a/lib/Sharing/DeckShareProvider.php +++ b/lib/Sharing/DeckShareProvider.php @@ -32,6 +32,7 @@ use OCP\Share\Exceptions\GenericShareException; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager; +use OCP\Share\IPartialShareProvider; use OCP\Share\IShare; /** Taken from the talk shareapicontroller helper */ @@ -42,7 +43,7 @@ public function formatShare(IShare $share): array; public function canAccessShare(IShare $share, string $user): bool; } -class DeckShareProvider implements \OCP\Share\IShareProvider { +class DeckShareProvider implements \OCP\Share\IShareProvider, IPartialShareProvider { public const DECK_FOLDER = '/Deck'; public const DECK_FOLDER_PLACEHOLDER = '/{DECK_PLACEHOLDER}'; @@ -419,7 +420,7 @@ public function restore(IShare $share, string $recipient): IShare { $qb->executeStatement(); - return $this->getShareById((int)$share->getId(), $recipient); + return $this->getShareById((string)$share->getId(), $recipient); } /** @@ -702,6 +703,32 @@ public function getSharesByPath(Node $path): array { * @return IShare[] */ public function getSharedWith($userId, $shareType, $node, $limit, $offset): array { + return $this->_getSharedWith($userId, $limit, $offset, $node); + } + + public function getSharedWithByPath( + string $userId, + int $shareType, + string $path, + bool $forChildren, + int $limit, + int $offset, + ): iterable { + return $this->_getSharedWith($userId, $limit, $offset, null, $path, $forChildren); + } + + /** + * Get received shared for the given user. + * You can optionally provide a node or a path to filter the shares. + */ + public function _getSharedWith( + string $userId, + int $limit, + int $offset, + ?Node $node = null, + ?string $path = null, + ?bool $forChildren = false, + ): array { $allBoards = $this->boardMapper->findBoardIds($userId); /** @var IShare[] $shares */ @@ -740,6 +767,17 @@ public function getSharedWith($userId, $shareType, $node, $limit, $offset): arra $qb->andWhere($qb->expr()->eq('s.file_source', $qb->createNamedParameter($node->getId()))); } + if ($path !== null) { + $qb->leftJoin('s', 'share', 'sc', $qb->expr()->eq('s.parent', 'sc.id')) + ->andWhere($qb->expr()->eq('sc.share_type', $qb->createNamedParameter(IShare::TYPE_DECK_USER))); + + if ($forChildren) { + $qb->andWhere($qb->expr()->like('sc.file_target', $qb->createNamedParameter($this->dbConnection->escapeLikeParameter($path) . '_%'))); + } else { + $qb->andWhere($qb->expr()->eq('sc.file_target', $qb->createNamedParameter($path))); + } + } + $qb->andWhere($qb->expr()->eq('s.share_type', $qb->createNamedParameter(IShare::TYPE_DECK))) ->andWhere($qb->expr()->in('db.id', $qb->createNamedParameter( $boards, diff --git a/tests/integration/run.sh b/tests/integration/run.sh index 1dfe35b70..1ef66e721 100755 --- a/tests/integration/run.sh +++ b/tests/integration/run.sh @@ -7,8 +7,7 @@ HIDE_OC_LOGS=$2 # Nextcloud integration tests composer ( - cd ${OC_PATH}build/integration - composer install + composer --working-dir $OC_PATH install ) INSTALLED=$($OCC status | grep installed: | cut -d " " -f 5)