diff options
author | Maxence Lange <maxence@artificial-owl.com> | 2018-11-12 21:57:32 -0100 |
---|---|---|
committer | Maxence Lange <maxence@artificial-owl.com> | 2018-11-12 21:57:32 -0100 |
commit | f4a93ec743bee2beb19f45ba3132a1d7d996b49c (patch) | |
tree | 0180b152f39376d40ed48fa69499bd199d3d41a5 /lib | |
parent | 6d2d8f9565c54d9168767f377fb2d9adb602255d (diff) |
cleaning code
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Service/ActivityPub/FollowService.php | 100 | ||||
-rw-r--r-- | lib/Service/ActivityPub/NoteService.php | 95 | ||||
-rw-r--r-- | lib/Service/ActivityPub/PersonService.php | 143 | ||||
-rw-r--r-- | lib/Service/ActivityPub/UndoService.php | 66 | ||||
-rw-r--r-- | lib/Service/ActivityService.php (renamed from lib/Service/ActivityPubService.php) | 143 | ||||
-rw-r--r-- | lib/Service/ActorService.php | 101 | ||||
-rw-r--r-- | lib/Service/ConfigService.php | 32 | ||||
-rw-r--r-- | lib/Service/CurlService.php | 3 | ||||
-rw-r--r-- | lib/Service/ICoreService.php | 4 | ||||
-rw-r--r-- | lib/Service/ImportService.php | 123 | ||||
-rw-r--r-- | lib/Service/InstanceService.php | 42 | ||||
-rw-r--r-- | lib/Service/MiscService.php | 49 | ||||
-rw-r--r-- | lib/Service/PostService.php | 93 |
13 files changed, 805 insertions, 189 deletions
diff --git a/lib/Service/ActivityPub/FollowService.php b/lib/Service/ActivityPub/FollowService.php new file mode 100644 index 00000000..644ea74b --- /dev/null +++ b/lib/Service/ActivityPub/FollowService.php @@ -0,0 +1,100 @@ +<?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\Service\ActivityPub; + + +use Exception; +use OCA\Social\Db\FollowsRequest; +use OCA\Social\Model\ActivityPub\ACore; +use OCA\Social\Model\ActivityPub\Person; +use OCA\Social\Model\ActivityPub\Follow; +use OCA\Social\Model\ActivityPub\OrderedCollection; +use OCA\Social\Service\ICoreService; +use OCA\Social\Service\MiscService; + + +class FollowService implements ICoreService { + + + /** @var FollowsRequest */ + private $followsRequest; + + /** @var MiscService */ + private $miscService; + + + /** + * NoteService constructor. + * + * @param FollowsRequest $followsRequest + * @param MiscService $miscService + */ + public function __construct(FollowsRequest $followsRequest, MiscService $miscService) { + $this->followsRequest = $followsRequest; + $this->miscService = $miscService; + } + + + /** + * @param Person $actor + * + * @return OrderedCollection + */ + public function getFollowers(Person $actor): OrderedCollection { + $collection = new OrderedCollection(); + $collection->setId($actor->getFollowers()); + $collection->setTotalItems(20); + $collection->setFirst('...'); + + return $collection; + } + + + /** + * This method is called when saving the Follow object + * + * @param ACore $follow + * + * @throws Exception + */ + public function save(ACore $follow) { + /** @var Follow $follow */ + + if ($follow->getMetaBool('Undo') === false) { + $this->followsRequest->save($follow); + } else { + $this->followsRequest->delete($follow); + } + } + + +} + diff --git a/lib/Service/ActivityPub/NoteService.php b/lib/Service/ActivityPub/NoteService.php index 47bf912c..d6f96558 100644 --- a/lib/Service/ActivityPub/NoteService.php +++ b/lib/Service/ActivityPub/NoteService.php @@ -34,10 +34,12 @@ use Exception; use OC\User\NoUserException; use OCA\Social\Db\NotesRequest; use OCA\Social\Exceptions\ActorDoesNotExistException; -use OCA\Social\Model\ActivityPub\Core; +use OCA\Social\Exceptions\RequestException; +use OCA\Social\Model\ActivityPub\ACore; use OCA\Social\Model\ActivityPub\Note; +use OCA\Social\Model\ActivityPub\Person; use OCA\Social\Model\InstancePath; -use OCA\Social\Service\ActivityPubService; +use OCA\Social\Service\ActivityService; use OCA\Social\Service\ActorService; use OCA\Social\Service\ConfigService; use OCA\Social\Service\CurlService; @@ -53,6 +55,9 @@ class NoteService implements ICoreService { /** @var ActorService */ private $actorService; + /** @var PersonService */ + private $personService; + /** @var CurlService */ private $curlService; @@ -68,17 +73,18 @@ class NoteService implements ICoreService { * * @param NotesRequest $notesRequest * @param ActorService $actorService + * @param PersonService $personService * @param CurlService $curlService * @param ConfigService $configService * @param MiscService $miscService */ public function __construct( - NotesRequest $notesRequest, ActorService $actorService, - CurlService $curlService, ConfigService $configService, - MiscService $miscService + NotesRequest $notesRequest, ActorService $actorService, PersonService $personService, + CurlService $curlService, ConfigService $configService, MiscService $miscService ) { $this->notesRequest = $notesRequest; $this->actorService = $actorService; + $this->personService = $personService; $this->curlService = $curlService; $this->configService = $configService; $this->miscService = $miscService; @@ -102,7 +108,7 @@ class NoteService implements ICoreService { $note->setAttributedTo( $this->configService->getRoot() . '@' . $actor->getPreferredUsername() ); - $note->setTo(ActivityPubService::TO_PUBLIC); + $note->setTo(ActivityService::TO_PUBLIC); $note->setContent($content); $note->saveAs($this); @@ -113,19 +119,43 @@ class NoteService implements ICoreService { /** * @param Note $note - * @param string $to - * @param int $type + * @param string $account + * + * @throws RequestException */ - public function assignTo(Note $note, string $to, int $type) { - $note->addToArray($to); + public function assignTo(Note $note, string $account) { + if ($account === '') { + return; + } + + $actor = $this->personService->getFromAccount($account); + + $note->addToArray($actor->getId()); $note->addTag( [ 'type' => 'Mention', - 'href' => $to + 'href' => $actor->getId() ] ); - $note->addInstancePath(new InstancePath($to, $type)); + $note->addInstancePath(new InstancePath($actor->getInbox())); + } + + + /** + * @param Note $note + * @param array $accounts + * + * @throws RequestException + */ + public function assignToArray(Note $note, array $accounts) { + if ($accounts === []) { + return; + } + + foreach ($accounts as $account) { + $this->assignTo($note, $account); + } } @@ -134,6 +164,10 @@ class NoteService implements ICoreService { * @param string $replyTo */ public function replyTo(Note $note, string $replyTo) { + if ($replyTo === '') { + return; + } + $note->setInReplyTo($replyTo); $note->addInstancePath(new InstancePath($replyTo)); } @@ -142,13 +176,44 @@ class NoteService implements ICoreService { /** * This method is called when saving the Note object * - * @param Core $note + * @param ACore $note * * @throws Exception */ - public function save(Core $note) { + public function save(ACore $note) { /** @var Note $note */ - $this->notesRequest->create($note); + $this->notesRequest->save($note); } + + /** + * @param string $userId + * + * @return Note[] + */ + public function getTimeline(): array { + return $this->notesRequest->getPublicNotes(); + } + + + /** + * @param Person $actor + * + * @return Note[] + */ + public function getNotesForActor(Person $actor): array { + $privates = $this->getPrivateNotesForActor($actor); + + return $privates; + } + + + /** + * @param Person $actor + * + * @return Note[] + */ + private function getPrivateNotesForActor(Person $actor): array { + return $this->notesRequest->getNotesForActorId($actor->getId()); + } } diff --git a/lib/Service/ActivityPub/PersonService.php b/lib/Service/ActivityPub/PersonService.php new file mode 100644 index 00000000..93e4ee82 --- /dev/null +++ b/lib/Service/ActivityPub/PersonService.php @@ -0,0 +1,143 @@ +<?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\Service\ActivityPub; + + +use daita\MySmallPhpTools\Traits\TArrayTools; +use Exception; +use OCA\Social\Db\CacheActorsRequest; +use OCA\Social\Exceptions\CacheActorDoesNotExistException; +use OCA\Social\Exceptions\RequestException; +use OCA\Social\Model\ActivityPub\ACore; +use OCA\Social\Model\ActivityPub\Person; +use OCA\Social\Model\InstancePath; +use OCA\Social\Service\ICoreService; +use OCA\Social\Service\InstanceService; +use OCA\Social\Service\MiscService; + + +/** + * Class PersonService + * + * @package OCA\Social\Service\ActivityPub + */ +class PersonService implements ICoreService { + + + use TArrayTools; + + + /** @var CacheActorsRequest */ + private $cacheActorsRequest; + + /** @var InstanceService */ + private $instanceService; + + /** @var MiscService */ + private $miscService; + + + /** + * UndoService constructor. + * + * @param CacheActorsRequest $cacheActorsRequest + * @param InstanceService $instanceService + * @param MiscService $miscService + */ + public function __construct( + CacheActorsRequest $cacheActorsRequest, InstanceService $instanceService, + MiscService $miscService + ) { + $this->cacheActorsRequest = $cacheActorsRequest; + $this->instanceService = $instanceService; + $this->miscService = $miscService; + } + + + /** + * @param string $account + * + * @return Person + * @throws RequestException + * @throws Exception + */ + public function getFromAccount(string $account): Person { + + try { + $actor = $this->cacheActorsRequest->getFromAccount($account); + } catch (CacheActorDoesNotExistException $e) { + + $object = $this->instanceService->retrieveAccount($account); + $actor = new Person(); + $actor->import($object); + + $actor->setAccount($account); + $actor->setPreferredUsername($this->get('preferredUsername', $object, '')); + $actor->setPublicKey($this->get('publicKey.publicKeyPem', $object)); + $actor->setSharedInbox($this->get('endpoints.sharedInbox', $object)); + $this->save($actor); + } + + return $actor; + } + + + /** + * This method is called when saving the Follow object + * + * @param ACore $person + * + * @throws Exception + */ + public function save(ACore $person) { + /** @var Person $person */ + $this->cacheActorsRequest->save($person); + } + + + // /** + // * @param Person $actor + // * @param int $type + // * + // * @return string + // */ + // public function getPathFromActor(Person $actor, int $type) { + // switch ($type) { + // case InstancePath::INBOX: + // return parse_url($actor->getInbox(), PHP_URL_PATH); + // } + // + // return ''; + // } + + +} + diff --git a/lib/Service/ActivityPub/UndoService.php b/lib/Service/ActivityPub/UndoService.php new file mode 100644 index 00000000..c1d0efae --- /dev/null +++ b/lib/Service/ActivityPub/UndoService.php @@ -0,0 +1,66 @@ +<?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\Service\ActivityPub; + + +use Exception; +use OCA\Social\Model\ActivityPub\ACore; +use OCA\Social\Service\ICoreService; +use OCA\Social\Service\MiscService; + + +class UndoService implements ICoreService { + + + /** @var MiscService */ + private $miscService; + + + /** + * UndoService constructor. + * + * @param MiscService $miscService + */ + public function __construct(MiscService $miscService) { + $this->miscService = $miscService; + } + + + /** + * @param ACore $undo + * + * @throws Exception + */ + public function save(ACore $undo) { + } + +} + diff --git a/lib/Service/ActivityPubService.php b/lib/Service/ActivityService.php index b2d65423..45e8e489 100644 --- a/lib/Service/ActivityPubService.php +++ b/lib/Service/ActivityService.php @@ -31,21 +31,32 @@ namespace OCA\Social\Service; use daita\MySmallPhpTools\Model\Request; +use daita\MySmallPhpTools\Traits\TArrayTools; use DateTime; use Exception; use OC\User\NoUserException; use OCA\Social\Db\ActorsRequest; use OCA\Social\Exceptions\ActorDoesNotExistException; use OCA\Social\Exceptions\RequestException; -use OCA\Social\Model\ActivityPub\ActivityCreate; -use OCA\Social\Model\ActivityPub\Actor; -use OCA\Social\Model\ActivityPub\Core; +use OCA\Social\Exceptions\UnknownItemException; +use OCA\Social\Model\ActivityPub\ACore; +use OCA\Social\Model\ActivityPub\Activity; +use OCA\Social\Model\ActivityPub\Person; use OCA\Social\Model\InstancePath; +use OCA\Social\Service\ActivityPub\FollowService; +use OCA\Social\Service\ActivityPub\NoteService; +use OCA\Social\Service\ActivityPub\PersonService; +use OCA\Social\Service\ActivityPub\UndoService; use OCP\IRequest; -class ActivityPubService { +class ActivityService { + use TArrayTools; + + + const REQUEST_INBOX = 1; + const CONTEXT_ACTIVITYSTREAMS = 'https://www.w3.org/ns/activitystreams'; const CONTEXT_SECURITY = 'https://w3id.org/security/v1'; @@ -60,6 +71,18 @@ class ActivityPubService { /** @var ActorService */ private $actorService; + /** @var PersonService */ + private $personService; + + /** @var NoteService */ + private $noteService; + + /** @var UndoService */ + private $undoService; + + /** @var FollowService */ + private $followService; + /** @var InstanceService */ private $instanceService; @@ -74,22 +97,33 @@ class ActivityPubService { /** - * ActivityPubService constructor. + * ActivityService constructor. * * @param ActorsRequest $actorsRequest * @param CurlService $curlService * @param ActorService $actorService + * @param PersonService $personService + * @param NoteService $noteService + * @param UndoService $undoService + * @param FollowService $followService * @param InstanceService $instanceService * @param ConfigService $configService * @param MiscService $miscService */ public function __construct( ActorsRequest $actorsRequest, CurlService $curlService, ActorService $actorService, - InstanceService $instanceService, ConfigService $configService, MiscService $miscService + PersonService $personService, NoteService $noteService, UndoService $undoService, + FollowService $followService, + InstanceService $instanceService, ConfigService $configService, + MiscService $miscService ) { $this->curlService = $curlService; $this->actorsRequest = $actorsRequest; $this->actorService = $actorService; + $this->personService = $personService; + $this->noteService = $noteService; + $this->undoService = $undoService; + $this->followService = $followService; $this->instanceService = $instanceService; $this->configService = $configService; $this->miscService = $miscService; @@ -105,22 +139,24 @@ class ActivityPubService { /** * @param string $userId * - * @param Core $item - * @param Core $activity + * @param ACore $item + * @param int $type + * @param ACore $activity * * @return array * @throws ActorDoesNotExistException * @throws NoUserException * @throws RequestException */ - public function createActivity($userId, Core $item, Core &$activity = null): array { + public function createActivity($userId, ACore $item, int $type, ACore &$activity = null + ): array { + + $activity = new Activity(true); - $activity = new ActivityCreate(true); // $this->activityStreamsService->initCore($activity); - $actor = $this->actorService->getActorFromUserId($userId); + $activity->setObject($item); $activity->setId($item->getId() . '/activity'); - $activity->addInstancePaths($item->getInstancePaths()); // if ($item->getToArray() !== []) { @@ -129,30 +165,30 @@ class ActivityPubService { // $activity->setTo($item->getTo()); // } + $actor = $this->actorService->getActorFromUserId($userId); $activity->setActor($actor); - $activity->setObject($item); $this->setupCore($activity); - $result = $this->request($activity); + $result = $this->request($activity, $type); return $result; } /** - * @param Core $activity + * @param ACore $activity * * @return array * @throws RequestException */ - public function request(Core $activity) { + public function request(ACore $activity, int $type) { $hosts = $this->instanceService->getInstancesFromActivity($activity); $result = []; foreach ($hosts as $host) { foreach ($host->getInstancePaths() as $path) { - $result[] = $this->generateRequest($host->getAddress(), $path, $activity); + $result[] = $this->generateRequest($host->getAddress(), $path, $type, $activity); } } @@ -163,23 +199,24 @@ class ActivityPubService { /** * @param string $address * @param InstancePath $path - * @param Core $activity + * @param ACore $activity * * @return Request[] * @throws RequestException */ - public function generateRequest(string $address, InstancePath $path, Core $activity): array { + public function generateRequest(string $address, InstancePath $path, int $type, ACore $activity + ): array { $document = json_encode($activity); - $date = date(self::DATE_FORMAT); - + $date = gmdate(self::DATE_FORMAT); +//$date = str_replace('UTC', 'GMT', $date); $localActor = $activity->getActor(); - $remoteActor = $this->getRemoteActor($path->getUri()); +// $remoteActor = $this->getRemoteActor($path->getUri()); - $remotePath = $this->actorService->getPathFromActor($remoteActor, $path->getType()); +// $remotePath = $this->personService->getPathFromActor($remoteActor, $path->getType()); $localActorLink = $this->configService->getRoot() . '@' . $localActor->getPreferredUsername(); - $signature = "(request-target): post " . $remotePath . "\nhost: " . $address + $signature = "(request-target): post " . $path->getPath() . "\nhost: " . $address . "\ndate: " . $date; openssl_sign($signature, $signed, $localActor->getPrivateKey(), OPENSSL_ALGO_SHA256); @@ -189,7 +226,11 @@ class ActivityPubService { 'keyId="' . $localActorLink . '",headers="(request-target) host date",signature="' . $signed . '"'; - $request = new Request($remotePath, Request::TYPE_POST); + if ($type === self::REQUEST_INBOX) { + $requestType = Request::TYPE_POST; + } + + $request = new Request($path->getPath(), $requestType); $request->addHeader('Host: ' . $address); $request->addHeader('Date: ' . $date); $request->addHeader('Signature: ' . $header); @@ -245,11 +286,11 @@ class ActivityPubService { /** * @param string $uriId * - * @return Actor + * @return Person * @throws RequestException */ private function getRemoteActor(string $uriId) { - $actor = $this->actorService->getFromUri($uriId); + $actor = $this->personService->getFromAccount($uriId); return $actor; } @@ -284,7 +325,7 @@ class ActivityPubService { $signatureHeader = $request->getHeader('Signature'); $sign = $this->parseSignatureHeader($signatureHeader); - $this->miscService->mustContains(['keyId', 'headers', 'signature'], $sign); + $this->mustContains(['keyId', 'headers', 'signature'], $sign); $keyId = $sign['keyId']; $headers = $sign['headers']; @@ -360,9 +401,9 @@ class ActivityPubService { /** - * @param Core $activity + * @param ACore $activity */ - private function setupCore(Core $activity) { + private function setupCore(ACore $activity) { // $this->initCore($activity); if ($activity->isTopLevel()) { @@ -379,4 +420,46 @@ class ActivityPubService { } } + + /** + * @param ACore $activity + * + * @throws UnknownItemException + */ + public function save(Acore $activity) { + + if ($activity->gotObject()) { + $this->save($activity->getObject()); + } + + switch ($activity->getType()) { +// case 'Activity': +// $service = $this; +// break; + + case 'Undo': + $service = $this->undoService; + break; + + case 'Follow': + $service = $this->followService; + break; + + case 'Note': + $service = $this->noteService; + break; + + default: + throw new UnknownItemException(); + } + + try { + $service->save($activity); + } catch (Exception $e) { + $this->miscService->log( + 2, 'Cannot save ' . $activity->getType() . ': ' . $e->getMessage() + ); + } + } } + diff --git a/lib/Service/ActorService.php b/lib/Service/ActorService.php index b7d3cecb..1d293647 100644 --- a/lib/Service/ActorService.php +++ b/lib/Service/ActorService.php @@ -34,32 +34,29 @@ use daita\MySmallPhpTools\Traits\TArrayTools; use Exception; use OC\User\NoUserException; use OCA\Social\Db\ActorsRequest; -use OCA\Social\Db\CacheActorsRequest; use OCA\Social\Exceptions\AccountAlreadyExistsException; use OCA\Social\Exceptions\ActorDoesNotExistException; -use OCA\Social\Exceptions\CacheActorDoesNotExistException; -use OCA\Social\Exceptions\RequestException; -use OCA\Social\Model\ActivityPub\Actor; +use OCA\Social\Model\ActivityPub\Person; use OCA\Social\Model\InstancePath; + +/** + * Class ActorService + * + * @package OCA\Social\Service + */ class ActorService { use TArrayTools; - /** @var InstanceService */ - private $instanceService; - /** @var ConfigService */ private $configService; /** @var ActorsRequest */ private $actorsRequest; - /** @var CacheActorsRequest */ - private $cacheActorsRequest; - /** @var MiscService */ private $miscService; @@ -68,20 +65,14 @@ class ActorService { * ActorService constructor. * * @param ActorsRequest $actorsRequest - * @param CacheActorsRequest $cacheActorsRequest - * @param InstanceService $instanceService * @param ConfigService $configService * @param MiscService $miscService */ public function __construct( - ActorsRequest $actorsRequest, - CacheActorsRequest $cacheActorsRequest, InstanceService $instanceService, - ConfigService $configService, MiscService $miscService + ActorsRequest $actorsRequest, ConfigService $configService, MiscService $miscService ) { $this->configService = $configService; - $this->instanceService = $instanceService; $this->actorsRequest = $actorsRequest; - $this->cacheActorsRequest = $cacheActorsRequest; $this->miscService = $miscService; } @@ -89,11 +80,11 @@ class ActorService { /** * @param string $username * - * @return Actor + * @return Person * @throws ActorDoesNotExistException */ - public function getActor(string $username): Actor { + public function getActor(string $username): Person { $actor = $this->actorsRequest->getFromUsername($username); |