diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 977857d34..62b6b2b71 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -37,6 +37,7 @@ use OCA\Social\Search\UnifiedSearchProvider; use OCA\Social\Service\ConfigService; use OCA\Social\Service\UpdateService; +use OCA\Social\WellKnown\WebFingerHandler; use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; @@ -73,9 +74,7 @@ public function __construct(array $params = []) { */ public function register(IRegistrationContext $context): void { $context->registerSearchProvider(UnifiedSearchProvider::class); - - // TODO: nc21, uncomment - // $context->registerEventListener(WellKnownEvent::class, WellKnownListener::class); + $context->registerWellKnownHandler(WebFingerHandler::class); } diff --git a/lib/Listeners/WellKnownListener.php b/lib/Listeners/WellKnownListener.php deleted file mode 100644 index 8eb18c641..000000000 --- a/lib/Listeners/WellKnownListener.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @copyright 2020, Maxence Lange - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - - -namespace OCA\Social\Listeners; - - -use OC\WellKnown\Event\WellKnownEvent; -use OCA\Social\Exceptions\CacheActorDoesNotExistException; -use OCA\Social\Exceptions\SocialAppConfigException; -use OCA\Social\Exceptions\UnauthorizedFediverseException; -use OCA\Social\Service\WellKnownService; -use OCP\EventDispatcher\Event; -use OCP\EventDispatcher\IEventListener; -use OCP\WellKnown\IWellKnownManager; - - -/** - * Class WellKnownListener - * - * @package OCA\Social\Listeners - */ -class WellKnownListener implements IEventListener { - - - private $wellKnownService; - - - /** - * WellKnownListener constructor. - * - * @param WellKnownService $wellKnownService - */ - public function __construct(WellKnownService $wellKnownService) { - $this->wellKnownService = $wellKnownService; - } - - - /** - * @param Event $event - */ - public function handle(Event $event): void { - if (!$event instanceof WellKnownEvent) { - return; - } - - $wellKnown = $event->getWellKnown(); - if ($wellKnown->getService() === IWellKnownManager::WEBFINGER) { - try { - $this->wellKnownService->webfinger($wellKnown); - } catch (CacheActorDoesNotExistException | SocialAppConfigException | UnauthorizedFediverseException $e) { - } - } - } - -} - diff --git a/lib/Model/WebfingerLink.php b/lib/Model/WebfingerLink.php deleted file mode 100644 index 5e44f5935..000000000 --- a/lib/Model/WebfingerLink.php +++ /dev/null @@ -1,148 +0,0 @@ - - * @copyright 2018, Maxence Lange - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - - -namespace OCA\Social\Model; - -use JsonSerializable; - - -/** - * Class WebfingerLink - * - * @package OCA\Social\Model - */ -class WebfingerLink implements JsonSerializable { - - - /** @var string */ - private $href = ''; - - /** @var string */ - private $rel = ''; - - /** @var string */ - private $template = ''; - - /** @var string */ - private $type = ''; - - - /** - * @return string - */ - public function getHref(): string { - return $this->href; - } - - /** - * @param string $value - * - * @return WebfingerLink - */ - public function setHref(string $value): self { - $this->href = $value; - - return $this; - } - - - /** - * @return string - */ - public function getType(): string { - return $this->type; - } - - /** - * @param string $value - * - * @return WebfingerLink - */ - public function setType(string $value): self { - $this->type = $value; - - return $this; - } - - - /** - * @return string - */ - public function getRel(): string { - return $this->rel; - } - - /** - * @param string $value - * - * @return WebfingerLink - */ - public function setRel(string $value): self { - $this->rel = $value; - - return $this; - } - - - /** - * @return string - */ - public function getTemplate(): string { - return $this->template; - } - - /** - * @param string $value - * - * @return WebfingerLink - */ - public function setTemplate(string $value): self { - $this->template = $value; - - return $this; - } - - - /** - * @return array - */ - public function jsonSerialize(): array { - $data = [ - 'rel' => $this->getRel(), - 'type' => $this->getType(), - 'template' => $this->getTemplate(), - 'href' => $this->getHref() - ]; - - return array_filter($data); - } - -} - diff --git a/lib/Service/WellKnownService.php b/lib/Service/WellKnownService.php deleted file mode 100644 index 2ce5342f7..000000000 --- a/lib/Service/WellKnownService.php +++ /dev/null @@ -1,132 +0,0 @@ - - * @copyright 2018, Maxence Lange - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -namespace OCA\Social\Service; - - -use OC\Webfinger\Event\WebfingerEvent; -use OCA\Social\Db\CacheActorsRequest; -use OCA\Social\Exceptions\CacheActorDoesNotExistException; -use OCA\Social\Exceptions\SocialAppConfigException; -use OCA\Social\Exceptions\UnauthorizedFediverseException; -use OCA\Social\Model\WebfingerLink; -use OCP\IURLGenerator; -use OCP\WellKnown\Model\IWellKnown; - -class WellKnownService { - - - /** @var IURLGenerator */ - private $urlGenerator; - - /** @var CacheActorsRequest */ - private $cacheActorsRequest; - - /** @var CacheActorService */ - private $cacheActorService; - - /** @var FediverseService */ - private $fediverseService; - - /** @var ConfigService */ - private $configService; - - /** @var MiscService */ - private $miscService; - - - /** - * WebfingerService constructor. - * - * @param IURLGenerator $urlGenerator - * @param CacheActorsRequest $cacheActorsRequest - * @param CacheActorService $cacheActorService - * @param FediverseService $fediverseService - * @param ConfigService $configService - * @param MiscService $miscService - */ - public function __construct( - IURLGenerator $urlGenerator, CacheActorsRequest $cacheActorsRequest, - CacheActorService $cacheActorService, FediverseService $fediverseService, - ConfigService $configService, MiscService $miscService - ) { - $this->urlGenerator = $urlGenerator; - $this->cacheActorsRequest = $cacheActorsRequest; - $this->cacheActorService = $cacheActorService; - $this->fediverseService = $fediverseService; - $this->configService = $configService; - $this->miscService = $miscService; - - } - - - /** - * @param IWellKnown $wellKnown - * - * @throws CacheActorDoesNotExistException - * @throws SocialAppConfigException - * @throws UnauthorizedFediverseException - */ - public function webfinger(IWellKnown $wellKnown) { - $this->fediverseService->jailed(); - - $subject = $wellKnown->getSubject(); - - if (strpos($subject, 'acct:') === 0) { - $subject = substr($subject, 5); - } - - try { - $actor = $this->cacheActorService->getFromLocalAccount($subject); - } catch (CacheActorDoesNotExistException $e) { - $actor = $this->cacheActorsRequest->getFromId($subject); - if (!$actor->isLocal()) { - throw new CacheActorDoesNotExistException(); - } - } - - $href = $this->configService->getSocialUrl() . '@' . $actor->getPreferredUsername(); - $href = rtrim($href, '/'); - - $linkPerson = new WebfingerLink(); - $linkPerson->setRel('self'); - $linkPerson->setType('application/activity+json'); - $linkPerson->setHref($href); - - $linkOstatus = new WebfingerLink(); - $linkOstatus->setRel('http://ostatus.org/schema/1.0/subscribe'); - $subscribe = $this->urlGenerator->linkToRouteAbsolute('social.OStatus.subscribe') . '?uri={uri}'; - $linkOstatus->setTemplate($subscribe); - - $wellKnown->addLinkSerialized($linkPerson) - ->addLinkSerialized($linkOstatus); - } - -} - diff --git a/lib/WellKnown/WebFingerHandler.php b/lib/WellKnown/WebFingerHandler.php new file mode 100644 index 000000000..772936fe3 --- /dev/null +++ b/lib/WellKnown/WebFingerHandler.php @@ -0,0 +1,120 @@ + + * + * @author 2020 Christoph Wurst + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +namespace OCA\Social\WellKnown; + +use OCA\Social\Db\CacheActorsRequest; +use OCA\Social\Exceptions\CacheActorDoesNotExistException; +use OCA\Social\Exceptions\SocialAppConfigException; +use OCA\Social\Service\CacheActorService; +use OCA\Social\Service\ConfigService; +use OCA\Social\Service\FediverseService; +use OCP\Http\WellKnown\IHandler; +use OCP\Http\WellKnown\IRequestContext; +use OCP\Http\WellKnown\IResponse; +use OCP\Http\WellKnown\JrdResponse; +use OCP\IURLGenerator; +use function rtrim; +use function strpos; +use function substr; + +class WebFingerHandler implements IHandler { + + /** @var IURLGenerator */ + private $urlGenerator; + + /** @var CacheActorsRequest */ + private $cacheActorsRequest; + + /** @var CacheActorService */ + private $cacheActorService; + + /** @var FediverseService */ + private $fediverseService; + + /** @var ConfigService */ + private $configService; + + public function __construct(IURLGenerator $urlGenerator, + CacheActorsRequest $cacheActorsRequest, + CacheActorService $cacheActorService, + FediverseService $fediverseService, + ConfigService $configService) { + $this->urlGenerator = $urlGenerator; + $this->cacheActorsRequest = $cacheActorsRequest; + $this->cacheActorService = $cacheActorService; + $this->fediverseService = $fediverseService; + $this->configService = $configService; + } + + public function handle(string $service, IRequestContext $context, ?IResponse $previousResponse): ?IResponse { + if ($service !== 'webfinger') { + return $previousResponse; + } + + $this->fediverseService->jailed(); + + $subject = $context->getHttpRequest()->getParam('resource', ''); + + if (strpos($subject, 'acct:') === 0) { + $subject = substr($subject, 5); + } + + try { + $actor = $this->cacheActorService->getFromLocalAccount($subject); + } catch (CacheActorDoesNotExistException $e) { + try { + $actor = $this->cacheActorsRequest->getFromId($subject); + } catch (CacheActorDoesNotExistException $e) { + // Nothing to add, return what was already defined + + return $previousResponse; + } + + if (!$actor->isLocal()) { + // Nothing to add, return what was already defined + + return $previousResponse; + } + } catch (SocialAppConfigException $e) { + // Something isn't right, we can't answer the request at the moment + + return $previousResponse; + } + + $href = rtrim($this->configService->getSocialUrl() . '@' . $actor->getPreferredUsername(), '/'); + $subscribe = $this->urlGenerator->linkToRouteAbsolute('social.OStatus.subscribe') . '?uri={uri}'; + + $response = $previousResponse; + if (!($response instanceof JrdResponse)) { + // We override null or any other types + $response = new JrdResponse($subject); + } + + return $response + ->addLink('self', 'application/activity+json', $href) + ->addLink('http://ostatus.org/schema/1.0/subscribe', null, $subscribe); + } +}