]> source.dussan.org Git - nextcloud-server.git/commitdiff
Use a route instead of s.php and convert tokens asap
authorkondou <kondou@ts.unde.re>
Sun, 3 Aug 2014 09:31:28 +0000 (11:31 +0200)
committerkondou <kondou@ts.unde.re>
Thu, 4 Sep 2014 13:23:55 +0000 (15:23 +0200)
12 files changed:
apps/files_sharing/public.php
config/config.sample.php
core/ajax/share.php
core/js/js.js
core/js/share.js
core/js/tests/specs/shareSpec.js
core/routes.php
core/share/controller.php [new file with mode: 0644]
lib/private/share/constants.php
lib/private/share/share.php
public.php
s.php [deleted file]

index 63938201eb22e0df7ca36f373abf5d6a496b9502..bf90c0b5dfcb71346e0c15f08fe3d2ae714fd92e 100644 (file)
@@ -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
index 71105a8b10d85b4259396394f2bed6bbc50cae21..1e876e688ff8cffc5cce0aa6334cb0837aaed775 100755 (executable)
@@ -201,6 +201,18 @@ $CONFIG = array(
 /* Whether ownCloud should log the last successfull cron exec */
 "cron_log" => true,
 
+/*
+ * Length of sharing tokens and the resulting links.
+ * This value defines how many possible sharing links there are, choosing a low value like 1 will make it easy to guess
+ * sharing links and will also limit the maximum number of shares. Behaviour after all tokens are used is undefined and
+ * may result in breakage.
+ * 1: Length of 4. Maximum of 65536 tokens. Links may look like this: example.com/s/1ekf
+ * 2: Length of 8. Maximum of 2^32 tokens. Links may look like this: example.com/s/1z141z3
+ * 3: (Default) Length of 16. Maximum of 2^64 tokens. Links may look like this: example.com/s/3w5e11264sgsf
+ * 4: (Old default, but base36) Length of 32. Maximum of 2^128 tokens. Links may look like this: example.com/s/f5lxx1zz5pnorynqglhzmsp33
+ */
+"sharing_token_length" => 3,
+
 /*
  * Configure the size in bytes log rotation should happen, 0 or false disables the rotation.
  * This rotates the current owncloud logfile to a new name, this way the total log usage
index 536f0e2ebd82b52a4025dfd6a87dac5bd8529aea..c6da79a8a42599b8b91b2ecaa4450eb810760be0 100644 (file)
@@ -46,8 +46,6 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo
                                                (!empty($_POST['expirationDate']) ? new \DateTime($_POST['expirationDate']) : null)
                                        );
 
-                                       $token = base_convert($token, 16, 36);
-
                                        if (is_string($token)) {
                                                OC_JSON::success(array('data' => array('token' => $token)));
                                        } else {
index 9a60b0aad692bb2743200e382145a67acc0ad909..bf33e3f2e48e5820f6eba74c5ba902065b43e3d3 100644 (file)
@@ -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);
        },
 
index d00b5f1ccf9fb6514a1614b98f7e2925a605665c..67ddd9c487059dc47d6c055051ffb2201c21e80d 100644 (file)
@@ -663,8 +663,6 @@ OC.Share={
                        // TODO: use oc webroot ?
                        var link = parent.location.protocol+'//'+location.host+OC.linkTo('', 'public.php')+'?service=files&'+type+'='+encodeURIComponent(file);
                } else {
-                       // convert the token to base36
-                       //token = parseInt(token, 16).toString(36);
                        //TODO add path param when showing a link to file in a subfolder of a public link share
                        var service='';
                        if(linkSharetype === 'folder' || linkSharetype === 'file'){
@@ -677,7 +675,7 @@ OC.Share={
                        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.linkTo('', 's.php')+'?t='+token;
+                               var link = parent.location.protocol+'//'+location.host+OC.generateUrl('/s/')+token;
                        }
                }
                $('#linkText').val(link);
index 06c4b98df2a95cdf41ad5636f4466c7447708a8a..e712ea58bc2f9e7b210b2c08378cfc96dafcbb13 100644 (file)
@@ -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() {
index 28a3680dd91a382db1d8d1b137968049013aa39f..fac67f2317529dd548b6656af8498c432eb009a4 100644 (file)
@@ -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 (file)
index 0000000..c1741af
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Copyright (c) 2014 Christopher Schäpers <christopher@schaepers.it>
+ * 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';
+       }
+}
+?>
index cf935bd4c0e1e273393e9ddb805e20092375a061..1ba4929899a41d061ffb701716908d004935f375 100644 (file)
@@ -34,8 +34,6 @@ class Constants {
        const FORMAT_STATUSES = -2;
        const FORMAT_SOURCES = -3;  // ToDo Check if it is still in use otherwise remove it
 
-       const TOKEN_LENGTH = 16; // old length is 32, thus 32 in db_structure.xml
-
        protected static $shareTypeUserAndGroups = -1;
        protected static $shareTypeGroupUserUnique = 2;
        protected static $backends = array();
index e2e9b94125e8ee7895ea307ad4cf92dcf370b82c..dfe0f65340b389b62ea4dc72b649e2d8270cb2b8 100644 (file)
@@ -640,7 +640,26 @@ class Share extends \OC\Share\Constants {
                                if (isset($oldToken)) {
                                        $token = $oldToken;
                                } else {
-                                       $token = \OC_Util::generateRandomBytes(self::TOKEN_LENGTH);
+                                       // Determine how long the token should be
+                                       switch (\OC_Config::getValue("sharing_token_length", 3)) {
+                                               case 1:
+                                                       $tokenLength = 4;
+                                                       break;
+                                               case 2:
+                                                       $tokenLength = 8;
+                                                       break;
+                                               // Default is 3, so skip the 3 block
+                                               case 4:
+                                                       $tokenLength = 32;
+                                                       break;
+                                               // Anything other than 1-4 should be default 3
+                                               default:
+                                                       $tokenLength = 16;
+                                                       break;
+                                       }
+                                       $token = \OC::$server->getSecureRandom()->getLowStrengthGenerator()->generate($tokenLength,
+                                               \OCP\Security\ISecureRandom::CHAR_LOWER.\OCP\Security\ISecureRandom::CHAR_DIGITS
+                                       );
                                }
                                $result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions,
                                        null, $token, $itemSourceName, $expirationDate);
index b4578d991c821a2b72c84f241d252e8672ce293c..0e04db66da79c6ada33e45b12f58363afb3e3082 100644 (file)
@@ -36,8 +36,6 @@ try {
        \OC::$REQUESTEDAPP = $app;
        OC_App::loadApps(array('authentication'));
        OC_App::loadApps(array('filesystem', 'logging'));
-       print_r($_GET);
-       print_r($parts);
 
        OC_Util::checkAppEnabled($app);
        OC_App::loadApp($app);
diff --git a/s.php b/s.php
deleted file mode 100644 (file)
index 9223fd7..0000000
--- a/s.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-try {
-
-       require_once 'lib/base.php';
-       OC::checkMaintenanceMode();
-       OC::checkSingleUserMode();
-       $file = OCP\CONFIG::getAppValue('core', 'public_files');
-       if(is_null($file)) {
-               header('HTTP/1.0 404 Not Found');
-               exit;
-       }
-
-       // convert the token to hex, if it's base36
-       if (strlen((string)$_GET['t']) != 16 && strlen((string)$_GET['t']) != 32) {
-               $_GET['t'] = base_convert($_GET['t'], 36, 16);
-
-               // the token should have leading zeroes and needs to be padded
-               if (strlen((string)$_GET['t']) != 16) {
-                       $padding = '';
-                       for ($i = 0; $i < (16 - strlen((string)$_GET['t'])); $i++) {
-                               $padding .= '0';
-                       }
-                       $_GET['t'] = $padding . $_GET['t'];
-               }
-       }
-
-       print($_GET['t']);
-
-       OC_Util::checkAppEnabled('files_sharing');
-       OC_App::loadApp('files_sharing');
-       OC_User::setIncognitoMode(true);
-
-       require_once OC_App::getAppPath('files_sharing') .'/public.php';
-
-} catch (Exception $ex) {
-       //show the user a detailed error page
-       OC_Response::setStatus(OC_Response::STATUS_INTERNAL_SERVER_ERROR);
-       \OCP\Util::writeLog('remote', $ex->getMessage(), \OCP\Util::FATAL);
-       OC_Template::printExceptionErrorPage($ex);
-}