| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2022-04-15 11:34:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 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\Service; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | use Exception; | 
					
						
							|  |  |  | use OC\User\NoUserException; | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | use OCA\Social\AP; | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | use OCA\Social\Db\ActorsRequest; | 
					
						
							| 
									
										
										
										
											2018-11-29 18:28:37 +00:00
										 |  |  | use OCA\Social\Db\FollowsRequest; | 
					
						
							| 
									
										
										
										
											2019-05-16 17:46:06 +00:00
										 |  |  | use OCA\Social\Db\StreamRequest; | 
					
						
							| 
									
										
										
										
											2018-10-01 12:14:23 +00:00
										 |  |  | use OCA\Social\Exceptions\AccountAlreadyExistsException; | 
					
						
							| 
									
										
										
										
											2020-07-27 20:39:03 +00:00
										 |  |  | use OCA\Social\Exceptions\AccountDoesNotExistException; | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | use OCA\Social\Exceptions\ActorDoesNotExistException; | 
					
						
							| 
									
										
										
										
											2019-09-25 12:37:32 +00:00
										 |  |  | use OCA\Social\Exceptions\ItemAlreadyExistsException; | 
					
						
							| 
									
										
										
										
											2019-01-15 13:29:14 +00:00
										 |  |  | use OCA\Social\Exceptions\ItemUnknownException; | 
					
						
							| 
									
										
										
										
											2018-11-15 11:26:25 +00:00
										 |  |  | use OCA\Social\Exceptions\SocialAppConfigException; | 
					
						
							| 
									
										
										
										
											2020-09-01 14:14:19 +00:00
										 |  |  | use OCA\Social\Exceptions\StreamNotFoundException; | 
					
						
							| 
									
										
										
										
											2018-12-05 18:37:49 +00:00
										 |  |  | use OCA\Social\Exceptions\UrlCloudException; | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | use OCA\Social\Interfaces\Actor\PersonInterface; | 
					
						
							|  |  |  | use OCA\Social\Model\ActivityPub\ACore; | 
					
						
							|  |  |  | use OCA\Social\Model\ActivityPub\Activity\Delete; | 
					
						
							| 
									
										
										
										
											2018-12-13 09:40:27 +00:00
										 |  |  | use OCA\Social\Model\ActivityPub\Actor\Person; | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | use OCA\Social\Model\InstancePath; | 
					
						
							| 
									
										
										
										
											2022-11-03 14:23:07 +00:00
										 |  |  | use OCA\Social\Tools\Traits\TArrayTools; | 
					
						
							| 
									
										
										
										
											2018-12-05 18:37:49 +00:00
										 |  |  | use OCP\Accounts\IAccountManager; | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | use OCP\IUser; | 
					
						
							| 
									
										
										
										
											2018-12-05 18:37:49 +00:00
										 |  |  | use OCP\IUserManager; | 
					
						
							| 
									
										
										
										
											2020-07-27 20:39:03 +00:00
										 |  |  | use OCP\IUserSession; | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | use Psr\Log\LoggerInterface; | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 22:57:32 +00:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Class ActorService | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @package OCA\Social\Service | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-12-17 09:12:27 +00:00
										 |  |  | class AccountService { | 
					
						
							| 
									
										
										
										
											2022-04-15 11:34:01 +00:00
										 |  |  | 	public const KEY_PAIR_LIFESPAN = 7; | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | 	public const TIME_RETENTION = 3600; // seconds before fully delete account
 | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 	use TArrayTools; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-14 13:56:20 +00:00
										 |  |  | 	private IUserManager $userManager; | 
					
						
							|  |  |  | 	private IUserSession $userSession; | 
					
						
							|  |  |  | 	private IAccountManager $accountManager; | 
					
						
							|  |  |  | 	private ActorsRequest $actorsRequest; | 
					
						
							|  |  |  | 	private FollowsRequest $followsRequest; | 
					
						
							|  |  |  | 	private StreamRequest $streamRequest; | 
					
						
							|  |  |  | 	private ActorService $actorService; | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | 	private ActivityService $activityService; | 
					
						
							|  |  |  | 	private AccountService $accountService; | 
					
						
							| 
									
										
										
										
											2022-04-14 13:56:20 +00:00
										 |  |  | 	private SignatureService $signatureService; | 
					
						
							|  |  |  | 	private DocumentService $documentService; | 
					
						
							|  |  |  | 	private ConfigService $configService; | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | 	private LoggerInterface $logger; | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	public function __construct( | 
					
						
							| 
									
										
										
										
											2022-11-03 14:23:07 +00:00
										 |  |  | 		IUserManager $userManager, | 
					
						
							|  |  |  | 		IUserSession $userSession, | 
					
						
							|  |  |  | 		IAccountManager $accountManager, | 
					
						
							| 
									
										
										
										
											2020-07-27 20:39:03 +00:00
										 |  |  | 		ActorsRequest $actorsRequest, | 
					
						
							| 
									
										
										
										
											2022-11-03 14:23:07 +00:00
										 |  |  | 		FollowsRequest $followsRequest, | 
					
						
							|  |  |  | 		StreamRequest $streamRequest, | 
					
						
							|  |  |  | 		ActorService $actorService, | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | 		ActivityService $activityService, | 
					
						
							| 
									
										
										
										
											2022-11-03 14:23:07 +00:00
										 |  |  | 		DocumentService $documentService, | 
					
						
							|  |  |  | 		SignatureService $signatureService, | 
					
						
							|  |  |  | 		ConfigService $configService, | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | 		LoggerInterface $logger | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 	) { | 
					
						
							| 
									
										
										
										
											2018-12-05 22:56:52 +00:00
										 |  |  | 		$this->userManager = $userManager; | 
					
						
							| 
									
										
										
										
											2020-07-27 20:39:03 +00:00
										 |  |  | 		$this->userSession = $userSession; | 
					
						
							| 
									
										
										
										
											2018-12-05 18:37:49 +00:00
										 |  |  | 		$this->accountManager = $accountManager; | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 		$this->actorsRequest = $actorsRequest; | 
					
						
							| 
									
										
										
										
											2018-11-29 18:28:37 +00:00
										 |  |  | 		$this->followsRequest = $followsRequest; | 
					
						
							| 
									
										
										
										
											2019-05-16 17:46:06 +00:00
										 |  |  | 		$this->streamRequest = $streamRequest; | 
					
						
							| 
									
										
										
										
											2018-12-17 09:12:27 +00:00
										 |  |  | 		$this->actorService = $actorService; | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | 		$this->activityService = $activityService; | 
					
						
							| 
									
										
										
										
											2018-12-05 18:37:49 +00:00
										 |  |  | 		$this->documentService = $documentService; | 
					
						
							| 
									
										
										
										
											2018-12-16 22:53:00 +00:00
										 |  |  | 		$this->signatureService = $signatureService; | 
					
						
							| 
									
										
										
										
											2018-11-14 13:37:54 +00:00
										 |  |  | 		$this->configService = $configService; | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | 		$this->logger = $logger; | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param string $username | 
					
						
							|  |  |  | 	 * | 
					
						
							| 
									
										
										
										
											2018-11-12 22:57:32 +00:00
										 |  |  | 	 * @return Person | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 	 * @throws ActorDoesNotExistException | 
					
						
							| 
									
										
										
										
											2018-11-15 11:26:25 +00:00
										 |  |  | 	 * @throws SocialAppConfigException | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-11-12 22:57:32 +00:00
										 |  |  | 	public function getActor(string $username): Person { | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 		$actor = $this->actorsRequest->getFromUsername($username); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return $actor; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 13:37:54 +00:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param string $id | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @return Person | 
					
						
							|  |  |  | 	 * @throws ActorDoesNotExistException | 
					
						
							| 
									
										
										
										
											2018-11-15 11:26:25 +00:00
										 |  |  | 	 * @throws SocialAppConfigException | 
					
						
							| 
									
										
										
										
											2018-11-14 13:37:54 +00:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-12-17 09:12:27 +00:00
										 |  |  | 	public function getFromId(string $id): Person { | 
					
						
							| 
									
										
										
										
											2018-11-13 14:30:48 +00:00
										 |  |  | 		$actor = $this->actorsRequest->getFromId($id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return $actor; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 20:39:03 +00:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @return Person | 
					
						
							|  |  |  | 	 * @throws AccountDoesNotExistException | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	public function getCurrentViewer(): Person { | 
					
						
							|  |  |  | 		$user = $this->userSession->getUser(); | 
					
						
							|  |  |  | 		if ($user === null) { | 
					
						
							|  |  |  | 			throw new AccountDoesNotExistException(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		try { | 
					
						
							|  |  |  | 			return $this->getActorFromUserId($user->getUID()); | 
					
						
							|  |  |  | 		} catch (Exception $e) { | 
					
						
							|  |  |  | 			throw new AccountDoesNotExistException(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param string $userId | 
					
						
							| 
									
										
										
										
											2018-11-29 17:41:55 +00:00
										 |  |  | 	 * @param bool $create | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 	 * | 
					
						
							| 
									
										
										
										
											2018-11-12 22:57:32 +00:00
										 |  |  | 	 * @return Person | 
					
						
							| 
									
										
										
										
											2018-11-29 17:41:55 +00:00
										 |  |  | 	 * @throws AccountAlreadyExistsException | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 	 * @throws ActorDoesNotExistException | 
					
						
							|  |  |  | 	 * @throws NoUserException | 
					
						
							| 
									
										
										
										
											2018-11-15 11:26:25 +00:00
										 |  |  | 	 * @throws SocialAppConfigException | 
					
						
							| 
									
										
										
										
											2018-12-05 18:37:49 +00:00
										 |  |  | 	 * @throws UrlCloudException | 
					
						
							| 
									
										
										
										
											2019-09-25 12:37:32 +00:00
										 |  |  | 	 * @throws ItemAlreadyExistsException | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-11-29 17:41:55 +00:00
										 |  |  | 	public function getActorFromUserId(string $userId, bool $create = false): Person { | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | 		$this->confirmUserId($userId); | 
					
						
							| 
									
										
										
										
											2018-11-29 17:41:55 +00:00
										 |  |  | 		try { | 
					
						
							|  |  |  | 			$actor = $this->actorsRequest->getFromUserId($userId); | 
					
						
							|  |  |  | 		} catch (ActorDoesNotExistException $e) { | 
					
						
							|  |  |  | 			if ($create) { | 
					
						
							|  |  |  | 				$this->createActor($userId, $userId); | 
					
						
							|  |  |  | 				$actor = $this->actorsRequest->getFromUserId($userId); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				throw new ActorDoesNotExistException(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		return $actor; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2018-10-01 12:14:23 +00:00
										 |  |  | 	 * Method should be called by the frontend and will generate a fresh Social account for | 
					
						
							|  |  |  | 	 * the user, using the userId and the username. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * Pair of keys are created at this point. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * Return exceptions if an account already exist for this user or if the username is already | 
					
						
							|  |  |  | 	 * taken | 
					
						
							|  |  |  | 	 * | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 	 * @param string $userId | 
					
						
							| 
									
										
										
										
											2018-10-01 12:14:23 +00:00
										 |  |  | 	 * @param string $username | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 	 * | 
					
						
							| 
									
										
										
										
											2018-10-01 12:14:23 +00:00
										 |  |  | 	 * @throws AccountAlreadyExistsException | 
					
						
							| 
									
										
										
										
											2019-09-25 12:37:32 +00:00
										 |  |  | 	 * @throws ItemAlreadyExistsException | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 	 * @throws NoUserException | 
					
						
							| 
									
										
										
										
											2018-11-28 15:39:25 +00:00
										 |  |  | 	 * @throws SocialAppConfigException | 
					
						
							| 
									
										
										
										
											2018-12-05 18:37:49 +00:00
										 |  |  | 	 * @throws UrlCloudException | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 	 */ | 
					
						
							|  |  |  | 	public function createActor(string $userId, string $username) { | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | 		$this->confirmUserId($userId); | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 		$this->checkActorUsername($username); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		try { | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | 			$actor = $this->actorsRequest->getFromUsername($username); | 
					
						
							|  |  |  | 			if ($actor->getDeleted() > 0) { | 
					
						
							|  |  |  | 				throw new AccountAlreadyExistsException( | 
					
						
							|  |  |  | 					'actor with that name was deleted but is still in retention. Please try again later' | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-10-01 12:14:23 +00:00
										 |  |  | 			throw new AccountAlreadyExistsException('actor with that name already exist'); | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 		} catch (ActorDoesNotExistException $e) { | 
					
						
							|  |  |  | 			/* we do nohtin */ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		try { | 
					
						
							|  |  |  | 			$this->actorsRequest->getFromUserId($userId); | 
					
						
							| 
									
										
										
										
											2018-10-01 12:14:23 +00:00
										 |  |  | 			throw new AccountAlreadyExistsException('account for this user already exist'); | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 		} catch (ActorDoesNotExistException $e) { | 
					
						
							|  |  |  | 			/* we do nohtin */ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 22:57:32 +00:00
										 |  |  | 		$actor = new Person(); | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 		$actor->setUserId($userId); | 
					
						
							|  |  |  | 		$actor->setPreferredUsername($username); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-16 22:53:00 +00:00
										 |  |  | 		$this->signatureService->generateKeys($actor); | 
					
						
							| 
									
										
										
										
											2018-11-15 11:26:25 +00:00
										 |  |  | 		$this->actorsRequest->create($actor); | 
					
						
							| 
									
										
										
										
											2018-11-14 13:37:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// generate cache.
 | 
					
						
							| 
									
										
										
										
											2019-01-16 13:06:20 +00:00
										 |  |  | 		$this->cacheLocalActorByUsername($username); | 
					
						
							| 
									
										
										
										
											2019-09-23 10:34:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// generate loopback
 | 
					
						
							|  |  |  | 		$this->followsRequest->generateLoopbackAccount($actor); | 
					
						
							| 
									
										
										
										
											2018-11-15 11:26:25 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param string $handle | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @throws ItemUnknownException | 
					
						
							|  |  |  | 	 * @throws SocialAppConfigException | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	public function deleteActor(string $handle): void { | 
					
						
							|  |  |  | 		try { | 
					
						
							|  |  |  | 			$actor = $this->actorsRequest->getFromUsername($handle); | 
					
						
							|  |  |  | 		} catch (ActorDoesNotExistException $e) { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// set as deleted locally
 | 
					
						
							|  |  |  | 		$this->actorsRequest->setAsDeleted($actor->getPreferredUsername()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// delete related data
 | 
					
						
							|  |  |  | 		/** @var PersonInterface $interface */ | 
					
						
							|  |  |  | 		$interface = AP::$activityPub->getInterfaceFromType(Person::TYPE); | 
					
						
							| 
									
										
										
										
											2023-01-06 17:35:38 +00:00
										 |  |  | 		$interface->delete($actor); | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// broadcast delete event
 | 
					
						
							|  |  |  | 		$delete = new Delete(); | 
					
						
							|  |  |  | 		$delete->setId($actor->getId() . '#delete'); | 
					
						
							|  |  |  | 		$delete->setActorId($actor->getId()); | 
					
						
							|  |  |  | 		$delete->setToArray([ACore::CONTEXT_PUBLIC]); | 
					
						
							|  |  |  | 		$delete->setObjectId($actor->getId()); | 
					
						
							|  |  |  | 		$delete->addInstancePath( | 
					
						
							|  |  |  | 			new InstancePath( | 
					
						
							|  |  |  | 				$actor->getInbox(), | 
					
						
							|  |  |  | 				InstancePath::TYPE_ALL, | 
					
						
							|  |  |  | 				InstancePath::PRIORITY_LOW | 
					
						
							|  |  |  | 			) | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		$this->signatureService->signObject($actor, $delete); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$this->activityService->request($delete); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-15 11:26:25 +00:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param string $username | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @throws SocialAppConfigException | 
					
						
							| 
									
										
										
										
											2018-12-05 18:37:49 +00:00
										 |  |  | 	 * @throws UrlCloudException | 
					
						
							| 
									
										
										
										
											2019-09-25 12:37:32 +00:00
										 |  |  | 	 * @throws ItemAlreadyExistsException | 
					
						
							| 
									
										
										
										
											2018-11-15 11:26:25 +00:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2019-01-16 13:06:20 +00:00
										 |  |  | 	public function cacheLocalActorByUsername(string $username) { | 
					
						
							| 
									
										
										
										
											2018-11-15 11:26:25 +00:00
										 |  |  | 		try { | 
					
						
							| 
									
										
										
										
											2018-12-05 18:37:49 +00:00
										 |  |  | 			$actor = $this->getActor($username); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-08 11:37:17 +00:00
										 |  |  | 			try { | 
					
						
							|  |  |  | 				$this->updateCacheLocalActorName($actor); | 
					
						
							|  |  |  | 			} catch (NoUserException $e) { | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-15 13:29:14 +00:00
										 |  |  | 			try { | 
					
						
							|  |  |  | 				$iconId = $this->documentService->cacheLocalAvatarByUsername($actor); | 
					
						
							|  |  |  | 				$actor->setIconId($iconId); | 
					
						
							|  |  |  | 			} catch (ItemUnknownException $e) { | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-12-05 18:37:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-16 13:06:20 +00:00
										 |  |  | 			$this->addLocalActorDetailCount($actor); | 
					
						
							|  |  |  | 			$this->actorService->cacheLocalActor($actor); | 
					
						
							| 
									
										
										
										
											2018-11-15 11:26:25 +00:00
										 |  |  | 		} catch (ActorDoesNotExistException $e) { | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-16 13:06:20 +00:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param Person $actor | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	public function cacheLocalActorDetailCount(Person $actor) { | 
					
						
							|  |  |  | 		if (!$actor->isLocal()) { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$this->addLocalActorDetailCount($actor); | 
					
						
							|  |  |  | 		$this->actorService->cacheLocalActor($actor); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param Person $actor | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2023-01-12 13:43:04 +00:00
										 |  |  | 	public function addLocalActorDetailCount(Person $actor) { | 
					
						
							| 
									
										
										
										
											2020-09-01 14:14:19 +00:00
										 |  |  | 		$lastPostCreation = ''; | 
					
						
							|  |  |  | 		try { | 
					
						
							|  |  |  | 			$lastPost = $this->streamRequest->lastNoteFromActorId($actor->getId()); | 
					
						
							| 
									
										
										
										
											2020-09-03 01:56:36 +00:00
										 |  |  | 			$lastPostCreation = date('Y-m-d', $lastPost->getPublishedTime()); | 
					
						
							| 
									
										
										
										
											2020-09-01 14:14:19 +00:00
										 |  |  | 		} catch (StreamNotFoundException $e) { | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-16 13:06:20 +00:00
										 |  |  | 		$count = [ | 
					
						
							| 
									
										
										
										
											2019-10-02 16:40:38 +00:00
										 |  |  | 			'followers' => $this->followsRequest->countFollowers($actor->getId()), | 
					
						
							|  |  |  | 			'following' => $this->followsRequest->countFollowing($actor->getId()), | 
					
						
							| 
									
										
										
										
											2022-04-15 11:34:01 +00:00
										 |  |  | 			'post' => $this->streamRequest->countNotesFromActorId($actor->getId()) | 
					
						
							| 
									
										
										
										
											2019-01-16 13:06:20 +00:00
										 |  |  | 		]; | 
					
						
							| 
									
										
										
										
											2019-06-20 23:59:40 +00:00
										 |  |  | 		$actor->setDetailArray('count', $count); | 
					
						
							| 
									
										
										
										
											2020-09-01 14:14:19 +00:00
										 |  |  | 		$actor->setDetail('last_post_creation', $lastPostCreation); | 
					
						
							| 
									
										
										
										
											2019-01-16 13:06:20 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-05 22:56:52 +00:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param Person $actor | 
					
						
							| 
									
										
										
										
											2018-12-08 11:37:17 +00:00
										 |  |  | 	 * | 
					
						
							|  |  |  | 	 * @throws NoUserException | 
					
						
							| 
									
										
										
										
											2018-12-05 22:56:52 +00:00
										 |  |  | 	 */ | 
					
						
							|  |  |  | 	private function updateCacheLocalActorName(Person &$actor) { | 
					
						
							|  |  |  | 		$user = $this->userManager->get($actor->getUserId()); | 
					
						
							| 
									
										
										
										
											2018-12-08 11:37:17 +00:00
										 |  |  | 		if ($user === null) { | 
					
						
							|  |  |  | 			throw new NoUserException(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-12-05 22:56:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		try { | 
					
						
							| 
									
										
										
										
											2018-12-12 09:44:13 +00:00
										 |  |  | 			$account = $this->accountManager->getAccount($user); | 
					
						
							| 
									
										
										
										
											2018-12-05 22:56:52 +00:00
										 |  |  | 			$displayNameProperty = $account->getProperty(IAccountManager::PROPERTY_DISPLAYNAME); | 
					
						
							|  |  |  | 			if ($displayNameProperty->getScope() === IAccountManager::VISIBILITY_PUBLIC) { | 
					
						
							|  |  |  | 				$actor->setName($displayNameProperty->getValue()); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-12-12 09:44:13 +00:00
										 |  |  | 		} catch (Exception $e) { | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | 			$this->logger->error('Issue while trying to updateCacheLocalActorName: ' . $e->getMessage()); | 
					
						
							| 
									
										
										
										
											2018-12-05 22:56:52 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-05-06 08:29:07 +00:00
										 |  |  | 	 * @param string $username | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2019-05-06 08:29:07 +00:00
										 |  |  | 	private function checkActorUsername(string $username) { | 
					
						
							| 
									
										
										
										
											2018-10-01 12:14:23 +00:00
										 |  |  | 		$accepted = 'qwertyuiopasdfghjklzxcvbnm'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 22:57:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @return int | 
					
						
							|  |  |  | 	 * @throws Exception | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	public function manageDeletedActors(): int { | 
					
						
							|  |  |  | 		$entries = $this->actorsRequest->getAll(); | 
					
						
							|  |  |  | 		$deleted = 0; | 
					
						
							|  |  |  | 		foreach ($entries as $item) { | 
					
						
							|  |  |  | 			// delete after an hour
 | 
					
						
							|  |  |  | 			if ($item->getDeleted() === 0) { | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if ($item->getDeleted() < (time() - self::TIME_RETENTION)) { | 
					
						
							|  |  |  | 				$this->actorsRequest->delete($item->getPreferredUsername()); | 
					
						
							|  |  |  | 				$deleted++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return $deleted; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-26 12:33:48 +00:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @return int | 
					
						
							| 
									
										
										
										
											2019-06-12 10:51:28 +00:00
										 |  |  | 	 * @throws Exception | 
					
						
							| 
									
										
										
										
											2018-11-26 12:33:48 +00:00
										 |  |  | 	 */ | 
					
						
							|  |  |  | 	public function manageCacheLocalActors(): int { | 
					
						
							|  |  |  | 		$update = $this->actorsRequest->getAll(); | 
					
						
							|  |  |  | 		foreach ($update as $item) { | 
					
						
							|  |  |  | 			try { | 
					
						
							| 
									
										
										
										
											2019-01-16 13:06:20 +00:00
										 |  |  | 				$this->cacheLocalActorByUsername($item->getPreferredUsername()); | 
					
						
							| 
									
										
										
										
											2018-11-26 12:33:48 +00:00
										 |  |  | 			} catch (Exception $e) { | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return sizeof($update); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-02 11:20:11 +00:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @return int | 
					
						
							| 
									
										
										
										
											2019-06-12 10:51:28 +00:00
										 |  |  | 	 * @throws Exception | 
					
						
							| 
									
										
										
										
											2019-01-02 11:20:11 +00:00
										 |  |  | 	 */ | 
					
						
							|  |  |  | 	public function blindKeyRotation(): int { | 
					
						
							|  |  |  | 		$update = $this->actorsRequest->getAll(); | 
					
						
							|  |  |  | 		$count = 0; | 
					
						
							|  |  |  | 		foreach ($update as $actor) { | 
					
						
							|  |  |  | 			try { | 
					
						
							|  |  |  | 				if ($actor->getCreation() < (time() - (self::KEY_PAIR_LIFESPAN * 3600 * 24))) { | 
					
						
							|  |  |  | 					$this->signatureService->generateKeys($actor); | 
					
						
							|  |  |  | 					$this->actorsRequest->refreshKeys($actor); | 
					
						
							|  |  |  | 					$count++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} catch (Exception $e) { | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return $count; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-01-05 09:58:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param string $userId | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * @return IUser | 
					
						
							|  |  |  | 	 * @throws NoUserException | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	public function confirmUserId(string &$userId): IUser { | 
					
						
							|  |  |  | 		$user = $this->userManager->get($userId); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if ($user === null) { | 
					
						
							|  |  |  | 			throw new NoUserException('user does not exist'); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$userId = $user->getUID(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return $user; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-28 11:41:24 +00:00
										 |  |  | } |