Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a single public api for resolving a cloud id to a user and remote and back #3297

Merged
merged 7 commits into from
Feb 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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