summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Command/CacheRefresh.php3
-rw-r--r--lib/Cron/Cache.php5
-rw-r--r--lib/Db/ActorsRequest.php28
-rw-r--r--lib/Db/CacheActorsRequest.php40
-rw-r--r--lib/Interfaces/Actor/PersonInterface.php11
-rw-r--r--lib/Model/ActivityPub/Actor/Person.php10
-rw-r--r--lib/Service/AccountService.php25
-rw-r--r--lib/Service/ActorService.php20
-rw-r--r--lib/Service/CacheActorService.php1
-rw-r--r--lib/Service/SignatureService.php24
10 files changed, 151 insertions, 16 deletions
diff --git a/lib/Command/CacheRefresh.php b/lib/Command/CacheRefresh.php
index 413e958f..c90355a3 100644
--- a/lib/Command/CacheRefresh.php
+++ b/lib/Command/CacheRefresh.php
@@ -102,6 +102,9 @@ class CacheRefresh extends Base {
*/
protected function execute(InputInterface $input, OutputInterface $output) {
+ $result = $this->actorService->blindKeyRotation();
+ $output->writeLn($result . ' key pairs refreshed');
+
$result = $this->actorService->manageCacheLocalActors();
$output->writeLn($result . ' local accounts regenerated');
diff --git a/lib/Cron/Cache.php b/lib/Cron/Cache.php
index fdaae753..ed7d2ee4 100644
--- a/lib/Cron/Cache.php
+++ b/lib/Cron/Cache.php
@@ -95,6 +95,11 @@ class Cache extends TimedJob {
private function manageCache() {
try {
+ $this->accountService->blindKeyRotation();
+ } catch (Exception $e) {
+ }
+
+ try {
$this->accountService->manageCacheLocalActors();
} catch (Exception $e) {
}
diff --git a/lib/Db/ActorsRequest.php b/lib/Db/ActorsRequest.php
index be241ab4..cedb6bab 100644
--- a/lib/Db/ActorsRequest.php
+++ b/lib/Db/ActorsRequest.php
@@ -30,11 +30,13 @@ declare(strict_types=1);
namespace OCA\Social\Db;
+use DateTime;
use OCA\Social\Exceptions\ActorDoesNotExistException;
use OCA\Social\Exceptions\SocialAppConfigException;
use OCA\Social\Model\ActivityPub\Actor\Person;
use OCA\Social\Service\ConfigService;
use OCA\Social\Service\MiscService;
+use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
class ActorsRequest extends ActorsRequestBuilder {
@@ -77,7 +79,11 @@ class ActorsRequest extends ActorsRequestBuilder {
'preferred_username', $qb->createNamedParameter($actor->getPreferredUsername())
)
->setValue('public_key', $qb->createNamedParameter($actor->getPublicKey()))
- ->setValue('private_key', $qb->createNamedParameter($actor->getPrivateKey()));
+ ->setValue('private_key', $qb->createNamedParameter($actor->getPrivateKey()))
+ ->setValue(
+ 'creation',
+ $qb->createNamedParameter(new DateTime('now'), IQueryBuilder::PARAM_DATE)
+ );
$qb->execute();
@@ -85,6 +91,9 @@ class ActorsRequest extends ActorsRequestBuilder {
}
+ /**
+ * @param Person $actor
+ */
public function update(Person $actor) {
$qb = $this->getActorsUpdateSql();
$qb->set('avatar_version', $qb->createNamedParameter($actor->getAvatarVersion()));
@@ -95,6 +104,23 @@ class ActorsRequest extends ActorsRequestBuilder {
/**
+ * @param Person $actor
+ */
+ public function refreshKeys(Person $actor) {
+ $qb = $this->getActorsUpdateSql();
+ $qb->set('public_key', $qb->createNamedParameter($actor->getPublicKey()))
+ ->set('private_key', $qb->createNamedParameter($actor->getPrivateKey()))
+ ->set(
+ 'creation',
+ $qb->createNamedParameter(new DateTime('now'), IQueryBuilder::PARAM_DATE)
+ );
+ $this->limitToIdString($qb, $actor->getId());
+
+ $qb->execute();
+ }
+
+
+ /**
* return Actor from database based on the username
*
* @param string $username
diff --git a/lib/Db/CacheActorsRequest.php b/lib/Db/CacheActorsRequest.php
index 7fb7ec5c..bca8b39d 100644
--- a/lib/Db/CacheActorsRequest.php
+++ b/lib/Db/CacheActorsRequest.php
@@ -103,6 +103,46 @@ class CacheActorsRequest extends CacheActorsRequestBuilder {
/**
+ * insert cache about an Actor in database.
+ *
+ * @param Person $actor
+ */
+ public function update(Person $actor) {
+ $qb = $this->getCacheActorsUpdateSql();
+ $qb->set('account', $qb->createNamedParameter($actor->getAccount()))
+ ->set('following', $qb->createNamedParameter($actor->getFollowing()))
+ ->set('followers', $qb->createNamedParameter($actor->getFollowers()))
+ ->set('inbox', $qb->createNamedParameter($actor->getInbox()))
+ ->set('shared_inbox', $qb->createNamedParameter($actor->getSharedInbox()))
+ ->set('outbox', $qb->createNamedParameter($actor->getOutbox()))
+ ->set('featured', $qb->createNamedParameter($actor->getFeatured()))
+ ->set('url', $qb->createNamedParameter($actor->getUrl()))
+ ->set('preferred_username', $qb->createNamedParameter($actor->getPreferredUsername()))
+ ->set('name', $qb->createNamedParameter($actor->getName()))
+ ->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(
+ 'creation',
+ $qb->createNamedParameter(new DateTime('now'), IQueryBuilder::PARAM_DATE)
+ );
+
+ if ($actor->gotIcon()) {
+ $iconId = $actor->getIcon()
+ ->getId();
+ } else {
+ $iconId = $actor->getIconId();
+ }
+ $qb->set('icon_id', $qb->createNamedParameter($iconId));
+
+ $this->limitToIdString($qb, $actor->getId());
+
+ $qb->execute();
+ }
+
+
+ /**
* get Cached version of an Actor, based on the UriId
*
* @param string $id
diff --git a/lib/Interfaces/Actor/PersonInterface.php b/lib/Interfaces/Actor/PersonInterface.php
index 9dfe83cd..acea191f 100644
--- a/lib/Interfaces/Actor/PersonInterface.php
+++ b/lib/Interfaces/Actor/PersonInterface.php
@@ -110,7 +110,9 @@ class PersonInterface implements IActivityPubInterface {
*/
public function getItemById(string $id): ACore {
try {
- return $this->cacheActorsRequest->getFromId($id);
+ $actor = $this->cacheActorsRequest->getFromId($id);
+
+ return $actor;
} catch (CacheActorDoesNotExistException $e) {
throw new ItemNotFoundException();
}
@@ -122,7 +124,12 @@ class PersonInterface implements IActivityPubInterface {
*/
public function save(ACore $person) {
/** @var Person $person */
- $this->actorService->save($person);
+ try {
+ $this->getItemById($person->getId());
+ $this->actorService->update($person);
+ } catch (ItemNotFoundException $e) {
+ $this->actorService->save($person);
+ }
}
diff --git a/lib/Model/ActivityPub/Actor/Person.php b/lib/Model/ActivityPub/Actor/Person.php
index 5d215fda..6383ca03 100644
--- a/lib/Model/ActivityPub/Actor/Person.php
+++ b/lib/Model/ActivityPub/Actor/Person.php
@@ -31,6 +31,7 @@ declare(strict_types=1);
namespace OCA\Social\Model\ActivityPub\Actor;
+use DateTime;
use JsonSerializable;
use OCA\Social\Exceptions\UrlCloudException;
use OCA\Social\Model\ActivityPub\ACore;
@@ -474,7 +475,12 @@ class Person extends ACore implements JsonSerializable {
*/
public function importFromDatabase(array $data) {
parent::importFromDatabase($data);
- $this->setPreferredUsername($this->validate(self::AS_USERNAME, 'preferred_username', $data, ''))
+
+ $dTime = new DateTime($this->get('creation', $data, 'yesterday'));
+
+ $this->setPreferredUsername(
+ $this->validate(self::AS_USERNAME, 'preferred_username', $data, '')
+ )
->setName($this->validate(self::AS_USERNAME, 'name', $data, ''))
->setAccount($this->validate(self::AS_ACCOUNT, 'account', $data, ''))
->setPublicKey($this->get('public_key', $data, ''))
@@ -486,7 +492,7 @@ class Person extends ACore implements JsonSerializable {
->setSharedInbox($this->validate(self::AS_URL, 'shared_inbox', $data, ''))
->setFeatured($this->validate(self::AS_URL, 'featured', $data, ''))
->setDetails($this->getArray('details', $data, []))
- ->setCreation($this->getInt('creation', $data, 0));
+ ->setCreation($dTime->getTimestamp());
}
diff --git a/lib/Service/AccountService.php b/lib/Service/AccountService.php
index 62b183e2..ff868350 100644
--- a/lib/Service/AccountService.php
+++ b/lib/Service/AccountService.php
@@ -53,6 +53,9 @@ use OCP\IUserManager;
class AccountService {
+ const KEY_PAIR_LIFESPAN = 7;
+
+
use TArrayTools;
@@ -310,4 +313,26 @@ class AccountService {
}
+ /**
+ * @throws Exception
+ * @return int
+ */
+ public function blindKeyRotation(): int {
+ $update = $this->actorsRequest->getAll();
+ $count = 0;
+ foreach ($update as $actor) {
+ try {
+ if ($actor->getCreation() < (time() - (self::KEY_PAIR_LIFESPAN * 3600 * 24))) {
+ $this->signatureService->generateKeys($actor);
+ $this->actorsRequest->refreshKeys($actor);
+ $count++;
+ }
+ } catch (Exception $e) {
+ }
+ }
+
+ return $count;
+ }
+
+
}
diff --git a/lib/Service/ActorService.php b/lib/Service/ActorService.php
index 6b2438f7..8dea61bd 100644
--- a/lib/Service/ActorService.php
+++ b/lib/Service/ActorService.php
@@ -124,6 +124,24 @@ class ActorService {
* @param Person $actor
*/
public function save(Person $actor) {
+ $this->cacheDocumentIfNeeded($actor);
+ $this->cacheActorsRequest->save($actor);
+ }
+
+
+ /**
+ * @param Person $actor
+ */
+ public function update(Person $actor) {
+ $this->cacheDocumentIfNeeded($actor);
+ $this->cacheActorsRequest->update($actor);
+ }
+
+
+ /**
+ * @param Person $actor
+ */
+ private function cacheDocumentIfNeeded(Person $actor) {
if ($actor->gotIcon()) {
try {
$icon = $this->cacheDocumentsRequest->getBySource(
@@ -135,8 +153,6 @@ class ActorService {
$this->cacheDocumentsRequest->save($actor->getIcon());
}
}
-
- $this->cacheActorsRequest->save($actor);
}
}
diff --git a/lib/Service/CacheActorService.php b/lib/Service/CacheActorService.php
index 07babd87..d4e4473f 100644
--- a/lib/Service/CacheActorService.php
+++ b/lib/Service/CacheActorService.php
@@ -130,7 +130,6 @@ class CacheActorService {
try {
if ($refresh) {
- $this->cacheActorsRequest->deleteFromId($id);
throw new CacheActorDoesNotExistException();
}
diff --git a/lib/Service/SignatureService.php b/lib/Service/SignatureService.php
index 2b693b1b..4e328ec1 100644
--- a/lib/Service/SignatureService.php
+++ b/lib/Service/SignatureService.php
@@ -214,13 +214,19 @@ class SignatureService {
$signature = new LinkedDataSignature();
$signature->import(json_decode($object->getSource(), true));
$signature->setPublicKey($this->retrieveKey($actorId));
- if ($signature->verify()) {
- $object->setOrigin(
- $this->getKeyOrigin($actorId), SignatureService::ORIGIN_SIGNATURE
- );
+ if (!$signature->verify()) {
+ $signature->setPublicKey($this->retrieveKey($actorId, true));
+ }
- return true;
+ if (!$signature->verify()) {
+ return false;
}
+
+ $object->setOrigin(
+ $this->getKeyOrigin($actorId), SignatureService::ORIGIN_SIGNATURE
+ );
+
+ return true;
} catch (LinkedDataSignatureMissingException $e) {
}
@@ -345,7 +351,9 @@ class SignatureService {
/**
- * @param $keyId
+ * @param string $keyId
+ *
+ * @param bool $refresh
*
* @return string
* @throws InvalidOriginException
@@ -359,8 +367,8 @@ class SignatureService {
* @throws SocialAppConfigException
* @throws ItemUnknownException
*/
- private function retrieveKey($keyId): string {
- $actor = $this->cacheActorService->getFromId($keyId);
+ private function retrieveKey(string $keyId, bool $refresh = false): string {
+ $actor = $this->cacheActorService->getFromId($keyId, $refresh);
return $actor->getPublicKey();
}