kopia lustrzana https://github.com/nextcloud/social
Merge pull request #1508 from nextcloud/enh/noid/well-known-services
manage multiple well-known servicespull/1511/head
commit
91158956b7
|
@ -1,6 +1,7 @@
|
|||
js/
|
||||
\.idea/
|
||||
node_modules/
|
||||
build/
|
||||
vendor/
|
||||
img/twemoji/
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ declare(strict_types=1);
|
|||
* @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
*
|
||||
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
@ -58,7 +59,7 @@ final class JrdResponse implements IResponse {
|
|||
*
|
||||
* @since 21.0.0
|
||||
*/
|
||||
public function __construct(string $subject, int $httpCode = Http::STATUS_OK) {
|
||||
public function __construct(string $subject = '', int $httpCode = Http::STATUS_OK) {
|
||||
$this->subject = $subject;
|
||||
$this->httpCode = $httpCode;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ namespace OCA\Social\WellKnown;
|
|||
|
||||
use OCA\Social\Db\CacheActorsRequest;
|
||||
use OCA\Social\Exceptions\CacheActorDoesNotExistException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\UnauthorizedFediverseException;
|
||||
use OCA\Social\Service\CacheActorService;
|
||||
use OCA\Social\Service\ConfigService;
|
||||
use OCA\Social\Service\FediverseService;
|
||||
|
@ -55,12 +57,51 @@ class WebfingerHandler implements IHandler {
|
|||
$this->configService = $configService;
|
||||
}
|
||||
|
||||
public function handle(string $service, IRequestContext $context, ?IResponse $previousResponse): ?IResponse {
|
||||
// See https://docs.joinmastodon.org/spec/webfinger/
|
||||
|
||||
$this->fediverseService->jailed();
|
||||
/**
|
||||
* @see https://docs.joinmastodon.org/spec/webfinger/
|
||||
*
|
||||
* @param string $service
|
||||
* @param IRequestContext $context
|
||||
* @param IResponse|null $previousResponse
|
||||
*
|
||||
* @return IResponse|null
|
||||
*/
|
||||
public function handle(
|
||||
string $service,
|
||||
IRequestContext $context,
|
||||
?IResponse $previousResponse
|
||||
): ?IResponse {
|
||||
try {
|
||||
$this->fediverseService->jailed();
|
||||
} catch (UnauthorizedFediverseException $e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (strtolower($service)) {
|
||||
case 'webfinger':
|
||||
return $this->handleWebfinger($context);
|
||||
|
||||
case 'nodeinfo':
|
||||
return $this->handleNodeInfo($context);
|
||||
|
||||
case 'host-meta':
|
||||
return $this->handleHostMeta($context);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* handle request on /.well-known/webfinger
|
||||
*
|
||||
* @param IRequestContext $context
|
||||
*
|
||||
* @return IResponse|null
|
||||
*/
|
||||
public function handleWebfinger(IRequestContext $context): ?IResponse {
|
||||
$subject = $context->getHttpRequest()->getParam('resource');
|
||||
|
||||
if (strpos($subject, 'acct:') === 0) {
|
||||
$subject = substr($subject, 5);
|
||||
}
|
||||
|
@ -68,6 +109,8 @@ class WebfingerHandler implements IHandler {
|
|||
$actor = null;
|
||||
try {
|
||||
$actor = $this->cacheActorService->getFromLocalAccount($subject);
|
||||
} catch (SocialAppConfigException $e) {
|
||||
return null;
|
||||
} catch (CacheActorDoesNotExistException $e) {
|
||||
}
|
||||
|
||||
|
@ -81,7 +124,7 @@ class WebfingerHandler implements IHandler {
|
|||
if ($actor === null || !$actor->isLocal()) {
|
||||
return new JrdResponse('', Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
||||
// ActivityPub profile
|
||||
$href = $this->configService->getSocialUrl() . '@' . $actor->getPreferredUsername();
|
||||
$href = rtrim($href, '/');
|
||||
|
@ -109,4 +152,46 @@ class WebfingerHandler implements IHandler {
|
|||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* handle request on /.well-known/nodeinfo
|
||||
* returns Json
|
||||
*
|
||||
* @param IRequestContext $context
|
||||
*
|
||||
* @return IResponse|null
|
||||
*/
|
||||
private function handleNodeInfo(IRequestContext $context): ?IResponse {
|
||||
$response = new JrdResponse();
|
||||
$response->addLink(
|
||||
'http://nodeinfo.diaspora.software/ns/schema/2.0',
|
||||
null,
|
||||
$this->urlGenerator->linkToRouteAbsolute('social.OAuth.nodeinfo2')
|
||||
);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* handle request on /.well-known/host-meta
|
||||
* returns xml/xrd
|
||||
*
|
||||
* @param IRequestContext $context
|
||||
*
|
||||
* @return IResponse|null
|
||||
*/
|
||||
private function handleHostMeta(IRequestContext $context): ?IResponse {
|
||||
$response = new XrdResponse();
|
||||
try {
|
||||
$url = $this->configService->getCloudUrl(true) . '/.well-known/webfinger?resource={uri}';
|
||||
} catch (SocialAppConfigException $e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$response->addLink('lrdd', $url);
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2022 Maxence Lange <maxence@artificial-owl.com>
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Social\WellKnown;
|
||||
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\AppFramework\Http\TextPlainResponse;
|
||||
use OCP\Http\WellKnown\IResponse;
|
||||
|
||||
final class XrdResponse implements IResponse {
|
||||
private ?string $expires = null;
|
||||
private int $httpCode;
|
||||
|
||||
/** @var mixed[] */
|
||||
private array $links = [];
|
||||
|
||||
public function __construct(int $httpCode = Http::STATUS_OK) {
|
||||
$this->httpCode = $httpCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $expires
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @since 21.0.0
|
||||
*/
|
||||
public function setExpires(string $expires): self {
|
||||
$this->expires = $expires;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function setHttpCode(int $httpCode): self {
|
||||
$this->httpCode = $httpCode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a link
|
||||
*
|
||||
* @param string $rel
|
||||
* @param string $template
|
||||
*
|
||||
* @return XrdResponse
|
||||
*/
|
||||
public function addLink(string $rel, string $template): self {
|
||||
$this->links[] = [
|
||||
'rel' => $rel,
|
||||
'template' => $template
|
||||
];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function toHttpResponse(): Response {
|
||||
$data = [];
|
||||
$data[] = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
$data[] = '<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">';
|
||||
|
||||
foreach ($this->links as $link) {
|
||||
$data[] = ' <Link rel="' . $link['rel'] . '" template="' . $link['template'] . '"/>';
|
||||
}
|
||||
|
||||
$data[] = '</XRD>';
|
||||
|
||||
$response = new TextPlainResponse(implode("\n", $data) . "\n", $this->httpCode);
|
||||
$response->addHeader('Content-Type', 'application/xrd+xml'); // overwrite default header
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
Ładowanie…
Reference in New Issue