summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxence Lange <maxence@artificial-owl.com>2019-06-21 11:36:55 -0100
committerGitHub <noreply@github.com>2019-06-21 11:36:55 -0100
commite97cfb34c8c52a30094388439b5790c5312b55e5 (patch)
tree0d1f773ca6b037e5183abb95c7d247bd250165c1
parent20a4cb0b6f547fc85b3e05cd5a1de247d33ad918 (diff)
parent35389b47af9d5099c675ea4893542e00fce5322c (diff)
Merge pull request #578 from nextcloud/feature/573/request-on-host-meta
request on host-meta
-rw-r--r--composer.lock8
-rw-r--r--lib/Exceptions/HostMetaException.php40
-rw-r--r--lib/Service/AccountService.php5
-rw-r--r--lib/Service/CacheActorService.php4
-rw-r--r--lib/Service/CheckService.php23
-rw-r--r--lib/Service/ConfigService.php30
-rw-r--r--lib/Service/CurlService.php56
-rw-r--r--lib/hostmeta.php61
-rw-r--r--lib/webfinger.php15
9 files changed, 220 insertions, 22 deletions
diff --git a/composer.lock b/composer.lock
index 94cfaf21..199ef46a 100644
--- a/composer.lock
+++ b/composer.lock
@@ -12,12 +12,12 @@
"source": {
"type": "git",
"url": "https://github.com/daita/my-small-php-tools.git",
- "reference": "6e8f346a2ee488655316d1e4139c27417d6b7e4d"
+ "reference": "59516b3d988cb14b49db050df8b6a94290c44298"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/daita/my-small-php-tools/zipball/6e8f346a2ee488655316d1e4139c27417d6b7e4d",
- "reference": "6e8f346a2ee488655316d1e4139c27417d6b7e4d",
+ "url": "https://api.github.com/repos/daita/my-small-php-tools/zipball/59516b3d988cb14b49db050df8b6a94290c44298",
+ "reference": "59516b3d988cb14b49db050df8b6a94290c44298",
"shasum": ""
},
"require": {
@@ -40,7 +40,7 @@
}
],
"description": "My small PHP Tools",
- "time": "2019-05-29T20:52:05+00:00"
+ "time": "2019-06-11T20:45:04+00:00"
},
{
"name": "friendica/json-ld",
diff --git a/lib/Exceptions/HostMetaException.php b/lib/Exceptions/HostMetaException.php
new file mode 100644
index 00000000..9c58ede4
--- /dev/null
+++ b/lib/Exceptions/HostMetaException.php
@@ -0,0 +1,40 @@
+<?php
+declare(strict_types=1);
+
+
+/**
+ * Nextcloud - Social Support
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ * @copyright 2018, 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\Exceptions;
+
+
+use Exception;
+
+
+class HostMetaException extends Exception {
+
+}
+
diff --git a/lib/Service/AccountService.php b/lib/Service/AccountService.php
index d7ff1941..cfe304bf 100644
--- a/lib/Service/AccountService.php
+++ b/lib/Service/AccountService.php
@@ -216,6 +216,7 @@ class AccountService {
}
$this->configService->setCoreValue('public_webfinger', 'social/lib/webfinger.php');
+ $this->configService->setCoreValue('public_host-meta', 'social/lib/hostmeta.php');
$actor = new Person();
$actor->setUserId($userId);
@@ -320,8 +321,8 @@ class AccountService {
/**
- * @throws Exception
* @return int
+ * @throws Exception
*/
public function manageCacheLocalActors(): int {
$update = $this->actorsRequest->getAll();
@@ -337,8 +338,8 @@ class AccountService {
/**
- * @throws Exception
* @return int
+ * @throws Exception
*/
public function blindKeyRotation(): int {
$update = $this->actorsRequest->getAll();
diff --git a/lib/Service/CacheActorService.php b/lib/Service/CacheActorService.php
index e0c989d8..41ec3954 100644
--- a/lib/Service/CacheActorService.php
+++ b/lib/Service/CacheActorService.php
@@ -185,13 +185,15 @@ class CacheActorService {
* @throws CacheActorDoesNotExistException
* @throws InvalidOriginException
* @throws InvalidResourceException
+ * @throws ItemUnknownException
* @throws MalformedArrayException
* @throws RedundancyLimitException
* @throws RequestContentException
- * @throws RetrieveAccountFormatException
* @throws RequestNetworkException
+ * @throws RequestResultNotJsonException
* @throws RequestResultSizeException
* @throws RequestServerException
+ * @throws RetrieveAccountFormatException
* @throws SocialAppConfigException
* @throws ItemUnknownException
* @throws RequestResultNotJsonException
diff --git a/lib/Service/CheckService.php b/lib/Service/CheckService.php
index 47a4a133..3e65a26f 100644
--- a/lib/Service/CheckService.php
+++ b/lib/Service/CheckService.php
@@ -50,17 +50,30 @@ class CheckService {
use TStringTools;
+ const CACHE_PREFIX = 'social_check_';
+
+
+ /** @var ICache */
private $cache;
+
+ /** @var IConfig */
private $config;
+
+ /** @var IClientService */
private $clientService;
+
+ /** @var IRequest */
private $request;
+
+ /** @var IURLGenerator */
private $urlGenerator;
+ /** @var ConfigService */
+ private $configService;
+
/** @var FollowsRequest */
private $followRequest;
- const CACHE_PREFIX = 'social_check_';
-
/**
* CheckService constructor.
@@ -71,10 +84,11 @@ class CheckService {
* @param IRequest $request
* @param IURLGenerator $urlGenerator
* @param FollowsRequest $followRequest
+ * @param ConfigService $configService
*/
public function __construct(
ICache $cache, IConfig $config, IClientService $clientService, IRequest $request,
- IURLGenerator $urlGenerator, FollowsRequest $followRequest
+ IURLGenerator $urlGenerator, FollowsRequest $followRequest, ConfigService $configService
) {
$this->cache = $cache;
$this->config = $config;
@@ -82,6 +96,7 @@ class CheckService {
$this->request = $request;
$this->urlGenerator = $urlGenerator;
$this->followRequest = $followRequest;
+ $this->configService = $configService;
}
@@ -139,6 +154,8 @@ class CheckService {
*
*/
public function checkInstallationStatus() {
+ $this->configService->setCoreValue('public_webfinger', 'social/lib/webfinger.php');
+ $this->configService->setCoreValue('public_host-meta', 'social/lib/hostmeta.php');
$this->checkStatusTableFollows();
}
diff --git a/lib/Service/ConfigService.php b/lib/Service/ConfigService.php
index cf747f6f..0e25ff09 100644
--- a/lib/Service/ConfigService.php
+++ b/lib/Service/ConfigService.php
@@ -51,7 +51,8 @@ class ConfigService {
use TArrayTools;
- const SOCIAL_ADDRESS = 'address';
+ const CLOUD_ADDRESS = 'address';
+ const SOCIAL_ADDRESS = 'social_address';
const SOCIAL_SERVICE = 'service';
const SOCIAL_MAX_SIZE = 'max_size';
const SOCIAL_ACCESS_TYPE = 'access_type';
@@ -64,6 +65,7 @@ class ConfigService {
/** @var array */
public $defaults = [
+ self::CLOUD_ADDRESS => '',
self::SOCIAL_ADDRESS => '',
self::SOCIAL_SERVICE => 1,
self::SOCIAL_MAX_SIZE => 10,
@@ -258,7 +260,7 @@ class ConfigService {
* @param string $cloudAddress
*/
public function setCloudAddress(string $cloudAddress) {
- $this->setAppValue(self::SOCIAL_ADDRESS, $cloudAddress);
+ $this->setAppValue(self::CLOUD_ADDRESS, $cloudAddress);
}
/**
@@ -268,7 +270,7 @@ class ConfigService {
* @throws SocialAppConfigException
*/
public function getCloudAddress(bool $host = false) {
- $address = $this->getAppValue(self::SOCIAL_ADDRESS);
+ $address = $this->getAppValue(self::CLOUD_ADDRESS);
if ($address === '') {
throw new SocialAppConfigException();
}
@@ -295,6 +297,28 @@ class ConfigService {
/**
+ * @param string $address
+ */
+ public function setSocialAddress(string $address) {
+ $this->setAppValue(self::SOCIAL_ADDRESS, $address);
+ }
+
+ /**
+ * @return string
+ * @throws SocialAppConfigException
+ */
+ public function getSocialAddress(): string {
+ $address = $this->getAppValue(self::SOCIAL_ADDRESS);
+
+ if ($address === '') {
+ return $this->getCloudAddress(true);
+ }
+
+ return $address;
+ }
+
+
+ /**
* @param string $path
*
* @return string
diff --git a/lib/Service/CurlService.php b/lib/Service/CurlService.php
index cbea8819..7775baff 100644
--- a/lib/Service/CurlService.php
+++ b/lib/Service/CurlService.php
@@ -37,6 +37,7 @@ use daita\MySmallPhpTools\Traits\TArrayTools;
use daita\MySmallPhpTools\Traits\TPathTools;
use Exception;
use OCA\Social\AP;
+use OCA\Social\Exceptions\HostMetaException;
use OCA\Social\Exceptions\InvalidOriginException;
use OCA\Social\Exceptions\InvalidResourceException;
use OCA\Social\Exceptions\RedundancyLimitException;
@@ -108,7 +109,7 @@ class CurlService {
* @throws SocialAppConfigException
* @throws UnauthorizedFediverseException
*/
- public function webfingerAccount(string $account): array {
+ public function webfingerAccount(string &$account): array {
$account = $this->withoutBeginAt($account);
// we consider an account is like an email
@@ -121,7 +122,13 @@ class CurlService {
throw new InvalidResourceException();
}
- $request = new Request('/.well-known/webfinger');
+ try {
+ $path = $this->hostMeta($host);
+ } catch (HostMetaException $e) {
+ $path = '/.well-known/webfinger';
+ }
+
+ $request = new Request($path);
$request->addData('resource', 'acct:' . $account);
$request->setAddress($host);
@@ -134,11 +141,43 @@ class CurlService {
} else throw $e;
}
+ $subject = $this->get('subject', $result, '');
+ list($type, $temp) = explode(':', $subject, 2);
+ if ($type === 'acct') {
+ $account = $temp;
+ }
+
return $result;
}
/**
+ * @param string $host
+ *
+ * @return string
+ * @throws HostMetaException
+ */
+ public function hostMeta(string &$host): string {
+ $request = new Request('/.well-known/host-meta');
+ $request->setAddress($host);
+
+ try {
+ $result = $this->request($request);
+ } catch (Exception $e) {
+ $this->miscService->log(
+ 'hostMeta Exception - ' . get_class($e) . ' - ' . $e->getMessage(), 0
+ );
+ throw new HostMetaException($e->getMessage());
+ }
+
+ $url = $this->get('Link.@attributes.template', $result, '');
+ $host = parse_url($url, PHP_URL_HOST);
+
+ return parse_url($url, PHP_URL_PATH);
+ }
+
+
+ /**
* @param string $account
*
* @return Person
@@ -156,7 +195,7 @@ class CurlService {
* @throws RequestResultNotJsonException
* @throws UnauthorizedFediverseException
*/
- public function retrieveAccount(string $account): Person {
+ public function retrieveAccount(string &$account): Person {
$result = $this->webfingerAccount($account);
try {
@@ -252,9 +291,16 @@ class CurlService {
}
$this->miscService->log(
- '[>>] request: ' . json_encode($request) . ' - result: ' . $result, 1
+ '[>>] request: ' . json_encode($request) . ' - content-type: '
+ . $request->getContentType() . ' - result: ' . $result, 1
);
+ if (strpos($request->getContentType(), 'application/xrd') === 0) {
+ $xml = simplexml_load_string($result);
+ $result = json_encode($xml, JSON_UNESCAPED_SLASHES);
+ $this->miscService->log('XRD conversion to JSON: ' . $result, 1);
+ }
+
$result = json_decode((string)$result, true);
if (is_array($result)) {
return $result;
@@ -427,6 +473,8 @@ class CurlService {
$this->parseRequestResultCurl($curl, $request);
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+ $contentType = curl_getinfo($curl, CURLINFO_CONTENT_TYPE);
+ $request->setContentType(($contentType === null) ? '' : $contentType);
$request->setResultCode($code);
$this->parseRequestResultCode301($code, $request);
diff --git a/lib/hostmeta.php b/lib/hostmeta.php
new file mode 100644
index 00000000..94dd8413
--- /dev/null
+++ b/lib/hostmeta.php
@@ -0,0 +1,61 @@
+<?php
+declare(strict_types=1);
+
+/**
+ * Nextcloud - Social Support
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Maxence Lange <maxence@artificial-owl.com>
+ * @copyright 2018, 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;
+
+
+use Exception;
+use OC;
+use OCA\Social\Service\ConfigService;
+use OCA\Social\Service\FediverseService;
+
+require_once(__DIR__ . '/../appinfo/autoload.php');
+
+try {
+ $fediverseService = OC::$server->query(FediverseService::class);
+ /** @var ConfigService $configService */
+ $configService = OC::$server->query(ConfigService::class);
+ $fediverseService->jailed();
+
+} catch (Exception $e) {
+ OC::$server->getLogger()
+ ->log(1, 'Exception on hostmeta - ' . $e->getMessage());
+ http_response_code(404);
+ exit;
+}
+
+header('Content-type: application/xdr+xml');
+
+try {
+ $url = $configService->getCloudAddress() . '/.well-known/webfinger?resource={uri}';
+ echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
+ echo '<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">' . "\n";
+ echo ' <Link rel="lrdd" type="application/xrd+xml" template="' . $url . '"/>' . "\n";
+ echo '</XRD>' . "\n";
+} catch (Exceptions\SocialAppConfigException $e) {
+}
diff --git a/lib/webfinger.php b/lib/webfinger.php
index 432b2c0b..8ccbb26d 100644
--- a/lib/webfinger.php
+++ b/lib/webfinger.php
@@ -62,10 +62,15 @@ try {
$fediverseService->jailed();
- if ($configService->getCloudAddress(true) !== $instance) {
- throw new Exception(
- 'instance is ' . $instance . ', expected ' . $configService->getCloudAddress(true)
- );
+ if ($configService->getSocialAddress() !== $instance) {
+
+ if ($configService->getCloudAddress(true) === $instance) {
+ $instance = $configService->getSocialAddress();
+ } else {
+ throw new Exception(
+ 'instance is ' . $instance . ', expected ' . $configService->getSocialAddress()
+ );
+ }
}
$cacheActorService->getFromLocalAccount($username);
@@ -85,7 +90,7 @@ if (substr($href, -1) === '/') {
}
$finger = [
- 'subject' => $subject,
+ 'subject' => 'acct:' . $username . '@' . $instance,
'links' => [
[
'rel' => 'self',