From dd30d98cac596cddcbf4a9f56a88807c8c4fe356 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Wed, 2 Jan 2019 10:20:11 -0100 Subject: [PATCH] refresh keys after 7 days Signed-off-by: Maxence Lange --- lib/Command/CacheRefresh.php | 3 +++ lib/Cron/Cache.php | 5 +++++ lib/Db/ActorsRequest.php | 28 +++++++++++++++++++++++++- lib/Model/ActivityPub/Actor/Person.php | 10 +++++++-- lib/Service/AccountService.php | 25 +++++++++++++++++++++++ 5 files changed, 68 insertions(+), 3 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 @@ -94,6 +94,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())); @@ -94,6 +103,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 * 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; + } + + }