mirror of
https://github.com/nextcloud/server.git
synced 2026-04-15 22:11:17 -04:00
Use a route instead of s.php and convert tokens asap
This commit is contained in:
parent
0f2ad9862e
commit
2a4c51389c
12 changed files with 69 additions and 54 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
23
core/share/controller.php
Normal file
23
core/share/controller.php
Normal file
|
|
@ -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';
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
41
s.php
41
s.php
|
|
@ -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);
|
||||
}
|
||||
Loading…
Reference in a new issue