summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxence Lange <maxence@artificial-owl.com>2019-06-21 10:58:10 -0100
committerGitHub <noreply@github.com>2019-06-21 10:58:10 -0100
commit20a4cb0b6f547fc85b3e05cd5a1de247d33ad918 (patch)
tree27deb5ff990ee5dd862db3469e7a2c04d1af15e3
parent74a2f80209733543c48035184c2321158a0e2da3 (diff)
parent177e0a03308bea4cb0cc2449423d4a50af15cb21 (diff)
Merge pull request #586 from nextcloud/rewrite-announce
Better Announce
-rw-r--r--lib/Command/Fediverse.php3
-rw-r--r--lib/Db/CacheActorsRequest.php10
-rw-r--r--lib/Db/CoreRequestBuilder.php13
-rw-r--r--lib/Db/StreamRequest.php145
-rw-r--r--lib/Db/StreamRequestBuilder.php22
-rw-r--r--lib/Interfaces/Activity/AcceptInterface.php19
-rw-r--r--lib/Interfaces/Activity/AddInterface.php16
-rw-r--r--lib/Interfaces/Activity/BlockInterface.php16
-rw-r--r--lib/Interfaces/Activity/CreateInterface.php16
-rw-r--r--lib/Interfaces/Activity/DeleteInterface.php17
-rw-r--r--lib/Interfaces/Activity/LikeInterface.php16
-rw-r--r--lib/Interfaces/Activity/RejectInterface.php16
-rw-r--r--lib/Interfaces/Activity/RemoveInterface.php15
-rw-r--r--lib/Interfaces/Activity/UndoInterface.php15
-rw-r--r--lib/Interfaces/Activity/UpdateInterface.php16
-rw-r--r--lib/Interfaces/Actor/PersonInterface.php35
-rw-r--r--lib/Interfaces/IActivityPubInterface.php19
-rw-r--r--lib/Interfaces/Internal/SocialAppNotificationInterface.php24
-rw-r--r--lib/Interfaces/Object/AnnounceInterface.php80
-rw-r--r--lib/Interfaces/Object/DocumentInterface.php15
-rw-r--r--lib/Interfaces/Object/FollowInterface.php15
-rw-r--r--lib/Interfaces/Object/ImageInterface.php17
-rw-r--r--lib/Interfaces/Object/NoteInterface.php39
-rw-r--r--lib/Migration/Version0002Date20190506000001.php8
-rw-r--r--lib/Migration/Version0002Date20190618000001.php18
-rw-r--r--lib/Model/ActivityPub/ACore.php13
-rw-r--r--lib/Model/ActivityPub/Actor/Person.php78
-rw-r--r--lib/Model/ActivityPub/Item.php36
-rw-r--r--lib/Model/ActivityPub/Object/Announce.php2
-rw-r--r--lib/Model/ActivityPub/Stream.php16
-rw-r--r--lib/Model/LinkedDataSignature.php8
-rw-r--r--lib/Service/AccountService.php2
-rw-r--r--lib/Service/ActivityService.php4
-rw-r--r--lib/Service/BoostService.php47
-rw-r--r--lib/Service/CacheActorService.php1
-rw-r--r--lib/Service/CurlService.php3
-rw-r--r--lib/Service/NoteService.php20
-rw-r--r--lib/Service/SignatureService.php11
-rw-r--r--lib/Service/StreamQueueService.php23
-rw-r--r--lib/Traits/TDetails.php143
40 files changed, 846 insertions, 186 deletions
diff --git a/lib/Command/Fediverse.php b/lib/Command/Fediverse.php
index 0a2dbf6e..ac8ce4ab 100644
--- a/lib/Command/Fediverse.php
+++ b/lib/Command/Fediverse.php
@@ -33,6 +33,7 @@ namespace OCA\Social\Command;
use Exception;
use OC\Core\Command\Base;
+use OCA\Social\Exceptions\SocialAppConfigException;
use OCA\Social\Exceptions\UnauthorizedFediverseException;
use OCA\Social\Service\ConfigService;
use OCA\Social\Service\FediverseService;
@@ -208,6 +209,8 @@ class Fediverse extends Base {
/**
* @param string $address
+ *
+ * @throws SocialAppConfigException
*/
private function testAddress(string $address) {
try {
diff --git a/lib/Db/CacheActorsRequest.php b/lib/Db/CacheActorsRequest.php
index 4abfe820..3867d7bd 100644
--- a/lib/Db/CacheActorsRequest.php
+++ b/lib/Db/CacheActorsRequest.php
@@ -31,6 +31,7 @@ namespace OCA\Social\Db;
use DateTime;
+use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Exception;
use OCA\Social\Exceptions\CacheActorDoesNotExistException;
use OCA\Social\Model\ActivityPub\Actor\Person;
@@ -84,7 +85,7 @@ class CacheActorsRequest extends CacheActorsRequestBuilder {
->setValue('summary', $qb->createNamedParameter($actor->getSummary()))
->setValue('public_key', $qb->createNamedParameter($actor->getPublicKey()))
->setValue('source', $qb->createNamedParameter($actor->getSource()))
- ->setValue('details', $qb->createNamedParameter(json_encode($actor->getDetails())));
+ ->setValue('details', $qb->createNamedParameter(json_encode($actor->getDetailsAll())));
try {
if ($actor->getCreation() > 0) {
@@ -112,7 +113,10 @@ class CacheActorsRequest extends CacheActorsRequestBuilder {
$this->generatePrimaryKey($qb, $actor->getId());
- $qb->execute();
+ try {
+ $qb->execute();
+ } catch (UniqueConstraintViolationException $e) {
+ }
}
@@ -140,7 +144,7 @@ class CacheActorsRequest extends CacheActorsRequestBuilder {
->set('summary', $qb->createNamedParameter($actor->getSummary()))
->set('public_key', $qb->createNamedParameter($actor->getPublicKey()))
->set('source', $qb->createNamedParameter($actor->getSource()))
- ->set('details', $qb->createNamedParameter(json_encode($actor->getDetails())));
+ ->set('details', $qb->createNamedParameter(json_encode($actor->getDetailsAll())));
try {
if ($actor->getCreation() > 0) {
diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php
index a8cb3009..259b0374 100644
--- a/lib/Db/CoreRequestBuilder.php
+++ b/lib/Db/CoreRequestBuilder.php
@@ -652,8 +652,9 @@ class CoreRequestBuilder {
/**
* @param IQueryBuilder $qb
* @param string $fieldActorId
+ * @param string $alias
*/
- protected function leftJoinCacheActors(IQueryBuilder &$qb, string $fieldActorId) {
+ protected function leftJoinCacheActors(IQueryBuilder &$qb, string $fieldActorId, string $alias = '') {
if ($qb->getType() !== QueryBuilder::SELECT) {
return;
}
@@ -661,7 +662,7 @@ class CoreRequestBuilder {
$expr = $qb->expr();
$func = $qb->func();
- $pf = $this->defaultSelectAlias;
+ $pf = ($alias === '') ? $this->defaultSelectAlias : $alias;
$qb->selectAlias('ca.id', 'cacheactor_id')
->selectAlias('ca.type', 'cacheactor_type')
@@ -949,16 +950,16 @@ class CoreRequestBuilder {
try {
$this->parseFollowLeftJoin($data, 'as_follower');
- $actor->addDetailBool('following', true);
+ $actor->setDetailBool('following', true);
} catch (InvalidResourceException $e) {
- $actor->addDetailBool('following', false);
+ $actor->setDetailBool('following', false);
}
try {
$this->parseFollowLeftJoin($data, 'as_followed');
- $actor->addDetailBool('followed', true);
+ $actor->setDetailBool('followed', true);
} catch (InvalidResourceException $e) {
- $actor->addDetailBool('followed', false);
+ $actor->setDetailBool('followed', false);
}
$actor->setCompleteDetails(true);
diff --git a/lib/Db/StreamRequest.php b/lib/Db/StreamRequest.php
index 745b30d3..db16ad95 100644
--- a/lib/Db/StreamRequest.php
+++ b/lib/Db/StreamRequest.php
@@ -32,9 +32,13 @@ namespace OCA\Social\Db;
use daita\MySmallPhpTools\Model\Cache;
use DateTime;
+use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
+use Doctrine\DBAL\Query\QueryBuilder;
use Exception;
use OCA\Social\Exceptions\DateTimeException;
+use OCA\Social\Exceptions\ItemUnknownException;
+use OCA\Social\Exceptions\SocialAppConfigException;
use OCA\Social\Exceptions\StreamNotFoundException;
use OCA\Social\Model\ActivityPub\ACore;
use OCA\Social\Model\ActivityPub\Actor\Person;
@@ -73,7 +77,6 @@ class StreamRequest extends StreamRequestBuilder {
*/
public function save(Stream $stream) {
$qb = $this->saveStream($stream);
-
if ($stream->getType() === Note::TYPE) {
/** @var Note $stream */
$qb->setValue(
@@ -86,7 +89,30 @@ class StreamRequest extends StreamRequestBuilder {
);
}
- $qb->execute();
+ try {
+ $qb->execute();
+ } catch (UniqueConstraintViolationException $e) {
+ }
+ }
+
+
+ /**
+ * @param Stream $stream \
+ *
+ * @return Statement|int
+ */
+ public function update(Stream $stream) {
+ $qb = $this->getStreamUpdateSql();
+
+ $qb->set('details', $qb->createNamedParameter(json_encode($stream->getDetailsAll())));
+ $qb->set(
+ 'cc', $qb->createNamedParameter(
+ json_encode($stream->getCcArray(), JSON_UNESCAPED_SLASHES)
+ )
+ );
+ $this->limitToIdString($qb, $stream->getId());
+
+ return $qb->execute();
}
@@ -100,10 +126,21 @@ class StreamRequest extends StreamRequestBuilder {
$this->limitToIdString($qb, $stream->getId());
- try {
- $qb->execute();
- } catch (UniqueConstraintViolationException $e) {
- }
+ $qb->execute();
+ }
+
+
+ /**
+ * @param string $itemId
+ * @param string $to
+ */
+ public function updateAttributedTo(string $itemId, string $to) {
+ $qb = $this->getStreamUpdateSql();
+ $qb->set('attributed_to', $qb->createNamedParameter($to));
+
+ $this->limitToIdString($qb, $itemId);
+
+ $qb->execute();
}
@@ -176,15 +213,15 @@ class StreamRequest extends StreamRequestBuilder {
/**
- * @param Person $actor
* @param string $type
- *
* @param string $objectId
*
* @return Stream
* @throws StreamNotFoundException
+ * @throws ItemUnknownException
+ * @throws SocialAppConfigException
*/
- public function getStreamByObjectId(Person $actor, string $type, string $objectId): Stream {
+ public function getStreamByObjectId(string $objectId, string $type): Stream {
if ($objectId === '') {
throw new StreamNotFoundException('missing objectId');
};
@@ -192,7 +229,6 @@ class StreamRequest extends StreamRequestBuilder {
$qb = $this->getStreamSelectSql();
$this->limitToObjectId($qb, $objectId);
$this->limitToType($qb, $type);
- $this->limitToAttributedTo($qb, $actor->getId());
$cursor = $qb->execute();
$data = $cursor->fetch();
@@ -200,8 +236,7 @@ class StreamRequest extends StreamRequestBuilder {
if ($data === false) {
throw new StreamNotFoundException(
- 'StreamByObjectId not found - ' . $actor->getId() . ' - ' . $type . ' - '
- . $objectId
+ 'StreamByObjectId not found - ' . $type . ' - ' . $objectId
);
}
@@ -245,11 +280,12 @@ class StreamRequest extends StreamRequestBuilder {
$this->joinFollowing($qb, $actor);
$this->limitPaginate($qb, $since, $limit);
- $this->filterHiddenOnTimeline($qb);
- $this->leftJoinCacheActors($qb, 'attributed_to');
+ $this->leftJoinCacheActors($qb, 'object_id', 'f');
$this->leftJoinStreamAction($qb);
+ $this->filterDuplicate($qb);
+
$streams = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
@@ -357,7 +393,7 @@ class StreamRequest extends StreamRequestBuilder {
$this->limitToRecipient($qb, $actor->getId(), true);
$this->filterRecipient($qb, ACore::CONTEXT_PUBLIC);
$this->filterRecipient($qb, $actor->getFollowers());
- $this->filterHiddenOnTimeline($qb);
+// $this->filterHiddenOnTimeline($qb);
$this->leftJoinCacheActors($qb, 'attributed_to');
@@ -391,11 +427,12 @@ class StreamRequest extends StreamRequestBuilder {
$qb = $this->getStreamSelectSql();
$this->limitPaginate($qb, $since, $limit);
- if ($localOnly) {
- $this->limitToLocal($qb, true);
- }
+// if ($localOnly) {
+ $this->limitToLocal($qb, $localOnly);
+// }
+
+ $this->limitToType($qb, Note::TYPE);
- $this->filterHiddenOnTimeline($qb);
$this->leftJoinCacheActors($qb, 'attributed_to');
$this->leftJoinStreamAction($qb);
@@ -442,7 +479,7 @@ class StreamRequest extends StreamRequestBuilder {
$qb->andWhere($this->exprValueWithinJsonFormat($qb, 'hashtags', '' . $hashtag));
$this->limitPaginate($qb, $since, $limit);
- $this->filterHiddenOnTimeline($qb);
+// $this->filterHiddenOnTimeline($qb);
$this->leftJoinCacheActors($qb, 'attributed_to');
$this->leftJoinStreamAction($qb);
@@ -463,6 +500,8 @@ class StreamRequest extends StreamRequestBuilder {
*
* @return Stream[]
* @throws DateTimeException
+ * @throws ItemUnknownException
+ * @throws SocialAppConfigException
*/
public function getNoteSince(int $since): array {
$qb = $this->getStreamSelectSql();
@@ -561,6 +600,7 @@ class StreamRequest extends StreamRequestBuilder {
->setValue('source', $qb->createNamedParameter($stream->getSource()))
->setValue('activity_id', $qb->createNamedParameter($stream->getActivityId()))
->setValue('object_id', $qb->createNamedParameter($stream->getObjectId()))
+ ->setValue('details', $qb->createNamedParameter(json_encode($stream->getDetailsAll())))
->setValue('cache', $qb->createNamedParameter($cache))
->setValue(
'hidden_on_timeline',
@@ -591,5 +631,70 @@ class StreamRequest extends StreamRequestBuilder {
return $qb;
}
+
+ /**
+ * @param IQueryBuilder $qb
+ * @param Person $actor
+ */
+ private function leftJoinFollowStatus(IQueryBuilder $qb, Person $actor) {
+ if ($qb->getType() !== QueryBuilder::SELECT) {
+ return;
+ }
+
+ $expr = $qb->expr();
+ $func = $qb->func();
+ $pf = $this->defaultSelectAlias . '.';
+
+ $on = $expr->andX();
+ $on->add($this->exprLimitToDBField($qb, 'actor_id', $actor->getId(), false, 'fs'));
+ $on->add($expr->eq($func->lower($pf . 'attributed_to'), $func->lower('fs.object_id')));
+ $on->add($this->exprLimitToDBFieldInt($qb, 'accepted', 1, 'fs'));
+
+ $qb->leftJoin($this->defaultSelectAlias, CoreRequestBuilder::TABLE_FOLLOWS, 'fs', $on);
+ }
+
+
+ /**
+ * @param IQueryBuilder $qb
+ */
+ private function filterDuplicate(IQueryBuilder $qb) {
+ $actor = $this->viewer;
+
+ if ($actor === null) {
+ return;
+ }
+
+ $this->leftJoinFollowStatus($qb, $actor);
+
+ $func = $qb->func();
+ $expr = $qb->expr();
+
+ $filter = $expr->orX();
+ $filter->add($this->exprLimitToDBFieldInt($qb, 'hidden_on_timeline', 0, 's'));
+
+ $follower = $expr->andX();
+ $follower->add(
+ $expr->neq(
+ $func->lower('attributed_to'),
+ $func->lower($qb->createNamedParameter($actor->getId()))
+ )
+ );
+ $follower->add($expr->isNull('fs.id'));
+// $follower->add(
+// $expr->eq(
+// $func->lower('f.object_id'),
+// $func->lower('s.attributed_to')
+// )
+// );
+ // needed ?
+// $follower->add($this->exprLimitToDBField($qb, 'actor_id', $actor->getId(), false, 'f'));
+// $follower->add($this->exprLimitToDBFieldInt($qb, 'accepted', 1, 'f'));
+
+ $filter->add($follower);
+
+ $qb->andWhere($filter);
+ }
+
+
}
diff --git a/lib/Db/StreamRequestBuilder.php b/lib/Db/StreamRequestBuilder.php
index 910d4641..3198887b 100644
--- a/lib/Db/StreamRequestBuilder.php
+++ b/lib/Db/StreamRequestBuilder.php
@@ -39,6 +39,7 @@ use OCA\Social\Exceptions\ItemUnknownException;
use OCA\Social\Exceptions\SocialAppConfigException;
use OCA\Social\Model\ActivityPub\ACore;
use OCA\Social\Model\ActivityPub\Actor\Person;
+use OCA\Social\Model\ActivityPub\Object\Announce;
use OCA\Social\Model\ActivityPub\Stream;
use OCA\Social\Model\InstancePath;
use OCP\DB\QueryBuilder\ICompositeExpression;
@@ -98,7 +99,8 @@ class StreamRequestBuilder extends CoreRequestBuilder {
's.object_id', 's.attributed_to', 's.in_reply_to', 's.source', 's.local',
's.instances', 's.creation', 's.hidden_on_timeline'
)
- ->from(self::TABLE_STREAMS, 's');
+ ->from(self::TABLE_STREAMS, 's')
+ ->groupBy('s.id');
$this->defaultSelectAlias = 's';
@@ -160,19 +162,26 @@ class StreamRequestBuilder extends CoreRequestBuilder {
$func = $qb->func();
$expr = $qb->expr();
+
$filter = $expr->orX();
+ $filter->add($this->exprLimitToDBFieldInt($qb, 'hidden_on_timeline', 0));
+
$filter->add(
$expr->neq(
$func->lower('attributed_to'),
$func->lower($qb->createNamedParameter($actor->getId()))
)
);
- $filter->add(
+
+ $follower = $expr->andX();
+ $follower->add(
$expr->eq(
- 'hidden_on_timeline',
- $qb->createNamedParameter('0')
+ $func->lower('f.object_id'),
+ $func->lower('attributed_to')
)
);
+ $follower->add($this->exprLimitToDBField($qb, 'actor_id', $actor->getId(), false, 'f'));
+ $filter->add($follower);
$qb->andwhere($filter);
}
@@ -188,6 +197,7 @@ class StreamRequestBuilder extends CoreRequestBuilder {
}
$on = $this->exprJoinFollowing($qb, $actor);
+ $qb->selectAlias('f.object_id', 'following_actor_id');
$qb->join($this->defaultSelectAlias, CoreRequestBuilder::TABLE_FOLLOWS, 'f', $on);
}
@@ -431,6 +441,10 @@ class StreamRequestBuilder extends CoreRequestBuilder {
$item->setAction($action);
+ if ($item->getType() === Announce::TYPE) {
+ $item->setAttributedTo($this->get('following_actor_id', $data, ''));
+ }
+
return $item;
}
diff --git a/lib/Interfaces/Activity/AcceptInterface.php b/lib/Interfaces/Activity/AcceptInterface.php
index 5e3aa5fb..fc726028 100644
--- a/lib/Interfaces/Activity/AcceptInterface.php
+++ b/lib/Interfaces/Activity/AcceptInterface.php
@@ -98,12 +98,31 @@ class AcceptInterface implements IActivityPubInterface {
}
+
+ /**
+ * @param ACore $item
+ */
+ public function update(ACore $item) {
+ }
+
+
/**
* @param ACore $item
*/
public function delete(ACore $item) {
}
+
+
+ /**
+ * @param ACore $item
+ * @param string $source
+ */
+ public function event(ACore $item, string $source) {
+ }
+
+
+
/**
* @param ACore $activity
* @param ACore $item
diff --git a/lib/Interfaces/Activity/AddInterface.php b/lib/Interfaces/Activity/AddInterface.php
index 706460ab..8aa7da89 100644
--- a/lib/Interfaces/Activity/AddInterface.php
+++ b/lib/Interfaces/Activity/AddInterface.php
@@ -101,9 +101,25 @@ class AddInterface implements IActivityPubInterface {
/**
* @param ACore $item
*/
+ public function update(ACore $item) {
+ }
+
+
+ /**
+ * @param ACore $item
+ */
public function delete(ACore $item) {
}
+
+ /**
+ * @param ACore $item
+ * @param string $source
+ */
+ public function event(ACore $item, string $source) {
+ }
+
+
/**
* @param ACore $activity
* @param ACore $item
diff --git a/lib/Interfaces/Activity/BlockInterface.php b/lib/Interfaces/Activity/BlockInterface.php
index 4bc2f792..3fe46f94 100644
--- a/lib/Interfaces/Activity/BlockInterface.php
+++ b/lib/Interfaces/Activity/BlockInterface.php
@@ -101,9 +101,25 @@ class BlockInterface implements IActivityPubInterface {
/**
* @param ACore $item
*/
+ public function update(ACore $item) {
+ }
+
+
+ /**
+ * @param ACore $item
+ */
public function delete(ACore $item) {
}
+
+ /**
+ * @param ACore $item
+ * @param string $source
+ */
+ public function event(ACore $item, string $source) {
+ }
+
+
/**
* @param ACore $activity
* @param ACore $item
diff --git a/lib/Interfaces/Activity/CreateInterface.php b/lib/Interfaces/Activity/CreateInterface.php
index e7a72d32..a625655b 100644
--- a/lib/Interfaces/Activity/CreateInterface.php
+++ b/lib/Interfaces/Activity/CreateInterface.php
@@ -101,9 +101,25 @@ class CreateInterface implements IActivityPubInterface {
/**
* @param ACore $item
*/
+ public function update(ACore $item) {
+ }
+
+
+ /**
+ * @param ACore $item
+ */
public function delete(ACore $item) {
}
+
+ /**
+ * @param ACore $item
+ * @param string $source
+ */
+ public function event(ACore $item, string $source) {
+ }
+
+
/**
* @param ACore $activity
* @param ACore $item
diff --git a/lib/Interfaces/Activity/DeleteInterface.php b/lib/Interfaces/Activity/DeleteInterface.php
index 9b631f4d..6f86d8d0 100644
--- a/lib/Interfaces/Activity/DeleteInterface.php
+++ b/lib/Interfaces/Activity/DeleteInterface.php
@@ -128,14 +128,29 @@ class DeleteInterface implements IActivityPubInterface {
/**
* @param ACore $item
*/
+ public function save(ACore $item) {
+ }
+
+
+ /**
+ * @param ACore $item
+ */
+ public function update(ACore $item) {
+ }
+
+
+ /**
+ * @param ACore $item
+ */
public function delete(ACore $item) {
}
/**
* @param ACore $item
+ * @param string $source
*/
- public function save(ACore $item) {
+ public function event(ACore $item, string $source) {
}
diff --git a/lib/Interfaces/Activity/LikeInterface.php b/lib/Interfaces/Activity/LikeInterface.php
index d1e78abc..fba4a6e3 100644
--- a/lib/Interfaces/Activity/LikeInterface.php
+++ b/lib/Interfaces/Activity/LikeInterface.php
@@ -101,9 +101,25 @@ class LikeInterface implements IActivityPubInterface {
/**
* @param ACore $item
*/
+ public function update(ACore $item) {
+ }
+
+
+ /**
+ * @param ACore $item
+ */
public function delete(ACore $item) {
}
+
+ /**
+ * @param ACore $item
+ * @param string $source
+ */
+ public function event(ACore $item, string $source) {
+ }
+
+
/**
* @param ACore $activity
* @param ACore $item
diff --git a/lib/Interfaces/Activity/RejectInterface.php b/lib/Interfaces/Activity/RejectInterface.php
index be46e6d3..6f21ba1a 100644
--- a/