diff options
author | Maxence Lange <maxence@artificial-owl.com> | 2022-12-07 10:23:19 -0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-07 10:23:19 -0100 |
commit | 1ee0228e8c8de28a4a2a969bf8e36c70c9effc98 (patch) | |
tree | 0f721566adb05dd99baf9ccb9006ec554bf41364 | |
parent | 75178872c402deb824eac3b400ed3a47fc36adc4 (diff) | |
parent | 0b2f66b210630622011cafd55727b9b29b1b6b85 (diff) |
Merge pull request #1546 from nextcloud/enh/noid/delete-account
move and delete account
27 files changed, 846 insertions, 81 deletions
diff --git a/appinfo/info.xml b/appinfo/info.xml index 27810482..bf032c47 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -45,6 +45,7 @@ <commands> <command>OCA\Social\Command\AccountCreate</command> + <command>OCA\Social\Command\AccountDelete</command> <command>OCA\Social\Command\AccountFollowing</command> <command>OCA\Social\Command\CacheRefresh</command> <command>OCA\Social\Command\CheckInstall</command> diff --git a/lib/Command/AccountDelete.php b/lib/Command/AccountDelete.php new file mode 100644 index 00000000..aaad6d9e --- /dev/null +++ b/lib/Command/AccountDelete.php @@ -0,0 +1,88 @@ +<?php + +declare(strict_types=1); + + +/** + * Nextcloud - Social Support + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018, Maxence Lange <maxence@artificial-owl.com> + * @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 <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCA\Social\Command; + +use Exception; +use OC\Core\Command\Base; +use OCA\Social\Interfaces\Actor\PersonInterface; +use OCA\Social\Service\AccountService; +use OCA\Social\Service\CacheActorService; +use OCA\Social\Service\ConfigService; +use OCP\IUserManager; +use OCP\Server; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class AccountDelete extends Base { + private IUserManager $userManager; + private AccountService $accountService; + private CacheActorService $cacheActorService; + private ConfigService $configService; + + public function __construct( + IUserManager $userManager, + AccountService $accountService, + CacheActorService $cacheActorService, + ConfigService $configService + ) { + parent::__construct(); + + $this->userManager = $userManager; + $this->accountService = $accountService; + $this->cacheActorService = $cacheActorService; + $this->configService = $configService; + } + + protected function configure(): void { + parent::configure(); + $this->setName('social:account:delete') + ->addArgument('account', InputArgument::REQUIRED, 'Social Local Account') + ->setDescription('Delete a local social account'); + } + + /** + * @throws Exception + */ + protected function execute(InputInterface $input, OutputInterface $output): int { + $account = $input->getArgument('account'); + + // TODO: broadcast to other instance + throw new Exception('not fully available'); + + $actor = $this->cacheActorService->getFromLocalAccount($account); + $personInterface = Server::get(PersonInterface::class); + $personInterface->deleteActor($actor->getId()); + + return 0; + } +} diff --git a/lib/Db/ActionsRequest.php b/lib/Db/ActionsRequest.php index a678a8f6..4795c76d 100644 --- a/lib/Db/ActionsRequest.php +++ b/lib/Db/ActionsRequest.php @@ -153,13 +153,21 @@ class ActionsRequest extends ActionsRequestBuilder { } -// /** -// * @param string $objectId -// */ -// public function deleteLikes(string $objectId) { -// $qb = $this->getActionsDeleteSql(); -// $this->limitToObjectId($qb, $objectId); -// -// $qb->execute(); -// } + public function deleteByActor(string $actorId): void { + $qb = $this->getActionsDeleteSql(); + $qb->limitToDBField('actor_id_prim', $qb->prim($actorId)); + + $qb->executeStatement(); + } + + + public function moveAccount(string $actorId, string $newId): void { + $qb = $this->getActionsUpdateSql(); + $qb->set('actor_id', $qb->createNamedParameter($newId)) + ->set('actor_id_prim', $qb->createNamedParameter($qb->prim($newId))); + + $qb->limitToDBField('actor_id_prim', $qb->prim($actorId)); + + $qb->executeStatement(); + } } diff --git a/lib/Db/ActionsRequestBuilder.php b/lib/Db/ActionsRequestBuilder.php index bf139db9..9e068b85 100644 --- a/lib/Db/ActionsRequestBuilder.php +++ b/lib/Db/ActionsRequestBuilder.php @@ -31,11 +31,11 @@ declare(strict_types=1); namespace OCA\Social\Db; -use OCA\Social\Tools\Exceptions\RowNotFoundException; -use OCA\Social\Tools\Traits\TArrayTools; use OCA\Social\Exceptions\ActionDoesNotExistException; use OCA\Social\Exceptions\InvalidResourceException; use OCA\Social\Model\ActivityPub\ACore; +use OCA\Social\Tools\Exceptions\RowNotFoundException; +use OCA\Social\Tools\Traits\TArrayTools; /** * Class ActionsRequestBuilder @@ -105,7 +105,8 @@ class ActionsRequestBuilder extends CoreRequestBuilder { */ protected function getActionsDeleteSql(): SocialQueryBuilder { $qb = $this->getQueryBuilder(); - $qb->delete(self::TABLE_ACTIONS); + $qb->delete(self::TABLE_ACTIONS) + ->setDefaultSelectAlias('a'); return $qb; } diff --git a/lib/Db/CacheActorsRequest.php b/lib/Db/CacheActorsRequest.php index ecab744e..520a8250 100644 --- a/lib/Db/CacheActorsRequest.php +++ b/lib/Db/CacheActorsRequest.php @@ -241,7 +241,7 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { */ public function deleteCacheById(string $id) { $qb = $this->getCacheActorsDeleteSql(); - $this->limitToIdString($qb, $id); + $qb->limitToIdPrim($qb->prim($id)); $qb->execute(); } diff --git a/lib/Db/CacheActorsRequestBuilder.php b/lib/Db/CacheActorsRequestBuilder.php index 11992cae..b79e5348 100644 --- a/lib/Db/CacheActorsRequestBuilder.php +++ b/lib/Db/CacheActorsRequestBuilder.php @@ -96,9 +96,9 @@ class CacheActorsRequestBuilder extends CoreRequestBuilder { /** * Base of the Sql Delete request * - * @return IQueryBuilder + * @return SocialQueryBuilder */ - protected function getCacheActorsDeleteSql(): IQueryBuilder { + protected function getCacheActorsDeleteSql(): SocialQueryBuilder { $qb = $this->getQueryBuilder(); $qb->delete(self::TABLE_CACHE_ACTORS); diff --git a/lib/Db/CacheDocumentsRequest.php b/lib/Db/CacheDocumentsRequest.php index 88e6e284..88fb20f8 100644 --- a/lib/Db/CacheDocumentsRequest.php +++ b/lib/Db/CacheDocumentsRequest.php @@ -56,6 +56,7 @@ class CacheDocumentsRequest extends CacheDocumentsRequestBuilder { ->setValue('local_copy', $qb->createNamedParameter($document->getLocalCopy())) ->setValue('resized_copy', $qb->createNamedParameter($document->getResizedCopy())) ->setValue('parent_id', $qb->createNamedParameter($document->getParentId())) + ->setValue('parent_id_prim', $qb->createNamedParameter($qb->prim($document->getParentId()))) ->setValue('public', $qb->createNamedParameter(($document->isPublic()) ? '1' : '0')); try { @@ -83,6 +84,7 @@ class CacheDocumentsRequest extends CacheDocumentsRequestBuilder { ->set('local_copy', $qb->createNamedParameter($document->getLocalCopy())) ->set('resized_copy', $qb->createNamedParameter($document->getResizedCopy())) ->set('parent_id', $qb->createNamedParameter($document->getParentId())) + ->set('parent_id_prim', $qb->createNamedParameter($qb->prim($document->getParentId()))) ->set('public', $qb->createNamedParameter(($document->isPublic()) ? '1' : '0')); try { @@ -239,4 +241,22 @@ class CacheDocumentsRequest extends CacheDocumentsRequestBuilder { $qb->execute(); } + + public function deleteByParent(string $parentId): void { + $qb = $this->getCacheDocumentsDeleteSql(); + $qb->limitToDBField('parent_id_prim', $qb->prim($parentId)); + + $qb->executeStatement(); + } + + + public function moveAccount(string $actorId, string $newId): void { + $qb = $this->getCacheDocumentsUpdateSql(); + $qb->set('parent_id', $qb->createNamedParameter($newId)) + ->set('parent_id_prim', $qb->createNamedParameter($qb->prim($newId))); + + $qb->limitToDBField('parent_id_prim', $qb->prim($actorId)); + + $qb->executeStatement(); + } } diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index a7c93c11..99fe2289 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -36,6 +36,7 @@ use DateTime; use Doctrine\DBAL\Query\QueryBuilder; use Exception; use OC; +use OC\DB\Connection; use OC\DB\SchemaWrapper; use OCA\Social\Exceptions\InvalidResourceException; use OCA\Social\Model\ActivityPub\Actor\Person; @@ -1263,10 +1264,10 @@ class CoreRequestBuilder { * this just empty all tables from the app. */ public function emptyAll() { - $schema = new SchemaWrapper(Server::get(IDBConnection::class)); + $schema = new SchemaWrapper(Server::get(Connection::class)); foreach (array_keys(self::$tables) as $table) { if ($schema->hasTable($table)) { - $qb = $this->dbConnection->getQueryBuilder(); + $qb = $this->getQueryBuilder(); $qb->delete($table); $qb->execute(); } @@ -1278,7 +1279,7 @@ class CoreRequestBuilder { * this just empty all tables from the app. */ public function uninstallSocialTables() { - $schema = new SchemaWrapper(Server::get(IDBConnection::class)); + $schema = new SchemaWrapper(Server::get(Connection::class)); foreach (array_keys(self::$tables) as $table) { if ($schema->hasTable($table)) { $schema->dropTable($table); @@ -1293,7 +1294,7 @@ class CoreRequestBuilder { * */ public function uninstallFromMigrations() { - $qb = $this->dbConnection->getQueryBuilder(); + $qb = $this->getQueryBuilder(); $qb->delete('migrations'); $qb->where($this->exprLimitToDBField($qb, 'app', 'social', true, true)); @@ -1304,12 +1305,12 @@ class CoreRequestBuilder { * */ public function uninstallFromJobs() { - $qb = $this->dbConnection->getQueryBuilder(); + $qb = $this->getQueryBuilder(); $qb->delete('jobs'); $qb->where($this->exprLimitToDBField($qb, 'class', 'OCA\Social\Cron\Cache', true, true)); $qb->execute(); - $qb = $this->dbConnection->getQueryBuilder(); + $qb = $this->getQueryBuilder(); $qb->delete('jobs'); $qb->where($this->exprLimitToDBField($qb, 'class', 'OCA\Social\Cron\Queue', true, true)); $qb->execute(); diff --git a/lib/Db/FollowsRequest.php b/lib/Db/FollowsRequest.php index 7c799dab..43a7643e 100644 --- a/lib/Db/FollowsRequest.php +++ b/lib/Db/FollowsRequest.php @@ -31,12 +31,12 @@ declare(strict_types=1); namespace OCA\Social\Db; -use OCA\Social\Tools\Traits\TArrayTools; use DateTime; use Exception; use OCA\Social\Exceptions\FollowNotFoundException; use OCA\Social\Model\ActivityPub\Actor\Person; use OCA\Social\Model\ActivityPub\Object\Follow; +use OCA\Social\Tools\Traits\TArrayTools; use OCP\DB\QueryBuilder\IQueryBuilder; /** @@ -285,13 +285,10 @@ class FollowsRequest extends FollowsRequestBuilder { */ public function deleteRelatedId(string $actorId) { $qb = $this->getFollowsDeleteSql(); - $this->limitToActorId($qb, $actorId); - - $qb->execute(); - - $qb = $this->getFollowsDeleteSql(); - $this->limitToObjectId($qb, $actorId); - + $orX = $qb->expr()->orX(); + $orX->add($qb->exprLimitToDBField('actor_id_prim', $qb->prim($actorId))); + $orX->add($qb->exprLimitToDBField('object_id_prim', $qb->prim($actorId))); + $qb->where($orX); $qb->execute(); } @@ -304,4 +301,36 @@ class FollowsRequest extends FollowsRequestBuilder { $qb->execute(); } + + + /** + * @param string $actorId + * @param Person $new + */ + public function moveAccountFollowers(string $actorId, Person $new): void { + $qb = $this->getFollowsUpdateSql(); + $qb->set('object_id', $qb->createNamedParameter($new->getId())) + ->set('object_id_prim', $qb->createNamedParameter($qb->prim($new->getId()))) + ->set('follow_id', $qb->createNamedParameter($new->getFollowers())) + ->set('follow_id_prim', $qb->createNamedParameter($qb->prim($new->getFollowers()))); + + $qb->limitToObjectIdPrim($qb->prim($actorId)); + + $qb->executeStatement(); + } + + + /** + * @param string $actorId + * @param Person $new + */ + public function moveAccountFollowing(string $actorId, Person $new): void { + $qb = $this->getFollowsUpdateSql(); + $qb->set('actor_id', $qb->createNamedParameter($new->getId())) + ->set('actor_id_prim', $qb->createNamedParameter($qb->prim($new->getId()))); + + $qb->limitToActorIdPrim($qb->prim($actorId)); + + $qb->executeStatement(); + } } diff --git a/lib/Db/FollowsRequestBuilder.php b/lib/Db/FollowsRequestBuilder.php index a2d2b82e..a7918c72 100644 --- a/lib/Db/FollowsRequestBuilder.php +++ b/lib/Db/FollowsRequestBuilder.php @@ -36,7 +36,6 @@ use OCA\Social\Tools\Traits\TArrayTools; use OCA\Social\Exceptions\FollowNotFoundException; use OCA\Social\Exceptions\InvalidResourceException; use OCA\Social\Model\ActivityPub\Object\Follow; -use OCP\DB\QueryBuilder\IQueryBuilder; /** * Class FollowsRequestBuilder @@ -63,9 +62,9 @@ class FollowsRequestBuilder extends CoreRequestBuilder { /** * Base of the Sql Update request * - * @return IQueryBuilder + * @return SocialQueryBuilder */ - protected function getFollowsUpdateSql(): IQueryBuilder { + protected function getFollowsUpdateSql(): SocialQueryBuilder { $qb = $this->getQueryBuilder(); $qb->update(self::TABLE_FOLLOWS); @@ -114,9 +113,9 @@ class FollowsRequestBuilder extends CoreRequestBuilder { /** * Base of the Sql Delete request * - * @return IQueryBuilder + * @return SocialQueryBuilder */ - protected function getFollowsDeleteSql(): IQueryBuilder { + protected function getFollowsDeleteSql(): SocialQueryBuilder { $qb = $this->getQueryBuilder(); $qb->delete(self::TABLE_FOLLOWS); diff --git a/lib/Db/RequestQueueRequest.php b/lib/Db/RequestQueueRequest.php index 4da8fbe2..7ee48257 100644 --- a/lib/Db/RequestQueueRequest.php +++ b/lib/Db/RequestQueueRequest.php @@ -47,6 +47,7 @@ class RequestQueueRequest extends RequestQueueRequestBuilder { * Create a new Queue in the database. * * @param RequestQueue[] $queues + * * @throws Exception */ public function multiple(array $queues): void { @@ -64,6 +65,7 @@ class RequestQueueRequest extends RequestQueueRequestBuilder { $qb = $this->getRequestQueueInsertSql(); $qb->setValue('token', $qb->createNamedParameter($queue->getToken())) ->setValue('author', $qb->createNamedParameter($queue->getAuthor())) + ->setValue('author_prim', $qb->createNamedParameter($qb->prim($queue->getAuthor()))) ->setValue('activity', $qb->createNamedParameter($queue->getActivity())) ->setValue( 'instance', $qb->createNamedParameter( @@ -197,4 +199,21 @@ class RequestQueueRequest extends RequestQueueRequestBuilder { $qb->executeStatement(); } + + public function deleteByAuthor(string $actorId): void { + $qb = $this->getRequestQueueDeleteSql(); + $qb->limitToDBField('author_prim', $qb->prim($actorId)); + + $qb->executeStatement(); + } + +// public function moveAccount(string $actorId, string $newId, string $instance): void { +// $qb = $this->getRequestQueueUpdateSql(); +// $qb->set('author', $qb->createNamedParameter($newId)) +// ->set('author_prim', $qb->createNamedParameter($qb->prim($newId))) +// ->set('instance', $qb->createNamedParameter($instance)); +// $qb->limitToDBField('author_prim', $qb->prim($actorId)); +// +// $qb->execute(); +// } } diff --git a/lib/Db/SocialCrossQueryBuilder.php b/lib/Db/SocialCrossQueryBuilder.php index 3bc16b12..239e0404 100644 --- a/lib/Db/SocialCrossQueryBuilder.php +++ b/lib/Db/SocialCrossQueryBuilder.php @@ -293,7 +293,7 @@ class SocialCrossQueryBuilder extends SocialCoreQueryBuilder { * @param string $aliasDest * @param string $alias */ - public function innerJoinSteamDest( + public function innerJoinStreamDest( string $type, string $field = 'id_prim', string $aliasDest = 'sd', string $alias = '' ) { $this->andWhere($this->exprInnerJoinStreamDest($type, $field, $aliasDest, $alias)); diff --git a/lib/Db/SocialLimitsQueryBuilder.php b/lib/Db/SocialLimitsQueryBuilder.php index e025c740..88bc4369 100644 --- a/lib/Db/SocialLimitsQueryBuilder.php +++ b/lib/Db/SocialLimitsQueryBuilder.php @@ -189,7 +189,7 @@ class SocialLimitsQueryBuilder extends SocialCrossQueryBuilder { * @param string $alias */ public function limitToActorIdPrim(string $actorId, string $alias = '') { - $this->limitToDBField('actor_id', $actorId, false, $alias); + $this->limitToDBField('actor_id_prim', $actorId, false, $alias); } @@ -278,7 +278,7 @@ class SocialLimitsQueryBuilder extends SocialCrossQueryBuilder { */ public function limitToAttributedTo(string $actorId, bool $prim = false) { if ($prim) { - $this->limitToDBField('attributed_to_prim', $this->prim($actorId), false); + $this->limitToDBField('attributed_to_prim', $this->prim($actorId)); return; } @@ -437,7 +437,7 @@ class SocialLimitsQueryBuilder extends SocialCrossQueryBuilder { ) { if (!$this->hasViewer()) { $this->selectDestFollowing($aliasDest); - $this->innerJoinSteamDest('recipient', 'id_prim', 'sd', 's'); + $this->innerJoinStreamDest('recipient', 'id_prim', 'sd', 's'); $this->limitToDest(ACore::CONTEXT_PUBLIC, 'recipient', '', $aliasDest); return; diff --git a/lib/Db/StreamDestRequest.php b/lib/Db/StreamDestRequest.php index 95f23758..2281d9d9 100644 --- a/lib/Db/StreamDestRequest.php +++ b/lib/Db/StreamDestRequest.php @@ -31,14 +31,16 @@ declare(strict_types=1); namespace OCA\Social\Db; -use OCA\Social\Tools\Traits\TStringTools; use Exception; -use OCP\DB\Exception as DBException; +use OCA\Social\Model\ActivityPub\Actor\Person; use OCA\Social\Model\ActivityPub\Internal\SocialAppNotification; use OCA\Social\Model\ActivityPub\Stream; +use OCA\Social\Model\StreamDest; use OCA\Social\Service\CacheActorService; use OCA\Social\Service\ConfigService; use OCA\Social\Service\MiscService; +use OCA\Social\Tools\Traits\TStringTools; +use OCP\DB\Exception as DBException; use OCP\IDBConnection; use OCP\IURLGenerator; use Psr\Log\LoggerInterface; @@ -54,7 +56,8 @@ class StreamDestRequest extends StreamDestRequestBuilder { private CacheActorService $cacheActorService; public function __construct( - IDBConnection $connection, LoggerInterface $logger, IURLGenerator $urlGenerator, CacheActorService $cacheActorService, + IDBConnection $connection, LoggerInterface $logger, IURLGenerator $urlGenerator, + CacheActorService $cacheActorService, ConfigService $configService, MiscService $miscService ) { parent::__construct($connection, $logger, $urlGenerator, $configService, $miscService); @@ -153,9 +156,50 @@ class StreamDestRequest extends StreamDestRequestBuilder { } public function emptyStreamDest(): void { - $qb = $this->dbConnection->getQueryBuilder(); + $qb = $this->getQueryBuilder(); $qb->delete(self::TABLE_STREAM_DEST); $qb->executeStatement(); } + + + /** + * @param string $actorId + * + * @return StreamDest[] + */ + public function getRelatedToActor(Person $actor): array { + $qb = $this->getStreamDestSelectSql(); + $orX = $qb->expr()->orX(); + $orX->add($qb->exprLimitToDBField('actor_id', $qb->prim($actor->getId()))); + $orX->add($qb->exprLimitToDBField('actor_id', $qb->prim($actor->getFollowers()))); + $orX->add($qb->exprLimitToDBField('actor_id', $qb->prim($actor->getFollowing()))); + $qb->where($orX); + + return $this->getStreamDestsFromRequest($qb); + } + + + /** + * @param string $actorId + */ + public function deleteRelatedToActor(string $actorId): void { + $qb = $this->getStreamDestDeleteSql(); + $qb->limitToActorId($qb->prim($actorId)); + + $qb->executeStatement(); + } + + + + /** + * @param string $actorId + */ + public function moveActor(string $actorId, string $newId): void { + $qb = $this->getStreamDestUpdateSql(); + $qb->set('actor_id', $qb->createNamedParameter($qb->prim($newId))); + $qb->limitToActorId($qb->prim($actorId)); + + $qb->executeStatement(); + } } diff --git a/lib/Db/StreamDestRequestBuilder.php b/lib/Db/StreamDestRequestBuilder.php index 61bac94e..5087b6a0 100644 --- a/lib/Db/StreamDestRequestBuilder.php +++ b/lib/Db/StreamDestRequestBuilder.php @@ -30,8 +30,10 @@ declare(strict_types=1); namespace OCA\Social\Db; +use OCA\Social\Exceptions\StreamDestDoesNotExistException; +use OCA\Social\Model\StreamDest; +use OCA\Social\Tools\Exceptions\RowNotFoundException; use OCA\Social\Tools\Traits\TArrayTools; -use OCP\DB\QueryBuilder\IQueryBuilder; /** * Class StreamDestRequestBuilder @@ -56,9 +58,9 @@ class StreamDestRequestBuilder extends CoreRequestBuilder { /** * Base of the Sql Update request * - * @return IQueryBuilder + * @return SocialQueryBuilder */ - protected function getStreamDestUpdateSql(): IQueryBuilder { + protected function getStreamDestUpdateSql(): SocialQueryBuilder { $qb = $this->getQueryBuilder(); $qb->update(self::TABLE_STREAM_DEST); @@ -75,7 +77,7 @@ class StreamDestRequestBuilder extends CoreRequestBuilder { $qb = $this->getQueryBuilder(); /** @noinspection PhpMethodParametersCountMismatchInspection */ - $qb->select('sd.actor_id', 'sd.stream_id', 'sd.type') + $qb->select('sd.actor_id', 'sd.stream_id', 'sd.type', 'sd.subtype') |