diff --git a/lib/Model/ActivityPub/ACore.php b/lib/Model/ActivityPub/ACore.php index a230d40a..0ea904bc 100644 --- a/lib/Model/ActivityPub/ACore.php +++ b/lib/Model/ActivityPub/ACore.php @@ -31,8 +31,10 @@ namespace OCA\Social\Model\ActivityPub; use daita\MySmallPhpTools\Traits\TArrayTools; +use daita\MySmallPhpTools\Traits\TPathTools; use JsonSerializable; use OCA\Social\Exceptions\ActivityCantBeVerifiedException; +use OCA\Social\Exceptions\UrlCloudException; use OCA\Social\Model\InstancePath; use OCA\Social\Service\ICoreService; @@ -41,6 +43,7 @@ abstract class ACore implements JsonSerializable { use TArrayTools; + use TPathTools; const CONTEXT_ACTIVITYSTREAMS = 'https://www.w3.org/ns/activitystreams'; @@ -48,7 +51,10 @@ abstract class ACore implements JsonSerializable { /** @var string */ - private $root = ''; + private $urlSocial = ''; + + /** @var string */ + private $urlCloud = ''; // /** @var bool */ // private $isTopLevel = false; @@ -101,6 +107,9 @@ abstract class ACore implements JsonSerializable { /** @var string */ private $actorId = ''; + /** @var Document */ + private $icon = null; + /** @var ACore */ private $object = null; @@ -155,14 +164,27 @@ abstract class ACore implements JsonSerializable { return $this; } - public function generateUniqueId(string $base) { + /** + * @param string $base + * + * @throws UrlCloudException + */ + public function generateUniqueId(string $base = '') { + if ($this->getUrlCloud() === '') { + throw new UrlCloudException(); + } + + if ($base !== '') { + $base = $this->withoutEndSlash($this->withBeginSlash($base)); + } + $uuid = sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xfff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) ); - $this->setId($base . '/' . $uuid); + $this->setId($this->getUrlCloud() . $base . '/' . $uuid); } /** @@ -178,9 +200,10 @@ abstract class ACore implements JsonSerializable { * @return ACore */ public function setType(string $type): ACore { - if ($type !== '') { - $this->type = $type; - } +// if ($type !== '') { + $this->type = $type; + +// } return $this; } @@ -343,8 +366,8 @@ abstract class ACore implements JsonSerializable { /** * @return string */ - public function getUrlRoot(): string { - return $this->root; + public function getUrlSocial(): string { + return $this->urlSocial; } /** @@ -352,8 +375,27 @@ abstract class ACore implements JsonSerializable { * * @return ACore */ - public function setUrlRoot(string $path): ACore { - $this->root = $path; + public function setUrlSocial(string $path): ACore { + $this->urlSocial = $path; + + return $this; + } + + + /** + * @return string + */ + public function getUrlCloud(): string { + return $this->urlCloud; + } + + /** + * @param string $path + * + * @return ACore + */ + public function setUrlCloud(string $path): ACore { + $this->urlCloud = $path; return $this; } @@ -653,7 +695,6 @@ abstract class ACore implements JsonSerializable { return $this; } - return $this->getParent() ->getRoot($chain); } @@ -822,6 +863,23 @@ abstract class ACore implements JsonSerializable { * @param array $data */ public function import(array $data) { + $this->setId($this->get('id', $data, '')); + $this->setType($this->get('type', $data, '')); + $this->setUrl($this->get('url', $data, '')); + $this->setSummary($this->get('summary', $data, '')); + $this->setToArray($this->getArray('to', $data, [])); + $this->setCcArray($this->getArray('cc', $data, [])); + $this->setPublished($this->get('published', $data, '')); + $this->setActorId($this->get('actor', $data, '')); + $this->setObjectId($this->get('object', $data, '')); + $this->setLocal(($this->getInt('local', $data, 0) === 1)); + } + + + /** + * @param array $data + */ + public function importFromDatabase(array $data) { $this->setId($this->get('id', $data, '')); $this->setType($this->get('type', $data, '')); $this->setUrl($this->get('url', $data, '')); @@ -851,7 +909,7 @@ abstract class ACore implements JsonSerializable { $this->addEntry('id', $this->getId()); $this->addEntry('type', $this->getType()); - $this->addEntry('url', $this->getId()); + $this->addEntry('url', $this->getUrl()); $this->addEntry('to', $this->getTo()); $this->addEntryArray('to', $this->getToArray()); @@ -880,11 +938,17 @@ abstract class ACore implements JsonSerializable { $this->addEntry('object', $this->getObjectId()); } + if ($this->gotIcon()) { + $this->addEntryItem('icon', $this->getIcon()); + } + if ($this->isCompleteDetails()) { $this->addEntry('source', $this->getSource()); } - $this->addEntryBool('local', $this->isLocal()); + if ($this->isLocal()) { + $this->addEntryBool('local', $this->isLocal()); + } return $this->getEntries(); } diff --git a/lib/Service/ActivityPub/PersonService.php b/lib/Service/ActivityPub/PersonService.php index 23bb6bea..871bf7a3 100644 --- a/lib/Service/ActivityPub/PersonService.php +++ b/lib/Service/ActivityPub/PersonService.php @@ -34,11 +34,16 @@ namespace OCA\Social\Service\ActivityPub; use daita\MySmallPhpTools\Traits\TArrayTools; use Exception; use OCA\Social\Db\CacheActorsRequest; +use OCA\Social\Db\CacheDocumentsRequest; use OCA\Social\Exceptions\CacheActorDoesNotExistException; +use OCA\Social\Exceptions\CacheDocumentDoesNotExistException; use OCA\Social\Exceptions\InvalidResourceException; use OCA\Social\Exceptions\RequestException; +use OCA\Social\Exceptions\SocialAppConfigException; +use OCA\Social\Exceptions\UrlCloudException; use OCA\Social\Model\ActivityPub\ACore; use OCA\Social\Model\ActivityPub\Person; +use OCA\Social\Service\ConfigService; use OCA\Social\Service\ICoreService; use OCA\Social\Service\InstanceService; use OCA\Social\Service\MiscService; @@ -58,9 +63,15 @@ class PersonService implements ICoreService { /** @var CacheActorsRequest */ private $cacheActorsRequest; + /** @var CacheDocumentsRequest */ + private $cacheDocumentsRequest; + /** @var InstanceService */ private $instanceService; + /** @var ConfigService */ + private $configService; + /** @var MiscService */ private $miscService; @@ -69,15 +80,19 @@ class PersonService implements ICoreService { * UndoService constructor. * * @param CacheActorsRequest $cacheActorsRequest + * @param CacheDocumentsRequest $cacheDocumentsRequest * @param InstanceService $instanceService + * @param ConfigService $configService * @param MiscService $miscService */ public function __construct( - CacheActorsRequest $cacheActorsRequest, InstanceService $instanceService, - MiscService $miscService + CacheActorsRequest $cacheActorsRequest, CacheDocumentsRequest $cacheDocumentsRequest, + InstanceService $instanceService, ConfigService $configService, MiscService $miscService ) { $this->cacheActorsRequest = $cacheActorsRequest; + $this->cacheDocumentsRequest = $cacheDocumentsRequest; $this->instanceService = $instanceService; + $this->configService = $configService; $this->miscService = $miscService; } @@ -108,6 +123,8 @@ class PersonService implements ICoreService { * @return Person * @throws InvalidResourceException * @throws RequestException + * @throws SocialAppConfigException + * @throws UrlCloudException */ public function getFromId(string $id, bool $refresh = false): Person { @@ -125,19 +142,8 @@ class PersonService implements ICoreService { $actor = $this->cacheActorsRequest->getFromId($id); } catch (CacheActorDoesNotExistException $e) { $object = $this->instanceService->retrieveObject($id); - $actor = new Person(); - $actor->import($object); - $actor->setSource(json_encode($object, JSON_UNESCAPED_SLASHES)); - - $actor->setPreferredUsername($this->get('preferredUsername', $object, '')); - $actor->setPublicKey($this->get('publicKey.publicKeyPem', $object)); - $actor->setSharedInbox($this->get('endpoints.sharedInbox', $object)); + $actor = $this->generateActorFromObject($object); $actor->setAccount($actor->getPreferredUsername() . '@' . $this->get('_host', $object)); - - if ($actor->getType() !== Person::TYPE) { - throw new InvalidResourceException(); - } - try { $this->parse($actor); } catch (Exception $e) { @@ -158,6 +164,8 @@ class PersonService implements ICoreService { * @throws InvalidResourceException * @throws RequestException * @throws CacheActorDoesNotExistException + * @throws SocialAppConfigException + * @throws UrlCloudException */ public function getFromAccount(string $account, bool $retrieve = true): Person { @@ -169,19 +177,8 @@ class PersonService implements ICoreService { } $object = $this->instanceService->retrieveAccount($account); - - $actor = new Person(); - $actor->import($object); - + $actor = $this->generateActorFromObject($object); $actor->setAccount($account); - $actor->setPreferredUsername($this->get('preferredUsername', $object, '')); - $actor->setPublicKey($this->get('publicKey.publicKeyPem', $object)); - $actor->setSharedInbox($this->get('endpoints.sharedInbox', $object)); - - if ($actor->getType() !== Person::TYPE) { - throw new InvalidResourceException(); - } - try { $this->parse($actor); } catch (Exception $e) { @@ -193,6 +190,40 @@ class PersonService implements ICoreService { } + /** + * @param array $object + * + * @return Person + * @throws InvalidResourceException + * @throws SocialAppConfigException + * @throws UrlCloudException + */ + private function generateActorFromObject(array $object) { + + $actor = new Person(); + $actor->setUrlCloud($this->configService->getCloudAddress()); + $actor->import($object); + + if ($actor->getType() !== Person::TYPE) { + throw new InvalidResourceException(); + } + + $actor->setSource(json_encode($object, JSON_UNESCAPED_SLASHES)); +// $actor->setPreferredUsername($this->get('preferredUsername', $object, '')); +// $actor->setPublicKey($this->get('publicKey.publicKeyPem', $object)); +// $actor->setSharedInbox($this->get('endpoints.sharedInbox', $object)); +// $actor->setAccount($actor->getPreferredUsername() . '@' . $this->get('_host', $object)); +// +// $icon = new Image($actor); +// $icon->setUrlCloud($this->configService->getCloudAddress()); +// $icon->import($this->getArray('icon', $object, [])); +// if ($icon->getType() === Image::TYPE) { +// $actor->setIcon($icon); +// } +// + return $actor; + } + /** * @param string $search * diff --git a/lib/Service/ConfigService.php b/lib/Service/ConfigService.php index 4ecaa335..578db10e 100644 --- a/lib/Service/ConfigService.php +++ b/lib/Service/ConfigService.php @@ -211,13 +211,11 @@ class ConfigService { } /** - * @param bool $host + * @param string $cloudAddress * * @return string - * @throws SocialAppConfigException */ public function setCloudAddress(string $cloudAddress) { - // TODO: Validate $this->setAppValue(self::SOCIAL_ADDRESS, $cloudAddress); } @@ -249,10 +247,11 @@ class ConfigService { /** + * // TODO - check the Apps folder * @return string * @throws SocialAppConfigException */ - public function getUrlRoot(): string { + public function getUrlSocial(): string { return $this->getCloudAddress() . '/apps/social/'; } @@ -267,7 +266,7 @@ class ConfigService { public function generateId(string $path = '', $generateId = true): string { $path = $this->withoutBeginSlash($this->withEndSlash($path)); - $id = $this->getUrlRoot() . $path; + $id = $this->getUrlSocial() . $path; if ($generateId === true) { $id .= time() . crc32(uniqid()); } diff --git a/lib/Service/ImportService.php b/lib/Service/ImportService.php index 95fae20a..381fac1e 100644 --- a/lib/Service/ImportService.php +++ b/lib/Service/ImportService.php @@ -33,14 +33,18 @@ namespace OCA\Social\Service; use daita\MySmallPhpTools\Traits\TArrayTools; use Exception; +use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Exceptions\UnknownItemException; +use OCA\Social\Exceptions\UrlCloudException; use OCA\Social\Model\ActivityPub\ACore; use OCA\Social\Model\ActivityPub\Activity\Accept; use OCA\Social\Model\ActivityPub\Activity\Create; use OCA\Social\Model\ActivityPub\Activity\Delete; use OCA\Social\Model\ActivityPub\Activity\Reject; use OCA\Social\Model\ActivityPub\Activity\Tombstone; +use OCA\Social\Model\ActivityPub\Document; use OCA\Social\Model\ActivityPub\Follow; +use OCA\Social\Model\ActivityPub\Image; use OCA\Social\Model\ActivityPub\Note; use OCA\Social\Model\ActivityPub\Activity\Undo; use OCA\Social\Service\ActivityPub\DeleteService; @@ -67,6 +71,8 @@ class ImportService { /** @var DeleteService */ private $deleteService; + private $configService; + /** @var MiscService */ private $miscService; @@ -78,17 +84,18 @@ class ImportService { * @param UndoService $undoService * @param FollowService $followService * @param DeleteService $deleteService + * @param ConfigService $configService * @param MiscService $miscService */ public function __construct( NoteService $noteService, UndoService $undoService, FollowService $followService, - DeleteService $deleteService, - MiscService $miscService + DeleteService $deleteService, ConfigService $configService, MiscService $miscService ) { $this->noteService = $noteService; $this->undoService = $undoService; $this->followService = $followService; $this->deleteService = $deleteService; + $this->configService = $configService; $this->miscService = $miscService; } @@ -98,6 +105,8 @@ class ImportService { * * @return ACore * @throws UnknownItemException + * @throws UrlCloudException + * @throws SocialAppConfigException */ public function import(string $json) { $data = json_decode($json, true); @@ -113,6 +122,8 @@ class ImportService { * * @return ACore * @throws UnknownItemException + * @throws UrlCloudException + * @throws SocialAppConfigException */ private function createItem(array $data, $root = null): ACore { @@ -217,6 +228,10 @@ class ImportService { $service = $this->followService; break; +// case Image::TYPE: +// $service = $this->imageService; +// break; + case Note::TYPE: $service = $this->noteService; break;