summaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/App/AppManager.php15
-rw-r--r--lib/private/App/AppStore/Fetcher/AppFetcher.php7
-rw-r--r--lib/private/App/AppStore/Fetcher/Fetcher.php39
-rw-r--r--lib/private/Archive/TAR.php19
-rw-r--r--lib/private/Archive/ZIP.php18
-rw-r--r--lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php38
-rw-r--r--lib/private/Files/ObjectStore/ObjectStoreStorage.php21
-rw-r--r--lib/private/Files/Storage/DAV.php18
-rw-r--r--lib/private/Files/Stream/Close.php119
-rw-r--r--lib/private/Files/Stream/Quota.php94
-rw-r--r--lib/private/Files/Stream/StaticStream.php171
-rw-r--r--lib/private/Files/View.php25
-rw-r--r--lib/private/Memcache/APC.php136
-rw-r--r--lib/private/Memcache/Factory.php6
-rw-r--r--lib/private/Repair/RepairInvalidShares.php24
-rw-r--r--lib/private/Security/CertificateManager.php20
-rw-r--r--lib/private/Server.php5
-rw-r--r--lib/private/Setup/PostgreSQL.php16
-rw-r--r--lib/private/Share20/Manager.php1
-rw-r--r--lib/private/Template/CSSResourceLocator.php42
-rwxr-xr-x[-rw-r--r--]lib/private/Template/ResourceLocator.php0
-rw-r--r--lib/private/Template/SCSSCacher.php189
-rw-r--r--lib/private/TemplateLayout.php24
-rw-r--r--lib/private/User/Database.php1
-rw-r--r--lib/private/User/Session.php1
-rw-r--r--lib/private/legacy/app.php8
26 files changed, 472 insertions, 585 deletions
diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php
index fca5c9b87ac..6b819ef7ac1 100644
--- a/lib/private/App/AppManager.php
+++ b/lib/private/App/AppManager.php
@@ -221,6 +221,21 @@ class AppManager implements IAppManager {
}
/**
+ * Whether a list of types contains a protected app type
+ *
+ * @param string[] $types
+ * @return bool
+ */
+ public function hasProtectedAppType($types) {
+ if (empty($types)) {
+ return false;
+ }
+
+ $protectedTypes = array_intersect($this->protectedAppTypes, $types);
+ return !empty($protectedTypes);
+ }
+
+ /**
* Enable an app only for specific groups
*
* @param string $appId
diff --git a/lib/private/App/AppStore/Fetcher/AppFetcher.php b/lib/private/App/AppStore/Fetcher/AppFetcher.php
index 9ebc12dbc27..7c5efafc92f 100644
--- a/lib/private/App/AppStore/Fetcher/AppFetcher.php
+++ b/lib/private/App/AppStore/Fetcher/AppFetcher.php
@@ -59,11 +59,14 @@ class AppFetcher extends Fetcher {
/**
* Only returns the latest compatible app release in the releases array
*
+ * @param string $ETag
+ * @param string $content
+ *
* @return array
*/
- protected function fetch() {
+ protected function fetch($ETag, $content) {
/** @var mixed[] $response */
- $response = parent::fetch();
+ $response = parent::fetch($ETag, $content);
$ncVersion = $this->config->getSystemValue('version');
$ncMajorVersion = explode('.', $ncVersion)[0];
diff --git a/lib/private/App/AppStore/Fetcher/Fetcher.php b/lib/private/App/AppStore/Fetcher/Fetcher.php
index 2067242e817..dab79e11821 100644
--- a/lib/private/App/AppStore/Fetcher/Fetcher.php
+++ b/lib/private/App/AppStore/Fetcher/Fetcher.php
@@ -21,6 +21,7 @@
namespace OC\App\AppStore\Fetcher;
+use OCP\AppFramework\Http;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
@@ -62,15 +63,37 @@ abstract class Fetcher {
/**
* Fetches the response from the server
*
+ * @param string $ETag
+ * @param string $content
+ *
* @return array
*/
- protected function fetch() {
+ protected function fetch($ETag, $content) {
+ $options = [];
+
+ if ($ETag !== '') {
+ $options['headers'] = [
+ 'If-None-Match' => $ETag,
+ ];
+ }
+
$client = $this->clientService->newClient();
- $response = $client->get($this->endpointUrl);
+ $response = $client->get($this->endpointUrl, $options);
+
$responseJson = [];
- $responseJson['data'] = json_decode($response->getBody(), true);
+ if ($response->getStatusCode() === Http::STATUS_NOT_MODIFIED) {
+ $responseJson['data'] = json_decode($content, true);
+ } else {
+ $responseJson['data'] = json_decode($response->getBody(), true);
+ $ETag = $response->getHeader('ETag');
+ }
+
$responseJson['timestamp'] = $this->timeFactory->getTime();
$responseJson['ncversion'] = $this->config->getSystemValue('version');
+ if ($ETag !== '') {
+ $responseJson['ETag'] = $ETag;
+ }
+
return $responseJson;
}
@@ -82,6 +105,9 @@ abstract class Fetcher {
public function get() {
$rootFolder = $this->appData->getFolder('/');
+ $ETag = '';
+ $content = '';
+
try {
// File does already exists
$file = $rootFolder->getFile($this->fileName);
@@ -95,6 +121,11 @@ abstract class Fetcher {
isset($jsonBlob['ncversion']) && $jsonBlob['ncversion'] === $this->config->getSystemValue('version', '0.0.0')) {
return $jsonBlob['data'];
}
+
+ if (isset($jsonBlob['ETag'])) {
+ $ETag = $jsonBlob['ETag'];
+ $content = json_encode($jsonBlob['data']);
+ }
}
} catch (NotFoundException $e) {
// File does not already exists
@@ -103,7 +134,7 @@ abstract class Fetcher {
// Refresh the file content
try {
- $responseJson = $this->fetch();
+ $responseJson = $this->fetch($ETag, $content);
$file->putContent(json_encode($responseJson));
return json_decode($file->getContent(), true)['data'];
} catch (\Exception $e) {
diff --git a/lib/private/Archive/TAR.php b/lib/private/Archive/TAR.php
index bbd24bd05a1..07ccd09f399 100644
--- a/lib/private/Archive/TAR.php
+++ b/lib/private/Archive/TAR.php
@@ -33,6 +33,8 @@
namespace OC\Archive;
+use Icewind\Streams\CallbackWrapper;
+
class TAR extends Archive {
const PLAIN = 0;
const GZIP = 1;
@@ -359,22 +361,19 @@ class TAR extends Archive {
if ($mode == 'r' or $mode == 'rb') {
return fopen($tmpFile, $mode);
} else {
- \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
- self::$tempFiles[$tmpFile] = $path;
- return fopen('close://' . $tmpFile, $mode);
+ $handle = fopen($tmpFile, $mode);
+ return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
+ $this->writeBack($tmpFile, $path);
+ });
}
}
- private static $tempFiles = array();
-
/**
* write back temporary files
*/
- function writeBack($tmpFile) {
- if (isset(self::$tempFiles[$tmpFile])) {
- $this->addFile(self::$tempFiles[$tmpFile], $tmpFile);
- unlink($tmpFile);
- }
+ function writeBack($tmpFile, $path) {
+ $this->addFile($path, $tmpFile);
+ unlink($tmpFile);
}
/**
diff --git a/lib/private/Archive/ZIP.php b/lib/private/Archive/ZIP.php
index 9e9fe40b2b4..0ed0f48acc4 100644
--- a/lib/private/Archive/ZIP.php
+++ b/lib/private/Archive/ZIP.php
@@ -31,6 +31,8 @@
namespace OC\Archive;
+use Icewind\Streams\CallbackWrapper;
+
class ZIP extends Archive{
/**
* @var \ZipArchive zip
@@ -198,24 +200,22 @@ class ZIP extends Archive{
$ext='';
}
$tmpFile=\OCP\Files::tmpFile($ext);
- \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
if($this->fileExists($path)) {
$this->extractFile($path, $tmpFile);
}
- self::$tempFiles[$tmpFile]=$path;
- return fopen('close://'.$tmpFile, $mode);
+ $handle = fopen($tmpFile, $mode);
+ return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
+ $this->writeBack($tmpFile, $path);
+ });
}
}
- private static $tempFiles=array();
/**
* write back temporary files
*/
- function writeBack($tmpFile) {
- if(isset(self::$tempFiles[$tmpFile])) {
- $this->addFile(self::$tempFiles[$tmpFile], $tmpFile);
- unlink($tmpFile);
- }
+ function writeBack($tmpFile, $path) {
+ $this->addFile($path, $tmpFile);
+ unlink($tmpFile);
}
/**
diff --git a/lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php b/lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php
index f9170e97a02..f172260df79 100644
--- a/lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php
+++ b/lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php
@@ -30,6 +30,8 @@ use OC\DB\QueryBuilder\Literal;
use OC\DB\QueryBuilder\QueryFunction;
use OC\DB\QueryBuilder\QuoteHelper;
use OCP\DB\QueryBuilder\IExpressionBuilder;
+use OCP\DB\QueryBuilder\ILiteral;
+use OCP\DB\QueryBuilder\IQueryFunction;
use OCP\IDBConnection;
class ExpressionBuilder implements IExpressionBuilder {
@@ -39,12 +41,16 @@ class ExpressionBuilder implements IExpressionBuilder {
/** @var QuoteHelper */
protected $helper;
+ /** @var IDBConnection */
+ protected $connection;
+
/**
* Initializes a new <tt>ExpressionBuilder</tt>.
*
* @param \OCP\IDBConnection $connection
*/
public function __construct(IDBConnection $connection) {
+ $this->connection = $connection;
$this->helper = new QuoteHelper();
$this->expressionBuilder = new DoctrineExpressionBuilder($connection);
}
@@ -345,12 +351,42 @@ class ExpressionBuilder implements IExpressionBuilder {
}
/**
+ * Binary AND Operator copies a bit to the result if it exists in both operands.
+ *
+ * @param string|ILiteral $x The field or value to check
+ * @param int $y Bitmap that must be set
+ * @return IQueryFunction
+ * @since 12.0.0
+ */
+ public function bitwiseAnd($x, $y) {
+ return new QueryFunction($this->connection->getDatabasePlatform()->getBitAndComparisonExpression(
+ $this->helper->quoteColumnName($x),
+ $y
+ ));
+ }
+
+ /**
+ * Binary OR Operator copies a bit if it exists in either operand.
+ *
+ * @param string|ILiteral $x The field or value to check
+ * @param int $y Bitmap that must be set
+ * @return IQueryFunction
+ * @since 12.0.0
+ */
+ public function bitwiseOr($x, $y) {
+ return new QueryFunction($this->connection->getDatabasePlatform()->getBitOrComparisonExpression(
+ $this->helper->quoteColumnName($x),
+ $y
+ ));
+ }
+
+ /**
* Quotes a given input parameter.
*
* @param mixed $input The parameter to be quoted.
* @param mixed|null $type One of the IQueryBuilder::PARAM_* constants
*
- * @return Literal
+ * @return ILiteral
*/
public function literal($input, $type = null) {
return new Literal($this->expressionBuilder->literal($input, $type));
diff --git a/lib/private/Files/ObjectStore/ObjectStoreStorage.php b/lib/private/Files/ObjectStore/ObjectStoreStorage.php
index 2dcf830cc1e..ab77c21e6c4 100644
--- a/lib/private/Files/ObjectStore/ObjectStoreStorage.php
+++ b/lib/private/Files/ObjectStore/ObjectStoreStorage.php
@@ -25,16 +25,12 @@
namespace OC\Files\ObjectStore;
+use Icewind\Streams\CallbackWrapper;
use Icewind\Streams\IteratorDirectory;
use OC\Files\Cache\CacheEntry;
use OCP\Files\ObjectStore\IObjectStore;
class ObjectStoreStorage extends \OC\Files\Storage\Common {
-
- /**
- * @var array
- */
- private static $tmpFiles = array();
/**
* @var \OCP\Files\ObjectStore\IObjectStore $objectStore
*/
@@ -291,14 +287,14 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common {
$ext = '';
}
$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
- \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
if ($this->file_exists($path)) {
$source = $this->fopen($path, 'r');
file_put_contents($tmpFile, $source);
}
- self::$tmpFiles[$tmpFile] = $path;
-
- return fopen('close://' . $tmpFile, $mode);
+ $handle = fopen($tmpFile, $mode);
+ return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
+ $this->writeBack($tmpFile, $path);
+ });
}
return false;
}
@@ -368,12 +364,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common {
return true;
}
- public function writeBack($tmpFile) {
- if (!isset(self::$tmpFiles[$tmpFile])) {
- return;
- }
-
- $path = self::$tmpFiles[$tmpFile];
+ public function writeBack($tmpFile, $path) {
$stat = $this->stat($path);
if (empty($stat)) {
// create new file
diff --git a/lib/private/Files/Storage/DAV.php b/lib/private/Files/Storage/DAV.php
index ea4bbba2748..62906f9355b 100644
--- a/lib/private/Files/Storage/DAV.php
+++ b/lib/private/Files/Storage/DAV.php
@@ -36,6 +36,7 @@ namespace OC\Files\Storage;
use Exception;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Message\ResponseInterface;
+use Icewind\Streams\CallbackWrapper;
use OC\Files\Filesystem;
use OC\Files\Stream\Close;
use Icewind\Streams\IteratorDirectory;
@@ -77,8 +78,6 @@ class DAV extends Common {
private $client;
/** @var ArrayCache */
private $statCache;
- /** @var array */
- private static $tempFiles = [];
/** @var \OCP\Http\Client\IClientService */
private $httpClientService;
@@ -409,20 +408,19 @@ class DAV extends Common {
}
$tmpFile = $tempManager->getTemporaryFile($ext);
}
- Close::registerCallback($tmpFile, array($this, 'writeBack'));
- self::$tempFiles[$tmpFile] = $path;
- return fopen('close://' . $tmpFile, $mode);
+ $handle = fopen($tmpFile, $mode);
+ return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
+ $this->writeBack($tmpFile, $path);
+ });
}
}
/**
* @param string $tmpFile
*/
- public function writeBack($tmpFile) {
- if (isset(self::$tempFiles[$tmpFile])) {
- $this->uploadFile($tmpFile, self::$tempFiles[$tmpFile]);
- unlink($tmpFile);
- }
+ public function writeBack($tmpFile, $path) {
+ $this->uploadFile($tmpFile, $path);
+ unlink($tmpFile);
}
/** {@inheritdoc} */
diff --git a/lib/private/Files/Stream/Close.php b/lib/private/Files/Stream/Close.php
deleted file mode 100644
index 7cc9903c912..00000000000
--- a/lib/private/Files/Stream/Close.php
+++ /dev/null
@@ -1,119 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- *
- * @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 OC\Files\Stream;
-
-/**
- * stream wrapper that provides a callback on stream close
- */
-class Close {
- private static $callBacks = array();
- private $path = '';
- private $source;
- private static $open = array();
-
- public function stream_open($path, $mode, $options, &$opened_path) {
- $path = substr($path, strlen('close://'));
- $this->path = $path;
- $this->source = fopen($path, $mode);
- if (is_resource($this->source)) {
- $this->meta = stream_get_meta_data($this->source);
- }
- self::$open[] = $path;
- return is_resource($this->source);
- }
-
- public function stream_seek($offset, $whence = SEEK_SET) {
- return fseek($this->source, $offset, $whence) === 0;
- }
-
- public function stream_tell() {
- return ftell($this->source);
- }
-
- public function stream_read($count) {
- return fread($this->source, $count);
- }
-
- public function stream_write($data) {
- return fwrite($this->source, $data);
- }
-
- public function stream_set_option($option, $arg1, $arg2) {
- switch ($option) {
- case STREAM_OPTION_BLOCKING:
- stream_set_blocking($this->source, $arg1);
- break;
- case STREAM_OPTION_READ_TIMEOUT:
- stream_set_timeout($this->source, $arg1, $arg2);
- break;
- case STREAM_OPTION_WRITE_BUFFER:
- stream_set_write_buffer($this->source, $arg1, $arg2);
- }
- }
-
- public function stream_stat() {
- return fstat($this->source);
- }
-
- public function stream_lock($mode) {
- flock($this->source, $mode);
- }
-
- public function stream_flush() {
- return fflush($this->source);
- }
-
- public function stream_eof() {
- return feof($this->source);
- }
-
- public function url_stat($path) {
- $path = substr($path, strlen('close://'));
- if (file_exists($path)) {
- return stat($path);
- } else {
- return false;
- }
- }
-
- public function stream_close() {
- fclose($this->source);
- if (isset(self::$callBacks[$this->path])) {
- call_user_func(self::$callBacks[$this->path], $this->path);
- }
- }
-
- public function unlink($path) {
- $path = substr($path, strlen('close://'));
- return unlink($path);
- }
-
- /**
- * @param string $path
- */
- public static function registerCallback($path, $callback) {
- self::$callBacks[$path] = $callback;
- }
-}
diff --git a/lib/private/Files/Stream/Quota.php b/lib/private/Files/Stream/Quota.php
index f064ca6c011..624a2021b9c 100644
--- a/lib/private/Files/Stream/Quota.php
+++ b/lib/private/Files/Stream/Quota.php
@@ -25,61 +25,44 @@
namespace OC\Files\Stream;
+use Icewind\Streams\Wrapper;
+
/**
* stream wrapper limits the amount of data that can be written to a stream
*
- * usage: void \OC\Files\Stream\Quota::register($id, $stream, $limit)
- * or: resource \OC\Files\Stream\Quota::wrap($stream, $limit)
+ * usage: resource \OC\Files\Stream\Quota::wrap($stream, $limit)
*/
-class Quota {
- private static $streams = array();
-
- /**
- * @var resource $source
- */
- private $source;
-
+class Quota extends Wrapper {
/**
* @var int $limit
*/
private $limit;
/**
- * @param string $id
- * @param resource $stream
- * @param int $limit
- */
- public static function register($id, $stream, $limit) {
- self::$streams[$id] = array($stream, $limit);
- }
-
- /**
- * remove all registered streams
- */
- public static function clear() {
- self::$streams = array();
- }
-
- /**
* @param resource $stream
* @param int $limit
* @return resource
*/
static public function wrap($stream, $limit) {
- $id = uniqid();
- self::register($id, $stream, $limit);
- $meta = stream_get_meta_data($stream);
- return fopen('quota://' . $id, $meta['mode']);
+ $context = stream_context_create(array(
+ 'quota' => array(
+ 'source' => $stream,
+ 'limit' => $limit
+ )
+ ));
+ return Wrapper::wrapSource($stream, $context, 'quota', self::class);
}
public function stream_open($path, $mode, $options, &$opened_path) {
- $id = substr($path, strlen('quota://'));
- if (isset(self::$streams[$id])) {
- list($this->source, $this->limit) = self::$streams[$id];
- return true;
- } else {
- return false;
- }
+ $context = $this->loadContext('quota');
+ $this->source = $context['source'];
+ $this->limit = $context['limit'];
+
+ return true;
+ }
+
+ public function dir_opendir($path, $options) {
+ return false;
}
public function stream_seek($offset, $whence = SEEK_SET) {
@@ -103,10 +86,6 @@ class Quota {
return fseek($this->source, $offset, $whence) === 0;
}
- public function stream_tell() {
- return ftell($this->source);
- }
-
public function stream_read($count) {
$this->limit -= $count;
return fread($this->source, $count);
@@ -121,37 +100,4 @@ class Quota {
$this->limit -= $size;
return fwrite($this->source, $data);
}
-
- public function stream_set_option($option, $arg1, $arg2) {
- switch ($option) {
- case STREAM_OPTION_BLOCKING:
- stream_set_blocking($this->source, $arg1);
- break;
- case STREAM_OPTION_READ_TIMEOUT:
- stream_set_timeout($this->source, $arg1, $arg2);
- break;
- case STREAM_OPTION_WRITE_BUFFER:
- stream_set_write_buffer($this->source, $arg1, $arg2);
- }
- }
-
- public function stream_stat() {
- return fstat($this->source);
- }
-
- public function stream_lock($mode) {
- return flock($this->source, $mode);
- }
-
- public function stream_flush() {
- return fflush($this->source);
- }
-
- public function stream_eof() {
- return feof($this->source);
- }
-
- public function stream_close() {
- fclose($this->source);
- }
}
diff --git a/lib/private/Files/Stream/StaticStream.php b/lib/private/Files/Stream/StaticStream.php
deleted file mode 100644
index 3c91b23fd36..00000000000
--- a/lib/private/Files/Stream/StaticStream.php
+++ /dev/null
@@ -1,171 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- *
- * @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 OC\Files\Stream;
-
-class StaticStream {
- const MODE_FILE = 0100000;
-
- public $context;
- protected static $data = array();
-
- protected $path = '';
- protected $pointer = 0;
- protected $writable = false;
-
- public function stream_close() {
- }
-
- public function stream_eof() {
- return $this->pointer >= strlen(self::$data[$this->path]);
- }
-
- public function stream_flush() {
- }
-
- public static function clear() {
- self::$data = array();
- }
-
- public function stream_open($path, $mode, $options, &$opened_path) {
- switch ($mode[0]) {
- case 'r':
- if (!isset(self::$data[$path])) return false;
- $this->path = $path;
- $this->writable = isset($mode[1]) && $mode[1] == '+';
- break;
- case 'w':
- self::$data[$path] = '';
- $this->path = $path;
- $this->writable = true;
- break;
- case 'a':
- if (!isset(self::$data[$path])) self::$data[$path] = '';
- $this->path = $path;
- $this->writable = true;
- $this->pointer = strlen(self::$data[$path]);
- break;
- case 'x':
- if (isset(self::$data[$path])) return false;
- $this->path = $path;
- $this->writable = true;
- break;
- case 'c':
- if (!isset(self::$data[$path])) self::$data[$path] = '';
- $this->path = $path;
- $this->writable = true;
- break;
- default:
- return false;
- }
- $opened_path = $this->path;
- return true;
- }
-
- public function stream_read($count) {
- $bytes = min(strlen(self::$data[$this->path]) - $this->pointer, $count);
- $data = substr(self::$data[$this->path], $this->pointer, $bytes);
- $this->pointer += $bytes;
- return $data;
- }
-
- public function stream_seek($offset, $whence = SEEK_SET) {
- $len = strlen(self::$data[$this->path]);
- switch ($whence) {
- case SEEK_SET:
- if ($offset <= $len) {
- $this->pointer = $offset;
- return true;
- }
- break;
- case SEEK_CUR:
- if ($this->pointer + $offset <= $len) {
- $this->pointer += $offset;
- return true;
- }
- break;
- case SEEK_END:
- if ($len + $offset <= $len) {
- $this->pointer = $len + $offset;
- return true;
- }
- break;
- }
- return false;
- }
-
- public function stream_stat() {
- return $this->url_stat($this->path);
- }
-
- public function stream_tell() {
- return $this->pointer;
- }
-
- public function stream_write($data) {
- if (!$this->writable) return 0;
- $size = strlen($data);
- if ($this->stream_eof()) {
- self::$data[$this->path] .= $data;
- } else {
- self::$data[$this->path] = substr_replace(
- self::$data[$this->path],
- $data,
- $this->pointer
- );
- }
- $this->pointer += $size;
- return $size;
- }
-
- public function unlink($path) {
- if (isset(self::$data[$path])) {
- unset(self::$data[$path]);
- }
- return true;
- }
-
- public function url_stat($path) {
- if (isset(self::$data[$path])) {
- $size = strlen(self::$data[$path]);
- $time = time();
- $data = array(
- 'dev' => 0,
- 'ino' => 0,
- 'mode' => self::MODE_FILE | 0777,
- 'nlink' => 1,
- 'uid' => 0,
- 'gid' => 0,
- 'rdev' => '',
- 'size' => $size,
- 'atime' => $time,
- 'mtime' => $time,
- 'ctime' => $time,
- 'blksize' => -1,
- 'blocks' => -1,
- );
- return array_values($data) + $data;
- }
- return false;
- }
-}
diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php
index 6facc7b9462..909c49197b8 100644
--- a/lib/private/Files/View.php
+++ b/lib/private/Files/View.php
@@ -931,39 +931,36 @@ class View {
/**
* @param string $path
- * @param string $mode
+ * @param string $mode 'r' or 'w'
* @return resource
*/
public function fopen($path, $mode) {
+ $mode = str_replace('b', '', $mode); // the binary flag is a windows only feature which we do not support
$hooks = array();
switch ($mode) {
case 'r':
- case 'rb':
$hooks[] = 'read';
break;
case 'r+':
- case 'rb+':
case 'w+':
- case 'wb+':
case 'x+':
- case 'xb+':
case 'a+':
- case 'ab+':
$hooks[] = 'read';
$hooks[] = 'write';
break;
case 'w':
- case 'wb':
case 'x':
- case 'xb':
case 'a':
- case 'ab':
$hooks[] = 'write';
break;
default:
\OCP\Util::writeLog('core', 'invalid mode (' . $mode . ') for ' . $path, \OCP\Util::ERROR);
}
+ if ($mode !== 'r' && $mode !== 'w') {
+ \OC::$server->getLogger()->info('Trying to open a file with a mode other than "r" or "w" can cause severe performance issues with some backends');
+ }
+
return $this->basicOperation('fopen', $path, $hooks, $mode);
}
@@ -1005,7 +1002,7 @@ class View {
// Create the directories if any
if (!$this->file_exists($filePath)) {
$result = $this->createParentDirectories($filePath);
- if($result === false) {
+ if ($result === false) {
return false;
}
}
@@ -1357,7 +1354,7 @@ class View {
//add the sizes of other mount points to the folder
$extOnly = ($includeMountPoints === 'ext');
$mounts = Filesystem::getMountManager()->findIn($path);
- $info->setSubMounts(array_filter($mounts, function(IMountPoint $mount) use ($extOnly) {
+ $info->setSubMounts(array_filter($mounts, function (IMountPoint $mount) use ($extOnly) {
$subStorage = $mount->getStorage();
return !($extOnly && $subStorage instanceof \OCA\Files_Sharing\SharedStorage);
}));
@@ -2106,13 +2103,13 @@ class View {
private function createParentDirectories($filePath) {
$directoryParts = explode('/', $filePath);
$directoryParts = array_filter($directoryParts);
- foreach($directoryParts as $key => $part) {
+ foreach ($directoryParts as $key => $part) {
$currentPathElements = array_slice($directoryParts, 0, $key);
$currentPath = '/' . implode('/', $currentPathElements);
- if($this->is_file($currentPath)) {
+ if ($this->is_file($currentPath)) {
return false;
}
- if(!$this->file_exists($currentPath)) {
+ if (!$this->file_exists($currentPath)) {
$this->mkdir($currentPath);
}
}
diff --git a/lib/private/Memcache/APC.php b/lib/private/Memcache/APC.php
deleted file mode 100644
index 7db6d64b085..00000000000
--- a/lib/private/Memcache/APC.php
+++ /dev/null
@@ -1,136 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Andreas Fischer <bantu@owncloud.com>
- * @author Clark Tomlinson <fallen013@gmail.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Otto Sabart <ottosabart@seberm.com>
- * @author Robin Appelman <robin@icewind.nl>
- *
- * @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 OC\Memcache;
-
-use OCP\IMemcache;
-
-class APC extends Cache implements IMemcache {
- use CASTrait {
- cas as casEmulated;
- }
-
- use CADTrait;
-
- public function get($key) {
- $result = apc_fetch($this->getPrefix() . $key, $success);
- if (!$success) {
- return null;
- }
- return $result;
- }
-
- public function set($key, $value, $ttl = 0) {
- return apc_store($this->getPrefix() . $key, $value, $ttl);
- }
-
- public function hasKey($key) {
- return apc_exists($this->getPrefix() . $key);
- }
-
- public function remove($key) {
- return apc_delete($this->getPrefix() . $key);
- }
-
- public function clear($prefix = '') {
- $ns = $this->getPrefix() . $prefix;
- $ns = preg_quote($ns, '/');
- $iter = new \APCIterator('user', '/^' . $ns . '/', APC_ITER_KEY);
- return apc_delete($iter);
- }
-
- /**
- * Set a value in the cache if it's not already stored
- *
- * @param string $key
- * @param mixed $value
- * @param int $ttl Time To Live in seconds. Defaults to 60*60*24
- * @return bool
- */
- public function add($key, $value, $ttl = 0) {
- return apc_add($this->getPrefix() . $key, $value, $ttl);
- }
-
- /**
- * Increase a stored number
- *
- * @param string $key
- * @param int $step
- * @return int | bool
- */
- public function inc($key, $step = 1) {
- $this->add($key, 0);
- return apc_inc($this->getPrefix() . $key, $step);
- }
-
- /**
- * Decrease a stored number
- *
- * @param string $key
- * @param int $step
- * @return int | bool
- */
- public function dec($key, $step = 1) {
- return apc_dec($this->getPrefix() . $key, $step);
- }
-
- /**
- * Compare and set
- *
- * @param string $key
- * @param mixed $old
- * @param mixed $new
- * @return bool
- */
- public function cas($key, $old, $new) {
- // apc only does cas for ints
- if (is_int($old) and is_int($new)) {
- return apc_cas($this->getPrefix() . $key, $old, $new);
- } else {
- return $this->casEmulated($key, $old, $new);
- }
- }
-
- static public function isAvailable() {
- if (!extension_loaded('apc')) {
- return false;
- } elseif (!\OC::$server->getIniWrapper()->getBool('apc.enabled')) {
- return false;
- } elseif (!\OC::$server->getIniWrapper()->getBool('apc.enable_cli') && \OC::$CLI) {
- return false;
- } else {
- return true;
- }
- }
-}
-
-if (!function_exists('apc_exists')) {
- function apc_exists($keys) {
- $result = false;
- apc_fetch($keys, $result);
- return $result;
- }
-}
diff --git a/lib/private/Memcache/Factory.php b/lib/private/Memcache/Factory.php
index f3841d31679..8e62e020faa 100644
--- a/lib/private/Memcache/Factory.php
+++ b/lib/private/Memcache/Factory.php
@@ -83,7 +83,7 @@ class Factory implements ICacheFactory {
$missingCacheMessage = 'Memcache {class} not available for {use} cache';
$missingCacheHint = 'Is the matching PHP module installed and enabled?';
- if (!$localCacheClass::isAvailable()) {
+ if (!class_exists($localCacheClass) || !$localCacheClass::isAvailable()) {
if (\OC::$CLI && !defined('PHPUNIT_RUN')) {
// CLI should not hard-fail on broken memcache
$this->logger->info($missingCacheMessage, [
@@ -98,7 +98,7 @@ class Factory implements ICacheFactory {
]), $missingCacheHint);
}
}
- if (!$distributedCacheClass::isAvailable()) {
+ if (!class_exists($distributedCacheClass) || !$distributedCacheClass::isAvailable()) {
if (\OC::$CLI && !defined('PHPUNIT_RUN')) {
// CLI should not hard-fail on broken memcache
$this->logger->info($missingCacheMessage, [
@@ -113,7 +113,7 @@ class Factory implements ICacheFactory {
]), $missingCacheHint);
}
}
- if (!($lockingCacheClass && $lockingCacheClass::isAvailable())) {
+ if (!($lockingCacheClass && class_exists($distributedCacheClass) && $lockingCacheClass::isAvailable())) {
// don't fallback since the fallback might not be suitable for storing lock
$lockingCacheClass = self::NULL_CACHE;
}
diff --git a/lib/private/Repair/RepairInvalidShares.php b/lib/private/Repair/RepairInvalidShares.php
index 6cb690057bb..04624c910dd 100644
--- a/lib/private/Repair/RepairInvalidShares.php
+++ b/lib/private/Repair/RepairInvalidShares.php
@@ -27,6 +27,7 @@ namespace OC\Repair;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
+use Doctrine\DBAL\Platforms\OraclePlatform;
/**
* Repairs shares with invalid data
@@ -92,6 +93,26 @@ class RepairInvalidShares implements IRepairStep {
}
/**
+ * Adjust file share permissions
+ */
+ private function adjustFileSharePermissions(IOutput $out) {
+ $mask = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_SHARE;
+ $builder = $this->connection->getQueryBuilder();
+
+ $permsFunc = $builder->expr()->bitwiseAnd('permissions', $mask);
+ $builder
+ ->update('share')
+ ->set('permissions', $permsFunc)
+ ->where($builder->expr()->eq('item_type', $builder->expr()->literal('file')))
+ ->andWhere($builder->expr()->neq('permissions', $permsFunc));
+
+ $updatedEntries = $builder->execute();
+ if ($updatedEntries > 0) {
+ $out->info('Fixed file share permissions for ' . $updatedEntries . ' shares');
+ }
+ }
+
+ /**
* Remove shares where the parent share does not exist anymore
*/
private function removeSharesNonExistingParent(IOutput $out) {
@@ -137,6 +158,9 @@ class RepairInvalidShares implements IRepairStep {
// this situation was only possible before 9.1
$this->addShareLinkDeletePermission($out);
}
+ if (version_compare($ocVersionFromBeforeUpdate, '12.0.0.11', '<')) {
+ $this->adjustFileSharePermissions($out);
+ }
$this->removeSharesNonExistingParent($out);
}
diff --git a/lib/private/Security/CertificateManager.php b/lib/private/Security/CertificateManager.php
index f7bf0df58c5..461ef9457a7 100644
--- a/lib/private/Security/CertificateManager.php
+++ b/lib/private/Security/CertificateManager.php
@@ -30,6 +30,7 @@ namespace OC\Security;
use OC\Files\Filesystem;
use OCP\ICertificateManager;
use OCP\IConfig;
+use OCP\ILogger;
/**
* Manage trusted certificates for users
@@ -51,14 +52,21 @@ class CertificateManager implements ICertificateManager {
protected $config;
/**
+ * @var ILogger
+ */
+ protected $logger;
+
+ /**
* @param string $uid
* @param \OC\Files\View $view relative to data/
* @param IConfig $config
+ * @param ILogger $logger
*/
- public function __construct($uid, \OC\Files\View $view, IConfig $config) {
+ public function __construct($uid, \OC\Files\View $view, IConfig $config, ILogger $logger) {
$this->uid = $uid;
$this->view = $view;
$this->config = $config;
+ $this->logger = $logger;
}
/**
@@ -104,6 +112,13 @@ class CertificateManager implements ICertificateManager {
$this->view->mkdir($path);
}
+ $defaultCertificates = file_get_contents(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
+ if (strlen($defaultCertificates) < 1024) { // sanity check to verify that we have some content for our bundle
+ // log as exception so we have a stacktrace
+ $this->logger->logException(new \Exception('Shipped ca-bundle is empty, refusing to create certificate bundle'));
+ return;
+ }
+
$fhCerts = $this->view->fopen($path . '/rootcerts.crt', 'w');
// Write user certificates
@@ -117,7 +132,6 @@ class CertificateManager implements ICertificateManager {
}
// Append the default certificates
- $defaultCertificates = file_get_contents(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
fwrite($fhCerts, $defaultCertificates);
// Append the system certificate bundle
@@ -203,7 +217,7 @@ class CertificateManager implements ICertificateManager {
}
if ($this->needsRebundling($uid)) {
if (is_null($uid)) {
- $manager = new CertificateManager(null, $this->view, $this->config);
+ $manager = new CertificateManager(null, $this->view, $this->config, $this->logger);
$manager->createCertificateBundle();
} else {
$this->createCertificateBundle();
diff --git a/lib/private/Server.php b/lib/private/Server.php
index 06be694622a..6888c492910 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -483,7 +483,7 @@ class Server extends ServerContainer implements IServerContainer {
$uid = $user ? $user : null;
return new ClientService(
$c->getConfig(),
- new \OC\Security\CertificateManager($uid, new View(), $c->getConfig())
+ new \OC\Security\CertificateManager($uid, new View(), $c->getConfig(), $c->getLogger())
);
});
$this->registerService('EventLogger', function (Server $c) {
@@ -899,7 +899,6 @@ class Server extends ServerContainer implements IServerContainer {
return $this->query('SystemTagObjectMapper');
}
-
/**
* Returns the avatar manager, used for avatar functionality
*
@@ -1222,7 +1221,7 @@ class Server extends ServerContainer implements IServerContainer {
}
$userId = $user->getUID();
}
- return new CertificateManager($userId, new View(), $this->getConfig());
+ return new CertificateManager($userId, new View(), $this->getConfig(), $this->getLogger());
}
/**
diff --git a/lib/private/Setup/PostgreSQL.php b/lib/private/Setup/PostgreSQL.php
index 085e8609ab2..c01e5bc0332 100644
--- a/lib/private/Setup/PostgreSQL.php
+++ b/lib/private/Setup/PostgreSQL.php
@@ -150,14 +150,16 @@ class PostgreSQL extends AbstractDatabase {
}
private function createDBUser(IDBConnection $connection) {
+ $dbUser = $this->dbUser;
try {
- if ($this->userExists($connection)) {
- // change the password
- $query = $connection->prepare("ALTER ROLE " . addslashes($this->dbUser) . " WITH CREATEDB PASSWORD '" . addslashes($this->dbPassword) . "'");
- } else {
- // create the user
- $query = $connection->prepare("CREATE USER " . addslashes($this->dbUser) . " CREATEDB PASSWORD '" . addslashes($this->dbPassword) . "'");
- }
+ $i = 1;
+ while ($this->userExists($connection)) {
+ $i++;
+ $this->dbUser = $dbUser . $i;
+ };
+
+ // create the user
+ $query = $connection->prepare("CREATE USER " . addslashes($this->dbUser) . " CREATEDB PASSWORD '" . addslashes($this->dbPassword) . "'");
$query->execute();
} catch (DatabaseException $e) {
$this->logger->error('Error while trying to create database user');
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index 6eab5e05a2f..acc142f62be 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -587,7 +587,6 @@ class Manager implements IManager {
$share->setPassword($this->hasher->hash($share->getPassword()));
}
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
- $this->linkCreateChecks($share);
$share->setToken(
$this->secureRandom->generate(
\OC\Share\Constants::TOKEN_LENGTH,
diff --git a/lib/private/Template/CSSResourceLocator.php b/lib/private/Template/CSSResourceLocator.php
index ffeaf765ff5..351e6d1366f 100644
--- a/lib/private/Template/CSSResourceLocator.php
+++ b/lib/private/Template/CSSResourceLocator.php
@@ -25,13 +25,34 @@
namespace OC\Template;
+use OCP\ILogger;
+
class CSSResourceLocator extends ResourceLocator {
+
+ /** @var SCSSCacher */
+ protected $scssCacher;
+
+ /**
+ * @param ILogger $logger
+ * @param string $theme
+ * @param array $core_map
+ * @param array $party_map
+ * @param SCSSCacher $scssCacher
+ */
+ public function __construct(ILogger $logger, $theme, $core_map, $party_map, SCSSCacher $scssCacher) {
+ $this->scssCacher = $scssCacher;
+
+ parent::__construct($logger, $theme, $core_map, $party_map);
+ }
+
/**
* @param string $style
*/
public function doFind($style) {
if (strpos($style, '3rdparty') === 0
&& $this->appendIfExist($this->thirdpartyroot, $style.'.css')
+ || $this->cacheAndAppendScssIfExist($this->serverroot, $style.'.scss')
+ || $this->cacheAndAppendScssIfExist($this->serverroot, 'core/'.$style.'.scss')
|| $this->appendIfExist($this->serverroot, $style.'.css')
|| $this->appendIfExist($this->serverroot, 'core/'.$style.'.css')
) {
@@ -53,4 +74,25 @@ class CSSResourceLocator extends ResourceLocator {
|| $this->appendIfExist($this->serverroot, $theme_dir.$style.'.css')
|| $this->appendIfExist($this->serverroot, $theme_dir.'core/'.$style.'.css');
}
+
+ /**
+ * cache and append the scss $file if exist at $root
+ *
+ * @param string $root path to check
+ * @param string $file the filename
+ * @param string|null $webRoot base for path, default map $root to $webRoot
+ * @return bool True if the resource was found and cached, false otherwise
+ */
+ protected function cacheAndAppendScssIfExist($root, $file, $webRoot = null) {
+ if (is_file($root.'/'.$file)) {
+ if($this->scssCacher->process($root, $file)) {
+ $this->append($root, $this->scssCacher->getCachedSCSS('core', $file), $webRoot, false);
+ return true;
+ } else {
+ $this->logger->error('Failed to compile and/or save '.$root.'/'.$file, ['app' => 'core']);
+ return false;
+ }
+ }
+ return false;
+ }
}
diff --git a/lib/private/Template/ResourceLocator.php b/lib/private/Template/ResourceLocator.php
index 420317d27ac..420317d27ac 100644..100755
--- a/lib/private/Template/ResourceLocator.php
+++ b/lib/private/Template/ResourceLocator.php
diff --git a/lib/private/Template/SCSSCacher.php b/lib/private/Template/SCSSCacher.php
new file mode 100644
index 00000000000..0c1711b9fb7
--- /dev/null
+++ b/lib/private/Template/SCSSCacher.php
@@ -0,0 +1,189 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016, John Molakvoæ (skjnldsv@protonmail.com)
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Template;
+
+use Leafo\ScssPhp\Compiler;
+use Leafo\ScssPhp\Exception\ParserException;
+use Leafo\ScssPhp\Formatter\Crunched;
+use Leafo\ScssPhp\Formatter\Expanded;
+use OC\SystemConfig;
+use OCP\Files\IAppData;
+use OCP\Files\NotFoundException;
+use OCP\Files\SimpleFS\ISimpleFolder;
+use OCP\ILogger;
+use OCP\IURLGenerator;
+
+class SCSSCacher {
+
+ /** @var ILogger */
+ protected $logger;
+
+ /** @var IAppData */
+ protected $appData;
+
+ /** @var IURLGenerator */
+ protected $urlGenerator;
+
+ /** @var SystemConfig */
+ protected $systemConfig;
+
+ /**
+ * @param ILogger $logger
+ * @param IAppData $appData
+ * @param IURLGenerator $urlGenerator
+ * @param SystemConfig $systemConfig
+ */
+ public function __construct(ILogger $logger, IAppData $appData, IURLGenerator $urlGenerator, SystemConfig $systemConfig) {
+ $this->logger = $logger;
+ $this->appData = $appData;
+ $this->urlGenerator = $urlGenerator;
+ $this->systemConfig = $systemConfig;
+ }
+
+ /**
+ * Process the caching process if needed
+ * @param string $root Root path to the nextcloud installation
+ * @param string $file
+ * @return boolean
+ */
+ public function process($root, $file) {
+ $path = explode('/', $root . '/' . $file);
+
+ $fileNameSCSS = array_pop($path);
+ $fileNameCSS = str_replace('.scss', '.css', $fileNameSCSS);
+
+ $path = implode('/', $path);
+
+ $webDir = explode('/', $file);
+ array_pop($webDir);
+ $webDir = implode('/', $webDir);
+
+ try {
+ $folder = $this->appData->getFolder('core');
+ } catch(NotFoundException $e) {
+ // creating css appdata folder
+ $folder = $this->appData->newFolder('core');
+ }
+
+ if($this->isCached($fileNameCSS, $fileNameSCSS, $folder, $path)) {
+ return true;
+ } else {
+ return $this->cache($path, $fileNameCSS, $fileNameSCSS, $folder, $webDir);
+ }
+ }
+
+ /**
+ * Check if the file is cached or not
+ * @param string $fileNameCSS
+ * @param string $fileNameSCSS
+ * @param ISimpleFolder $folder
+ * @param string $path
+ * @return boolean
+ */
+ private function isCached($fileNameCSS, $fileNameSCSS, ISimpleFolder $folder, $path) {
+ try{
+ $cachedFile = $folder->getFile($fileNameCSS);
+ if( $cachedFile->getMTime() > filemtime($path.'/'.$fileNameSCSS)
+ && $cachedFile->getSize() > 0 ) {
+ return true;
+ }
+ } catch(NotFoundException $e) {
+ return false;
+ }
+ return false;
+ }
+
+ /**
+ * Cache the file with AppData
+ * @param string $path
+ * @param string $fileNameCSS
+ * @param string $fileNameSCSS
+ * @param ISimpleFolder $folder
+ * @param string $webDir
+ * @return boolean
+ */
+ private function cache($path, $fileNameCSS, $fileNameSCSS, ISimpleFolder $folder, $webDir) {
+ $scss = new Compiler();
+ $scss->setImportPaths($path);
+ if($this->systemConfig->getValue('debug')) {
+ // Debug mode
+ $scss->setFormatter(Expanded::class);
+ $scss->setLineNumberStyle(Compiler::LINE_COMMENTS);
+ } else {
+ // Compression
+ $scss->setFormatter(Crunched::class);
+ }
+
+ try {
+ $cachedfile = $folder->getFile($fileNameCSS);
+ } catch(NotFoundException $e) {
+ $cachedfile = $folder->newFile($fileNameCSS);
+ }
+
+ // Compile
+ try {
+ $compiledScss = $scss->compile('@import "'.$fileNameSCSS.'";');
+ } catch(ParserException $e) {
+ $this->logger->error($e, ['app' => 'core']);
+ return false;
+ }
+
+ try {
+ $cachedfile->putContent($this->rebaseUrls($compiledScss, $webDir));
+ $this->logger->debug($webDir.'/'.$fileNameSCSS.' compiled and successfully cached', ['app' => 'core']);
+ return true;
+ } catch(NotFoundException $e) {
+ return false;
+ }
+ }
+
+ /**
+ * Add the correct uri prefix to make uri valid again
+ * @param string $css
+ * @param string $webDir
+ * @return string
+ */
+ private function rebaseUrls($css, $webDir) {
+ $re = '/url\([\'"]([\.\w?=\/-]*)[\'"]\)/x';
+ // OC\Route\Router:75
+ if(($this->systemConfig->getValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true')) {
+ $subst = 'url(\'../../'.$webDir.'/$1\')';
+ } else {
+ $subst = 'url(\'../../../'.$webDir.'/$1\')';
+ }
+ return preg_replace($re, $subst, $css);
+ }
+
+ /**
+ * Return the cached css file uri
+ * @param string $appName the app name
+ * @param string $fileName
+ * @return string
+ */
+ public function getCachedSCSS($appName, $fileName) {
+ $tmpfileLoc = explode('/', $fileName);
+ $fileName = array_pop($tmpfileLoc);
+ $fileName = str_replace('.scss', '.css', $fileName);
+
+ return substr($this->urlGenerator->linkToRoute('core.Css.getCss', array('fileName' => $fileName, 'appName' => $appName)), strlen(\OC::$WEBROOT) + 1);
+ }
+}
diff --git a/lib/private/TemplateLayout.php b/lib/private/TemplateLayout.php
index ad9f8bac0e4..bc6a485ad43 100644
--- a/lib/private/TemplateLayout.php
+++ b/lib/private/TemplateLayout.php
@@ -36,6 +36,7 @@
namespace OC;
use OC\Template\JSConfigHelper;
+use OC\Template\SCSSCacher;
class TemplateLayout extends \OC_Template {
@@ -159,8 +160,17 @@ class TemplateLayout extends \OC_Template {
$this->append( 'jsfiles', $web.'/'.$file . '?v=' . self::$versionHash);
}
- // Add the css files
- $cssFiles = self::findStylesheetFiles(\OC_Util::$styles);
+ // Add the css files and check if server is already installed to prevent
+ // appdata initialisation before database configuration
+ if(\OC::$server->getSystemConfig()->getValue('installed', false)) {
+ $cssFiles = self::findStylesheetFiles(\OC_Util::$styles);
+ } else {
+ $cssFiles = array(
+ [\OC::$SERVERROOT, \OC::$WEBROOT, 'core/css/global.css'],
+ [\OC::$SERVERROOT, \OC::$WEBROOT, 'core/css/fonts.css'],
+ [\OC::$SERVERROOT, \OC::$WEBROOT, 'core/css/installation.css']
+ );
+ }
$this->assign('cssfiles', array());
$this->assign('printcssfiles', []);
$this->assign('versionHash', self::$versionHash);
@@ -184,11 +194,19 @@ class TemplateLayout extends \OC_Template {
// Read the selected theme from the config file
$theme = \OC_Util::getTheme();
+ $SCSSCacher = new SCSSCacher(
+ \OC::$server->getLogger(),
+ \OC::$server->getAppDataDir('css'),
+ \OC::$server->getURLGenerator(),
+ \OC::$server->getSystemConfig()
+ );
+
$locator = new \OC\Template\CSSResourceLocator(
\OC::$server->getLogger(),
$theme,
array( \OC::$SERVERROOT => \OC::$WEBROOT ),
- array( \OC::$SERVERROOT => \OC::$WEBROOT ));
+ array( \OC::$SERVERROOT => \OC::$WEBROOT ),
+ $SCSSCacher);
$locator->find($styles);
return $locator->getResources();
}
diff --git a/lib/private/User/Database.php b/lib/private/User/Database.php
index 28cb3302858..69826f49be3 100644
--- a/lib/private/User/Database.php
+++ b/lib/private/User/Database.php
@@ -75,6 +75,7 @@ class Database extends Backend implements IUserBackend {
*/
public function __construct($eventDispatcher = null) {
$this->cache = new CappedMemoryCache();
+ $this->cache[null] = false;
$this->eventDispatcher = $eventDispatcher ? $eventDispatcher : \OC::$server->getEventDispatcher();
}
diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php
index dcda825b9db..1834bd025d1 100644
--- a/lib/private/User/Session.php
+++ b/lib/private/User/Session.php
@@ -743,6 +743,7 @@ class Session implements IUserSession, Emitter {
//login
$this->setUser($user);
+ $this->setLoginName($this->tokenProvider->getToken($sessionId)->getLoginName());
$user->updateLastLoginTimestamp();
$this->manager->emit('\OC\User', 'postRememberedLogin', [$user]);
return true;
diff --git a/lib/private/legacy/app.php b/lib/private/legacy/app.php
index adf29601ac6..8ef7e08c733 100644
--- a/lib/private/legacy/app.php
+++ b/lib/private/legacy/app.php
@@ -273,9 +273,17 @@ class OC_App {
$appTypes = implode(',', $appData['types']);
} else {
$appTypes = '';
+ $appData['types'] = [];
}
\OC::$server->getAppConfig()->setValue($app, 'types', $appTypes);
+
+ if (\OC::$server->getAppManager()->hasProtectedAppType($appData['types'])) {
+ $enabled = \OC::$server->getAppConfig()->getValue($app, 'enabled', 'yes');
+ if ($enabled !== 'yes' && $enabled !== 'no') {
+ \OC::$server->getAppConfig()->setValue($app, 'enabled', 'yes');
+ }
+ }
}
/**