diff --git a/appinfo/routes.php b/appinfo/routes.php index 5505d745..37c77c19 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -32,7 +32,9 @@ return [ ['name' => 'Local#newPost', 'url' => '/api/v1/post', 'verb' => 'POST'], ['name' => 'Local#timeline', 'url' => '/api/v1/timeline', 'verb' => 'PUT'], - ['name' => 'Local#direct', 'url' => '/api/v1/direct', 'verb' => 'PUT'] + ['name' => 'Local#direct', 'url' => '/api/v1/direct', 'verb' => 'PUT'], + ['name' => 'Local#accountSearch', 'url' => '/api/v1/accounts/search', 'verb' => 'GET'], + ['name' => 'Local#actorInfo', 'url' => '/api/v1/actor/info', 'verb' => 'GET'] ] ]; diff --git a/lib/Controller/LocalController.php b/lib/Controller/LocalController.php index 39193c2d..4a8137c0 100644 --- a/lib/Controller/LocalController.php +++ b/lib/Controller/LocalController.php @@ -36,6 +36,7 @@ use Exception; use OCA\Social\AppInfo\Application; use OCA\Social\Model\Post; use OCA\Social\Service\ActivityPub\NoteService; +use OCA\Social\Service\ActivityPub\PersonService; use OCA\Social\Service\ActorService; use OCA\Social\Service\MiscService; use OCA\Social\Service\PostService; @@ -59,6 +60,9 @@ class LocalController extends Controller { /** @var string */ private $userId; + /** @var PersonService */ + private $personService; + /** @var ActorService */ private $actorService; @@ -77,13 +81,15 @@ class LocalController extends Controller { * * @param IRequest $request * @param string $userId + * @param PersonService $personService * @param ActorService $actorService * @param PostService $postService * @param NoteService $noteService * @param MiscService $miscService */ public function __construct( - IRequest $request, string $userId, ActorService $actorService, PostService $postService, + IRequest $request, string $userId, PersonService $personService, ActorService $actorService, + PostService $postService, NoteService $noteService, MiscService $miscService ) { @@ -92,6 +98,7 @@ class LocalController extends Controller { $this->userId = $userId; $this->actorService = $actorService; + $this->personService = $personService; $this->postService = $postService; $this->noteService = $noteService; $this->miscService = $miscService; @@ -129,6 +136,8 @@ class LocalController extends Controller { /** * Get timeline * + * // TODO: Delete the NoCSRF check + * * @NoCSRFRequired * @NoAdminRequired * @NoSubAdminRequired @@ -165,8 +174,57 @@ class LocalController extends Controller { } catch (Exception $e) { return $this->fail($e->getMessage()); } + } + /** + * + * // TODO: Delete the NoCSRF check + * + * @NoCSRFRequired + * @NoAdminRequired + * @NoSubAdminRequired + * + * @param string $search + * + * @return DataResponse + */ + public function accountSearch(string $search): DataResponse { + try { + $local = $this->actorService->searchLocalAccounts($search); + $remote = $this->personService->searchCachedAccounts($search); + $accounts = [ + 'local' => $local, + 'remote' => $remote + ]; + + return $this->success(['accounts' => $accounts]); + } catch (Exception $e) { + return $this->fail($e->getMessage()); + } + } + + + /** + * + * // TODO: Delete the NoCSRF check + * + * @NoCSRFRequired + * @NoAdminRequired + * @NoSubAdminRequired + * + * @param string $id + * + * @return DataResponse + */ + public function actorInfo(string $id): DataResponse { + try { + $actor = $this->personService->getFromId($id); + + return $this->success(['actor' => $actor]); + } catch (Exception $e) { + return $this->fail($e->getMessage()); + } } } diff --git a/lib/Db/ActorsRequest.php b/lib/Db/ActorsRequest.php index 9cfdc578..ebcf006f 100644 --- a/lib/Db/ActorsRequest.php +++ b/lib/Db/ActorsRequest.php @@ -134,5 +134,24 @@ class ActorsRequest extends ActorsRequestBuilder { } + /** + * @param string $search + * + * @return Person[] + */ + public function searchFromUsername(string $search): array { + $qb = $this->getActorsSelectSql(); + $this->searchInPreferredUsername($qb, $search); + + $accounts = []; + $cursor = $qb->execute(); + while ($data = $cursor->fetch()) { + $accounts[] = $this->parseActorsSelectSql($data); + } + $cursor->closeCursor(); + + return $accounts; + } + } diff --git a/lib/Db/ActorsRequestBuilder.php b/lib/Db/ActorsRequestBuilder.php index f19b44f5..9172681b 100644 --- a/lib/Db/ActorsRequestBuilder.php +++ b/lib/Db/ActorsRequestBuilder.php @@ -76,7 +76,8 @@ class ActorsRequestBuilder extends CoreRequestBuilder { /** @noinspection PhpMethodParametersCountMismatchInspection */ $qb->select( - 'sa.id', 'sa.user_id', 'sa.preferred_username', 'sa.name', 'sa.summary', 'sa.public_key', + 'sa.id', 'sa.user_id', 'sa.preferred_username', 'sa.name', 'sa.summary', + 'sa.public_key', 'sa.private_key', 'sa.creation' ) ->from(self::TABLE_SERVER_ACTORS, 'sa'); diff --git a/lib/Db/CacheActorsRequest.php b/lib/Db/CacheActorsRequest.php index 0c730160..a19cf3b9 100644 --- a/lib/Db/CacheActorsRequest.php +++ b/lib/Db/CacheActorsRequest.php @@ -118,6 +118,30 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { /** * get Cached version of an Actor, based on the UriId * + * @param string $id + * + * @return Person + * @throws CacheActorDoesNotExistException + */ + public function getFromId(string $id): Person { + $qb = $this->getCacheActorsSelectSql(); + $this->limitToIdString($qb, $id); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + if ($data === false) { + throw new CacheActorDoesNotExistException(); + } + + return $this->parseCacheActorsSelectSql($data); + } + + + /** + * get Cached version of an Actor, based on the Account + * * @param string $account * * @return Person @@ -139,5 +163,25 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { } + /** + * @param string $search + * + * @return Person[] + */ + public function searchAccounts(string $search): array { + $qb = $this->getCacheActorsSelectSql(); + $this->searchInAccount($qb, $search); + + $accounts = []; + $cursor = $qb->execute(); + while ($data = $cursor->fetch()) { + $accounts[] = $this->parseCacheActorsSelectSql($data); + } + $cursor->closeCursor(); + + return $accounts; + } + + } diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index d9f13693..5818bcf0 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -118,6 +118,16 @@ class CoreRequestBuilder { $this->limitToDBField($qb, 'preferred_username', $userId); } + /** + * Limit the request to the OwnerId + * + * @param IQueryBuilder $qb + * @param string $username + */ + protected function searchInPreferredUsername(IQueryBuilder &$qb, $username) { + $this->searchInDBField($qb, 'preferred_username', $username . '%'); + } + /** * Limit the request to the OwnerId @@ -152,6 +162,17 @@ class CoreRequestBuilder { } + /** + * Limit the request to the account + * + * @param IQueryBuilder $qb + * @param string $account + */ + protected function searchInAccount(IQueryBuilder &$qb, string $account) { + $this->searchInDBField($qb, 'account', $account . '%'); + } + + /** * Limit the request to the url * @@ -223,6 +244,18 @@ class CoreRequestBuilder { $qb->andWhere($orX); } + /** + * @param IQueryBuilder $qb + * @param string $field + * @param string $value + */ + private function searchInDBField(IQueryBuilder &$qb, string $field, string $value) { + $expr = $qb->expr(); + $pf = ($qb->getType() === QueryBuilder::SELECT) ? $this->defaultSelectAlias . '.' : ''; + $field = $pf . $field; + + $qb->andWhere($expr->like($field, $qb->createNamedParameter($value))); + } // /** // * Left Join service to get info about the serviceId diff --git a/lib/Service/ActivityPub/PersonService.php b/lib/Service/ActivityPub/PersonService.php index 59ded72e..f68a3797 100644 --- a/lib/Service/ActivityPub/PersonService.php +++ b/lib/Service/ActivityPub/PersonService.php @@ -87,7 +87,7 @@ class PersonService implements ICoreService { * * @return Person * @throws RequestException - * @throws Exception + * @throws InvalidResourceException */ public function getFromId(string $id): Person { @@ -111,8 +111,11 @@ class PersonService implements ICoreService { $actor->setPublicKey($this->get('publicKey.publicKeyPem', $object)); $actor->setSharedInbox($this->get('endpoints.sharedInbox', $object)); $actor->setAccount($actor->getPreferredUsername() . '@' . $this->get('_host', $object)); - - $this->save($actor); + try { + $this->save($actor); + } catch (Exception $e) { + throw new InvalidResourceException(); + } } return $actor; @@ -150,6 +153,16 @@ class PersonService implements ICoreService { } + /** + * @param string $search + * + * @return Person[] + */ + public function searchCachedAccounts(string $search): array { + return $this->cacheActorsRequest->searchAccounts($search); + } + + /** * This method is called when saving the Follow object * @@ -163,21 +176,5 @@ class PersonService implements ICoreService { } - // /** - // * @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/ActorService.php b/lib/Service/ActorService.php index 1d293647..0e9ea183 100644 --- a/lib/Service/ActorService.php +++ b/lib/Service/ActorService.php @@ -106,6 +106,16 @@ class ActorService { } + /** + * @param string $search + * + * @return Person[] + */ + public function searchLocalAccounts(string $search): array { + return $this->actorsRequest->searchFromUsername($search); + } + + /**