diff --git a/lib/Db/CoreQueryBuilder.php b/lib/Db/CoreQueryBuilder.php index 75c7e6cfe..b9ae6d7d5 100644 --- a/lib/Db/CoreQueryBuilder.php +++ b/lib/Db/CoreQueryBuilder.php @@ -80,6 +80,7 @@ class CoreQueryBuilder extends NC22ExtendedQueryBuilder { const SHARE = 'share'; const FILE_CACHE = 'filecache'; const STORAGES = 'storages'; + const TOKEN = 'token'; const OPTIONS = 'options'; const HELPER = 'circleshelper'; @@ -169,6 +170,7 @@ class CoreQueryBuilder extends NC22ExtendedQueryBuilder { ], self::SHARE => [ self::SHARE, + self::TOKEN, self::FILE_CACHE => [ self::STORAGES ], @@ -1038,6 +1040,38 @@ public function leftJoinMembersByInheritance(string $alias, string $field = ''): } + /** + * @param string $alias + * @param string $token + * + * @throws RequestBuilderException + */ + public function limitToShareToken(string $alias, string $token): void { + $this->leftJoinShareToken($alias); + + $aliasShareToken = $this->generateAlias($alias, self::TOKEN, $options); + $this->limit('token', $token, $aliasShareToken); + } + + /** + * @param string $alias + * @param string $field + * + * @throws RequestBuilderException + */ + public function leftJoinShareToken(string $alias, string $field = ''): void { + $expr = $this->expr(); + + $field = ($field === '') ? 'id' : $field; + $aliasShareToken = $this->generateAlias($alias, self::TOKEN, $options); + + $this->leftJoin( + $alias, CoreRequestBuilder::TABLE_TOKEN, $aliasShareToken, + $expr->eq($aliasShareToken . '.share_id', $alias . '.' . $field) + ); + } + + /** * limit the result to the point of view of a FederatedUser * diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index 988184990..173e77cc5 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -63,7 +63,7 @@ class CoreRequestBuilder { // wip const TABLE_SHARE_LOCK = 'circles_share_lock'; - const TABLE_TOKENS = 'circles_token'; + const TABLE_TOKEN = 'circles_token'; const TABLE_GSSHARES = 'circle_gsshares'; // rename ? const TABLE_GSSHARES_MOUNTPOINT = 'circle_gsshares_mp'; // rename ? @@ -144,7 +144,16 @@ class CoreRequestBuilder { ], self::TABLE_MOUNTPOINT => [], self::TABLE_SHARE_LOCK => [], - self::TABLE_TOKENS => [], + self::TABLE_TOKEN => [ + 'id', + 'share_id', + 'circle_id', + 'single_id', + 'member_id', + 'token', + 'password', + 'accepted' + ], self::TABLE_GSSHARES => [], self::TABLE_GSSHARES_MOUNTPOINT => [] ]; diff --git a/lib/Db/ShareTokenRequest.php b/lib/Db/ShareTokenRequest.php new file mode 100644 index 000000000..a80aad965 --- /dev/null +++ b/lib/Db/ShareTokenRequest.php @@ -0,0 +1,67 @@ + + * @copyright 2021 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + + +namespace OCA\Circles\Db; + + +use OCA\Circles\Model\ShareToken; + + +/** + * Class ShareTokenRequest + * + * @package OCA\Circles\Db + */ +class ShareTokenRequest extends ShareTokenRequestBuilder { + + + /** + * @param ShareToken $token + * + * @return void + */ + public function save(ShareToken $token): void { + $qb = $this->getTokenInsertSql(); + $qb->setValue('share_id', $qb->createNamedParameter($token->getShareId())) + ->setValue('circle_id', $qb->createNamedParameter($token->getCircleId())) + ->setValue('single_id', $qb->createNamedParameter($token->getSingleId())) + ->setValue('member_id', $qb->createNamedParameter($token->getMemberId())) + ->setValue('token', $qb->createNamedParameter($token->getToken())) + ->setValue('password', $qb->createNamedParameter($token->getPassword())) + ->setValue('accepted', $qb->createNamedParameter($token->getAccepted())); + + $qb->execute(); + $id = $qb->getLastInsertId(); + $token->setDbId($id); + } + +} + diff --git a/lib/Db/ShareTokenRequestBuilder.php b/lib/Db/ShareTokenRequestBuilder.php new file mode 100644 index 000000000..6eb4e2557 --- /dev/null +++ b/lib/Db/ShareTokenRequestBuilder.php @@ -0,0 +1,126 @@ + + * @copyright 2021 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + + +namespace OCA\Circles\Db; + + +use ArtificialOwl\MySmallPhpTools\Exceptions\RowNotFoundException; +use OCA\Circles\Exceptions\ShareTokenNotFoundException; +use OCA\Circles\Model\ShareToken; + + +/** + * Class ShareTokenRequestBuilder + * + * @package OCA\Circles\Db + */ +class ShareTokenRequestBuilder extends CoreRequestBuilder { + + + /** + * @return CoreQueryBuilder + */ + protected function getTokenInsertSql(): CoreQueryBuilder { + $qb = $this->getQueryBuilder(); + $qb->insert(self::TABLE_TOKEN); + + return $qb; + } + + + /** + * @return CoreQueryBuilder + */ + protected function getTokenUpdateSql(): CoreQueryBuilder { + $qb = $this->getQueryBuilder(); + $qb->update(self::TABLE_SHARE); + + return $qb; + } + + + /** + * @param string $alias + * + * @return CoreQueryBuilder + */ + protected function getTokenSelectSql(string $alias = CoreQueryBuilder::TOKEN): CoreQueryBuilder { + $qb = $this->getQueryBuilder(); + $qb->generateSelect(self::TABLE_TOKEN, self::$tables[self::TABLE_SHARE], $alias) + ->generateGroupBy(self::$tables[self::TABLE_SHARE], $alias); + + return $qb; + } + + + /** + * Base of the Sql Delete request + * + * @return CoreQueryBuilder + */ + protected function getTokenDeleteSql(): CoreQueryBuilder { + $qb = $this->getQueryBuilder(); + $qb->delete(self::TABLE_SHARE); + + return $qb; + } + + + /** + * @param CoreQueryBuilder $qb + * + * @return ShareToken + * @throws ShareTokenNotFoundException + */ + public function getItemFromRequest(CoreQueryBuilder $qb): ShareToken { + /** @var ShareToken $shareToken */ + try { + $shareToken = $qb->asItem(ShareToken::class); + } catch (RowNotFoundException $e) { + throw new ShareTokenNotFoundException(); + } + + return $shareToken; + } + + + /** + * @param CoreQueryBuilder $qb + * + * @return ShareToken[] + */ + public function getItemsFromRequest(CoreQueryBuilder $qb): array { + /** @var ShareToken[] $result */ + return $qb->asItems(ShareToken::class); + } + +} + diff --git a/lib/Db/ShareWrapperRequest.php b/lib/Db/ShareWrapperRequest.php index 274dcc5eb..aaa7f2870 100644 --- a/lib/Db/ShareWrapperRequest.php +++ b/lib/Db/ShareWrapperRequest.php @@ -238,7 +238,7 @@ public function getShareByToken(string $token, ?FederatedUser $federatedUser = n $qb->setOptions([CoreQueryBuilder::SHARE], ['getData' => true]); $qb->leftJoinCircle(CoreQueryBuilder::SHARE, null, 'share_with'); - $qb->limitToToken($token); + $qb->limitToShareToken(CoreQueryBuilder::SHARE, $token); if (!is_null($federatedUser)) { $qb->limitToInitiator(CoreQueryBuilder::SHARE, $federatedUser, 'share_with'); diff --git a/lib/Exceptions/ShareTokenNotFoundException.php b/lib/Exceptions/ShareTokenNotFoundException.php new file mode 100644 index 000000000..969ab1d38 --- /dev/null +++ b/lib/Exceptions/ShareTokenNotFoundException.php @@ -0,0 +1,38 @@ + + * @copyright 2021 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Circles\Exceptions; + + +class ShareTokenNotFoundException extends FederatedItemNotFoundException { + +} + + diff --git a/lib/Migration/Version0022Date20220526113601.php b/lib/Migration/Version0022Date20220526113601.php index de2e84b90..67bcc0ffb 100644 --- a/lib/Migration/Version0022Date20220526113601.php +++ b/lib/Migration/Version0022Date20220526113601.php @@ -469,6 +469,67 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt } + /** + * CIRCLES_TOKEN + */ + if (!$schema->hasTable('circles_token')) { + $table = $schema->createTable('circles_token'); + $table->addColumn( + 'id', 'integer', [ + 'autoincrement' => true, + 'notnull' => true, + 'length' => 11, + 'unsigned' => true, + ] + ); + $table->addColumn( + 'share_id', 'integer', [ + 'notnull' => false, + 'length' => 11 + ] + ); + $table->addColumn( + 'circle_id', 'string', [ + 'notnull' => false, + 'length' => 31 + ] + ); + $table->addColumn( + 'single_id', 'string', [ + 'notnull' => false, + 'length' => 31 + ] + ); + $table->addColumn( + 'member_id', 'string', [ + 'notnull' => false, + 'length' => 31 + ] + ); + $table->addColumn( + 'token', 'string', [ + 'notnull' => false, + 'length' => 31 + ] + ); + $table->addColumn( + 'password', 'string', [ + 'notnull' => false, + 'length' => 31 + ] + ); + $table->addColumn( + 'accepted', 'integer', [ + 'notnull' => false, + 'length' => 1 + ] + ); + + $table->setPrimaryKey(['id']); + $table->addUniqueIndex(['share_id', 'circle_id', 'single_id', 'member_id', 'token'], 'sicisimit'); + } + + /** * CIRCLES_MOUNT */ diff --git a/lib/Migration/Version0022Date20220626112233.php b/lib/Migration/Version0022Date20220703115023.php similarity index 77% rename from lib/Migration/Version0022Date20220626112233.php rename to lib/Migration/Version0022Date20220703115023.php index d8003edb8..de1130464 100644 --- a/lib/Migration/Version0022Date20220626112233.php +++ b/lib/Migration/Version0022Date20220703115023.php @@ -44,7 +44,7 @@ * * @package OCA\Circles\Migration */ -class Version0022Date20220626112233 extends SimpleMigrationStep { +class Version0022Date20220703115023 extends SimpleMigrationStep { /** @@ -201,6 +201,68 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt } + + /** + * CIRCLES_TOKEN + */ + if (!$schema->hasTable('circles_token')) { + $table = $schema->createTable('circles_token'); + $table->addColumn( + 'id', 'integer', [ + 'autoincrement' => true, + 'notnull' => true, + 'length' => 11, + 'unsigned' => true, + ] + ); + $table->addColumn( + 'share_id', 'integer', [ + 'notnull' => false, + 'length' => 11 + ] + ); + $table->addColumn( + 'circle_id', 'string', [ + 'notnull' => false, + 'length' => 31 + ] + ); + $table->addColumn( + 'single_id', 'string', [ + 'notnull' => false, + 'length' => 31 + ] + ); + $table->addColumn( + 'member_id', 'string', [ + 'notnull' => false, + 'length' => 31 + ] + ); + $table->addColumn( + 'token', 'string', [ + 'notnull' => false, + 'length' => 31 + ] + ); + $table->addColumn( + 'password', 'string', [ + 'notnull' => false, + 'length' => 31 + ] + ); + $table->addColumn( + 'accepted', 'integer', [ + 'notnull' => false, + 'length' => 1 + ] + ); + + $table->setPrimaryKey(['id']); + $table->addUniqueIndex(['share_id', 'circle_id', 'single_id', 'member_id', 'token'], 'sicisimit'); + } + + return $schema; } diff --git a/lib/Model/ShareToken.php b/lib/Model/ShareToken.php new file mode 100644 index 000000000..a25b993eb --- /dev/null +++ b/lib/Model/ShareToken.php @@ -0,0 +1,284 @@ + + * @copyright 2021 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + + +namespace OCA\Circles\Model; + + +use ArtificialOwl\MySmallPhpTools\Db\Nextcloud\nc22\INC22QueryRow; +use ArtificialOwl\MySmallPhpTools\IDeserializable; +use ArtificialOwl\MySmallPhpTools\Traits\TArrayTools; +use JsonSerializable; +use OCP\Share\IShare; + + +class ShareToken implements IDeserializable, INC22QueryRow, JsonSerializable { + + + use TArrayTools; + + + /** @var int */ + private $dbId = 0; + + /** @var int */ + private $shareId = 0; + + /** @var string */ + private $circleId = ''; + + /** @var string */ + private $singleId = ''; + + /** @var string */ + private $memberId = ''; + + /** @var string */ + private $token = ''; + + /** @var string */ + private $password = ''; + + /** @var int */ + private $accepted = IShare::STATUS_PENDING; + + + /** + * ShareToken constructor. + */ + function __construct() { + } + + + /** + * @param int $dbId + * + * @return ShareToken + */ + public function setDbId(int $dbId): self { + $this->dbId = $dbId; + + return $this; + } + + /** + * @return int + */ + public function getDbId(): int { + return $this->dbId; + } + + + /** + * @param int $shareId + * + * @return ShareToken + */ + public function setShareId(int $shareId): self { + $this->shareId = $shareId; + + return $this; + } + + /** + * @return int + */ + public function getShareId(): int { + return $this->shareId; + } + + + /** + * @param string $circleId + * + * @return ShareToken + */ + public function setCircleId(string $circleId): self { + $this->circleId = $circleId; + + return $this; + } + + /** + * @return string + */ + public function getCircleId(): string { + return $this->circleId; + } + + + /** + * @param string $singleId + * + * @return ShareToken + */ + public function setSingleId(string $singleId): self { + $this->singleId = $singleId; + + return $this; + } + + /** + * @return string + */ + public function getSingleId(): string { + return $this->singleId; + } + + + /** + * @param string $memberId + * + * @return ShareToken + */ + public function setMemberId(string $memberId): self { + $this->memberId = $memberId; + + return $this; + } + + /** + * @return string + */ + public function getMemberId(): string { + return $this->memberId; + } + + + /** + * @param string $token + * + * @return ShareToken + */ + public function setToken(string $token): self { + $this->token = $token; + + return $this; + } + + /** + * @return string + */ + public function getToken(): string { + return $this->token; + } + + + /** + * @param string $password + * + * @return ShareToken + */ + public function setPassword(string $password): self { + $this->password = $password; + + return $this; + } + + /** + * @return string + */ + public function getPassword(): string { + return $this->password; + } + + + /** + * @param int $accepted + * + * @return ShareToken + */ + public function setAccepted(int $accepted): self { + $this->accepted = $accepted; + + return $this; + } + + /** + * @return int + */ + public function getAccepted(): int { + return $this->accepted; + } + + + /** + * @param array $data + * + * @return ShareToken + */ + public function import(array $data): IDeserializable { + $this->setShareId($this->getInt('shareId', $data)); + $this->setCircleId($this->get('circleId', $data)); + $this->setSingleId($this->get('singleId', $data)); + $this->setMemberId($this->get('memberId', $data)); + $this->setToken($this->get('token', $data)); + $this->setPassword($this->get('password', $data)); + $this->setAccepted($this->getInt('accepted', $data, IShare::STATUS_PENDING)); + + return $this; + } + + + /** + * @param array $data + * @param string $prefix + * + * @return INC22QueryRow + */ + public function importFromDatabase(array $data, string $prefix = ''): INC22QueryRow { + $this->setShareId($this->getInt($prefix . 'share_id', $data)); + $this->setCircleId($this->get($prefix . 'circle_id', $data)); + $this->setSingleId($this->get($prefix . 'single_id', $data)); + $this->setMemberId($this->get($prefix . 'member_id', $data)); + $this->setToken($this->get($prefix . 'token', $data)); + $this->setPassword($this->get($prefix . 'password', $data)); + $this->setAccepted($this->getInt($prefix . 'accepted', $data, IShare::STATUS_PENDING)); + + return $this; + } + + /** + * @return array + */ + function jsonSerialize(): array { + return [ + 'shareId' => $this->getShareId(), + 'circleId' => $this->getCircleId(), + 'singleId' => $this->getSingleId(), + 'memberId' => $this->getMemberId(), + 'token' => $this->getToken(), + 'password' => $this->getPassword(), + 'accepted' => $this->getAccepted() + ]; + } + +} + diff --git a/lib/Model/SharesToken.php b/lib/Model/SharesToken.php index 4e5f899db..82193fc4c 100644 --- a/lib/Model/SharesToken.php +++ b/lib/Model/SharesToken.php @@ -34,7 +34,7 @@ /** * Class SharesToken - * + * @deprecated * @package OCA\Circles\Model */ class SharesToken implements JsonSerializable {