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

[Stable10] [WIP] Federated sharing new spec #33027

Merged
merged 22 commits into from
Dec 5, 2018
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
2 changes: 1 addition & 1 deletion apps/dav/appinfo/v1/publicwebdav.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@

$server = $serverFactory->createServer($baseuri, $requestUri, $authBackend, function (\Sabre\DAV\Server $server) use ($authBackend, $linkCheckPlugin) {
$isAjax = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest');
$federatedSharingApp = new \OCA\FederatedFileSharing\AppInfo\Application('federatedfilesharing');
$federatedSharingApp = new \OCA\FederatedFileSharing\AppInfo\Application();
$federatedShareProvider = $federatedSharingApp->getFederatedShareProvider();
if ($federatedShareProvider->isOutgoingServer2serverShareEnabled() === false && !$isAjax) {
// this is what is thrown when trying to access a non-existing share
Expand Down
35 changes: 3 additions & 32 deletions apps/federatedfilesharing/appinfo/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,9 @@
*
*/

$app = new \OCA\FederatedFileSharing\AppInfo\Application('federatedfilesharing');

use OCA\FederatedFileSharing\Notifier;
use OCP\Share\Events\AcceptShare;
use OCP\Share\Events\DeclineShare;
use OCP\Defaults;

$app = new \OCA\FederatedFileSharing\AppInfo\Application();

$manager = \OC::$server->getNotificationManager();
$manager->registerNotifier(function () {
Expand All @@ -46,30 +43,4 @@
// FIXME versions, comments, tags and sharing ui still uses it https://github.com/owncloud/core/search?utf8=%E2%9C%93&q=loadAdditionalScripts&type=
OCP\Util::connectHook('OCP\Share', 'share_link_access', 'OCA\FederatedFileSharing\HookHandler', 'loadPublicJS');

// react to accept and decline share events
$eventDispatcher = \OC::$server->getEventDispatcher();
$eventDispatcher->addListener(
AcceptShare::class,
function (AcceptShare $event) use ($app) {
/** @var \OCA\FederatedFileSharing\Notifications $notifications */
$notifications = $app->getContainer()->query('OCA\FederatedFileSharing\Notifications');
$notifications->sendAcceptShare(
$event->getRemote(),
$event->getRemoteId(),
$event->getShareToken()
);
}
);

$eventDispatcher->addListener(
DeclineShare::class,
function (DeclineShare $event) use ($app) {
/** @var \OCA\FederatedFileSharing\Notifications $notifications */
$notifications = $app->getContainer()->query('OCA\FederatedFileSharing\Notifications');
$notifications->sendDeclineShare(
$event->getRemote(),
$event->getRemoteId(),
$event->getShareToken()
);
}
);
$app->registerListeners();
44 changes: 44 additions & 0 deletions apps/federatedfilesharing/appinfo/routes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php
/**
* @author Viktar Dubiniuk <dubiniuk@owncloud.com>
*
* @copyright Copyright (c) 2018, ownCloud GmbH
* @license AGPL-3.0
*
* 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/>
*
*/

return [
'ocs' => [
// ocm 0.3
['root' => '/cloud', 'name' => 'RequestHandler#createShare', 'url' => '/shares', 'verb' => 'POST'],
['root' => '/cloud', 'name' => 'RequestHandler#reShare', 'url' => '/shares/{id}/reshare', 'verb' => 'POST'],
['root' => '/cloud', 'name' => 'RequestHandler#updatePermissions', 'url' => '/shares/{id}/permissions', 'verb' => 'POST'],
['root' => '/cloud', 'name' => 'RequestHandler#acceptShare', 'url' => '', 'verb' => 'POST'],
['root' => '/cloud', 'name' => 'RequestHandler#acceptShare', 'url' => '/shares/{id}/accept', 'verb' => 'POST'],
['root' => '/cloud', 'name' => 'RequestHandler#declineShare', 'url' => '/shares/{id}/decline', 'verb' => 'POST'],
['root' => '/cloud', 'name' => 'RequestHandler#unshare', 'url' => '/shares/{id}/unshare', 'verb' => 'POST'],
['root' => '/cloud', 'name' => 'RequestHandler#revoke', 'url' => '/shares/{id}/revoke', 'verb' => 'POST'],

// ocm 1.0-proposal1
['root' => '/', 'name' => 'OcmController#discovery', 'url' => '/ocm-provider', 'verb' => 'GET'],
],

'routes' => [
// ocm 1.0-proposal1
['name' => 'ocm#index', 'url' => '/', 'verb' => 'GET'],
['name' => 'ocm#createShare', 'url' => '/shares', 'verb' => 'POST'],
['name' => 'ocm#processNotification', 'url' => '/notifications', 'verb' => 'POST'],
]
];
163 changes: 163 additions & 0 deletions apps/federatedfilesharing/lib/Address.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<?php
/**
* @author Viktar Dubiniuk <dubiniuk@owncloud.com>
*
* @copyright Copyright (c) 2018, ownCloud GmbH
* @license AGPL-3.0
*
* 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 OCA\FederatedFileSharing;

/**
* Class Address
*
* @package OCA\FederatedFileSharing
*/
class Address {
/**
* @var string
*/
protected $cloudId;

/**
* @var string
*/
protected $displayName;

/**
* Address constructor.
*
* @param string $cloudId
* @param string $displayName
*/
public function __construct($cloudId, $displayName = '') {
$this->cloudId = $cloudId;
$this->displayName = $displayName;
}

/**
* Get user federated id
*
* @return string
*/
public function getCloudId() {
$origin = $this->getOrigin();
$userId = $this->getUserId();
return "{$userId}@{$origin}";
}

/**
* Get user id
*
* @return string
*/
public function getUserId() {
// userId is everything except the last part
$parts = \explode('@', $this->cloudId);
\array_pop($parts);
return \implode('@', $parts);
}

/**
* Get user host without protocol, index.php and a trailing slash
*
* @return string
*/
public function getHostName() {
// hostname is the last part
$origin = $this->getCleanOrigin();

// replace all characters before :// and :// itself
return \preg_replace('|^(.*?://)|', '', $origin);
}

/**
* Get user host with protocol but without trailing slash and index.php
*
* @return string
*/
public function getOrigin() {
return $this->getCleanOrigin();
}

/**
* Get user display name, fallback to userId if it is empty
*
* @return string
*/
public function getDisplayName() {
return ($this->displayName !== '') ? $this->displayName : $this->getUserId();
}

/**
* Checks if the user and host is the same with another address
*
* @param Address $address
*
* @return bool
*/
public function equalTo(Address $address) {
$thisUserId = $this->translateUid($this->getUserId());
$otherUserId = $this->translateUid($address->getUserId());
return $this->getHostName() === $address->getHostName()
&& $thisUserId === $otherUserId;
}

/**
* Some kind of ancient magic that was copypasted here and there
*
* @return mixed
*/
public function toLocalUid() {
return $this->translateUid($this->getUserId());
}

/**
* Cut index.php and trailing slash from remote URL
*
* @return string
*/
protected function getCleanOrigin() {
//Origin is the last part
$parts = \explode('@', $this->cloudId);
$rawOrigin = \array_pop($parts);
if ($fileNamePosition = \strpos($rawOrigin, '/index.php')) {
$rawOrigin = \substr($rawOrigin, 0, $fileNamePosition);
}

$normalizedOrigin = \rtrim(
\strtolower($rawOrigin),
'/'
);

return $normalizedOrigin;
}

/**
* @param string $uid
* @return mixed
*/
protected function translateUid($uid) {
// FIXME this should be a method in the user management instead
// Move to a helper instead of C&P meanwhile?
\OCP\Util::emitHook(
'\OCA\Files_Sharing\API\Server2Server',
'preLoginNameUsedAsUserName',
['uid' => &$uid]
);
return $uid;
}
}
53 changes: 12 additions & 41 deletions apps/federatedfilesharing/lib/AddressHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,47 +101,23 @@ public function splitUserRemote($address) {
}

/**
* generate remote URL part of federated ID
* @param string $uid
*
* @return string url of the current server
* @return Address
*/
public function generateRemoteURL() {
$url = $this->urlGenerator->getAbsoluteURL('/');
return $url;
public function getLocalUserFederatedAddress($uid) {
$host = $this->generateRemoteURL();
return new Address("{$uid}@{$host}");
}

/**
* check if two federated cloud IDs refer to the same user
* generate remote URL part of federated ID
*
* @param string $user1
* @param string $server1
* @param string $user2
* @param string $server2
* @return bool true if both users and servers are the same
* @return string url of the current server
*/
public function compareAddresses($user1, $server1, $user2, $server2) {
$normalizedServer1 = \strtolower($this->removeProtocolFromUrl($server1));
$normalizedServer2 = \strtolower($this->removeProtocolFromUrl($server2));

if (\rtrim($normalizedServer1, '/') === \rtrim($normalizedServer2, '/')) {
// FIXME this should be a method in the user management instead
\OCP\Util::emitHook(
'\OCA\Files_Sharing\API\Server2Server',
'preLoginNameUsedAsUserName',
['uid' => &$user1]
);
\OCP\Util::emitHook(
'\OCA\Files_Sharing\API\Server2Server',
'preLoginNameUsedAsUserName',
['uid' => &$user2]
);

if ($user1 === $user2) {
return true;
}
}

return false;
public function generateRemoteURL() {
$url = $this->urlGenerator->getAbsoluteURL('/');
return $url;
}

/**
Expand All @@ -151,13 +127,8 @@ public function compareAddresses($user1, $server1, $user2, $server2) {
* @return string
*/
public function removeProtocolFromUrl($url) {
if (\strpos($url, 'https://') === 0) {
return \substr($url, \strlen('https://'));
} elseif (\strpos($url, 'http://') === 0) {
return \substr($url, \strlen('http://'));
}

return $url;
// replace all characters before :// and :// itself
return \preg_replace('|^(.*?://)|', '', $url);
}

/**
Expand Down
Loading