diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index 63938201eb..bf90c0b5df 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -13,8 +13,12 @@ if ($appConfig->getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') { exit(); } +// Legacy sharing links via public.php have the token in $GET['t'] if (isset($_GET['t'])) { $token = $_GET['t']; +} + +if (isset($token)) { $linkItem = OCP\Share::getShareByToken($token, false); if (is_array($linkItem) && isset($linkItem['uid_owner'])) { // seems to be a valid share diff --git a/core/js/js.js b/core/js/js.js index 9a60b0aad6..bf33e3f2e4 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -246,6 +246,7 @@ var OC={ url = '/' + url; } + // TODO save somewhere whether the webserver is able to skip the index.php to have shorter links (e.g. for sharing) return OC.webroot + '/index.php' + _build(url, params); }, diff --git a/core/js/share.js b/core/js/share.js index f1652370d3..67ddd9c487 100644 --- a/core/js/share.js +++ b/core/js/share.js @@ -672,8 +672,11 @@ OC.Share={ } // TODO: use oc webroot ? - var link = parent.location.protocol+'//'+location.host+OC.linkTo('', 'public.php')+'?service='+service+'&t='+token; - + if (service !== 'files') { + var link = parent.location.protocol+'//'+location.host+OC.linkTo('', 'public.php')+'?service='+service+'&t='+token; + } else { + var link = parent.location.protocol+'//'+location.host+OC.generateUrl('/s/')+token; + } } $('#linkText').val(link); $('#linkText').show('blind'); diff --git a/core/js/tests/specs/shareSpec.js b/core/js/tests/specs/shareSpec.js index 06c4b98df2..e712ea58bc 100644 --- a/core/js/tests/specs/shareSpec.js +++ b/core/js/tests/specs/shareSpec.js @@ -151,7 +151,7 @@ describe('OC.Share tests', function() { expect($('#dropdown #linkCheckbox').prop('checked')).toEqual(true); // this is how the OC.Share class does it... var link = parent.location.protocol + '//' + location.host + - OC.linkTo('', 'public.php')+'?service=files&t=tehtoken'; + OC.generateUrl('/s/') + 'tehtoken'; expect($('#dropdown #linkText').val()).toEqual(link); }); it('does not show populated link share when a link share exists for a different file', function() { @@ -243,7 +243,7 @@ describe('OC.Share tests', function() { expect($('#dropdown #linkCheckbox').prop('checked')).toEqual(true); // this is how the OC.Share class does it... var link = parent.location.protocol + '//' + location.host + - OC.linkTo('', 'public.php')+'?service=files&t=tehtoken'; + OC.generateUrl('/s/') + 'tehtoken'; expect($('#dropdown #linkText').val()).toEqual(link); // nested one @@ -258,7 +258,7 @@ describe('OC.Share tests', function() { expect($('#dropdown #linkCheckbox').prop('checked')).toEqual(true); // this is how the OC.Share class does it... link = parent.location.protocol + '//' + location.host + - OC.linkTo('', 'public.php')+'?service=files&t=anothertoken'; + OC.generateUrl('/s/') + 'anothertoken'; expect($('#dropdown #linkText').val()).toEqual(link); }); describe('expiration date', function() { diff --git a/core/routes.php b/core/routes.php index 28a3680dd9..fac67f2317 100644 --- a/core/routes.php +++ b/core/routes.php @@ -100,6 +100,11 @@ $this->create('core_avatar_post_cropped', '/avatar/cropped') ->post() ->action('OC\Core\Avatar\Controller', 'postCroppedAvatar'); +// Sharing routes +$this->create('core_share_show_share', '/s/{token}') + ->get() + ->action('OC\Core\Share\Controller', 'showShare'); + // used for heartbeat $this->create('heartbeat', '/heartbeat')->action(function(){ // do nothing diff --git a/core/share/controller.php b/core/share/controller.php new file mode 100644 index 0000000000..c1741af0d9 --- /dev/null +++ b/core/share/controller.php @@ -0,0 +1,23 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Core\Share; + +class Controller { + public static function showShare($args) { + \OC_Util::checkAppEnabled('files_sharing'); + + $token = $args['token']; + + \OC_App::loadApp('files_sharing'); + \OC_User::setIncognitoMode(true); + + require_once \OC_App::getAppPath('files_sharing') .'/public.php'; + } +} +?> diff --git a/lib/private/helper.php b/lib/private/helper.php index 7c1edd1b05..f696b5a890 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -129,12 +129,12 @@ class OC_Helper { * Returns a absolute url to the given service. */ public static function linkToPublic($service, $add_slash = false) { - return OC::$server->getURLGenerator()->getAbsoluteURL( - self::linkTo( - '', 'public.php') . '?service=' . $service - . (($add_slash && $service[strlen($service) - 1] != '/') ? '/' : '' - ) - ); + if ($service === 'files') { + $url = OC::$server->getURLGenerator()->getAbsoluteURL('/s'); + } else { + $url = OC::$server->getURLGenerator()->getAbsoluteURL(self::linkTo('', 'public.php').'?service='.$service); + } + return $url . (($add_slash && $service[strlen($service) - 1] != '/') ? '/' : ''); } /** diff --git a/lib/private/share/constants.php b/lib/private/share/constants.php index 4c398c43c2..798327cc15 100644 --- a/lib/private/share/constants.php +++ b/lib/private/share/constants.php @@ -34,7 +34,7 @@ class Constants { const FORMAT_STATUSES = -2; const FORMAT_SOURCES = -3; // ToDo Check if it is still in use otherwise remove it - const TOKEN_LENGTH = 32; // see db_structure.xml + const TOKEN_LENGTH = 15; // old (oc7) length is 32, keep token length in db at least that for compatibility protected static $shareTypeUserAndGroups = -1; protected static $shareTypeGroupUserUnique = 2; diff --git a/lib/private/share/share.php b/lib/private/share/share.php index e2e9b94125..8441e6a94c 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -640,7 +640,10 @@ class Share extends \OC\Share\Constants { if (isset($oldToken)) { $token = $oldToken; } else { - $token = \OC_Util::generateRandomBytes(self::TOKEN_LENGTH); + $token = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(self::TOKEN_LENGTH, + \OCP\Security\ISecureRandom::CHAR_LOWER.\OCP\Security\ISecureRandom::CHAR_UPPER. + \OCP\Security\ISecureRandom::CHAR_DIGITS + ); } $result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, $token, $itemSourceName, $expirationDate); diff --git a/tests/lib/helper.php b/tests/lib/helper.php index 20b8571b91..cb342e295b 100644 --- a/tests/lib/helper.php +++ b/tests/lib/helper.php @@ -443,15 +443,33 @@ class Test_Helper extends PHPUnit_Framework_TestCase { public function testLinkToPublic() { \OC::$WEBROOT = ''; $result = \OC_Helper::linkToPublic('files'); - $this->assertEquals('http://localhost/public.php?service=files', $result); + $this->assertEquals('http://localhost/s', $result); $result = \OC_Helper::linkToPublic('files', false); - $this->assertEquals('http://localhost/public.php?service=files', $result); + $this->assertEquals('http://localhost/s', $result); + $result = \OC_Helper::linkToPublic('files', true); + $this->assertEquals('http://localhost/s/', $result); + + $result = \OC_Helper::linkToPublic('other'); + $this->assertEquals('http://localhost/public.php?service=other', $result); + $result = \OC_Helper::linkToPublic('other', false); + $this->assertEquals('http://localhost/public.php?service=other', $result); + $result = \OC_Helper::linkToPublic('other', true); + $this->assertEquals('http://localhost/public.php?service=other/', $result); \OC::$WEBROOT = '/owncloud'; $result = \OC_Helper::linkToPublic('files'); - $this->assertEquals('http://localhost/owncloud/public.php?service=files', $result); + $this->assertEquals('http://localhost/owncloud/s', $result); $result = \OC_Helper::linkToPublic('files', false); - $this->assertEquals('http://localhost/owncloud/public.php?service=files', $result); + $this->assertEquals('http://localhost/owncloud/s', $result); + $result = \OC_Helper::linkToPublic('files', true); + $this->assertEquals('http://localhost/owncloud/s/', $result); + + $result = \OC_Helper::linkToPublic('other'); + $this->assertEquals('http://localhost/owncloud/public.php?service=other', $result); + $result = \OC_Helper::linkToPublic('other', false); + $this->assertEquals('http://localhost/owncloud/public.php?service=other', $result); + $result = \OC_Helper::linkToPublic('other', true); + $this->assertEquals('http://localhost/owncloud/public.php?service=other/', $result); } /**