diff options
-rw-r--r-- | apps/files/command/scan.php | 190 | ||||
-rw-r--r-- | apps/files_sharing/tests/js/publicAppSpec.js | 3 | ||||
-rw-r--r-- | bower.json | 3 | ||||
-rw-r--r-- | config/config.sample.php | 16 | ||||
-rw-r--r-- | console.php | 10 | ||||
-rw-r--r-- | core/avatar/avatarcontroller.php | 24 | ||||
-rw-r--r-- | core/js/files/client.js | 22 | ||||
-rw-r--r-- | core/templates/404.php | 2 | ||||
-rw-r--r-- | core/vendor/.gitignore | 2 | ||||
-rw-r--r-- | core/vendor/base64/.bower.json | 29 | ||||
-rw-r--r-- | core/vendor/base64/LICENSE | 14 | ||||
-rw-r--r-- | core/vendor/base64/base64.js | 61 | ||||
-rw-r--r-- | lib/private/avatar.php | 69 | ||||
-rw-r--r-- | lib/private/helper.php | 21 | ||||
-rw-r--r-- | lib/private/route/router.php | 2 | ||||
-rw-r--r-- | lib/private/template.php | 2 | ||||
-rw-r--r-- | lib/private/template/functions.php | 2 | ||||
-rw-r--r-- | lib/private/templatelayout.php | 4 | ||||
-rw-r--r-- | lib/public/iavatar.php | 11 | ||||
-rw-r--r-- | lib/public/util.php | 2 | ||||
-rw-r--r-- | tests/core/avatar/avatarcontrollertest.php | 42 | ||||
-rw-r--r-- | tests/lib/avatartest.php | 15 | ||||
-rw-r--r-- | tests/lib/helper.php | 46 |
23 files changed, 441 insertions, 151 deletions
diff --git a/apps/files/command/scan.php b/apps/files/command/scan.php index 31ae555e041..7e00d8a2312 100644 --- a/apps/files/command/scan.php +++ b/apps/files/command/scan.php @@ -32,6 +32,7 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Helper\Table; class Scan extends Command { @@ -39,6 +40,15 @@ class Scan extends Command { * @var \OC\User\Manager $userManager */ private $userManager; + /** @var float */ + protected $execTime = 0; + /** @var int */ + protected $foldersCounter = 0; + /** @var int */ + protected $filesCounter = 0; + /** @var bool */ + protected $interrupted = false; + public function __construct(\OC\User\Manager $userManager) { $this->userManager = $userManager; @@ -64,7 +74,13 @@ class Scan extends Command { 'quiet', 'q', InputOption::VALUE_NONE, - 'suppress output' + 'suppress any output' + ) + ->addOption( + 'verbose', + '-v|vv|vvv', + InputOption::VALUE_NONE, + 'verbose the output' ) ->addOption( 'all', @@ -74,19 +90,31 @@ class Scan extends Command { ); } - protected function scanFiles($user, $path, $quiet, OutputInterface $output) { + protected function scanFiles($user, $path, $verbose, OutputInterface $output) { $scanner = new \OC\Files\Utils\Scanner($user, \OC::$server->getDatabaseConnection(), \OC::$server->getLogger()); - if (!$quiet) { + # printout and count + if ($verbose) { $scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function ($path) use ($output) { $output->writeln("Scanning file <info>$path</info>"); + $this->filesCounter += 1; }); $scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', function ($path) use ($output) { $output->writeln("Scanning folder <info>$path</info>"); + $this->foldersCounter += 1; }); $scanner->listen('\OC\Files\Utils\Scanner', 'StorageNotAvailable', function (StorageNotAvailableException $e) use ($output) { $output->writeln("Error while scanning, storage not available (" . $e->getMessage() . ")"); }); + # count only + } else { + $scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function ($path) use ($output) { + $this->filesCounter += 1; + }); + $scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', function ($path) use ($output) { + $this->foldersCounter += 1; + }); } + try { $scanner->scan($path); } catch (ForbiddenException $e) { @@ -95,6 +123,7 @@ class Scan extends Command { } } + protected function execute(InputInterface $input, OutputInterface $output) { $inputPath = $input->getOption('path'); if ($inputPath) { @@ -106,24 +135,173 @@ class Scan extends Command { } else { $users = $input->getArgument('user_id'); } - $quiet = $input->getOption('quiet'); - if (count($users) === 0) { $output->writeln("<error>Please specify the user id to scan, \"--all\" to scan for all users or \"--path=...\"</error>"); return; } + # no messaging level option means: no full printout but statistics + # $quiet means no print at all + # $verbose means full printout including statistics + # -q -v full stat + # 0 0 no yes + # 0 1 yes yes + # 1 -- no no (quiet overrules verbose) + $verbose = $input->getOption('verbose'); + $quiet = $input->getOption('quiet'); + # restrict the verbosity level to VERBOSITY_VERBOSE + if ($output->getVerbosity()>OutputInterface::VERBOSITY_VERBOSE) { + $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE); + } + if ($quiet) { + $verbose = false; + } + + $this->initTools(); + foreach ($users as $user) { if (is_object($user)) { $user = $user->getUID(); } $path = $inputPath ? $inputPath : '/' . $user; if ($this->userManager->userExists($user)) { - $this->scanFiles($user, $path, $quiet, $output); + # full: printout data if $verbose was set + $this->scanFiles($user, $path, $verbose, $output); } else { $output->writeln("<error>Unknown user $user</error>"); } } + + # stat: printout statistics if $quiet was not set + if (!$quiet) { + $this->presentStats($output); + } + + } + + + /** + * Checks if the command was interrupted by ctrl-c + */ + protected function checkForInterruption($output) { + if ($this->hasBeenInterrupted()) { + $this->presentResults($output); + exit; + } + } + + + /** + * Initialises some useful tools for the Command + */ + protected function initTools() { + // Start the timer + $this->execTime = -microtime(true); + // Convert PHP errors to exceptions + set_error_handler([$this, 'exceptionErrorHandler'], E_ALL); + + // Collect interrupts and notify the running command + pcntl_signal(SIGTERM, [$this, 'cancelOperation']); + pcntl_signal(SIGINT, [$this, 'cancelOperation']); + } + + + /** + * Changes the status of the command to "interrupted" + * + * Gives a chance to the command to properly terminate what it's doing + */ + private function cancelOperation() { + $this->interrupted = true; + } + + + /** + * Processes PHP errors as exceptions in order to be able to keep track of problems + * + * @see https://secure.php.net/manual/en/function.set-error-handler.php + * + * @param int $severity the level of the error raised + * @param string $message + * @param string $file the filename that the error was raised in + * @param int $line the line number the error was raised + * + * @throws \ErrorException + */ + public function exceptionErrorHandler($severity, $message, $file, $line) { + if (!(error_reporting() & $severity)) { + // This error code is not included in error_reporting + return; + } + throw new \ErrorException($message, 0, $severity, $file, $line); } + + + /** + * @return bool + */ + protected function hasBeenInterrupted() { + $cancelled = false; + pcntl_signal_dispatch(); + if ($this->interrupted) { + $cancelled = true; + } + + return $cancelled; + } + + + /** + * @param OutputInterface $output + */ + protected function presentStats(OutputInterface $output) { + // Stop the timer + $this->execTime += microtime(true); + $output->writeln(""); + + $headers = [ + 'Folders', 'Files', 'Elapsed time' + ]; + + $this->showSummary($headers, null, $output); + } + + + /** + * Shows a summary of operations + * + * @param string[] $headers + * @param string[] $rows + * @param OutputInterface $output + */ + protected function showSummary($headers, $rows, OutputInterface $output) { + $niceDate = $this->formatExecTime(); + if (!$rows) { + $rows = [ + $this->foldersCounter, + $this->filesCounter, + $niceDate, + ]; + } + $table = new Table($output); + $table + ->setHeaders($headers) + ->setRows([$rows]); + $table->render(); + } + + + /** + * Formats microtime into a human readable format + * + * @return string + */ + protected function formatExecTime() { + list($secs, $tens) = explode('.', sprintf("%.1f", ($this->execTime))); + $niceDate = date('H:i:s', $secs) . '.' . $tens; + + return $niceDate; + } + } diff --git a/apps/files_sharing/tests/js/publicAppSpec.js b/apps/files_sharing/tests/js/publicAppSpec.js index 74f008025e1..2aaf758f3e3 100644 --- a/apps/files_sharing/tests/js/publicAppSpec.js +++ b/apps/files_sharing/tests/js/publicAppSpec.js @@ -89,7 +89,8 @@ describe('OCA.Sharing.PublicApp tests', function() { it('Uses public webdav endpoint', function() { expect(fakeServer.requests.length).toEqual(1); expect(fakeServer.requests[0].method).toEqual('PROPFIND'); - expect(fakeServer.requests[0].url).toEqual('https://sh4tok@example.com/owncloud/public.php/webdav/subdir'); + expect(fakeServer.requests[0].url).toEqual('https://example.com/owncloud/public.php/webdav/subdir'); + expect(fakeServer.requests[0].requestHeaders.Authorization).toEqual('Basic c2g0dG9rOm51bGw='); }); describe('Download Url', function() { diff --git a/bower.json b/bower.json index eb8d1ce0b7f..ae9575249c9 100644 --- a/bower.json +++ b/bower.json @@ -29,6 +29,7 @@ "bootstrap": "~3.3.6", "backbone": "~1.2.3", "davclient.js": "https://github.com/evert/davclient.js.git", - "es6-promise": "https://github.com/jakearchibald/es6-promise.git#~2.3.0" + "es6-promise": "https://github.com/jakearchibald/es6-promise.git#~2.3.0", + "base64": "~0.3.0" } } diff --git a/config/config.sample.php b/config/config.sample.php index 9b10792944f..6e823e3968d 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -799,22 +799,6 @@ $CONFIG = array( 'ldapUserCleanupInterval' => 51, /** - * Enforce the existence of the home folder naming rule for all users - * - * Following scenario: - * * a home folder naming rule is set in LDAP advanced settings - * * a user doesn't have the home folder naming rule attribute set - * - * If this is set to **true** (default) it will NOT fallback to the core's - * default naming rule of using the internal user ID as home folder name. - * - * If this is set to **false** it will fallback for the users without the - * attribute set to naming the home folder like the internal user ID. - * - */ -'enforce_home_folder_naming_rule' => true, - -/** * Comments * * Global settings for the Comments infrastructure diff --git a/console.php b/console.php index 8bfbabf2a03..ab845aced50 100644 --- a/console.php +++ b/console.php @@ -64,6 +64,16 @@ try { } } + $oldWorkingDir = getcwd(); + if ($oldWorkingDir === false) { + echo "This script can be run from the ownCloud root directory only." . PHP_EOL; + echo "Can't determine current working dir - the script will continue to work but be aware of the above fact." . PHP_EOL; + } else if ($oldWorkingDir !== __DIR__ && !chdir(__DIR__)) { + echo "This script can be run from the ownCloud root directory only." . PHP_EOL; + echo "Can't change to ownCloud root diretory." . PHP_EOL; + exit(1); + } + $application = new Application(\OC::$server->getConfig()); $application->loadCommands(new ConsoleOutput()); $application->run(); diff --git a/core/avatar/avatarcontroller.php b/core/avatar/avatarcontroller.php index 6c0321e6b5e..e8139aa50ae 100644 --- a/core/avatar/avatarcontroller.php +++ b/core/avatar/avatarcontroller.php @@ -30,6 +30,7 @@ use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\DataDisplayResponse; +use OCP\Files\NotFoundException; use OCP\IAvatarManager; use OCP\ILogger; use OCP\IL10N; @@ -112,20 +113,23 @@ class AvatarController extends Controller { $size = 64; } - $avatar = $this->avatarManager->getAvatar($userId); - $image = $avatar->get($size); - - if ($image instanceof \OCP\IImage) { - $resp = new DataDisplayResponse($image->data(), + try { + $avatar = $this->avatarManager->getAvatar($userId)->getFile($size); + $resp = new DataDisplayResponse($avatar->getContent(), Http::STATUS_OK, - ['Content-Type' => $image->mimeType()]); - $resp->setETag(crc32($image->data())); - } else { + ['Content-Type' => $avatar->getMimeType()]); + $resp->setETag($avatar->getEtag()); + } catch (NotFoundException $e) { $user = $this->userManager->get($userId); - $userName = $user ? $user->getDisplayName() : ''; $resp = new DataResponse([ 'data' => [ - 'displayname' => $userName, + 'displayname' => $user->getDisplayName(), + ], + ]); + } catch (\Exception $e) { + $resp = new DataResponse([ + 'data' => [ + 'displayname' => '', ], ]); } diff --git a/core/js/files/client.js b/core/js/files/client.js index 8854ee0c809..3d31f974ff8 100644 --- a/core/js/files/client.js +++ b/core/js/files/client.js @@ -35,27 +35,25 @@ if (options.useHTTPS) { url = 'https://'; } - var credentials = ''; - if (options.userName) { - credentials += encodeURIComponent(options.userName); - } - if (options.password) { - credentials += ':' + encodeURIComponent(options.password); - } - if (credentials.length > 0) { - url += credentials + '@'; - } url += options.host + this._root; this._defaultHeaders = options.defaultHeaders || {'X-Requested-With': 'XMLHttpRequest'}; this._baseUrl = url; - this._client = new dav.Client({ + + var clientOptions = { baseUrl: this._baseUrl, xmlNamespaces: { 'DAV:': 'd', 'http://owncloud.org/ns': 'oc' } - }); + }; + if (options.userName) { + clientOptions.userName = options.userName; + } + if (options.password) { + clientOptions.password = options.password; + } + this._client = new dav.Client(clientOptions); this._client.xhrProvider = _.bind(this._xhrProvider, this); }; diff --git a/core/templates/404.php b/core/templates/404.php index c8d16e3e8f7..2b12b12cff7 100644 --- a/core/templates/404.php +++ b/core/templates/404.php @@ -16,7 +16,7 @@ if(!isset($_)) {//also provide standalone error page <li class="error"> <?php p($l->t('File not found')); ?><br> <p class="hint"><?php p($l->t('The specified document has not been found on the server.')); ?></p> - <p class="hint"><a href="<?php p(OC_Helper::linkTo('', 'index.php')) ?>"><?php p($l->t('You can click here to return to %s.', array($theme->getName()))); ?></a></p> + <p class="hint"><a href="<?php p(\OC::$server->getURLGenerator()->linkTo('', 'index.php')) ?>"><?php p($l->t('You can click here to return to %s.', array($theme->getName()))); ?></a></p> </li> </ul> <?php endif; ?> diff --git a/core/vendor/.gitignore b/core/vendor/.gitignore index 09b6a47c72d..3560e8c8668 100644 --- a/core/vendor/.gitignore +++ b/core/vendor/.gitignore @@ -133,3 +133,5 @@ es6-promise/** !es6-promise/LICENSE !es6-promise/dist/es6-promise.js +# base64 +base64/*min.js diff --git a/core/vendor/base64/.bower.json b/core/vendor/base64/.bower.json new file mode 100644 index 00000000000..43a7299706b --- /dev/null +++ b/core/vendor/base64/.bower.json @@ -0,0 +1,29 @@ +{ + "name": "base64", + "version": "0.3.0", + "description": "Base64 encoding and decoding", + "main": "./base64.js", + "license": "WTFPL", + "repository": { + "type": "git", + "url": "git://github.com/davidchambers/Base64.js.git" + }, + "ignore": [ + "**/.*", + "Makefile", + "coverage/", + "scripts/", + "test/" + ], + "homepage": "https://github.com/davidchambers/Base64.js", + "_release": "0.3.0", + "_resolution": { + "type": "version", + "tag": "0.3.0", + "commit": "772df096a5ffe983f40202684ad45eed1e0e2d59" + }, + "_source": "git://github.com/davidchambers/Base64.js.git", + "_target": "~0.3.0", + "_originalSource": "base64", + "_direct": true +}
\ No newline at end of file diff --git a/core/vendor/base64/LICENSE b/core/vendor/base64/LICENSE new file mode 100644 index 00000000000..483276716db --- /dev/null +++ b/core/vendor/base64/LICENSE @@ -0,0 +1,14 @@ + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (c) 2011..2012 David Chambers <dc@hashify.me> + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/core/vendor/base64/base64.js b/core/vendor/base64/base64.js new file mode 100644 index 00000000000..b82dded62c2 --- /dev/null +++ b/core/vendor/base64/base64.js @@ -0,0 +1,61 @@ +;(function () { + + var object = typeof exports != 'undefined' ? exports : this; // #8: web workers + var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + + function InvalidCharacterError(message) { + this.message = message; + } + InvalidCharacterError.prototype = new Error; + InvalidCharacterError.prototype.name = 'InvalidCharacterError'; + + // encoder + // [https://gist.github.com/999166] by [https://github.com/nignag] + object.btoa || ( + object.btoa = function (input) { + var str = String(input); + for ( + // initialize result and counter + var block, charCode, idx = 0, map = chars, output = ''; + // if the next str index does not exist: + // change the mapping table to "=" + // check if d has no fractional digits + str.charAt(idx | 0) || (map = '=', idx % 1); + // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 + output += map.charAt(63 & block >> 8 - idx % 1 * 8) + ) { + charCode = str.charCodeAt(idx += 3/4); + if (charCode > 0xFF) { + throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."); + } + block = block << 8 | charCode; + } + return output; + }); + + // decoder + // [https://gist.github.com/1020396] by [https://github.com/atk] + object.atob || ( + object.atob = function (input) { + var str = String(input).replace(/=+$/, ''); + if (str.length % 4 == 1) { + throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded."); + } + for ( + // initialize result and counters + var bc = 0, bs, buffer, idx = 0, output = ''; + // get next character + buffer = str.charAt(idx++); + // character found in table? initialize bit storage and add its ascii value; + ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, + // and if not first of each 4 characters, + // convert the first 8 bits to one ascii character + bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 + ) { + // try to find character in table (0-63, not found => -1) + buffer = chars.indexOf(buffer); + } + return output; + }); + +}()); diff --git a/lib/private/avatar.php b/lib/private/avatar.php index 37a813f3ff8..c87facd25da 100644 --- a/lib/private/avatar.php +++ b/lib/private/avatar.php @@ -31,6 +31,7 @@ namespace OC; use OCP\Files\Folder; use OCP\Files\File; +use OCP\Files\NotFoundException; use OCP\IL10N; use OC_Image; @@ -62,28 +63,14 @@ class Avatar implements \OCP\IAvatar { * @return boolean|\OCP\IImage containing the avatar or false if there's no image */ public function get ($size = 64) { - if ($this->folder->nodeExists('avatar.jpg')) { - $ext = 'jpg'; - } elseif ($this->folder->nodeExists('avatar.png')) { - $ext = 'png'; - } else { + try { + $file = $this->getFile($size); + } catch (NotFoundException $e) { return false; } $avatar = new OC_Image(); - if ($this->folder->nodeExists('avatar.' . $size . '.' . $ext)) { - /** @var File $node */ - $node = $this->folder->get('avatar.' . $size . '.' . $ext); - $avatar->loadFromData($node->getContent()); - } else { - /** @var File $node */ - $node = $this->folder->get('avatar.' . $ext); - $avatar->loadFromData($node->getContent()); - if ($size > 0) { - $avatar->resize($size); - } - $this->folder->newFile('avatar.' . $size . '.' . $ext)->putContent($avatar->data()); - } + $avatar->loadFromData($file->getContent()); return $avatar; } @@ -144,4 +131,50 @@ class Avatar implements \OCP\IAvatar { $this->folder->get('avatar.png')->delete(); } catch (\OCP\Files\NotFoundException $e) {} } + + /** + * Get the File of an avatar of size $size. + * + * @param int $size + * @return File + * @throws NotFoundException + */ + public function getFile($size) { + $ext = $this->getExtention(); + + $path = 'avatar.' . $size . '.' . $ext; + + try { + $file = $this->folder->get($path); + } catch (NotFoundException $e) { + if ($size <= 0) { + throw new NotFoundException; + } + + $avatar = new OC_Image(); + /** @var File $file */ + $file = $this->folder->get('avatar.' . $ext); + $avatar->loadFromData($file->getContent()); + $avatar->resize($size); + $file = $this->folder->newFile($path); + $file->putContent($avatar->data()); + } + + return $file; + } + + /** + * Get the extention of the avatar. If there is no avatar throw Exception + * + * @return string + * @throws NotFoundException + */ + private function getExtention() { + if ($this->folder->nodeExists('avatar.jpg')) { + return 'jpg'; + } elseif ($this->folder->nodeExists('avatar.png')) { + return 'png'; + } + throw new NotFoundException; + } } diff --git a/lib/private/helper.php b/lib/private/helper.php index 78a567638ef..779a67a2340 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -67,21 +67,6 @@ class OC_Helper { } /** - * Creates an url - * @param string $app app - * @param string $file file - * @param array $args array with param=>value, will be appended to the returned url - * The value of $args will be urlencoded - * @return string the url - * @deprecated Use \OC::$server->getURLGenerator()->linkTo($app, $file, $args) - * - * Returns a url to the given app and file. - */ - public static function linkTo( $app, $file, $args = array() ) { - return OC::$server->getURLGenerator()->linkTo($app, $file, $args); - } - - /** * Creates an absolute url * @param string $app app * @param string $file file @@ -93,7 +78,7 @@ class OC_Helper { */ public static function linkToAbsolute($app, $file, $args = array()) { return OC::$server->getURLGenerator()->getAbsoluteURL( - self::linkTo($app, $file, $args) + OC::$server->getURLGenerator()->linkTo($app, $file, $args) ); } @@ -117,7 +102,7 @@ class OC_Helper { * Returns a url to the given service. */ public static function linkToRemoteBase($service) { - return self::linkTo('', 'remote.php') . '/' . $service; + return OC::$server->getURLGenerator()->linkTo('', 'remote.php') . '/' . $service; } /** @@ -147,7 +132,7 @@ class OC_Helper { if ($service === 'files') { $url = OC::$server->getURLGenerator()->getAbsoluteURL('/s'); } else { - $url = OC::$server->getURLGenerator()->getAbsoluteURL(self::linkTo('', 'public.php').'?service='.$service); + $url = OC::$server->getURLGenerator()->getAbsoluteURL(OC::$server->getURLGenerator()->linkTo('', 'public.php').'?service='.$service); } return $url . (($add_slash && $service[strlen($service) - 1] != '/') ? '/' : ''); } diff --git a/lib/private/route/router.php b/lib/private/route/router.php index 4ca5e16ddf2..f144c543989 100644 --- a/lib/private/route/router.php +++ b/lib/private/route/router.php @@ -92,7 +92,7 @@ class Router implements IRouter { $this->logger = $logger; $baseUrl = \OC::$WEBROOT; if(!(getenv('front_controller_active') === 'true')) { - $baseUrl = \OC_Helper::linkTo('', 'index.php'); + $baseUrl = \OC::$server->getURLGenerator()->linkTo('', 'index.php'); } if (!\OC::$CLI) { $method = $_SERVER['REQUEST_METHOD']; diff --git a/lib/private/template.php b/lib/private/template.php index d794dacac23..04d6a906880 100644 --- a/lib/private/template.php +++ b/lib/private/template.php @@ -162,6 +162,8 @@ class OC_Template extends \OC\Template\Base { } if (\OC::$server->getRequest()->isUserAgent([\OC\AppFramework\Http\Request::USER_AGENT_IE])) { + // polyfill for btoa/atob for IE friends + OC_Util::addVendorScript('base64/base64'); // shim for the davclient.js library \OCP\Util::addScript('files/iedavclient'); } diff --git a/lib/private/template/functions.php b/lib/private/template/functions.php index d156d26f9ce..6298f25edc1 100644 --- a/lib/private/template/functions.php +++ b/lib/private/template/functions.php @@ -146,7 +146,7 @@ function component($app, $file) { * For further information have a look at OC_Helper::linkTo */ function link_to( $app, $file, $args = array() ) { - return OC_Helper::linkTo( $app, $file, $args ); + return \OC::$server->getURLGenerator()->linkTo($app, $file, $args); } /** diff --git a/lib/private/templatelayout.php b/lib/private/templatelayout.php index 8522dbccc00..fce018115ac 100644 --- a/lib/private/templatelayout.php +++ b/lib/private/templatelayout.php @@ -281,8 +281,8 @@ class OC_TemplateLayout extends OC_Template { $writer->writeAsset($cssCollection); } - $this->append('jsfiles', OC_Helper::linkTo('assets', "$jsHash.js")); - $this->append('cssfiles', OC_Helper::linkTo('assets', "$cssHash.css")); + $this->append('jsfiles', \OC::$server->getURLGenerator()->linkTo('assets', "$jsHash.js")); + $this->append('cssfiles', \OC::$server->getURLGenerator()->linkTo('assets', "$cssHash.css")); } /** diff --git a/lib/public/iavatar.php b/lib/public/iavatar.php index fc29212a599..3d92d00b83d 100644 --- a/lib/public/iavatar.php +++ b/lib/public/iavatar.php @@ -24,6 +24,8 @@ */ namespace OCP; +use OCP\Files\File; +use OCP\Files\NotFoundException; /** * This class provides avatar functionality @@ -64,4 +66,13 @@ interface IAvatar { * @since 6.0.0 */ public function remove(); + + /** + * Get the file of the avatar + * @param int $size + * @return File + * @throws NotFoundException + * @since 9.0.0 + */ + public function getFile($size); } diff --git a/lib/public/util.php b/lib/public/util.php index 4e783b764ed..e0c875438f2 100644 --- a/lib/public/util.php +++ b/lib/public/util.php @@ -316,7 +316,7 @@ class Util { * @since 4.0.0 - parameter $args was added in 4.5.0 */ public static function linkTo( $app, $file, $args = array() ) { - return(\OC_Helper::linkTo( $app, $file, $args )); + return \OC::$server->getURLGenerator()->linkTo($app, $file, $args); } /** diff --git a/tests/core/avatar/avatarcontrollertest.php b/tests/core/avatar/avatarcontrollertest.php index a113add72b9..7f69ba0aadb 100644 --- a/tests/core/avatar/avatarcontrollertest.php +++ b/tests/core/avatar/avatarcontrollertest.php @@ -26,8 +26,10 @@ use OCP\AppFramework\IAppContainer; use OCP\AppFramework\Http; use OCP\Files\Folder; use OCP\Files\File; +use OCP\Files\NotFoundException; use OCP\IUser; use OCP\IAvatar; +use Punic\Exception; use Test\Traits\UserTrait; /** @@ -56,6 +58,8 @@ class AvatarControllerTest extends \Test\TestCase { private $avatarMock; /** @var IUser */ private $userMock; + /** @var File */ + private $avatarFile; protected function setUp() { parent::setUp(); @@ -88,6 +92,10 @@ class AvatarControllerTest extends \Test\TestCase { ->willReturnMap([['userId', $this->userMock]]); $this->container['UserSession']->method('getUser')->willReturn($this->userMock); + $this->avatarFile = $this->getMock('OCP\Files\File'); + $this->avatarFile->method('getContnet')->willReturn('image data'); + $this->avatarFile->method('getMimeType')->willReturn('image type'); + $this->avatarFile->method('getEtag')->willReturn('my etag'); } public function tearDown() { @@ -100,6 +108,7 @@ class AvatarControllerTest extends \Test\TestCase { */ public function testGetAvatarNoAvatar() { $this->container['AvatarManager']->method('getAvatar')->willReturn($this->avatarMock); + $this->avatarMock->method('getFile')->will($this->throwException(new NotFoundException())); $response = $this->avatarController->getAvatar('userId', 32); //Comment out until JS is fixed @@ -112,12 +121,8 @@ class AvatarControllerTest extends \Test\TestCase { * Fetch the user's avatar */ public function testGetAvatar() { - $image = $this->getMock('OCP\IImage'); - $image->method('data')->willReturn('image data'); - $image->method('mimeType')->willReturn('image type'); - - $this->avatarMock->method('get')->willReturn($image); - $this->container['AvatarManager']->method('getAvatar')->willReturn($this->avatarMock); + $this->avatarMock->method('getFile')->willReturn($this->avatarFile); + $this->container['AvatarManager']->method('getAvatar')->with('userId')->willReturn($this->avatarMock); $response = $this->avatarController->getAvatar('userId', 32); @@ -125,17 +130,19 @@ class AvatarControllerTest extends \Test\TestCase { $this->assertArrayHasKey('Content-Type', $response->getHeaders()); $this->assertEquals('image type', $response->getHeaders()['Content-Type']); - $this->assertEquals(crc32('image data'), $response->getEtag()); + $this->assertEquals('my etag', $response->getEtag()); } /** * Fetch the avatar of a non-existing user */ public function testGetAvatarNoUser() { - $this->avatarMock->method('get')->willReturn(null); - $this->container['AvatarManager']->method('getAvatar')->willReturn($this->avatarMock); + $this->container['AvatarManager'] + ->method('getAvatar') + ->with('userDoesNotExist') + ->will($this->throwException(new \Exception('user does not exist'))); - $response = $this->avatarController->getAvatar('userDoesnotexist', 32); + $response = $this->avatarController->getAvatar('userDoesNotExist', 32); //Comment out until JS is fixed //$this->assertEquals(Http::STATUS_NOT_FOUND, $response->getStatus()); @@ -148,8 +155,9 @@ class AvatarControllerTest extends \Test\TestCase { */ public function testGetAvatarSize() { $this->avatarMock->expects($this->once()) - ->method('get') - ->with($this->equalTo(32)); + ->method('getFile') + ->with($this->equalTo(32)) + ->willReturn($this->avatarFile); $this->container['AvatarManager']->method('getAvatar')->willReturn($this->avatarMock); @@ -161,8 +169,9 @@ class AvatarControllerTest extends \Test\TestCase { */ public function testGetAvatarSizeMin() { $this->avatarMock->expects($this->once()) - ->method('get') - ->with($this->equalTo(64)); + ->method('getFile') + ->with($this->equalTo(64)) + ->willReturn($this->avatarFile); $this->container['AvatarManager']->method('getAvatar')->willReturn($this->avatarMock); @@ -174,8 +183,9 @@ class AvatarControllerTest extends \Test\TestCase { */ public function testGetAvatarSizeMax() { $this->avatarMock->expects($this->once()) - ->method('get') - ->with($this->equalTo(2048)); + ->method('getFile') + ->with($this->equalTo(2048)) + ->willReturn($this->avatarFile); $this->container['AvatarManager']->method('getAvatar')->willReturn($this->avatarMock); diff --git a/tests/lib/avatartest.php b/tests/lib/avatartest.php index 49e8be98c83..3d77a282a7d 100644 --- a/tests/lib/avatartest.php +++ b/tests/lib/avatartest.php @@ -60,12 +60,25 @@ class AvatarTest extends \Test\TestCase { $file = $this->getMock('\OCP\Files\File'); $file->method('getContent')->willReturn($expected->data()); - $this->folder->method('get')->with('avatar.png')->willReturn($file); + + $this->folder->method('get') + ->will($this->returnCallback( + function($path) use ($file) { + if ($path === 'avatar.png') { + return $file; + } else { + throw new \OCP\Files\NotFoundException; + } + } + )); $newFile = $this->getMock('\OCP\Files\File'); $newFile->expects($this->once()) ->method('putContent') ->with($expected2->data()); + $newFile->expects($this->once()) + ->method('getContent') + ->willReturn($expected2->data()); $this->folder->expects($this->once()) ->method('newFile') ->with('avatar.32.png') diff --git a/tests/lib/helper.php b/tests/lib/helper.php index b7deb3fc13d..469ffecc773 100644 --- a/tests/lib/helper.php +++ b/tests/lib/helper.php @@ -296,52 +296,6 @@ class Test_Helper extends \Test\TestCase { /** * @small - * test linkTo URL construction - * @dataProvider provideDocRootAppUrlParts - */ - public function testLinkToDocRoot($app, $file, $args, $expectedResult) { - \OC::$WEBROOT = ''; - $result = \OC_Helper::linkTo($app, $file, $args); - - $this->assertEquals($expectedResult, $result); - } - - /** - * @small - * test linkTo URL construction in sub directory - * @dataProvider provideSubDirAppUrlParts - */ - public function testLinkToSubDir($app, $file, $args, $expectedResult) { - \OC::$WEBROOT = '/owncloud'; - $result = \OC_Helper::linkTo($app, $file, $args); - - $this->assertEquals($expectedResult, $result); - } - - /** - * @return array - */ - public function provideDocRootAppUrlParts() { - return array( - array('files', 'ajax/list.php', array(), '/index.php/apps/files/ajax/list.php'), - array('files', 'ajax/list.php', array('trut' => 'trat', 'dut' => 'dat'), '/index.php/apps/files/ajax/list.php?trut=trat&dut=dat'), - array('', 'index.php', array('trut' => 'trat', 'dut' => 'dat'), '/index.php?trut=trat&dut=dat'), - ); - } - - /** - * @return array - */ - public function provideSubDirAppUrlParts() { - return array( - array('files', 'ajax/list.php', array(), '/owncloud/index.php/apps/files/ajax/list.php'), - array('files', 'ajax/list.php', array('trut' => 'trat', 'dut' => 'dat'), '/owncloud/index.php/apps/files/ajax/list.php?trut=trat&dut=dat'), - array('', 'index.php', array('trut' => 'trat', 'dut' => 'dat'), '/owncloud/index.php?trut=trat&dut=dat'), - ); - } - - /** - * @small * test linkToAbsolute URL construction * @dataProvider provideDocRootAppAbsoluteUrlParts */ |