aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
authorRobin Appelman <robin@icewind.nl>2017-02-09 14:54:32 +0100
committerGitHub <noreply@github.com>2017-02-09 14:54:32 +0100
commitbf88060a98ce397768d4afa7935b80751e4533f8 (patch)
tree6baaf10832fa68999eea01ab3df5241fdd3ece0a /lib/private
parent4a5a3681d921adad8c4cb5bb29180514446ea2b9 (diff)
parent0d8d658b7e3885d92103a6e6248b37863f9acf1b (diff)
downloadnextcloud-server-bf88060a98ce397768d4afa7935b80751e4533f8.tar.gz
nextcloud-server-bf88060a98ce397768d4afa7935b80751e4533f8.zip
Merge pull request #3297 from nextcloud/cloud-id-resolve
Add a single public api for resolving a cloud id to a user and remote and back
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/Federation/CloudId.php76
-rw-r--r--lib/private/Federation/CloudIdManager.php109
-rw-r--r--lib/private/Server.php13
-rw-r--r--lib/private/Share/Helper.php42
-rw-r--r--lib/private/Share20/ProviderFactory.php6
-rw-r--r--lib/private/User/User.php3
6 files changed, 209 insertions, 40 deletions
diff --git a/lib/private/Federation/CloudId.php b/lib/private/Federation/CloudId.php
new file mode 100644
index 00000000000..6ba4ff9166b
--- /dev/null
+++ b/lib/private/Federation/CloudId.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017, Robin Appelman <robin@icewind.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Federation;
+
+use OCP\Federation\ICloudId;
+
+class CloudId implements ICloudId {
+ /** @var string */
+ private $id;
+ /** @var string */
+ private $user;
+ /** @var string */
+ private $remote;
+
+ /**
+ * CloudId constructor.
+ *
+ * @param string $id
+ * @param string $user
+ * @param string $remote
+ */
+ public function __construct($id, $user, $remote) {
+ $this->id = $id;
+ $this->user = $user;
+ $this->remote = $remote;
+ }
+
+ /**
+ * The full remote cloud id
+ *
+ * @return string
+ */
+ public function getId() {
+ return $this->id;
+ }
+
+ public function getDisplayId() {
+ return str_replace('https://', '', str_replace('http://', '', $this->getId()));
+ }
+
+ /**
+ * The username on the remote server
+ *
+ * @return string
+ */
+ public function getUser() {
+ return $this->user;
+ }
+
+ /**
+ * The base address of the remote server
+ *
+ * @return string
+ */
+ public function getRemote() {
+ return $this->remote;
+ }
+}
diff --git a/lib/private/Federation/CloudIdManager.php b/lib/private/Federation/CloudIdManager.php
new file mode 100644
index 00000000000..45cc69b306e
--- /dev/null
+++ b/lib/private/Federation/CloudIdManager.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017, Robin Appelman <robin@icewind.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Federation;
+
+use OCP\Federation\ICloudId;
+use OCP\Federation\ICloudIdManager;
+
+class CloudIdManager implements ICloudIdManager {
+ /**
+ * @param string $cloudId
+ * @return ICloudId
+ */
+ public function resolveCloudId($cloudId) {
+ // TODO magic here to get the url and user instead of just splitting on @
+
+ if (!$this->isValidCloudId($cloudId)) {
+ throw new \InvalidArgumentException('Invalid cloud id');
+ }
+
+ // Find the first character that is not allowed in user names
+ $id = $this->fixRemoteURL($cloudId);
+ $posSlash = strpos($id, '/');
+ $posColon = strpos($id, ':');
+
+ if ($posSlash === false && $posColon === false) {
+ $invalidPos = strlen($id);
+ } else if ($posSlash === false) {
+ $invalidPos = $posColon;
+ } else if ($posColon === false) {
+ $invalidPos = $posSlash;
+ } else {
+ $invalidPos = min($posSlash, $posColon);
+ }
+
+ // Find the last @ before $invalidPos
+ $pos = $lastAtPos = 0;
+ while ($lastAtPos !== false && $lastAtPos <= $invalidPos) {
+ $pos = $lastAtPos;
+ $lastAtPos = strpos($id, '@', $pos + 1);
+ }
+
+ if ($pos !== false) {
+ $user = substr($id, 0, $pos);
+ $remote = substr($id, $pos + 1);
+ if (!empty($user) && !empty($remote)) {
+ return new CloudId($id, $user, $remote);
+ }
+ }
+ throw new \InvalidArgumentException('Invalid cloud id');
+ }
+
+ /**
+ * @param string $user
+ * @param string $remote
+ * @return CloudId
+ */
+ public function getCloudId($user, $remote) {
+ // TODO check what the correct url is for remote (asking the remote)
+ return new CloudId($user. '@' . $remote, $user, $remote);
+ }
+
+ /**
+ * Strips away a potential file names and trailing slashes:
+ * - http://localhost
+ * - http://localhost/
+ * - http://localhost/index.php
+ * - http://localhost/index.php/s/{shareToken}
+ *
+ * all return: http://localhost
+ *
+ * @param string $remote
+ * @return string
+ */
+ protected function fixRemoteURL($remote) {
+ $remote = str_replace('\\', '/', $remote);
+ if ($fileNamePosition = strpos($remote, '/index.php')) {
+ $remote = substr($remote, 0, $fileNamePosition);
+ }
+ $remote = rtrim($remote, '/');
+
+ return $remote;
+ }
+
+ /**
+ * @param string $cloudId
+ * @return bool
+ */
+ public function isValidCloudId($cloudId) {
+ return strpos($cloudId, '@') !== false;
+ }
+}
diff --git a/lib/private/Server.php b/lib/private/Server.php
index 3c716ae6ce6..bcbe23b0181 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -52,6 +52,7 @@ use OC\Diagnostics\EventLogger;
use OC\Diagnostics\NullEventLogger;
use OC\Diagnostics\NullQueryLogger;
use OC\Diagnostics\QueryLogger;
+use OC\Federation\CloudIdManager;
use OC\Files\Config\UserMountCache;
use OC\Files\Config\UserMountCacheListener;
use OC\Files\Mount\CacheMountProvider;
@@ -90,6 +91,7 @@ use OC\Security\TrustedDomainHelper;
use OC\Session\CryptoWrapper;
use OC\Tagging\TagMapper;
use OCA\Theming\ThemingDefaults;
+use OCP\Federation\ICloudIdManager;
use OCP\Authentication\LoginCredentials\IStore;
use OCP\IL10N;
use OCP\IServerContainer;
@@ -825,6 +827,10 @@ class Server extends ServerContainer implements IServerContainer {
return new LockdownManager();
});
+ $this->registerService(ICloudIdManager::class, function (Server $c) {
+ return new CloudIdManager();
+ });
+
/* To trick DI since we don't extend the DIContainer here */
$this->registerService(CleanPreviewsBackgroundJob::class, function (Server $c) {
return new CleanPreviewsBackgroundJob(
@@ -1570,4 +1576,11 @@ class Server extends ServerContainer implements IServerContainer {
public function getLockdownManager() {
return $this->query('LockdownManager');
}
+
+ /**
+ * @return \OCP\Federation\ICloudIdManager
+ */
+ public function getCloudIdManager() {
+ return $this->query(ICloudIdManager::class);
+ }
}
diff --git a/lib/private/Share/Helper.php b/lib/private/Share/Helper.php
index 20aaa793728..a1a56077d40 100644
--- a/lib/private/Share/Helper.php
+++ b/lib/private/Share/Helper.php
@@ -249,46 +249,14 @@ class Helper extends \OC\Share\Constants {
* @throws HintException
*/
public static function splitUserRemote($id) {
- if (strpos($id, '@') === false) {
+ try {
+ $cloudId = \OC::$server->getCloudIdManager()->resolveCloudId($id);
+ return [$cloudId->getUser(), $cloudId->getRemote()];
+ } catch (\InvalidArgumentException $e) {
$l = \OC::$server->getL10N('core');
$hint = $l->t('Invalid Federated Cloud ID');
- throw new HintException('Invalid Federated Cloud ID', $hint);
+ throw new HintException('Invalid Federated Cloud ID', $hint, 0, $e);
}
-
- // Find the first character that is not allowed in user names
- $id = str_replace('\\', '/', $id);
- $posSlash = strpos($id, '/');
- $posColon = strpos($id, ':');
-
- if ($posSlash === false && $posColon === false) {
- $invalidPos = strlen($id);
- } else if ($posSlash === false) {
- $invalidPos = $posColon;
- } else if ($posColon === false) {
- $invalidPos = $posSlash;
- } else {
- $invalidPos = min($posSlash, $posColon);
- }
-
- // Find the last @ before $invalidPos
- $pos = $lastAtPos = 0;
- while ($lastAtPos !== false && $lastAtPos <= $invalidPos) {
- $pos = $lastAtPos;
- $lastAtPos = strpos($id, '@', $pos + 1);
- }
-
- if ($pos !== false) {
- $user = substr($id, 0, $pos);
- $remote = substr($id, $pos + 1);
- $remote = self::fixRemoteURL($remote);
- if (!empty($user) && !empty($remote)) {
- return array($user, $remote);
- }
- }
-
- $l = \OC::$server->getL10N('core');
- $hint = $l->t('Invalid Federated Cloud ID');
- throw new HintException('Invalid Fededrated Cloud ID', $hint);
}
/**
diff --git a/lib/private/Share20/ProviderFactory.php b/lib/private/Share20/ProviderFactory.php
index 3f277a852b3..87d9d221810 100644
--- a/lib/private/Share20/ProviderFactory.php
+++ b/lib/private/Share20/ProviderFactory.php
@@ -96,7 +96,8 @@ class ProviderFactory implements IProviderFactory {
$l = $this->serverContainer->getL10N('federatedfilessharing');
$addressHandler = new AddressHandler(
$this->serverContainer->getURLGenerator(),
- $l
+ $l,
+ $this->serverContainer->getCloudIdManager()
);
$discoveryManager = new DiscoveryManager(
$this->serverContainer->getMemCacheFactory(),
@@ -121,7 +122,8 @@ class ProviderFactory implements IProviderFactory {
$this->serverContainer->getLogger(),
$this->serverContainer->getLazyRootFolder(),
$this->serverContainer->getConfig(),
- $this->serverContainer->getUserManager()
+ $this->serverContainer->getUserManager(),
+ $this->serverContainer->getCloudIdManager()
);
}
diff --git a/lib/private/User/User.php b/lib/private/User/User.php
index c37bb59028e..961f70f8a8e 100644
--- a/lib/private/User/User.php
+++ b/lib/private/User/User.php
@@ -411,7 +411,8 @@ class User implements IUser {
public function getCloudId() {
$uid = $this->getUID();
$server = $this->urlGenerator->getAbsoluteURL('/');
- return $uid . '@' . rtrim( $this->removeProtocolFromUrl($server), '/');
+ $server = rtrim( $this->removeProtocolFromUrl($server), '/');
+ return \OC::$server->getCloudIdManager()->getCloudId($uid, $server)->getId();
}
/**