aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorRobin Appelman <robin@icewind.nl>2017-01-27 12:52:17 +0100
committerRobin Appelman <robin@icewind.nl>2017-02-08 15:17:02 +0100
commitfa49c4a13b6c5455b13ad44cfc158b271aa9b616 (patch)
tree1014b6de1bd3761e2e26467c78c6f5fd4697ea56 /lib
parent1a591cea97313b8500154d6c2c9ce3aaf2f38a88 (diff)
downloadnextcloud-server-fa49c4a13b6c5455b13ad44cfc158b271aa9b616.tar.gz
nextcloud-server-fa49c4a13b6c5455b13ad44cfc158b271aa9b616.zip
Add a single public api for resolving a cloud id to a user and remote and back
Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'lib')
-rw-r--r--lib/composer/composer/autoload_classmap.php4
-rw-r--r--lib/composer/composer/autoload_static.php4
-rw-r--r--lib/private/Federation/CloudId.php74
-rw-r--r--lib/private/Federation/CloudIdManager.php108
-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
-rw-r--r--lib/public/Federation/ICloudId.php58
-rw-r--r--lib/public/Federation/ICloudIdManager.php55
-rw-r--r--lib/public/IServerContainer.php6
11 files changed, 333 insertions, 40 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 4a345ed7a6d..5bd9da04072 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -98,6 +98,8 @@ return array(
'OCP\\Encryption\\IFile' => $baseDir . '/lib/public/Encryption/IFile.php',
'OCP\\Encryption\\IManager' => $baseDir . '/lib/public/Encryption/IManager.php',
'OCP\\Encryption\\Keys\\IStorage' => $baseDir . '/lib/public/Encryption/Keys/IStorage.php',
+ 'OCP\\Federation\\ICloudId' => $baseDir . '/lib/public/Federation/ICloudId.php',
+ 'OCP\\Federation\\ICloudIdManager' => $baseDir . '/lib/public/Federation/ICloudIdManager.php',
'OCP\\Files' => $baseDir . '/lib/public/Files.php',
'OCP\\Files\\AlreadyExistsException' => $baseDir . '/lib/public/Files/AlreadyExistsException.php',
'OCP\\Files\\Cache\\ICache' => $baseDir . '/lib/public/Files/Cache/ICache.php',
@@ -497,6 +499,8 @@ return array(
'OC\\Encryption\\Manager' => $baseDir . '/lib/private/Encryption/Manager.php',
'OC\\Encryption\\Update' => $baseDir . '/lib/private/Encryption/Update.php',
'OC\\Encryption\\Util' => $baseDir . '/lib/private/Encryption/Util.php',
+ 'OC\\Federation\\CloudId' => $baseDir . '/lib/private/Federation/CloudId.php',
+ 'OC\\Federation\\CloudIdManager' => $baseDir . '/lib/private/Federation/CloudIdManager.php',
'OC\\Files\\AppData\\AppData' => $baseDir . '/lib/private/Files/AppData/AppData.php',
'OC\\Files\\AppData\\Factory' => $baseDir . '/lib/private/Files/AppData/Factory.php',
'OC\\Files\\Cache\\Cache' => $baseDir . '/lib/private/Files/Cache/Cache.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index f8d360fec4b..475b4c15542 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -128,6 +128,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OCP\\Encryption\\IFile' => __DIR__ . '/../../..' . '/lib/public/Encryption/IFile.php',
'OCP\\Encryption\\IManager' => __DIR__ . '/../../..' . '/lib/public/Encryption/IManager.php',
'OCP\\Encryption\\Keys\\IStorage' => __DIR__ . '/../../..' . '/lib/public/Encryption/Keys/IStorage.php',
+ 'OCP\\Federation\\ICloudId' => __DIR__ . '/../../..' . '/lib/public/Federation/ICloudId.php',
+ 'OCP\\Federation\\ICloudIdManager' => __DIR__ . '/../../..' . '/lib/public/Federation/ICloudIdManager.php',
'OCP\\Files' => __DIR__ . '/../../..' . '/lib/public/Files.php',
'OCP\\Files\\AlreadyExistsException' => __DIR__ . '/../../..' . '/lib/public/Files/AlreadyExistsException.php',
'OCP\\Files\\Cache\\ICache' => __DIR__ . '/../../..' . '/lib/public/Files/Cache/ICache.php',
@@ -527,6 +529,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Encryption\\Manager' => __DIR__ . '/../../..' . '/lib/private/Encryption/Manager.php',
'OC\\Encryption\\Update' => __DIR__ . '/../../..' . '/lib/private/Encryption/Update.php',
'OC\\Encryption\\Util' => __DIR__ . '/../../..' . '/lib/private/Encryption/Util.php',
+ 'OC\\Federation\\CloudId' => __DIR__ . '/../../..' . '/lib/private/Federation/CloudId.php',
+ 'OC\\Federation\\CloudIdManager' => __DIR__ . '/../../..' . '/lib/private/Federation/CloudIdManager.php',
'OC\\Files\\AppData\\AppData' => __DIR__ . '/../../..' . '/lib/private/Files/AppData/AppData.php',
'OC\\Files\\AppData\\Factory' => __DIR__ . '/../../..' . '/lib/private/Files/AppData/Factory.php',
'OC\\Files\\Cache\\Cache' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/Cache.php',
diff --git a/lib/private/Federation/CloudId.php b/lib/private/Federation/CloudId.php
new file mode 100644
index 00000000000..746bd2eaf71
--- /dev/null
+++ b/lib/private/Federation/CloudId.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017, Robin Appelman <robin@icewind.nl>
+ *
+ * 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;
+ }
+} \ No newline at end of file
diff --git a/lib/private/Federation/CloudIdManager.php b/lib/private/Federation/CloudIdManager.php
new file mode 100644
index 00000000000..d5d4e7f34cc
--- /dev/null
+++ b/lib/private/Federation/CloudIdManager.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017, Robin Appelman <robin@icewind.nl>
+ *
+ * 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 = str_replace('\\', '/', $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);
+ $remote = $this->fixRemoteURL($remote);
+ if (!empty($user) && !empty($remote)) {
+ return new CloudId($cloudId, $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;
+ }
+} \ No newline at end of file
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();
}
/**
diff --git a/lib/public/Federation/ICloudId.php b/lib/public/Federation/ICloudId.php
new file mode 100644
index 00000000000..0985544fee8
--- /dev/null
+++ b/lib/public/Federation/ICloudId.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017, Robin Appelman <robin@icewind.nl>
+ *
+ * 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 OCP\Federation;
+
+/**
+ * Parsed federated cloud id
+ *
+ * @since 12.0.0
+ */
+interface ICloudId {
+ /**
+ * The remote cloud id
+ *
+ * @return string
+ * @since 12.0.0
+ */
+ public function getId();
+
+ /**
+ * Get a clean representation of the cloud id for display
+ *
+ * @return string
+ * @since 12.0.0
+ */
+ public function getDisplayId();
+
+ /**
+ * The username on the remote server
+ *
+ * @return string
+ * @since 12.0.0
+ */
+ public function getUser();
+
+ /**
+ * The base address of the remote server
+ *
+ * @return string
+ * @since 12.0.0
+ */
+ public function getRemote();
+} \ No newline at end of file
diff --git a/lib/public/Federation/ICloudIdManager.php b/lib/public/Federation/ICloudIdManager.php
new file mode 100644
index 00000000000..a81a4af6186
--- /dev/null
+++ b/lib/public/Federation/ICloudIdManager.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017, Robin Appelman <robin@icewind.nl>
+ *
+ * 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 OCP\Federation;
+
+/**
+ * Interface for resolving federated cloud ids
+ *
+ * @since 12.0.0
+ */
+interface ICloudIdManager {
+ /**
+ * @param string $cloudId
+ * @return ICloudId
+ *
+ * @since 12.0.0
+ */
+ public function resolveCloudId($cloudId);
+
+ /**
+ * Get the cloud id for a remote user
+ *
+ * @param string $user
+ * @param string $remote
+ * @return ICloudId
+ *
+ * @since 12.0.0
+ */
+ public function getCloudId($user, $remote);
+
+ /**
+ * Check if the input is a correctly formatted cloud id
+ *
+ * @param string $cloudId
+ * @return bool
+ *
+ * @since 12.0.0
+ */
+ public function isValidCloudId($cloudId);
+} \ No newline at end of file
diff --git a/lib/public/IServerContainer.php b/lib/public/IServerContainer.php
index 87628be01f7..02a092ea660 100644
--- a/lib/public/IServerContainer.php
+++ b/lib/public/IServerContainer.php
@@ -525,4 +525,10 @@ interface IServerContainer {
* @since 8.0.0
*/
public function getDateTimeFormatter();
+
+ /**
+ * @return \OCP\Federation\ICloudIdManager
+ * @since 12.0.0
+ */
+ public function getCloudIdManager();
}