Skip to content

Commit

Permalink
Merge pull request #3297 from nextcloud/cloud-id-resolve
Browse files Browse the repository at this point in the history
Add a single public api for resolving a cloud id to a user and remote and back
  • Loading branch information
icewind1991 authored Feb 9, 2017
2 parents 4a5a368 + 0d8d658 commit bf88060
Show file tree
Hide file tree
Showing 35 changed files with 707 additions and 231 deletions.
73 changes: 13 additions & 60 deletions apps/federatedfilesharing/lib/AddressHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

namespace OCA\FederatedFileSharing;
use OC\HintException;
use OCP\Federation\ICloudIdManager;
use OCP\IL10N;
use OCP\IURLGenerator;

Expand All @@ -38,18 +39,24 @@ class AddressHandler {
/** @var IURLGenerator */
private $urlGenerator;

/** @var ICloudIdManager */
private $cloudIdManager;

/**
* AddressHandler constructor.
*
* @param IURLGenerator $urlGenerator
* @param IL10N $il10n
* @param ICloudIdManager $cloudIdManager
*/
public function __construct(
IURLGenerator $urlGenerator,
IL10N $il10n
IL10N $il10n,
ICloudIdManager $cloudIdManager
) {
$this->l = $il10n;
$this->urlGenerator = $urlGenerator;
$this->cloudIdManager = $cloudIdManager;
}

/**
Expand All @@ -60,44 +67,13 @@ public function __construct(
* @throws HintException
*/
public function splitUserRemote($address) {
if (strpos($address, '@') === false) {
try {
$cloudId = $this->cloudIdManager->resolveCloudId($address);
return [$cloudId->getUser(), $cloudId->getRemote()];
} catch (\InvalidArgumentException $e) {
$hint = $this->l->t('Invalid Federated Cloud ID');
throw new HintException('Invalid Federated Cloud ID', $hint);
}

// Find the first character that is not allowed in user names
$id = str_replace('\\', '/', $address);
$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);
throw new HintException('Invalid Federated Cloud ID', $hint, 0, $e);
}

if ($pos !== false) {
$user = substr($id, 0, $pos);
$remote = substr($id, $pos + 1);
$remote = $this->fixRemoteURL($remote);
if (!empty($user) && !empty($remote)) {
return array($user, $remote);
}
}

$hint = $this->l->t('Invalid Federated Cloud ID');
throw new HintException('Invalid Federated Cloud ID', $hint);
}

/**
Expand Down Expand Up @@ -175,27 +151,4 @@ public function urlContainProtocol($url) {

return false;
}

/**
* 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;
}

}
12 changes: 8 additions & 4 deletions apps/federatedfilesharing/lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ public function __construct() {
$container->registerService('RequestHandlerController', function(SimpleContainer $c) use ($server) {
$addressHandler = new AddressHandler(
$server->getURLGenerator(),
$server->getL10N('federatedfilesharing')
$server->getL10N('federatedfilesharing'),
$server->getCloudIdManager()
);
$notification = new Notifications(
$addressHandler,
Expand All @@ -64,7 +65,8 @@ public function __construct() {
$server->getShareManager(),
$notification,
$addressHandler,
$server->getUserManager()
$server->getUserManager(),
$server->getCloudIdManager()
);
});
}
Expand Down Expand Up @@ -94,7 +96,8 @@ public function getFederatedShareProvider() {
protected function initFederatedShareProvider() {
$addressHandler = new \OCA\FederatedFileSharing\AddressHandler(
\OC::$server->getURLGenerator(),
\OC::$server->getL10N('federatedfilesharing')
\OC::$server->getL10N('federatedfilesharing'),
\OC::$server->getCloudIdManager()
);
$discoveryManager = new \OCA\FederatedFileSharing\DiscoveryManager(
\OC::$server->getMemCacheFactory(),
Expand All @@ -119,7 +122,8 @@ protected function initFederatedShareProvider() {
\OC::$server->getLogger(),
\OC::$server->getLazyRootFolder(),
\OC::$server->getConfig(),
\OC::$server->getUserManager()
\OC::$server->getUserManager(),
\OC::$server->getCloudIdManager()
);
}

Expand Down
3 changes: 2 additions & 1 deletion apps/federatedfilesharing/lib/BackgroundJob/RetryJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ public function __construct(Notifications $notifications = null) {
} else {
$addressHandler = new AddressHandler(
\OC::$server->getURLGenerator(),
\OC::$server->getL10N('federatedfilesharing')
\OC::$server->getL10N('federatedfilesharing'),
\OC::$server->getCloudIdManager()
);
$discoveryManager = new DiscoveryManager(
\OC::$server->getMemCacheFactory(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
use OCP\Federation\ICloudIdManager;
use OCP\Files\StorageInvalidException;
use OCP\Http\Client\IClientService;
use OCP\IL10N;
Expand Down Expand Up @@ -74,6 +75,9 @@ class MountPublicLinkController extends Controller {
/** @var IClientService */
private $clientService;

/** @var ICloudIdManager */
private $cloudIdManager;

/**
* MountPublicLinkController constructor.
*
Expand All @@ -86,6 +90,7 @@ class MountPublicLinkController extends Controller {
* @param IL10N $l
* @param IUserSession $userSession
* @param IClientService $clientService
* @param ICloudIdManager $cloudIdManager
*/
public function __construct($appName,
IRequest $request,
Expand All @@ -95,7 +100,8 @@ public function __construct($appName,
ISession $session,
IL10N $l,
IUserSession $userSession,
IClientService $clientService
IClientService $clientService,
ICloudIdManager $cloudIdManager
) {
parent::__construct($appName, $request);

Expand All @@ -106,6 +112,7 @@ public function __construct($appName,
$this->l = $l;
$this->userSession = $userSession;
$this->clientService = $clientService;
$this->cloudIdManager = $cloudIdManager;
}

/**
Expand Down Expand Up @@ -177,7 +184,7 @@ public function askForFederatedShare($token, $remote, $password = '', $owner = '
return new JSONResponse(['message' => $this->l->t('Server to server sharing is not enabled on this server')], Http::STATUS_BAD_REQUEST);
}

$shareWith = $this->userSession->getUser()->getUID() . '@' . $this->addressHandler->generateRemoteURL();
$cloudId = $this->cloudIdManager->getCloudId($this->userSession->getUser()->getUID(), $this->addressHandler->generateRemoteURL());

$httpClient = $this->clientService->newClient();

Expand All @@ -187,7 +194,7 @@ public function askForFederatedShare($token, $remote, $password = '', $owner = '
'body' =>
[
'token' => $token,
'shareWith' => rtrim($shareWith, '/'),
'shareWith' => rtrim($cloudId->getId(), '/'),
'password' => $password
],
'connect_timeout' => 10,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
use OCP\AppFramework\OCS\OCSNotFoundException;
use OCP\AppFramework\OCSController;
use OCP\Constants;
use OCP\Federation\ICloudIdManager;
use OCP\Files\NotFoundException;
use OCP\IDBConnection;
use OCP\IRequest;
Expand Down Expand Up @@ -68,6 +69,9 @@ class RequestHandlerController extends OCSController {
/** @var string */
private $shareTable = 'share';

/** @var ICloudIdManager */
private $cloudIdManager;

/**
* Server2Server constructor.
*
Expand All @@ -79,6 +83,7 @@ class RequestHandlerController extends OCSController {
* @param Notifications $notifications
* @param AddressHandler $addressHandler
* @param IUserManager $userManager
* @param ICloudIdManager $cloudIdManager
*/
public function __construct($appName,
IRequest $request,
Expand All @@ -87,7 +92,8 @@ public function __construct($appName,
Share\IManager $shareManager,
Notifications $notifications,
AddressHandler $addressHandler,
IUserManager $userManager
IUserManager $userManager,
ICloudIdManager $cloudIdManager
) {
parent::__construct($appName, $request);

Expand All @@ -97,6 +103,7 @@ public function __construct($appName,
$this->notifications = $notifications;
$this->addressHandler = $addressHandler;
$this->userManager = $userManager;
$this->cloudIdManager = $cloudIdManager;
}

/**
Expand Down Expand Up @@ -164,7 +171,7 @@ public function createShare() {
$shareId = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share_external');

if ($ownerFederatedId === null) {
$ownerFederatedId = $owner . '@' . $this->cleanupRemote($remote);
$ownerFederatedId = $this->cloudIdManager->getCloudId($owner, $this->cleanupRemote($remote))->getId();
}
// if the owner of the share and the initiator are the same user
// we also complete the federated share ID for the initiator
Expand Down Expand Up @@ -424,7 +431,7 @@ public function unshare($id) {

$remote = $this->cleanupRemote($share['remote']);

$owner = $share['owner'] . '@' . $remote;
$owner = $this->cloudIdManager->getCloudId($share['owner'], $remote);
$mountpoint = $share['mountpoint'];
$user = $share['user'];

Expand Down
26 changes: 18 additions & 8 deletions apps/federatedfilesharing/lib/FederatedShareProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
namespace OCA\FederatedFileSharing;

use OC\Share20\Share;
use OCP\Federation\ICloudIdManager;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
use OCP\IConfig;
Expand Down Expand Up @@ -80,6 +81,9 @@ class FederatedShareProvider implements IShareProvider {
/** @var IUserManager */
private $userManager;

/** @var ICloudIdManager */
private $cloudIdManager;

/**
* DefaultShareProvider constructor.
*
Expand All @@ -92,6 +96,7 @@ class FederatedShareProvider implements IShareProvider {
* @param IRootFolder $rootFolder
* @param IConfig $config
* @param IUserManager $userManager
* @param ICloudIdManager $cloudIdManager
*/
public function __construct(
IDBConnection $connection,
Expand All @@ -102,7 +107,8 @@ public function __construct(
ILogger $logger,
IRootFolder $rootFolder,
IConfig $config,
IUserManager $userManager
IUserManager $userManager,
ICloudIdManager $cloudIdManager
) {
$this->dbConnection = $connection;
$this->addressHandler = $addressHandler;
Expand All @@ -113,6 +119,7 @@ public function __construct(
$this->rootFolder = $rootFolder;
$this->config = $config;
$this->userManager = $userManager;
$this->cloudIdManager = $cloudIdManager;
}

/**
Expand Down Expand Up @@ -153,17 +160,18 @@ public function create(IShare $share) {


// don't allow federated shares if source and target server are the same
list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
$cloudId = $this->cloudIdManager->resolveCloudId($shareWith);
$currentServer = $this->addressHandler->generateRemoteURL();
$currentUser = $sharedBy;
if ($this->addressHandler->compareAddresses($user, $remote, $currentUser, $currentServer)) {
if ($this->addressHandler->compareAddresses($cloudId->getUser(), $cloudId->getRemote(), $currentUser, $currentServer)) {
$message = 'Not allowed to create a federated share with the same user.';
$message_t = $this->l->t('Not allowed to create a federated share with the same user');
$this->logger->debug($message, ['app' => 'Federated File Sharing']);
throw new \Exception($message_t);
}

$share->setSharedWith($user . '@' . $remote);

$share->setSharedWith($cloudId->getId());

try {
$remoteShare = $this->getShareFromExternalShareTable($share);
Expand All @@ -173,8 +181,8 @@ public function create(IShare $share) {

if ($remoteShare) {
try {
$uidOwner = $remoteShare['owner'] . '@' . $remoteShare['remote'];
$shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, 'tmp_token_' . time());
$ownerCloudId = $this->cloudIdManager->getCloudId($remoteShare['owner'], $remoteShare['remote']);
$shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $ownerCloudId->getId(), $permissions, 'tmp_token_' . time());
$share->setId($shareId);
list($token, $remoteId) = $this->askOwnerToReShare($shareWith, $share, $shareId);
// remote share was create successfully if we get a valid token as return
Expand Down Expand Up @@ -227,15 +235,17 @@ protected function createFederatedShare(IShare $share) {
try {
$sharedByFederatedId = $share->getSharedBy();
if ($this->userManager->userExists($sharedByFederatedId)) {
$sharedByFederatedId = $sharedByFederatedId . '@' . $this->addressHandler->generateRemoteURL();
$cloudId = $this->cloudIdManager->getCloudId($sharedByFederatedId, $this->addressHandler->generateRemoteURL());
$sharedByFederatedId = $cloudId->getId();
}
$ownerCloudId = $this->cloudIdManager->getCloudId($share->getShareOwner(), $this->addressHandler->generateRemoteURL());
$send = $this->notifications->sendRemoteShare(
$token,
$share->getSharedWith(),
$share->getNode()->getName(),
$shareId,
$share->getShareOwner(),
$share->getShareOwner() . '@' . $this->addressHandler->generateRemoteURL(),
$ownerCloudId->getId(),
$share->getSharedBy(),
$sharedByFederatedId
);
Expand Down
Loading

0 comments on commit bf88060

Please sign in to comment.