diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Model/LinkedDataSignature.php | 10 | ||||
-rw-r--r-- | lib/Service/SignatureService.php | 119 |
2 files changed, 125 insertions, 4 deletions
diff --git a/lib/Model/LinkedDataSignature.php b/lib/Model/LinkedDataSignature.php index abf4406d..03009815 100644 --- a/lib/Model/LinkedDataSignature.php +++ b/lib/Model/LinkedDataSignature.php @@ -32,9 +32,12 @@ namespace OCA\Social\Model; use daita\MySmallPhpTools\Traits\TArrayTools; +use JsonLdException; use JsonSerializable; use OCA\Social\Exceptions\LinkedDataSignatureMissingException; use OCA\Social\Model\ActivityPub\ACore; +use OCA\Social\Service\SignatureService; +use stdClass; /** @@ -78,6 +81,7 @@ class LinkedDataSignature implements JsonSerializable { public function __construct() { } + /** * @return string */ @@ -96,6 +100,7 @@ class LinkedDataSignature implements JsonSerializable { return $this; } + /** * @return string */ @@ -305,8 +310,9 @@ class LinkedDataSignature implements JsonSerializable { $res = jsonld_normalize( $object, [ - 'algorithm' => 'URDNA2015', - 'format' => 'application/nquads' + 'algorithm' => 'URDNA2015', + 'format' => 'application/nquads', + 'documentLoader' => [SignatureService::class, 'documentLoader'] ] ); diff --git a/lib/Service/SignatureService.php b/lib/Service/SignatureService.php index 45da8ad4..fff546f6 100644 --- a/lib/Service/SignatureService.php +++ b/lib/Service/SignatureService.php @@ -35,10 +35,13 @@ use daita\MySmallPhpTools\Model\Request; use daita\MySmallPhpTools\Traits\TArrayTools; use DateTime; use Exception; +use JsonLdException; +use OCA\Social\AppInfo\Application; use OCA\Social\Db\ActorsRequest; use OCA\Social\Exceptions\ActorDoesNotExistException; use OCA\Social\Exceptions\InvalidOriginException; use OCA\Social\Exceptions\InvalidResourceException; +use OCA\Social\Exceptions\ItemUnknownException; use OCA\Social\Exceptions\LinkedDataSignatureMissingException; use OCA\Social\Exceptions\RedundancyLimitException; use OCA\Social\Exceptions\RequestContentException; @@ -48,12 +51,16 @@ use OCA\Social\Exceptions\RequestServerException; use OCA\Social\Exceptions\SignatureException; use OCA\Social\Exceptions\SignatureIsGoneException; use OCA\Social\Exceptions\SocialAppConfigException; -use OCA\Social\Exceptions\ItemUnknownException; use OCA\Social\Model\ActivityPub\ACore; use OCA\Social\Model\ActivityPub\Actor\Person; use OCA\Social\Model\LinkedDataSignature; use OCA\Social\Model\RequestQueue; +use OCP\Files\NotFoundException; +use OCP\Files\NotPermittedException; +use OCP\Files\SimpleFS\ISimpleFile; +use OCP\Files\SimpleFS\ISimpleFolder; use OCP\IRequest; +use stdClass; class SignatureService { @@ -256,7 +263,7 @@ class SignatureService { try { $signature->sign(); $object->setSignature($signature); - } catch (LinkedDataSignatureMissingException $e) { + } catch (Exception $e) { } } @@ -412,5 +419,113 @@ class SignatureService { } } + + /** + * @param string $url + * + * @return stdClass + * @throws NotPermittedException + * @throws JsonLdException + */ + public static function documentLoader($url): stdClass { + $recursion = 0; + $x = debug_backtrace(); + if ($x) { + foreach ($x as $n) { + if ($n['function'] === __FUNCTION__) { + $recursion++; + } + } + } + + if ($recursion > 5) { + exit(); + } + + $folder = self::getContextCacheFolder(); + $filename = parse_url($url, PHP_URL_HOST) . parse_url($url, PHP_URL_PATH); + $filename = str_replace('/', '.', $filename) . '.json'; + + try { + $cache = $folder->getFile($filename); + self::updateContextCacheDocument($cache, $url); + + $data = json_decode($cache->getContent()); + } catch (NotFoundException $e) { + $data = self::generateContextCacheDocument($folder, $filename, $url); + } + + return $data; + } + + + /** + * @return ISimpleFolder + * @throws NotPermittedException + */ + private static function getContextCacheFolder(): ISimpleFolder { + $path = 'context'; + + $appData = \OC::$server->getAppDataDir(Application::APP_NAME); + try { + $folder = $appData->getFolder($path); + } catch (NotFoundException $e) { + $folder = $appData->newFolder($path); + } + + return $folder; + } + + + /** + * @param ISimpleFolder $folder + * @param string $filename + * + * @param string $url + * + * @return stdClass + * @throws JsonLdException + * @throws NotPermittedException + */ + private static function generateContextCacheDocument( + ISimpleFolder $folder, string $filename, string $url + ): stdClass { + + try { + $data = jsonld_default_document_loader($url); + $content = json_encode($data); + } catch (JsonLdException $e) { + $context = file_get_contents(__DIR__ . '/../../context/' . $filename); + if (is_bool($context)) { + throw $e; + } + + $content = $context; + $data = json_decode($context); + } + + $cache = $folder->newFile($filename); + $cache->putContent($content); + + return $data; + } + + + /** + * @param ISimpleFile $cache + * @param string $url + * + * @throws NotPermittedException + */ + private static function updateContextCacheDocument(ISimpleFile $cache, string $url) { + if ($cache->getMTime() < (time() - 98765)) { + try { + $data = jsonld_default_document_loader($url); + $cache->putContent(json_encode($data)); + } catch (JsonLdException $e) { + } + } + } + } |