diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index 47461ef4..0fd2cadd 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -154,7 +154,7 @@ class CoreRequestBuilder { /** - * Limit the request to the ServiceId + * Limit the request to the ActorId * * @param IQueryBuilder $qb * @param string $actorId @@ -164,6 +164,17 @@ class CoreRequestBuilder { } + /** + * Limit the request to the FollowId + * + * @param IQueryBuilder $qb + * @param string $followId + */ + protected function limitToFollowId(IQueryBuilder &$qb, string $followId) { + $this->limitToDBField($qb, 'follow_id', $followId); + } + + /** * Limit the request to the ServiceId * diff --git a/lib/Db/FollowsRequest.php b/lib/Db/FollowsRequest.php index a0eddcd2..ea9ae38e 100644 --- a/lib/Db/FollowsRequest.php +++ b/lib/Db/FollowsRequest.php @@ -95,6 +95,27 @@ class FollowsRequest extends FollowsRequestBuilder { } + /** + * @param string $followId + * + * @return Follow[] + */ + public function getByFollowId(string $followId): array { + $qb = $this->getFollowsSelectSql(); + $this->limitToFollowId($qb, $followId); + $this->leftJoinCacheActors($qb, 'actor_id'); + + $follows = []; + $cursor = $qb->execute(); + while ($data = $cursor->fetch()) { + $follows[] = $this->parseFollowsSelectSql($data); + } + $cursor->closeCursor(); + + return $follows; + } + + /** * @param Follow $follow */ diff --git a/lib/Db/FollowsRequestBuilder.php b/lib/Db/FollowsRequestBuilder.php index b50e5e9c..1947dd4c 100644 --- a/lib/Db/FollowsRequestBuilder.php +++ b/lib/Db/FollowsRequestBuilder.php @@ -32,6 +32,7 @@ namespace OCA\Social\Db; use daita\MySmallPhpTools\Traits\TArrayTools; +use OCA\Social\Exceptions\InvalidResourceException; use OCA\Social\Model\ActivityPub\Follow; use OCP\DB\QueryBuilder\IQueryBuilder; @@ -82,7 +83,7 @@ class FollowsRequestBuilder extends CoreRequestBuilder { $qb = $this->dbConnection->getQueryBuilder(); /** @noinspection PhpMethodParametersCountMismatchInspection */ - $qb->select('f.id', 'f.actor_id', 'f.object_id', 'f.creation') + $qb->select('f.id', 'f.actor_id', 'f.object_id', 'f.follow_id', 'f.creation') ->from(self::TABLE_SERVER_FOLLOWS, 'f'); $this->defaultSelectAlias = 'f'; @@ -114,6 +115,14 @@ class FollowsRequestBuilder extends CoreRequestBuilder { $follow->setId($data['id']) ->setActorId($data['actor_id']) ->setObjectId($data['object_id']); + $follow->setFollowId($data['follow_id']); + + try { + $actor = $this->parseCacheActorsLeftJoin($data); + $follow->setCompleteDetails(true); + $follow->setActor($actor); + } catch (InvalidResourceException $e) { + } return $follow; } diff --git a/lib/Model/ActivityPub/Follow.php b/lib/Model/ActivityPub/Follow.php index 06c48dfd..c7818826 100644 --- a/lib/Model/ActivityPub/Follow.php +++ b/lib/Model/ActivityPub/Follow.php @@ -45,6 +45,10 @@ class Follow extends ACore implements JsonSerializable { const TYPE = 'Follow'; + /** @var string */ + private $followId = ''; + + /** * Follow constructor. * @@ -57,6 +61,25 @@ class Follow extends ACore implements JsonSerializable { } + /** + * @return string + */ + public function getFollowId(): string { + return $this->followId; + } + + /** + * @param string $followId + * + * @return Follow + */ + public function setFollowId(string $followId): Follow { + $this->followId = $followId; + + return $this; + } + + /** * @param array $data */ diff --git a/lib/Service/ActivityPub/FollowService.php b/lib/Service/ActivityPub/FollowService.php index 80ea5fd6..4b19309a 100644 --- a/lib/Service/ActivityPub/FollowService.php +++ b/lib/Service/ActivityPub/FollowService.php @@ -33,6 +33,7 @@ namespace OCA\Social\Service\ActivityPub; use Exception; use OCA\Social\Db\FollowsRequest; +use OCA\Social\Exceptions\ActorDoesNotExistException; use OCA\Social\Exceptions\FollowDoesNotExistException; use OCA\Social\Exceptions\RequestException; use OCA\Social\Exceptions\SocialAppConfigException; @@ -97,6 +98,7 @@ class FollowService implements ICoreService { * * @throws RequestException * @throws SocialAppConfigException + * @throws ActorDoesNotExistException */ public function followAccount(Person $actor, string $account) { $remoteActor = $this->personService->getFromAccount($account); @@ -111,8 +113,10 @@ class FollowService implements ICoreService { $this->miscService->log('CREATE NEW ONE !'); $this->followsRequest->save($follow); - $follow->addInstancePath(new InstancePath($remoteActor->getInbox())); - $this->activityService->manageRequest($follow, ActivityService::REQUEST_INBOX); + $follow->addInstancePath( + new InstancePath($remoteActor->getInbox(), InstancePath::TYPE_INBOX) + ); + $this->activityService->manageRequest($follow); } } @@ -157,15 +161,18 @@ class FollowService implements ICoreService { $remoteActor = $this->personService->getFromId($follow->getActorId()); $accept = new Accept(); - $accept->setId($follow->getObjectId() . '#accepts/follows/1234'); + // TODO: improve the generation of the Id + $accept->setId($follow->getObjectId() . '#accepts/follows/' . rand(1000, 100000000)); $accept->setActorId($follow->getObjectId()); $accept->setObject($follow); - $accept->addInstancePath(new InstancePath($remoteActor->getInbox())); + $accept->addInstancePath( + new InstancePath($remoteActor->getInbox(), InstancePath::TYPE_INBOX) + ); $follow->setParent($accept); - $this->activityService->manageRequest($accept, ActivityService::REQUEST_INBOX); + $this->activityService->manageRequest($accept); $this->followsRequest->accepted($follow); } catch (Exception $e) { } @@ -186,8 +193,12 @@ class FollowService implements ICoreService { try { $this->followsRequest->getByPersons($follow->getActorId(), $follow->getObjectId()); } catch (FollowDoesNotExistException $e) { - $this->followsRequest->save($follow); - $this->confirmFollowRequest($follow); + $actor = $this->personService->getFromId($follow->getObjectId()); + if ($actor->isLocal()) { + $follow->setFollowId($actor->getFollowers()); + $this->followsRequest->save($follow); + $this->confirmFollowRequest($follow); + } } } else { $parent = $follow->getParent();