aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/activitymanager.php196
-rw-r--r--lib/private/api.php113
-rw-r--r--lib/private/app.php13
-rw-r--r--lib/private/appframework/dependencyinjection/dicontainer.php18
-rw-r--r--lib/private/appframework/http/request.php8
-rw-r--r--lib/private/capabilitiesmanager.php64
-rw-r--r--lib/private/connector/sabre/exceptionloggerplugin.php1
-rw-r--r--lib/private/connector/sabre/file.php3
-rw-r--r--lib/private/db.php2
-rw-r--r--lib/private/db/connectionfactory.php6
-rw-r--r--lib/private/db/mdb2schemamanager.php3
-rw-r--r--lib/private/db/querybuilder/querybuilder.php42
-rw-r--r--lib/private/defaults.php19
-rw-r--r--lib/private/files/cache/storage.php48
-rw-r--r--lib/private/files/mount/mountpoint.php7
-rw-r--r--lib/private/files/objectstore/objectstorestorage.php5
-rw-r--r--lib/private/files/storage/common.php21
-rw-r--r--lib/private/files/storage/dav.php5
-rw-r--r--lib/private/files/storage/local.php1
-rw-r--r--lib/private/files/storage/wrapper/availability.php462
-rw-r--r--lib/private/files/storage/wrapper/encryption.php9
-rw-r--r--lib/private/files/storage/wrapper/wrapper.php18
-rw-r--r--lib/private/files/view.php6
-rw-r--r--lib/private/installer.php4
-rw-r--r--lib/private/ocs.php145
-rw-r--r--lib/private/ocs/cloud.php9
-rw-r--r--lib/private/ocs/corecapabilities.php56
-rw-r--r--lib/private/ocs/exception.php (renamed from lib/private/db/mssqlmigrator.php)17
-rw-r--r--lib/private/ocs/result.php45
-rw-r--r--lib/private/route/router.php6
-rw-r--r--lib/private/security/crypto.php17
-rw-r--r--lib/private/server.php17
-rw-r--r--lib/private/setup.php63
-rw-r--r--lib/private/setup/abstractdatabase.php47
-rw-r--r--lib/private/setup/mssql.php203
-rw-r--r--lib/private/setup/mysql.php187
-rw-r--r--lib/private/setup/oci.php38
-rw-r--r--lib/private/setup/postgresql.php40
-rw-r--r--lib/private/share/share.php4
-rw-r--r--lib/private/template.php4
-rw-r--r--lib/private/util.php11
41 files changed, 1284 insertions, 699 deletions
diff --git a/lib/private/activitymanager.php b/lib/private/activitymanager.php
index 7b1d5d29f2e..938335a87e1 100644
--- a/lib/private/activitymanager.php
+++ b/lib/private/activitymanager.php
@@ -56,14 +56,16 @@ class ActivityManager implements IManager {
$this->config = $config;
}
- /**
- * @var \Closure[]
- */
+ /** @var \Closure[] */
+ private $consumersClosures = array();
+
+ /** @var IConsumer[] */
private $consumers = array();
- /**
- * @var \Closure[]
- */
+ /** @var \Closure[] */
+ private $extensionsClosures = array();
+
+ /** @var IExtension[] */
private $extensions = array();
/** @var array list of filters "name" => "is valid" */
@@ -80,6 +82,48 @@ class ActivityManager implements IManager {
protected $specialParameters = array();
/**
+ * @return \OCP\Activity\IConsumer[]
+ */
+ protected function getConsumers() {
+ if (!empty($this->consumers)) {
+ return $this->consumers;
+ }
+
+ $this->consumers = [];
+ foreach($this->consumersClosures as $consumer) {
+ $c = $consumer();
+ if ($c instanceof IConsumer) {
+ $this->consumers[] = $c;
+ } else {
+ throw new \InvalidArgumentException('The given consumer does not implement the \OCP\Activity\IConsumer interface');
+ }
+ }
+
+ return $this->consumers;
+ }
+
+ /**
+ * @return \OCP\Activity\IExtension[]
+ */
+ protected function getExtensions() {
+ if (!empty($this->extensions)) {
+ return $this->extensions;
+ }
+
+ $this->extensions = [];
+ foreach($this->extensionsClosures as $extension) {
+ $e = $extension();
+ if ($e instanceof IExtension) {
+ $this->extensions[] = $e;
+ } else {
+ throw new \InvalidArgumentException('The given extension does not implement the \OCP\Activity\IExtension interface');
+ }
+ }
+
+ return $this->extensions;
+ }
+
+ /**
* @param $app
* @param $subject
* @param $subjectParams
@@ -93,10 +137,8 @@ class ActivityManager implements IManager {
* @return mixed
*/
function publishActivity($app, $subject, $subjectParams, $message, $messageParams, $file, $link, $affectedUser, $type, $priority) {
- foreach($this->consumers as $consumer) {
- $c = $consumer();
- if ($c instanceof IConsumer) {
- try {
+ foreach($this->getConsumers() as $c) {
+ try {
$c->receive(
$app,
$subject,
@@ -108,11 +150,9 @@ class ActivityManager implements IManager {
$affectedUser,
$type,
$priority);
- } catch (\Exception $ex) {
- // TODO: log the exception
- }
+ } catch (\Exception $ex) {
+ // TODO: log the exception
}
-
}
}
@@ -125,7 +165,8 @@ class ActivityManager implements IManager {
* @param \Closure $callable
*/
function registerConsumer(\Closure $callable) {
- array_push($this->consumers, $callable);
+ array_push($this->consumersClosures, $callable);
+ $this->consumers = [];
}
/**
@@ -138,7 +179,8 @@ class ActivityManager implements IManager {
* @return void
*/
function registerExtension(\Closure $callable) {
- array_push($this->extensions, $callable);
+ array_push($this->extensionsClosures, $callable);
+ $this->extensions = [];
}
/**
@@ -149,13 +191,10 @@ class ActivityManager implements IManager {
*/
function getNotificationTypes($languageCode) {
$notificationTypes = array();
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $result = $c->getNotificationTypes($languageCode);
- if (is_array($result)) {
- $notificationTypes = array_merge($notificationTypes, $result);
- }
+ foreach ($this->getExtensions() as $c) {
+ $result = $c->getNotificationTypes($languageCode);
+ if (is_array($result)) {
+ $notificationTypes = array_merge($notificationTypes, $result);
}
}
@@ -168,13 +207,10 @@ class ActivityManager implements IManager {
*/
function getDefaultTypes($method) {
$defaultTypes = array();
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $types = $c->getDefaultTypes($method);
- if (is_array($types)) {
- $defaultTypes = array_merge($types, $defaultTypes);
- }
+ foreach ($this->getExtensions() as $c) {
+ $types = $c->getDefaultTypes($method);
+ if (is_array($types)) {
+ $defaultTypes = array_merge($types, $defaultTypes);
}
}
return $defaultTypes;
@@ -189,14 +225,11 @@ class ActivityManager implements IManager {
return $this->typeIcons[$type];
}
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $icon = $c->getTypeIcon($type);
- if (is_string($icon)) {
- $this->typeIcons[$type] = $icon;
- return $icon;
- }
+ foreach ($this->getExtensions() as $c) {
+ $icon = $c->getTypeIcon($type);
+ if (is_string($icon)) {
+ $this->typeIcons[$type] = $icon;
+ return $icon;
}
}
@@ -214,13 +247,10 @@ class ActivityManager implements IManager {
* @return string|false
*/
function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) {
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $translation = $c->translate($app, $text, $params, $stripPath, $highlightParams, $languageCode);
- if (is_string($translation)) {
- return $translation;
- }
+ foreach ($this->getExtensions() as $c) {
+ $translation = $c->translate($app, $text, $params, $stripPath, $highlightParams, $languageCode);
+ if (is_string($translation)) {
+ return $translation;
}
}
@@ -241,14 +271,11 @@ class ActivityManager implements IManager {
$this->specialParameters[$app] = array();
}
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $specialParameter = $c->getSpecialParameterList($app, $text);
- if (is_array($specialParameter)) {
- $this->specialParameters[$app][$text] = $specialParameter;
- return $specialParameter;
- }
+ foreach ($this->getExtensions() as $c) {
+ $specialParameter = $c->getSpecialParameterList($app, $text);
+ if (is_array($specialParameter)) {
+ $this->specialParameters[$app][$text] = $specialParameter;
+ return $specialParameter;
}
}
@@ -261,13 +288,10 @@ class ActivityManager implements IManager {
* @return integer|false
*/
function getGroupParameter($activity) {
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $parameter = $c->getGroupParameter($activity);
- if ($parameter !== false) {
- return $parameter;
- }
+ foreach ($this->getExtensions() as $c) {
+ $parameter = $c->getGroupParameter($activity);
+ if ($parameter !== false) {
+ return $parameter;
}
}
@@ -282,14 +306,11 @@ class ActivityManager implements IManager {
'apps' => array(),
'top' => array(),
);
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $additionalEntries = $c->getNavigation();
- if (is_array($additionalEntries)) {
- $entries['apps'] = array_merge($entries['apps'], $additionalEntries['apps']);
- $entries['top'] = array_merge($entries['top'], $additionalEntries['top']);
- }
+ foreach ($this->getExtensions() as $c) {
+ $additionalEntries = $c->getNavigation();
+ if (is_array($additionalEntries)) {
+ $entries['apps'] = array_merge($entries['apps'], $additionalEntries['apps']);
+ $entries['top'] = array_merge($entries['top'], $additionalEntries['top']);
}
}
@@ -305,13 +326,10 @@ class ActivityManager implements IManager {
return $this->validFilters[$filterValue];
}
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- if ($c->isFilterValid($filterValue) === true) {
- $this->validFilters[$filterValue] = true;
- return true;
- }
+ foreach ($this->getExtensions() as $c) {
+ if ($c->isFilterValid($filterValue) === true) {
+ $this->validFilters[$filterValue] = true;
+ return true;
}
}
@@ -329,13 +347,10 @@ class ActivityManager implements IManager {
return $types;
}
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $result = $c->filterNotificationTypes($types, $filter);
- if (is_array($result)) {
- $types = $result;
- }
+ foreach ($this->getExtensions() as $c) {
+ $result = $c->filterNotificationTypes($types, $filter);
+ if (is_array($result)) {
+ $types = $result;
}
}
return $types;
@@ -353,16 +368,13 @@ class ActivityManager implements IManager {
$conditions = array();
$parameters = array();
- foreach($this->extensions as $extension) {
- $c = $extension();
- if ($c instanceof IExtension) {
- $result = $c->getQueryForFilter($filter);
- if (is_array($result)) {
- list($condition, $parameter) = $result;
- if ($condition && is_array($parameter)) {
- $conditions[] = $condition;
- $parameters = array_merge($parameters, $parameter);
- }
+ foreach ($this->getExtensions() as $c) {
+ $result = $c->getQueryForFilter($filter);
+ if (is_array($result)) {
+ list($condition, $parameter) = $result;
+ if ($condition && is_array($parameter)) {
+ $conditions[] = $condition;
+ $parameters = array_merge($parameters, $parameter);
}
}
}
diff --git a/lib/private/api.php b/lib/private/api.php
index 8e483b7efe9..fb2110471b2 100644
--- a/lib/private/api.php
+++ b/lib/private/api.php
@@ -1,4 +1,7 @@
<?php
+use OCP\API;
+use OCP\AppFramework\Http;
+
/**
* @author Bart Visscher <bartv@thisnet.nl>
* @author Bernhard Posselt <dev@bernhard-posselt.com>
@@ -82,7 +85,7 @@ class OC_API {
* @param array $requirements
*/
public static function register($method, $url, $action, $app,
- $authLevel = \OCP\API::USER_AUTH,
+ $authLevel = API::USER_AUTH,
$defaults = array(),
$requirements = array()) {
$name = strtolower($method).$url;
@@ -123,7 +126,7 @@ class OC_API {
if(!self::isAuthorised($action)) {
$responses[] = array(
'app' => $action['app'],
- 'response' => new OC_OCS_Result(null, \OCP\API::RESPOND_UNAUTHORISED, 'Unauthorised'),
+ 'response' => new OC_OCS_Result(null, API::RESPOND_UNAUTHORISED, 'Unauthorised'),
'shipped' => OC_App::isShipped($action['app']),
);
continue;
@@ -131,7 +134,7 @@ class OC_API {
if(!is_callable($action['action'])) {
$responses[] = array(
'app' => $action['app'],
- 'response' => new OC_OCS_Result(null, \OCP\API::RESPOND_NOT_FOUND, 'Api method not found'),
+ 'response' => new OC_OCS_Result(null, API::RESPOND_NOT_FOUND, 'Api method not found'),
'shipped' => OC_App::isShipped($action['app']),
);
continue;
@@ -252,15 +255,15 @@ class OC_API {
private static function isAuthorised($action) {
$level = $action['authlevel'];
switch($level) {
- case \OCP\API::GUEST_AUTH:
+ case API::GUEST_AUTH:
// Anyone can access
return true;
break;
- case \OCP\API::USER_AUTH:
+ case API::USER_AUTH:
// User required
return self::loginUser();
break;
- case \OCP\API::SUBADMIN_AUTH:
+ case API::SUBADMIN_AUTH:
// Check for subadmin
$user = self::loginUser();
if(!$user) {
@@ -275,7 +278,7 @@ class OC_API {
}
}
break;
- case \OCP\API::ADMIN_AUTH:
+ case API::ADMIN_AUTH:
// Check for admin
$user = self::loginUser();
if(!$user) {
@@ -342,28 +345,25 @@ class OC_API {
*/
public static function respond($result, $format='xml') {
// Send 401 headers if unauthorised
- if($result->getStatusCode() === \OCP\API::RESPOND_UNAUTHORISED) {
+ if($result->getStatusCode() === API::RESPOND_UNAUTHORISED) {
header('WWW-Authenticate: Basic realm="Authorisation Required"');
header('HTTP/1.0 401 Unauthorized');
}
- $response = array(
- 'ocs' => array(
- 'meta' => $result->getMeta(),
- 'data' => $result->getData(),
- ),
- );
- if ($format == 'json') {
- OC_JSON::encodedPrint($response);
- } else if ($format == 'xml') {
- header('Content-type: text/xml; charset=UTF-8');
- $writer = new XMLWriter();
- $writer->openMemory();
- $writer->setIndent( true );
- $writer->startDocument();
- self::toXML($response, $writer);
- $writer->endDocument();
- echo $writer->outputMemory(true);
+
+ foreach($result->getHeaders() as $name => $value) {
+ header($name . ': ' . $value);
}
+
+ if (self::isV2()) {
+ $statusCode = self::mapStatusCodes($result->getStatusCode());
+ if (!is_null($statusCode)) {
+ OC_Response::setStatus($statusCode);
+ }
+ }
+
+ self::setContentType($format);
+ $body = self::renderResult($result, $format);
+ echo $body;
}
/**
@@ -400,8 +400,8 @@ class OC_API {
/**
* Based on the requested format the response content type is set
*/
- public static function setContentType() {
- $format = self::requestedFormat();
+ public static function setContentType($format = null) {
+ $format = is_null($format) ? self::requestedFormat() : $format;
if ($format === 'xml') {
header('Content-type: text/xml; charset=UTF-8');
return;
@@ -415,5 +415,64 @@ class OC_API {
header('Content-Type: application/octet-stream; charset=utf-8');
}
+ /**
+ * @return boolean
+ */
+ private static function isV2() {
+ $request = \OC::$server->getRequest();
+ $script = $request->getScriptName();
+
+ return $script === '/ocs/v2.php';
+ }
+
+ /**
+ * @param integer $sc
+ * @return int
+ */
+ public static function mapStatusCodes($sc) {
+ switch ($sc) {
+ case API::RESPOND_NOT_FOUND:
+ return Http::STATUS_NOT_FOUND;
+ case API::RESPOND_SERVER_ERROR:
+ return Http::STATUS_INTERNAL_SERVER_ERROR;
+ case API::RESPOND_UNKNOWN_ERROR:
+ return Http::STATUS_INTERNAL_SERVER_ERROR;
+ case API::RESPOND_UNAUTHORISED:
+ // already handled for v1
+ return null;
+ case 100:
+ return Http::STATUS_OK;
+ }
+ // any 2xx, 4xx and 5xx will be used as is
+ if ($sc >= 200 && $sc < 600) {
+ return $sc;
+ }
+
+ return Http::STATUS_BAD_REQUEST;
+ }
+ /**
+ * @param OC_OCS_Result $result
+ * @param string $format
+ * @return string
+ */
+ public static function renderResult($result, $format) {
+ $response = array(
+ 'ocs' => array(
+ 'meta' => $result->getMeta(),
+ 'data' => $result->getData(),
+ ),
+ );
+ if ($format == 'json') {
+ return OC_JSON::encode($response);
+ }
+
+ $writer = new XMLWriter();
+ $writer->openMemory();
+ $writer->setIndent(true);
+ $writer->startDocument();
+ self::toXML($response, $writer);
+ $writer->endDocument();
+ return $writer->outputMemory(true);
+ }
}
diff --git a/lib/private/app.php b/lib/private/app.php
index 6c6f79dfa9d..e51fe73cb19 100644
--- a/lib/private/app.php
+++ b/lib/private/app.php
@@ -74,6 +74,16 @@ class OC_App {
}
/**
+ * Check if an app is loaded
+ *
+ * @param string $app
+ * @return bool
+ */
+ public static function isAppLoaded($app) {
+ return in_array($app, self::$loadedApps, true);
+ }
+
+ /**
* loads all apps
*
* @param array $types
@@ -421,6 +431,7 @@ class OC_App {
*/
public static function getSettingsNavigation() {
$l = \OC::$server->getL10N('lib');
+ $defaults = new OC_Defaults();
$settings = array();
// by default, settings only contain the help menu
@@ -431,7 +442,7 @@ class OC_App {
array(
"id" => "help",
"order" => 1000,
- "href" => OC_Helper::linkToRoute("settings_help"),
+ "href" => $defaults->getKnowledgeBaseUrl(),
"name" => $l->t("Help"),
"icon" => OC_Helper::imagePath("settings", "help.svg")
)
diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php
index c7ce6545972..c66b792064d 100644
--- a/lib/private/appframework/dependencyinjection/dicontainer.php
+++ b/lib/private/appframework/dependencyinjection/dicontainer.php
@@ -96,6 +96,10 @@ class DIContainer extends SimpleContainer implements IAppContainer {
return $this->getServer()->getMemCacheFactory();
});
+ $this->registerService('OC\\CapabilitiesManager', function($c) {
+ return $this->getServer()->getCapabilitiesManager();
+ });
+
$this->registerService('OCP\\IConfig', function($c) {
return $this->getServer()->getConfig();
});
@@ -212,6 +216,10 @@ class DIContainer extends SimpleContainer implements IAppContainer {
return $this->getServer()->getUserSession();
});
+ $this->registerService('OCP\\ISession', function($c) {
+ return $this->getServer()->getSession();
+ });
+
$this->registerService('ServerContainer', function ($c) {
return $this->getServer();
});
@@ -386,5 +394,15 @@ class DIContainer extends SimpleContainer implements IAppContainer {
\OCP\Util::writeLog($this->getAppName(), $message, $level);
}
+ /**
+ * Register a capability
+ *
+ * @param string $serviceName e.g. 'OCA\Files\Capabilities'
+ */
+ public function registerCapability($serviceName) {
+ $this->query('OC\CapabilitiesManager')->registerCapability(function() use ($serviceName) {
+ return $this->query($serviceName);
+ });
+ }
}
diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php
index baf2f0c4745..43f01dfde3f 100644
--- a/lib/private/appframework/http/request.php
+++ b/lib/private/appframework/http/request.php
@@ -416,12 +416,10 @@ class Request implements \ArrayAccess, \Countable, IRequest {
}
// Check if the token is valid
- if($token !== $this->items['requesttoken']) {
- // Not valid
- return false;
- } else {
- // Valid token
+ if(\OCP\Security\StringUtils::equals($token, $this->items['requesttoken'])) {
return true;
+ } else {
+ return false;
}
}
diff --git a/lib/private/capabilitiesmanager.php b/lib/private/capabilitiesmanager.php
new file mode 100644
index 00000000000..74154f2c631
--- /dev/null
+++ b/lib/private/capabilitiesmanager.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @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;
+
+
+use OCP\Capabilities\ICapability;
+
+class CapabilitiesManager {
+
+ /**
+ * @var \Closure[]
+ */
+ private $capabilities = array();
+
+ /**
+ * Get an array of al the capabilities that are registered at this manager
+ *
+ * @throws \InvalidArgumentException
+ * @return array
+ */
+ public function getCapabilities() {
+ $capabilities = [];
+ foreach($this->capabilities as $capability) {
+ $c = $capability();
+ if ($c instanceof ICapability) {
+ $capabilities = array_replace_recursive($capabilities, $c->getCapabilities());
+ } else {
+ throw new \InvalidArgumentException('The given Capability (' . get_class($c) . ') does not implement the ICapability interface');
+ }
+ }
+
+ return $capabilities;
+ }
+
+ /**
+ * In order to improve lazy loading a closure can be registered which will be called in case
+ * capabilities are actually requested
+ *
+ * $callable has to return an instance of OCP\Capabilities\ICapability
+ *
+ * @param \Closure $callable
+ */
+ public function registerCapability(\Closure $callable) {
+ array_push($this->capabilities, $callable);
+ }
+}
diff --git a/lib/private/connector/sabre/exceptionloggerplugin.php b/lib/private/connector/sabre/exceptionloggerplugin.php
index 0b89ae4aef6..741ba4d3e05 100644
--- a/lib/private/connector/sabre/exceptionloggerplugin.php
+++ b/lib/private/connector/sabre/exceptionloggerplugin.php
@@ -95,6 +95,7 @@ class ExceptionLoggerPlugin extends \Sabre\DAV\ServerPlugin {
$exception = [
'Message' => $message,
+ 'Exception' => $exceptionClass,
'Code' => $ex->getCode(),
'Trace' => $ex->getTraceAsString(),
'File' => $ex->getFile(),
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index 18bd3b8d91d..fa2f5ce18d7 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -208,10 +208,9 @@ class File extends Node implements IFile {
}
// since we skipped the view we need to scan and emit the hooks ourselves
- $partStorage->getScanner()->scanFile($internalPath);
+ $this->fileView->getUpdater()->update($this->path);
if ($view) {
- $this->fileView->getUpdater()->propagate($hookPath);
if (!$exists) {
\OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_post_create, array(
\OC\Files\Filesystem::signal_param_path => $hookPath
diff --git a/lib/private/db.php b/lib/private/db.php
index 1e93eb1892e..a4a7b7d17d4 100644
--- a/lib/private/db.php
+++ b/lib/private/db.php
@@ -121,7 +121,7 @@ class OC_DB {
if (is_string($stmt)) {
// convert to an array with 'sql'
if (stripos($stmt, 'LIMIT') !== false) { //OFFSET requires LIMIT, so we only need to check for LIMIT
- // TODO try to convert LIMIT OFFSET notation to parameters, see fixLimitClauseForMSSQL
+ // TODO try to convert LIMIT OFFSET notation to parameters
$message = 'LIMIT and OFFSET are forbidden for portability reasons,'
. ' pass an array with \'limit\' and \'offset\' instead';
throw new \OC\DatabaseException($message);
diff --git a/lib/private/db/connectionfactory.php b/lib/private/db/connectionfactory.php
index 83a59cddd7f..b6c3396e147 100644
--- a/lib/private/db/connectionfactory.php
+++ b/lib/private/db/connectionfactory.php
@@ -39,12 +39,6 @@ class ConnectionFactory {
* \Doctrine\DBAL\DriverManager::getConnection().
*/
protected $defaultConnectionParams = array(
- 'mssql' => array(
- 'adapter' => '\OC\DB\AdapterSQLSrv',
- 'charset' => 'UTF8',
- 'driver' => 'pdo_sqlsrv',
- 'wrapperClass' => 'OC\DB\Connection',
- ),
'mysql' => array(
'adapter' => '\OC\DB\AdapterMySQL',
'charset' => 'UTF8',
diff --git a/lib/private/db/mdb2schemamanager.php b/lib/private/db/mdb2schemamanager.php
index 6b9888d361b..aef485ed686 100644
--- a/lib/private/db/mdb2schemamanager.php
+++ b/lib/private/db/mdb2schemamanager.php
@@ -32,7 +32,6 @@ use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\Platforms\SqlitePlatform;
-use Doctrine\DBAL\Platforms\SQLServerPlatform;
class MDB2SchemaManager {
/**
@@ -85,8 +84,6 @@ class MDB2SchemaManager {
return new OracleMigrator($this->conn, $random, $config);
} else if ($platform instanceof MySqlPlatform) {
return new MySQLMigrator($this->conn, $random, $config);
- } else if ($platform instanceof SQLServerPlatform) {
- return new MsSqlMigrator($this->conn, $random, $config);
} else if ($platform instanceof PostgreSqlPlatform) {
return new Migrator($this->conn, $random, $config);
} else {
diff --git a/lib/private/db/querybuilder/querybuilder.php b/lib/private/db/querybuilder/querybuilder.php
index 1a1408876f1..1d97faf77cc 100644
--- a/lib/private/db/querybuilder/querybuilder.php
+++ b/lib/private/db/querybuilder/querybuilder.php
@@ -37,6 +37,9 @@ class QueryBuilder implements IQueryBuilder {
/** @var QuoteHelper */
private $helper;
+ /** @var bool */
+ private $automaticTablePrefix = true;
+
/**
* Initializes a new QueryBuilder.
*
@@ -49,6 +52,17 @@ class QueryBuilder implements IQueryBuilder {
}
/**
+ * Enable/disable automatic prefixing of table names with the oc_ prefix
+ *
+ * @param bool $enabled If set to true table names will be prefixed with the
+ * owncloud database prefix automatically.
+ * @since 8.2.0
+ */
+ public function automaticTablePrefix($enabled) {
+ $this->automaticTablePrefix = (bool) $enabled;
+ }
+
+ /**
* Gets an ExpressionBuilder used for object-oriented construction of query expressions.
* This producer method is intended for convenient inline usage. Example:
*
@@ -329,7 +343,7 @@ class QueryBuilder implements IQueryBuilder {
*/
public function delete($delete = null, $alias = null) {
$this->queryBuilder->delete(
- $this->helper->quoteColumnName($delete),
+ $this->getTableName($delete),
$alias
);
@@ -354,7 +368,7 @@ class QueryBuilder implements IQueryBuilder {
*/
public function update($update = null, $alias = null) {
$this->queryBuilder->update(
- $this->helper->quoteColumnName($update),
+ $this->getTableName($update),
$alias
);
@@ -382,7 +396,7 @@ class QueryBuilder implements IQueryBuilder {
*/
public function insert($insert = null) {
$this->queryBuilder->insert(
- $this->helper->quoteColumnName($insert)
+ $this->getTableName($insert)
);
return $this;
@@ -405,7 +419,7 @@ class QueryBuilder implements IQueryBuilder {
*/
public function from($from, $alias = null) {
$this->queryBuilder->from(
- $this->helper->quoteColumnName($from),
+ $this->getTableName($from),
$alias
);
@@ -432,7 +446,7 @@ class QueryBuilder implements IQueryBuilder {
public function join($fromAlias, $join, $alias, $condition = null) {
$this->queryBuilder->join(
$fromAlias,
- $this->helper->quoteColumnName($join),
+ $this->getTableName($join),
$alias,
$condition
);
@@ -460,7 +474,7 @@ class QueryBuilder implements IQueryBuilder {
public function innerJoin($fromAlias, $join, $alias, $condition = null) {
$this->queryBuilder->innerJoin(
$fromAlias,
- $this->helper->quoteColumnName($join),
+ $this->getTableName($join),
$alias,
$condition
);
@@ -488,7 +502,7 @@ class QueryBuilder implements IQueryBuilder {
public function leftJoin($fromAlias, $join, $alias, $condition = null) {
$this->queryBuilder->leftJoin(
$fromAlias,
- $this->helper->quoteColumnName($join),
+ $this->getTableName($join),
$alias,
$condition
);
@@ -516,7 +530,7 @@ class QueryBuilder implements IQueryBuilder {
public function rightJoin($fromAlias, $join, $alias, $condition = null) {
$this->queryBuilder->rightJoin(
$fromAlias,
- $this->helper->quoteColumnName($join),
+ $this->getTableName($join),
$alias,
$condition
);
@@ -984,4 +998,16 @@ class QueryBuilder implements IQueryBuilder {
public function createFunction($call) {
return new QueryFunction($call);
}
+
+ /**
+ * @param string $table
+ * @return string
+ */
+ private function getTableName($table) {
+ if ($this->automaticTablePrefix === false || strpos($table, '*PREFIX*') === 0) {
+ return $this->helper->quoteColumnName($table);
+ }
+
+ return $this->helper->quoteColumnName('*PREFIX*' . $table);
+ }
}
diff --git a/lib/private/defaults.php b/lib/private/defaults.php
index 16f45943f54..b86805357bd 100644
--- a/lib/private/defaults.php
+++ b/lib/private/defaults.php
@@ -46,9 +46,11 @@ class OC_Defaults {
private $defaultSlogan;
private $defaultLogoClaim;
private $defaultMailHeaderColor;
+ private $defaultKnowledgeBaseUrl;
function __construct() {
$this->l = \OC::$server->getL10N('lib');
+ $urlGenerator = \OC::$server->getURLGenerator();
$version = OC_Util::getVersion();
$this->defaultEntity = 'ownCloud'; /* e.g. company name, used for footers and copyright notices */
@@ -64,6 +66,7 @@ class OC_Defaults {
$this->defaultSlogan = $this->l->t('web services under your control');
$this->defaultLogoClaim = '';
$this->defaultMailHeaderColor = '#1d2d44'; /* header color of mail notifications */
+ $this->defaultKnowledgeBaseUrl = $urlGenerator->linkToRoute('settings_help');
$themePath = OC::$SERVERROOT . '/themes/' . OC_Util::getTheme() . '/defaults.php';
if (file_exists($themePath)) {
@@ -79,6 +82,7 @@ class OC_Defaults {
/**
* @param string $method
+ * @return bool
*/
private function themeExist($method) {
if (isset($this->theme) && method_exists($this->theme, $method)) {
@@ -280,4 +284,19 @@ class OC_Defaults {
}
}
+ /**
+ * get knowledge base URL, will be used for the "Help"-Link in the top
+ * right menu
+ *
+ * @return string
+ */
+ public function getKnowledgeBaseUrl() {
+ if ($this->themeExist('getKnowledgeBaseUrl')) {
+ return $this->theme->getKnowledgeBaseUrl();
+ } else {
+ return $this->defaultKnowledgeBaseUrl;
+ }
+
+ }
+
}
diff --git a/lib/private/files/cache/storage.php b/lib/private/files/cache/storage.php
index ebef245f399..338d8308281 100644
--- a/lib/private/files/cache/storage.php
+++ b/lib/private/files/cache/storage.php
@@ -43,9 +43,10 @@ class Storage {
/**
* @param \OC\Files\Storage\Storage|string $storage
+ * @param bool $isAvailable
* @throws \RuntimeException
*/
- public function __construct($storage) {
+ public function __construct($storage, $isAvailable = true) {
if ($storage instanceof \OC\Files\Storage\Storage) {
$this->storageId = $storage->getId();
} else {
@@ -53,17 +54,14 @@ class Storage {
}
$this->storageId = self::adjustStorageId($this->storageId);
- $sql = 'SELECT `numeric_id` FROM `*PREFIX*storages` WHERE `id` = ?';
- $result = \OC_DB::executeAudited($sql, array($this->storageId));
- if ($row = $result->fetchRow()) {
+ if ($row = self::getStorageById($this->storageId)) {
$this->numericId = $row['numeric_id'];
} else {
$connection = \OC_DB::getConnection();
- if ($connection->insertIfNotExist('*PREFIX*storages', ['id' => $this->storageId])) {
+ if ($connection->insertIfNotExist('*PREFIX*storages', ['id' => $this->storageId, 'available' => $isAvailable])) {
$this->numericId = \OC_DB::insertid('*PREFIX*storages');
} else {
- $result = \OC_DB::executeAudited($sql, array($this->storageId));
- if ($row = $result->fetchRow()) {
+ if ($row = self::getStorageById($this->storageId)) {
$this->numericId = $row['numeric_id'];
} else {
throw new \RuntimeException('Storage could neither be inserted nor be selected from the database');
@@ -73,6 +71,16 @@ class Storage {
}
/**
+ * @param string $storageId
+ * @return array|null
+ */
+ public static function getStorageById($storageId) {
+ $sql = 'SELECT * FROM `*PREFIX*storages` WHERE `id` = ?';
+ $result = \OC_DB::executeAudited($sql, array($storageId));
+ return $result->fetchRow();
+ }
+
+ /**
* Adjusts the storage id to use md5 if too long
* @param string $storageId storage id
* @return string unchanged $storageId if its length is less than 64 characters,
@@ -120,9 +128,7 @@ class Storage {
public static function getNumericStorageId($storageId) {
$storageId = self::adjustStorageId($storageId);
- $sql = 'SELECT `numeric_id` FROM `*PREFIX*storages` WHERE `id` = ?';
- $result = \OC_DB::executeAudited($sql, array($storageId));
- if ($row = $result->fetchRow()) {
+ if ($row = self::getStorageById($storageId)) {
return $row['numeric_id'];
} else {
return null;
@@ -130,6 +136,28 @@ class Storage {
}
/**
+ * @return array|null [ available, last_checked ]
+ */
+ public function getAvailability() {
+ if ($row = self::getStorageById($this->storageId)) {
+ return [
+ 'available' => $row['available'],
+ 'last_checked' => $row['last_checked']
+ ];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @param bool $isAvailable
+ */
+ public function setAvailability($isAvailable) {
+ $sql = 'UPDATE `*PREFIX*storages` SET `available` = ?, `last_checked` = ? WHERE `id` = ?';
+ \OC_DB::executeAudited($sql, array($isAvailable, time(), $this->storageId));
+ }
+
+ /**
* Check if a string storage id is known
*
* @param string $storageId
diff --git a/lib/private/files/mount/mountpoint.php b/lib/private/files/mount/mountpoint.php
index 2871bbd9083..5e4949aa9dd 100644
--- a/lib/private/files/mount/mountpoint.php
+++ b/lib/private/files/mount/mountpoint.php
@@ -29,6 +29,7 @@ namespace OC\Files\Mount;
use \OC\Files\Filesystem;
use OC\Files\Storage\StorageFactory;
use OC\Files\Storage\Storage;
+use OC\Files\Storage\Wrapper\Wrapper;
use OCP\Files\Mount\IMountPoint;
class MountPoint implements IMountPoint {
@@ -92,7 +93,11 @@ class MountPoint implements IMountPoint {
$this->mountPoint = $mountpoint;
if ($storage instanceof Storage) {
$this->class = get_class($storage);
- $this->storage = $this->loader->wrap($this, $storage);
+ $this->storage = $storage;
+ // only wrap if not already wrapped
+ if (!($this->storage instanceof Wrapper)) {
+ $this->storage = $this->loader->wrap($this, $this->storage);
+ }
} else {
// Update old classes to new namespace
if (strpos($storage, 'OC_Filestorage_') !== false) {
diff --git a/lib/private/files/objectstore/objectstorestorage.php b/lib/private/files/objectstore/objectstorestorage.php
index 24398649727..a85553186ae 100644
--- a/lib/private/files/objectstore/objectstorestorage.php
+++ b/lib/private/files/objectstore/objectstorestorage.php
@@ -24,6 +24,7 @@
namespace OC\Files\ObjectStore;
+use Icewind\Streams\IteratorDirectory;
use OCP\Files\ObjectStore\IObjectStore;
class ObjectStoreStorage extends \OC\Files\Storage\Common {
@@ -216,9 +217,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common {
$files[] = $file['name'];
}
- \OC\Files\Stream\Dir::register('objectstore' . $path . '/', $files);
-
- return opendir('fakedir://objectstore' . $path . '/');
+ return IteratorDirectory::wrap($files);
} catch (\Exception $e) {
\OCP\Util::writeLog('objectstore', $e->getMessage(), \OCP\Util::ERROR);
return false;
diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php
index 847cb8492fe..a5ed5fd3996 100644
--- a/lib/private/files/storage/common.php
+++ b/lib/private/files/storage/common.php
@@ -338,7 +338,7 @@ abstract class Common implements Storage {
}
if (!isset($this->watcher)) {
$this->watcher = new Watcher($storage);
- $globalPolicy = \OC::$server->getConfig()->getSystemValue('filesystem_check_changes', Watcher::CHECK_ONCE);
+ $globalPolicy = \OC::$server->getConfig()->getSystemValue('filesystem_check_changes', Watcher::CHECK_NEVER);
$this->watcher->setPolicy((int)$this->getMountOption('filesystem_check_changes', $globalPolicy));
}
return $this->watcher;
@@ -404,6 +404,11 @@ abstract class Common implements Storage {
return implode('/', $output);
}
+ /**
+ * Test a storage for availability
+ *
+ * @return bool
+ */
public function test() {
if ($this->stat('')) {
return true;
@@ -650,4 +655,18 @@ abstract class Common implements Storage {
public function changeLock($path, $type, ILockingProvider $provider) {
$provider->changeLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
}
+
+ /**
+ * @return array [ available, last_checked ]
+ */
+ public function getAvailability() {
+ return $this->getStorageCache()->getAvailability();
+ }
+
+ /**
+ * @param bool $isAvailable
+ */
+ public function setAvailability($isAvailable) {
+ $this->getStorageCache()->setAvailability($isAvailable);
+ }
}
diff --git a/lib/private/files/storage/dav.php b/lib/private/files/storage/dav.php
index 24cf3c29209..6e89dcccbcd 100644
--- a/lib/private/files/storage/dav.php
+++ b/lib/private/files/storage/dav.php
@@ -38,7 +38,7 @@ namespace OC\Files\Storage;
use Exception;
use OC\Files\Filesystem;
use OC\Files\Stream\Close;
-use OC\Files\Stream\Dir;
+use Icewind\Streams\IteratorDirectory;
use OC\MemCache\ArrayCache;
use OCP\Constants;
use OCP\Files;
@@ -211,8 +211,7 @@ class DAV extends Common {
$file = basename($file);
$content[] = $file;
}
- Dir::register($id, $content);
- return opendir('fakedir://' . $id);
+ return IteratorDirectory::wrap($content);
} catch (ClientHttpException $e) {
if ($e->getHttpStatus() === 404) {
$this->statCache->clear($path . '/');
diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php
index b7272b7d1f0..3676fe69131 100644
--- a/lib/private/files/storage/local.php
+++ b/lib/private/files/storage/local.php
@@ -35,7 +35,6 @@
*/
namespace OC\Files\Storage;
-
/**
* for local filestore, we only have to map the paths
*/
diff --git a/lib/private/files/storage/wrapper/availability.php b/lib/private/files/storage/wrapper/availability.php
new file mode 100644
index 00000000000..37319a8f7d1
--- /dev/null
+++ b/lib/private/files/storage/wrapper/availability.php
@@ -0,0 +1,462 @@
+<?php
+/**
+ * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @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\Storage\Wrapper;
+
+/**
+ * Availability checker for storages
+ *
+ * Throws a StorageNotAvailableException for storages with known failures
+ */
+class Availability extends Wrapper {
+ const RECHECK_TTL_SEC = 600; // 10 minutes
+
+ /**
+ * @return bool
+ */
+ private function updateAvailability() {
+ try {
+ $result = $this->test();
+ } catch (\Exception $e) {
+ $result = false;
+ }
+ $this->setAvailability($result);
+ return $result;
+ }
+
+ /**
+ * @return bool
+ */
+ private function isAvailable() {
+ $availability = $this->getAvailability();
+ if (!$availability['available']) {
+ // trigger a recheck if TTL reached
+ if ((time() - $availability['last_checked']) > self::RECHECK_TTL_SEC) {
+ return $this->updateAvailability();
+ }
+ }
+ return $availability['available'];
+ }
+
+ /**
+ * @throws \OCP\Files\StorageNotAvailableException
+ */
+ private function checkAvailability() {
+ if (!$this->isAvailable()) {
+ throw new \OCP\Files\StorageNotAvailableException();
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function mkdir($path) {
+ $this->checkAvailability();
+ try {
+ return parent::mkdir($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function rmdir($path) {
+ $this->checkAvailability();
+ try {
+ return parent::rmdir($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function opendir($path) {
+ $this->checkAvailability();
+ try {
+ return parent::opendir($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function is_dir($path) {
+ $this->checkAvailability();
+ try {
+ return parent::is_dir($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function is_file($path) {
+ $this->checkAvailability();
+ try {
+ return parent::is_file($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function stat($path) {
+ $this->checkAvailability();
+ try {
+ return parent::stat($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function filetype($path) {
+ $this->checkAvailability();
+ try {
+ return parent::filetype($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function filesize($path) {
+ $this->checkAvailability();
+ try {
+ return parent::filesize($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function isCreatable($path) {
+ $this->checkAvailability();
+ try {
+ return parent::isCreatable($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function isReadable($path) {
+ $this->checkAvailability();
+ try {
+ return parent::isReadable($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function isUpdatable($path) {
+ $this->checkAvailability();
+ try {
+ return parent::isUpdatable($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function isDeletable($path) {
+ $this->checkAvailability();
+ try {
+ return parent::isDeletable($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function isSharable($path) {
+ $this->checkAvailability();
+ try {
+ return parent::isSharable($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function getPermissions($path) {
+ $this->checkAvailability();
+ try {
+ return parent::getPermissions($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function file_exists($path) {
+ $this->checkAvailability();
+ try {
+ return parent::file_exists($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function filemtime($path) {
+ $this->checkAvailability();
+ try {
+ return parent::filemtime($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function file_get_contents($path) {
+ $this->checkAvailability();
+ try {
+ return parent::file_get_contents($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function file_put_contents($path, $data) {
+ $this->checkAvailability();
+ try {
+ return parent::file_put_contents($path, $data);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function unlink($path) {
+ $this->checkAvailability();
+ try {
+ return parent::unlink($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function rename($path1, $path2) {
+ $this->checkAvailability();
+ try {
+ return parent::rename($path1, $path2);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function copy($path1, $path2) {
+ $this->checkAvailability();
+ try {
+ return parent::copy($path1, $path2);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function fopen($path, $mode) {
+ $this->checkAvailability();
+ try {
+ return parent::fopen($path, $mode);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function getMimeType($path) {
+ $this->checkAvailability();
+ try {
+ return parent::getMimeType($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function hash($type, $path, $raw = false) {
+ $this->checkAvailability();
+ try {
+ return parent::hash($type, $path, $raw);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function free_space($path) {
+ $this->checkAvailability();
+ try {
+ return parent::free_space($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function search($query) {
+ $this->checkAvailability();
+ try {
+ return parent::search($query);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function touch($path, $mtime = null) {
+ $this->checkAvailability();
+ try {
+ return parent::touch($path, $mtime);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function getLocalFile($path) {
+ $this->checkAvailability();
+ try {
+ return parent::getLocalFile($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function getLocalFolder($path) {
+ $this->checkAvailability();
+ try {
+ return parent::getLocalFolder($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function hasUpdated($path, $time) {
+ $this->checkAvailability();
+ try {
+ return parent::hasUpdated($path, $time);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function getOwner($path) {
+ $this->checkAvailability();
+ try {
+ return parent::getOwner($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function getETag($path) {
+ $this->checkAvailability();
+ try {
+ return parent::getETag($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function getDirectDownload($path) {
+ $this->checkAvailability();
+ try {
+ return parent::getDirectDownload($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
+ $this->checkAvailability();
+ try {
+ return parent::copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
+ $this->checkAvailability();
+ try {
+ return parent::moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+
+ /** {@inheritdoc} */
+ public function getMetaData($path) {
+ $this->checkAvailability();
+ try {
+ return parent::getMetaData($path);
+ } catch (\OCP\Files\StorageNotAvailableException $e) {
+ $this->setAvailability(false);
+ throw $e;
+ }
+ }
+}
diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php
index 51aa13065c1..4ba9b21ddb4 100644
--- a/lib/private/files/storage/wrapper/encryption.php
+++ b/lib/private/files/storage/wrapper/encryption.php
@@ -127,12 +127,11 @@ class Encryption extends Wrapper {
$info = $this->getCache()->get($path);
if (isset($this->unencryptedSize[$fullPath])) {
$size = $this->unencryptedSize[$fullPath];
+ // update file cache
+ $info['encrypted'] = true;
+ $info['size'] = $size;
+ $this->getCache()->put($path, $info);
- if (isset($info['fileid'])) {
- $info['encrypted'] = true;
- $info['size'] = $size;
- $this->getCache()->put($path, $info);
- }
return $size;
}
diff --git a/lib/private/files/storage/wrapper/wrapper.php b/lib/private/files/storage/wrapper/wrapper.php
index d1414880beb..b43dd4fe142 100644
--- a/lib/private/files/storage/wrapper/wrapper.php
+++ b/lib/private/files/storage/wrapper/wrapper.php
@@ -498,6 +498,24 @@ class Wrapper implements \OC\Files\Storage\Storage {
}
/**
+ * Get availability of the storage
+ *
+ * @return array [ available, last_checked ]
+ */
+ public function getAvailability() {
+ return $this->storage->getAvailability();
+ }
+
+ /**
+ * Set availability of the storage
+ *
+ * @param bool $isAvailable
+ */
+ public function setAvailability($isAvailable) {
+ $this->storage->setAvailability($isAvailable);
+ }
+
+ /**
* @param string $path the path of the target folder
* @param string $fileName the name of the file itself
* @return void
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index da49db32d19..9afa9d40b20 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -1359,7 +1359,7 @@ class View {
// if sharing was disabled for the user we remove the share permissions
if (\OCP\Util::isSharingDisabledForUser()) {
- $content['permissions'] = $content['permissions'] & ~\OCP\Constants::PERMISSION_SHARE;
+ $rootEntry['permissions'] = $rootEntry['permissions'] & ~\OCP\Constants::PERMISSION_SHARE;
}
$files[] = new FileInfo($path . '/' . $rootEntry['name'], $subStorage, '', $rootEntry, $mount);
@@ -1661,11 +1661,11 @@ class View {
}
// verify database - e.g. mysql only 3-byte chars
- if (preg_match('%^(?:
+ if (preg_match('%(?:
\xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
-)*$%xs', $fileName)) {
+)%xs', $fileName)) {
throw new InvalidPathException($l10n->t('4-byte characters are not supported in file names'));
}
diff --git a/lib/private/installer.php b/lib/private/installer.php
index 37af8d0edcb..392dc1c0817 100644
--- a/lib/private/installer.php
+++ b/lib/private/installer.php
@@ -107,6 +107,10 @@ class OC_Installer{
}
$extractDir .= '/' . $info['id'];
+ if(!file_exists($extractDir)) {
+ OC_Helper::rmdirr($basedir);
+ throw new \Exception($l->t("Archive does not contain a directory named %s", $info['id']));
+ }
OC_Helper::copyr($extractDir, $basedir);
//remove temporary files
diff --git a/lib/private/ocs.php b/lib/private/ocs.php
index 6d166f8adb0..bb1aabf8f18 100644
--- a/lib/private/ocs.php
+++ b/lib/private/ocs.php
@@ -28,6 +28,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+use OCP\API;
/**
* Class to handle open collaboration services API requests
@@ -64,8 +65,7 @@ class OC_OCS {
}
}
if ($data === false) {
- echo self::generateXml('', 'fail', 400, 'Bad request. Please provide a valid '.$key);
- exit();
+ throw new \OC\OCS\Exception(new OC_OCS_Result(null, 400, 'Bad request. Please provide a valid '.$key));
} else {
// NOTE: Is the raw type necessary? It might be a little risky without sanitization
if ($type == 'raw') return $data;
@@ -78,23 +78,12 @@ class OC_OCS {
}
public static function notFound() {
- if($_SERVER['REQUEST_METHOD'] == 'GET') {
- $method='get';
- }elseif($_SERVER['REQUEST_METHOD'] == 'PUT') {
- $method='put';
- }elseif($_SERVER['REQUEST_METHOD'] == 'POST') {
- $method='post';
- }else{
- echo('internal server error: method not supported');
- exit();
- }
-
- $format = self::readData($method, 'format', 'text', '');
+ $format = OC_API::requestedFormat();
$txt='Invalid query, please check the syntax. API specifications are here:'
.' http://www.freedesktop.org/wiki/Specifications/open-collaboration-services. DEBUG OUTPUT:'."\n";
$txt.=OC_OCS::getDebugOutput();
- echo(OC_OCS::generateXml($format, 'failed', 999, $txt));
+ OC_API::respond(new OC_OCS_Result(null, API::RESPOND_UNKNOWN_ERROR, $txt), $format);
}
/**
@@ -110,130 +99,4 @@ class OC_OCS {
if(isset($_POST)) foreach($_POST as $key=>$value) $txt.='post parameter: '.$key.'->'.$value."\n";
return($txt);
}
-
-
- /**
- * generates the xml or json response for the API call from an multidimenional data array.
- * @param string $format
- * @param string $status
- * @param string $statuscode
- * @param string $message
- * @param array $data
- * @param string $tag
- * @param string $tagattribute
- * @param int $dimension
- * @param int|string $itemscount
- * @param int|string $itemsperpage
- * @return string xml/json
- */
- public static function generateXml($format, $status, $statuscode,
- $message, $data=array(), $tag='', $tagattribute='', $dimension=-1, $itemscount='', $itemsperpage='') {
- if($format=='json') {
- $json=array();
- $json['status']=$status;
- $json['statuscode']=$statuscode;
- $json['message']=$message;
- $json['totalitems']=$itemscount;
- $json['itemsperpage']=$itemsperpage;
- $json['data']=$data;
- return(json_encode($json));
- }else{
- $txt='';
- $writer = xmlwriter_open_memory();
- xmlwriter_set_indent( $writer, 2 );
- xmlwriter_start_document($writer );
- xmlwriter_start_element($writer, 'ocs');
- xmlwriter_start_element($writer, 'meta');
- xmlwriter_write_element($writer, 'status', $status);
- xmlwriter_write_element($writer, 'statuscode', $statuscode);
- xmlwriter_write_element($writer, 'message', $message);
- if($itemscount<>'') xmlwriter_write_element($writer, 'totalitems', $itemscount);
- if(!empty($itemsperpage)) xmlwriter_write_element($writer, 'itemsperpage', $itemsperpage);
- xmlwriter_end_element($writer);
- if($dimension=='0') {
- // 0 dimensions
- xmlwriter_write_element($writer, 'data', $data);
-
- }elseif($dimension=='1') {
- xmlwriter_start_element($writer, 'data');
- foreach($data as $key=>$entry) {
- xmlwriter_write_element($writer, $key, $entry);
- }
- xmlwriter_end_element($writer);
-
- }elseif($dimension=='2') {
- xmlwriter_start_element($writer, 'data');
- foreach($data as $entry) {
- xmlwriter_start_element($writer, $tag);
- if(!empty($tagattribute)) {
- xmlwriter_write_attribute($writer, 'details', $tagattribute);
- }
- foreach($entry as $key=>$value) {
- if(is_array($value)) {
- foreach($value as $k=>$v) {
- xmlwriter_write_element($writer, $k, $v);
- }
- } else {
- xmlwriter_write_element($writer, $key, $value);
- }
- }
- xmlwriter_end_element($writer);
- }
- xmlwriter_end_element($writer);
-
- }elseif($dimension=='3') {
- xmlwriter_start_element($writer, 'data');
- foreach($data as $entrykey=>$entry) {
- xmlwriter_start_element($writer, $tag);
- if(!empty($tagattribute)) {
- xmlwriter_write_attribute($writer, 'details', $tagattribute);
- }
- foreach($entry as $key=>$value) {
- if(is_array($value)) {
- xmlwriter_start_element($writer, $entrykey);
- foreach($value as $k=>$v) {
- xmlwriter_write_element($writer, $k, $v);
- }
- xmlwriter_end_element($writer);
- } else {
- xmlwriter_write_element($writer, $key, $value);
- }
- }
- xmlwriter_end_element($writer);
- }
- xmlwriter_end_element($writer);
- }elseif($dimension=='dynamic') {
- xmlwriter_start_element($writer, 'data');
- OC_OCS::toxml($writer, $data, 'comment');
- xmlwriter_end_element($writer);
- }
-
- xmlwriter_end_element($writer);
-
- xmlwriter_end_document( $writer );
- $txt.=xmlwriter_output_memory( $writer );
- unset($writer);
- return($txt);
- }
- }
-
- /**
- * @param resource $writer
- * @param array $data
- * @param string $node
- */
- public static function toXml($writer, $data, $node) {
- foreach($data as $key => $value) {
- if (is_numeric($key)) {
- $key = $node;
- }
- if (is_array($value)) {
- xmlwriter_start_element($writer, $key);
- OC_OCS::toxml($writer, $value, $node);
- xmlwriter_end_element($writer);
- }else{
- xmlwriter_write_element($writer, $key, $value);
- }
- }
- }
}
diff --git a/lib/private/ocs/cloud.php b/lib/private/ocs/cloud.php
index f662bde2858..8f4f1769e9c 100644
--- a/lib/private/ocs/cloud.php
+++ b/lib/private/ocs/cloud.php
@@ -3,6 +3,7 @@
* @author Bart Visscher <bartv@thisnet.nl>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin McCorkell <rmccorkell@karoshi.org.uk>
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Tom Needham <tom@owncloud.com>
*
@@ -36,12 +37,8 @@ class OC_OCS_Cloud {
'edition' => OC_Util::getEditionString(),
);
- $result['capabilities'] = array(
- 'core' => array(
- 'pollinterval' => OC_Config::getValue('pollinterval', 60),
- ),
- );
-
+ $result['capabilities'] = \OC::$server->getCapabilitiesManager()->getCapabilities();
+
return new OC_OCS_Result($result);
}
diff --git a/lib/private/ocs/corecapabilities.php b/lib/private/ocs/corecapabilities.php
new file mode 100644
index 00000000000..6b620ab0a84
--- /dev/null
+++ b/lib/private/ocs/corecapabilities.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @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\OCS;
+
+use OCP\Capabilities\ICapability;
+use OCP\IConfig;
+
+/**
+ * Class Capabilities
+ *
+ * @package OC\OCS
+ */
+class CoreCapabilities implements ICapability {
+
+ /** @var IConfig */
+ private $config;
+
+ /**
+ * @param IConfig $config
+ */
+ public function __construct(IConfig $config) {
+ $this->config = $config;
+ }
+
+ /**
+ * Return this classes capabilities
+ *
+ * @return array
+ */
+ public function getCapabilities() {
+ return [
+ 'core' => [
+ 'pollinterval' => $this->config->getSystemValue('pollinterval', 60)
+ ]
+ ];
+ }
+}
diff --git a/lib/private/db/mssqlmigrator.php b/lib/private/ocs/exception.php
index bedb5bac6c4..93bee773771 100644
--- a/lib/private/db/mssqlmigrator.php
+++ b/lib/private/ocs/exception.php
@@ -1,6 +1,5 @@
<?php
/**
- * @author Morris Jobke <hey@morrisjobke.de>
* @author Thomas Müller <thomas.mueller@tmit.eu>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
@@ -20,18 +19,16 @@
*
*/
-namespace OC\DB;
+namespace OC\OCS;
-use Doctrine\DBAL\Schema\Schema;
+class Exception extends \Exception {
-class MsSqlMigrator extends Migrator {
+ public function __construct(\OC_OCS_Result $result) {
+ $this->result = $result;
+ }
- /**
- * @param \Doctrine\DBAL\Schema\Schema $targetSchema
- */
- public function migrate(Schema $targetSchema) {
- throw new MigrationException('',
- 'Database migration is required to continue operation. This feature is provided within the Enterprise Edition.');
+ public function getResult() {
+ return $this->result;
}
}
diff --git a/lib/private/ocs/result.php b/lib/private/ocs/result.php
index 1ee2982ac4a..c4b0fbf33f3 100644
--- a/lib/private/ocs/result.php
+++ b/lib/private/ocs/result.php
@@ -27,7 +27,23 @@
class OC_OCS_Result{
- protected $data, $message, $statusCode, $items, $perPage;
+ /** @var array */
+ protected $data;
+
+ /** @var null|string */
+ protected $message;
+
+ /** @var int */
+ protected $statusCode;
+
+ /** @var integer */
+ protected $items;
+
+ /** @var integer */
+ protected $perPage;
+
+ /** @var array */
+ private $headers = [];
/**
* create the OCS_Result object
@@ -106,5 +122,32 @@ class OC_OCS_Result{
return ($this->statusCode == 100);
}
+ /**
+ * Adds a new header to the response
+ * @param string $name The name of the HTTP header
+ * @param string $value The value, null will delete it
+ * @return $this
+ */
+ public function addHeader($name, $value) {
+ $name = trim($name); // always remove leading and trailing whitespace
+ // to be able to reliably check for security
+ // headers
+
+ if(is_null($value)) {
+ unset($this->headers[$name]);
+ } else {
+ $this->headers[$name] = $value;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the set headers
+ * @return array the headers
+ */
+ public function getHeaders() {
+ return $this->headers;
+ }
}
diff --git a/lib/private/route/router.php b/lib/private/route/router.php
index 48992366092..33669452f2d 100644
--- a/lib/private/route/router.php
+++ b/lib/private/route/router.php
@@ -150,6 +150,12 @@ class Router implements IRouter {
\OC::$server->getEventLogger()->start('loadroutes' . $requestedApp, 'Loading Routes');
foreach ($routingFiles as $app => $file) {
if (!isset($this->loadedApps[$app])) {
+ if (!\OC_App::isAppLoaded($app)) {
+ // app MUST be loaded before app routes
+ // try again next time loadRoutes() is called
+ $this->loaded = false;
+ continue;
+ }
$this->loadedApps[$app] = true;
$this->useCollection($app);
$this->requireRouteFile($file, $app);
diff --git a/lib/private/security/crypto.php b/lib/private/security/crypto.php
index bca0f08090d..9bae1d6992c 100644
--- a/lib/private/security/crypto.php
+++ b/lib/private/security/crypto.php
@@ -23,11 +23,10 @@
namespace OC\Security;
-use Crypt_AES;
-use Crypt_Hash;
+use phpseclib\Crypt\AES;
+use phpseclib\Crypt\Hash;
use OCP\Security\ICrypto;
use OCP\Security\ISecureRandom;
-use OCP\Security\StringUtils;
use OCP\IConfig;
/**
@@ -41,7 +40,7 @@ use OCP\IConfig;
* @package OC\Security
*/
class Crypto implements ICrypto {
- /** @var Crypt_AES $cipher */
+ /** @var AES $cipher */
private $cipher;
/** @var int */
private $ivLength = 16;
@@ -50,8 +49,12 @@ class Crypto implements ICrypto {
/** @var ISecureRandom */
private $random;
+ /**
+ * @param IConfig $config
+ * @param ISecureRandom $random
+ */
function __construct(IConfig $config, ISecureRandom $random) {
- $this->cipher = new Crypt_AES();
+ $this->cipher = new AES();
$this->config = $config;
$this->random = $random;
}
@@ -69,7 +72,7 @@ class Crypto implements ICrypto {
// Append an "a" behind the password and hash it to prevent reusing the same password as for encryption
$password = hash('sha512', $password . 'a');
- $hash = new Crypt_Hash('sha512');
+ $hash = new Hash('sha512');
$hash->setKey($password);
return $hash->hash($message);
}
@@ -119,7 +122,7 @@ class Crypto implements ICrypto {
$this->cipher->setIV($iv);
- if(!StringUtils::equals($this->calculateHMAC($parts[0].$parts[1], $password), $hmac)) {
+ if(!\OCP\Security\StringUtils::equals($this->calculateHMAC($parts[0].$parts[1], $password), $hmac)) {
throw new \Exception('HMAC does not match.');
}
diff --git a/lib/private/server.php b/lib/private/server.php
index 12981fe7f19..9503cf16ff7 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -449,6 +449,14 @@ class Server extends SimpleContainer implements IServerContainer {
$c->getURLGenerator(),
\OC::$configDir);
});
+ $this->registerService('CapabilitiesManager', function (Server $c) {
+ $manager = new \OC\CapabilitiesManager();
+ $manager->registerCapability(function() use ($c) {
+ return new \OC\OCS\CoreCapabilities($c->getConfig());
+ });
+ return $manager;
+ });
+
}
/**
@@ -945,4 +953,13 @@ class Server extends SimpleContainer implements IServerContainer {
public function getMimeTypeDetector() {
return $this->query('MimeTypeDetector');
}
+
+ /**
+ * Get the manager of all the capabilities
+ *
+ * @return \OC\CapabilitiesManager
+ */
+ public function getCapabilitiesManager() {
+ return $this->query('CapabilitiesManager');
+ }
}
diff --git a/lib/private/setup.php b/lib/private/setup.php
index 50bf0dceafc..8f1ae389e45 100644
--- a/lib/private/setup.php
+++ b/lib/private/setup.php
@@ -39,6 +39,8 @@ use bantu\IniGetWrapper\IniGetWrapper;
use Exception;
use OCP\IConfig;
use OCP\IL10N;
+use OCP\ILogger;
+use OCP\Security\ISecureRandom;
class Setup {
/** @var \OCP\IConfig */
@@ -49,6 +51,10 @@ class Setup {
protected $l10n;
/** @var \OC_Defaults */
protected $defaults;
+ /** @var ILogger */
+ protected $logger;
+ /** @var ISecureRandom */
+ protected $random;
/**
* @param IConfig $config
@@ -58,18 +64,22 @@ class Setup {
function __construct(IConfig $config,
IniGetWrapper $iniWrapper,
IL10N $l10n,
- \OC_Defaults $defaults) {
+ \OC_Defaults $defaults,
+ ILogger $logger,
+ ISecureRandom $random
+ ) {
$this->config = $config;
$this->iniWrapper = $iniWrapper;
$this->l10n = $l10n;
$this->defaults = $defaults;
+ $this->logger = $logger;
+ $this->random = $random;
}
static $dbSetupClasses = array(
'mysql' => '\OC\Setup\MySQL',
'pgsql' => '\OC\Setup\PostgreSQL',
'oci' => '\OC\Setup\OCI',
- 'mssql' => '\OC\Setup\MSSQL',
'sqlite' => '\OC\Setup\Sqlite',
'sqlite3' => '\OC\Setup\Sqlite',
);
@@ -79,7 +89,7 @@ class Setup {
* @param string $name
* @return bool
*/
- public function class_exists($name) {
+ protected function class_exists($name) {
return class_exists($name);
}
@@ -88,11 +98,20 @@ class Setup {
* @param string $name
* @return bool
*/
- public function is_callable($name) {
+ protected function is_callable($name) {
return is_callable($name);
}
/**
+ * Wrapper around \PDO::getAvailableDrivers
+ *
+ * @return array
+ */
+ protected function getAvailableDbDriversForPdo() {
+ return \PDO::getAvailableDrivers();
+ }
+
+ /**
* Get the available and supported databases of this instance
*
* @param bool $allowAllDatabases
@@ -107,8 +126,8 @@ class Setup {
'name' => 'SQLite'
),
'mysql' => array(
- 'type' => 'function',
- 'call' => 'mysql_connect',
+ 'type' => 'pdo',
+ 'call' => 'mysql',
'name' => 'MySQL/MariaDB'
),
'pgsql' => array(
@@ -120,11 +139,6 @@ class Setup {
'type' => 'function',
'call' => 'oci_connect',
'name' => 'Oracle'
- ),
- 'mssql' => array(
- 'type' => 'function',
- 'call' => 'sqlsrv_connect',
- 'name' => 'MS SQL'
)
);
if ($allowAllDatabases) {
@@ -142,10 +156,15 @@ class Setup {
foreach($configuredDatabases as $database) {
if(array_key_exists($database, $availableDatabases)) {
$working = false;
- if($availableDatabases[$database]['type'] === 'class') {
- $working = $this->class_exists($availableDatabases[$database]['call']);
- } elseif ($availableDatabases[$database]['type'] === 'function') {
- $working = $this->is_callable($availableDatabases[$database]['call']);
+ $type = $availableDatabases[$database]['type'];
+ $call = $availableDatabases[$database]['call'];
+
+ if($type === 'class') {
+ $working = $this->class_exists($call);
+ } elseif ($type === 'function') {
+ $working = $this->is_callable($call);
+ } elseif($type === 'pdo') {
+ $working = in_array($call, $this->getAvailableDbDriversForPdo(), TRUE);
}
if($working) {
$supportedDatabases[$database] = $availableDatabases[$database]['name'];
@@ -218,7 +237,6 @@ class Setup {
'hasMySQL' => isset($databases['mysql']),
'hasPostgreSQL' => isset($databases['pgsql']),
'hasOracle' => isset($databases['oci']),
- 'hasMSSQL' => isset($databases['mssql']),
'databases' => $databases,
'directory' => $dataDir,
'htaccessWorking' => $htAccessWorking,
@@ -256,7 +274,8 @@ class Setup {
$class = self::$dbSetupClasses[$dbType];
/** @var \OC\Setup\AbstractDatabase $dbSetup */
- $dbSetup = new $class($l, 'db_structure.xml');
+ $dbSetup = new $class($l, 'db_structure.xml', $this->config,
+ $this->logger, $this->random);
$error = array_merge($error, $dbSetup->validate($options));
// validate the data directory
@@ -291,9 +310,9 @@ class Setup {
}
//generate a random salt that is used to salt the local user passwords
- $salt = \OC::$server->getSecureRandom()->getLowStrengthGenerator()->generate(30);
+ $salt = $this->random->getLowStrengthGenerator()->generate(30);
// generate a secret
- $secret = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(48);
+ $secret = $this->random->getMediumStrengthGenerator()->generate(48);
//write the config file
$this->config->setSystemValues([
@@ -358,7 +377,7 @@ class Setup {
//try to write logtimezone
if (date_default_timezone_get()) {
- \OC_Config::setValue('logtimezone', date_default_timezone_get());
+ $config->setSystemValue('logtimezone', date_default_timezone_get());
}
//and we are done
@@ -396,7 +415,9 @@ class Setup {
* @throws \OC\HintException If .htaccess does not include the current version
*/
public static function updateHtaccess() {
- $setupHelper = new \OC\Setup(\OC::$server->getConfig(), \OC::$server->getIniWrapper(), \OC::$server->getL10N('lib'), new \OC_Defaults());
+ $setupHelper = new \OC\Setup(\OC::$server->getConfig(), \OC::$server->getIniWrapper(),
+ \OC::$server->getL10N('lib'), new \OC_Defaults(), \OC::$server->getLogger(),
+ \OC::$server->getSecureRandom());
if(!$setupHelper->isCurrentHtaccess()) {
throw new \OC\HintException('.htaccess file has the wrong version. Please upload the correct version. Maybe you forgot to replace it after updating?');
}
diff --git a/lib/private/setup/abstractdatabase.php b/lib/private/setup/abstractdatabase.php
index 13daf1782fc..1ec853c3b02 100644
--- a/lib/private/setup/abstractdatabase.php
+++ b/lib/private/setup/abstractdatabase.php
@@ -22,22 +22,39 @@
*/
namespace OC\Setup;
+use OCP\IConfig;
+use OCP\ILogger;
+use OCP\Security\ISecureRandom;
+
abstract class AbstractDatabase {
- /**
- * @var \OC_L10N
- */
+ /** @var \OC_L10N */
protected $trans;
+ /** @var string */
protected $dbDefinitionFile;
- protected $dbuser;
- protected $dbpassword;
- protected $dbname;
- protected $dbhost;
- protected $tableprefix;
+ /** @var string */
+ protected $dbUser;
+ /** @var string */
+ protected $dbPassword;
+ /** @var string */
+ protected $dbName;
+ /** @var string */
+ protected $dbHost;
+ /** @var string */
+ protected $tablePrefix;
+ /** @var IConfig */
+ protected $config;
+ /** @var ILogger */
+ protected $logger;
+ /** @var ISecureRandom */
+ protected $random;
- public function __construct($trans, $dbDefinitionFile) {
+ public function __construct($trans, $dbDefinitionFile, IConfig $config, ILogger $logger, ISecureRandom $random) {
$this->trans = $trans;
$this->dbDefinitionFile = $dbDefinitionFile;
+ $this->config = $config;
+ $this->logger = $logger;
+ $this->random = $random;
}
public function validate($config) {
@@ -61,17 +78,17 @@ abstract class AbstractDatabase {
$dbHost = !empty($config['dbhost']) ? $config['dbhost'] : 'localhost';
$dbTablePrefix = isset($config['dbtableprefix']) ? $config['dbtableprefix'] : 'oc_';
- \OC_Config::setValues([
+ $this->config->setSystemValues([
'dbname' => $dbName,
'dbhost' => $dbHost,
'dbtableprefix' => $dbTablePrefix,
]);
- $this->dbuser = $dbUser;
- $this->dbpassword = $dbPass;
- $this->dbname = $dbName;
- $this->dbhost = $dbHost;
- $this->tableprefix = $dbTablePrefix;
+ $this->dbUser = $dbUser;
+ $this->dbPassword = $dbPass;
+ $this->dbName = $dbName;
+ $this->dbHost = $dbHost;
+ $this->tablePrefix = $dbTablePrefix;
}
abstract public function setupDatabase($userName);
diff --git a/lib/private/setup/mssql.php b/lib/private/setup/mssql.php
deleted file mode 100644
index 0ae02d6cbcc..00000000000
--- a/lib/private/setup/mssql.php
+++ /dev/null
@@ -1,203 +0,0 @@
-<?php
-/**
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @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\Setup;
-
-class MSSQL extends AbstractDatabase {
- public $dbprettyname = 'MS SQL Server';
-
- public function setupDatabase($username) {
- //check if the database user has admin right
- $masterConnectionInfo = array( "Database" => "master", "UID" => $this->dbuser, "PWD" => $this->dbpassword);
-
- $masterConnection = @sqlsrv_connect($this->dbhost, $masterConnectionInfo);
- if(!$masterConnection) {
- $entry = '';
- if( ($errors = sqlsrv_errors() ) != null) {
- $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />';
- }
- throw new \OC\DatabaseSetupException($this->trans->t('MS SQL username and/or password not valid: %s', array($entry)),
- $this->trans->t('You need to enter either an existing account or the administrator.'));
- }
-
- \OC_Config::setValues([
- 'dbuser' => $this->dbuser,
- 'dbpassword' => $this->dbpassword,
- ]);
-
- $this->createDBLogin($masterConnection);
-
- $this->createDatabase($masterConnection);
-
- $this->createDBUser($masterConnection);
-
- sqlsrv_close($masterConnection);
-
- $this->createDatabaseStructure();
- }
-
- private function createDBLogin($connection) {
- $query = "SELECT * FROM master.sys.server_principals WHERE name = '".$this->dbuser."';";
- $result = sqlsrv_query($connection, $query);
- if ($result === false) {
- if ( ($errors = sqlsrv_errors() ) != null) {
- $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />';
- } else {
- $entry = '';
- }
- $entry.='Offending command was: '.$query.'<br />';
- \OCP\Util::writeLog('setup.mssql', $entry, \OCP\Util::WARN);
- } else {
- $row = sqlsrv_fetch_array($result);
-
- if ($row === false) {
- if ( ($errors = sqlsrv_errors() ) != null) {
- $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />';
- } else {
- $entry = '';
- }
- $entry.='Offending command was: '.$query.'<br />';
- \OCP\Util::writeLog('setup.mssql', $entry, \OCP\Util::WARN);
- } else {
- if ($row == null) {
- $query = "CREATE LOGIN [".$this->dbuser."] WITH PASSWORD = '".$this->dbpassword."';";
- $result = sqlsrv_query($connection, $query);
- if (!$result or $result === false) {
- if ( ($errors = sqlsrv_errors() ) != null) {
- $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />';
- } else {
- $entry = '';
- }
- $entry.='Offending command was: '.$query.'<br />';
- \OCP\Util::writeLog('setup.mssql', $entry, \OCP\Util::WARN);
- }
- }
- }
- }
- }
-
- private function createDBUser($connection) {
- $query = "SELECT * FROM [".$this->dbname."].sys.database_principals WHERE name = '".$this->dbuser."';";
- $result = sqlsrv_query($connection, $query);
- if ($result === false) {
- if ( ($errors = sqlsrv_errors() ) != null) {
- $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />';
- } else {
- $entry = '';
- }
- $entry.='Offending command was: '.$query.'<br />';
- \OCP\Util::writeLog('setup.mssql', $entry, \OCP\Util::WARN);
- } else {
- $row = sqlsrv_fetch_array($result);
-
- if ($row === false) {
- if ( ($errors = sqlsrv_errors() ) != null) {
- $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />';
- } else {
- $entry = '';
- }
- $entry.='Offending command was: '.$query.'<br />';
- \OCP\Util::writeLog('setup.mssql', $entry, \OCP\Util::WARN);
- } else {
- if ($row == null) {
- $query = "USE [".$this->dbname."]; CREATE USER [".$this->dbuser."] FOR LOGIN [".$this->dbuser."];";
- $result = sqlsrv_query($connection, $query);
- if (!$result || $result === false) {
- if ( ($errors = sqlsrv_errors() ) != null) {
- $entry = 'DB Error: "'.print_r(sqlsrv_errors()).'"<br />';
- } else {
- $entry = '';
- }
- $entry.='Offending command was: '.$query.'<br />';
- \OCP\Util::writeLog('setup.mssql', $entry, \OCP\Util::WARN);
- }
- }
-
- $query = "USE [".$this->dbname."]; EXEC sp_addrolemember 'db_owner', '".$this->dbuser."';";
- $result = sqlsrv_query($connection, $query);
- if (!$result || $result === false) {
- if ( ($errors = sqlsrv_errors() ) != null) {
- $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />';
- } else {
- $entry = '';
- }
- $entry.='Offending command was: '.$query.'<br />';
- \OCP\Util::writeLog('setup.mssql', $entry, \OCP\Util::WARN);
- }
- }
- }
- }
-
- private function createDatabase($connection) {
- $query = "CREATE DATABASE [".$this->dbname."];";
- $result = sqlsrv_query($connection, $query);
- if (!$result || $result === false) {
- if ( ($errors = sqlsrv_errors() ) != null) {
- $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />';
- } else {
- $entry = '';
- }
- $entry.='Offending command was: '.$query.'<br />';
- \OCP\Util::writeLog('setup.mssql', $entry, \OCP\Util::WARN);
- }
- }
-
- private function createDatabaseStructure() {
- $connectionInfo = array( "Database" => $this->dbname, "UID" => $this->dbuser, "PWD" => $this->dbpassword);
-
- $connection = @sqlsrv_connect($this->dbhost, $connectionInfo);
-
- //fill the database if needed
- $query = "SELECT * FROM INFORMATION_SCHEMA.TABLES"
- ." WHERE TABLE_SCHEMA = '".$this->dbname."'"
- ." AND TABLE_NAME = '".$this->tableprefix."users'";
- $result = sqlsrv_query($connection, $query);
- if ($result === false) {
- if ( ($errors = sqlsrv_errors() ) != null) {
- $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />';
- } else {
- $entry = '';
- }
- $entry.='Offending command was: '.$query.'<br />';
- \OCP\Util::writeLog('setup.mssql', $entry, \OCP\Util::WARN);
- } else {
- $row = sqlsrv_fetch_array($result);
-
- if ($row === false) {
- if ( ($errors = sqlsrv_errors() ) != null) {
- $entry='DB Error: "'.print_r(sqlsrv_errors()).'"<br />';
- } else {
- $entry = '';
- }
- $entry.='Offending command was: '.$query.'<br />';
- \OCP\Util::writeLog('setup.mssql', $entry, \OCP\Util::WARN);
- } else {
- if ($row == null) {
- \OC_DB::createDbFromStructure($this->dbDefinitionFile);
- }
- }
- }
-
- sqlsrv_close($connection);
- }
-}
diff --git a/lib/private/setup/mysql.php b/lib/private/setup/mysql.php
index c01ff724b80..5597592f21e 100644
--- a/lib/private/setup/mysql.php
+++ b/lib/private/setup/mysql.php
@@ -23,110 +23,139 @@
*/
namespace OC\Setup;
+use OC\DB\ConnectionFactory;
+use OCP\IDBConnection;
+
class MySQL extends AbstractDatabase {
public $dbprettyname = 'MySQL/MariaDB';
public function setupDatabase($username) {
//check if the database user has admin right
- $connection = @mysql_connect($this->dbhost, $this->dbuser, $this->dbpassword);
- if(!$connection) {
- throw new \OC\DatabaseSetupException($this->trans->t('MySQL/MariaDB username and/or password not valid'),
- $this->trans->t('You need to enter either an existing account or the administrator.'));
- }
- //user already specified in config
- $oldUser=\OC_Config::getValue('dbuser', false);
-
- //we don't have a dbuser specified in config
- if($this->dbuser!=$oldUser) {
- //add prefix to the admin username to prevent collisions
- $adminUser=substr('oc_'.$username, 0, 16);
-
- $i = 1;
- while(true) {
- //this should be enough to check for admin rights in mysql
- $query="SELECT user FROM mysql.user WHERE user='$adminUser'";
-
- $result = mysql_query($query, $connection);
+ $connection = $this->connect();
- //current dbuser has admin rights
- if($result) {
- //new dbuser does not exist
- if(mysql_num_rows($result) === 0) {
- //use the admin login data for the new database user
- $this->dbuser=$adminUser;
-
- //create a random password so we don't need to store the admin password in the config file
- $this->dbpassword=\OC_Util::generateRandomBytes(30);
-
- $this->createDBUser($connection);
-
- break;
- } else {
- //repeat with different username
- $length=strlen((string)$i);
- $adminUser=substr('oc_'.$username, 0, 16 - $length).$i;
- $i++;
- }
- } else {
- break;
- }
- };
-
- \OC_Config::setValues([
- 'dbuser' => $this->dbuser,
- 'dbpassword' => $this->dbpassword,
- ]);
- }
+ $this->createSpecificUser($username, $connection);
//create the database
$this->createDatabase($connection);
//fill the database if needed
- $query='select count(*) from information_schema.tables'
- ." where table_schema='".$this->dbname."' AND table_name = '".$this->tableprefix."users';";
- $result = mysql_query($query, $connection);
- if($result) {
- $row=mysql_fetch_row($result);
- }
+ $query='select count(*) from information_schema.tables where table_schema=? AND table_name = ?';
+ $result = $connection->executeQuery($query, [$this->dbName, $this->tablePrefix.'users']);
+ $row = $result->fetch();
if(!$result or $row[0]==0) {
\OC_DB::createDbFromStructure($this->dbDefinitionFile);
}
- mysql_close($connection);
}
+ /**
+ * @param \OC\DB\Connection $connection
+ */
private function createDatabase($connection) {
- $name = $this->dbname;
- $user = $this->dbuser;
- //we cant use OC_BD functions here because we need to connect as the administrative user.
- $query = "CREATE DATABASE IF NOT EXISTS `$name` CHARACTER SET utf8 COLLATE utf8_bin;";
- $result = mysql_query($query, $connection);
- if(!$result) {
- $entry = $this->trans->t('DB Error: "%s"', array(mysql_error($connection))) . '<br />';
- $entry .= $this->trans->t('Offending command was: "%s"', array($query)) . '<br />';
- \OCP\Util::writeLog('setup.mssql', $entry, \OCP\Util::WARN);
- }
- $query="GRANT ALL PRIVILEGES ON `$name` . * TO '$user'";
+ try{
+ $name = $this->dbName;
+ $user = $this->dbUser;
+ //we cant use OC_BD functions here because we need to connect as the administrative user.
+ $query = "CREATE DATABASE IF NOT EXISTS `$name` CHARACTER SET utf8 COLLATE utf8_bin;";
+ $connection->executeUpdate($query);
- //this query will fail if there aren't the right permissions, ignore the error
- mysql_query($query, $connection);
+ //this query will fail if there aren't the right permissions, ignore the error
+ $query="GRANT ALL PRIVILEGES ON `$name` . * TO '$user'";
+ $connection->executeUpdate($query);
+ } catch (\Exception $ex) {
+ $this->logger->error('Database creation failed: {error}', [
+ 'app' => 'mysql.setup',
+ 'error' => $ex->getMessage()
+ ]);
+ }
}
+ /**
+ * @param IDbConnection $connection
+ * @throws \OC\DatabaseSetupException
+ */
private function createDBUser($connection) {
- $name = $this->dbuser;
- $password = $this->dbpassword;
+ $name = $this->dbUser;
+ $password = $this->dbPassword;
// we need to create 2 accounts, one for global use and one for local user. if we don't specify the local one,
// the anonymous user would take precedence when there is one.
$query = "CREATE USER '$name'@'localhost' IDENTIFIED BY '$password'";
- $result = mysql_query($query, $connection);
- if (!$result) {
- throw new \OC\DatabaseSetupException($this->trans->t("MySQL/MariaDB user '%s'@'localhost' exists already.", array($name)),
- $this->trans->t("Drop this user from MySQL/MariaDB", array($name)));
- }
+ $connection->executeUpdate($query);
$query = "CREATE USER '$name'@'%' IDENTIFIED BY '$password'";
- $result = mysql_query($query, $connection);
- if (!$result) {
- throw new \OC\DatabaseSetupException($this->trans->t("MySQL/MariaDB user '%s'@'%%' already exists", array($name)),
- $this->trans->t("Drop this user from MySQL/MariaDB."));
+ $connection->executeUpdate($query);
+ }
+
+ /**
+ * @return \OC\DB\Connection
+ * @throws \OC\DatabaseSetupException
+ */
+ private function connect() {
+ $type = 'mysql';
+ $connectionParams = array(
+ 'host' => $this->dbHost,
+ 'user' => $this->dbUser,
+ 'password' => $this->dbPassword,
+ 'tablePrefix' => $this->tablePrefix,
+ );
+ $cf = new ConnectionFactory();
+ return $cf->getConnection($type, $connectionParams);
+ }
+
+ /**
+ * @param $username
+ * @param IDBConnection $connection
+ * @return array
+ */
+ private function createSpecificUser($username, $connection) {
+ try {
+ //user already specified in config
+ $oldUser = $this->config->getSystemValue('dbuser', false);
+
+ //we don't have a dbuser specified in config
+ if ($this->dbUser !== $oldUser) {
+ //add prefix to the admin username to prevent collisions
+ $adminUser = substr('oc_' . $username, 0, 16);
+
+ $i = 1;
+ while (true) {
+ //this should be enough to check for admin rights in mysql
+ $query = 'SELECT user FROM mysql.user WHERE user=?';
+ $result = $connection->executeQuery($query, [$adminUser]);
+
+ //current dbuser has admin rights
+ if ($result) {
+ $data = $result->fetchAll();
+ //new dbuser does not exist
+ if (count($data) === 0) {
+ //use the admin login data for the new database user
+ $this->dbUser = $adminUser;
+
+ //create a random password so we don't need to store the admin password in the config file
+ $this->dbPassword = $this->random->getMediumStrengthGenerator()->generate(30);
+
+ $this->createDBUser($connection);
+
+ break;
+ } else {
+ //repeat with different username
+ $length = strlen((string)$i);
+ $adminUser = substr('oc_' . $username, 0, 16 - $length) . $i;
+ $i++;
+ }
+ } else {
+ break;
+ }
+ };
+ }
+ } catch (\Exception $ex) {
+ $this->logger->error('Specific user creation failed: {error}', [
+ 'app' => 'mysql.setup',
+ 'error' => $ex->getMessage()
+ ]);
}
+
+ $this->config->setSystemValues([
+ 'dbuser' => $this->dbUser,
+ 'dbpassword' => $this->dbPassword,
+ ]);
}
}
diff --git a/lib/private/setup/oci.php b/lib/private/setup/oci.php
index d46d5529da0..1e1eb1ff54e 100644
--- a/lib/private/setup/oci.php
+++ b/lib/private/setup/oci.php
@@ -38,10 +38,10 @@ class OCI extends AbstractDatabase {
$this->dbtablespace = 'USERS';
}
// allow empty hostname for oracle
- $this->dbhost = $config['dbhost'];
+ $this->dbHost = $config['dbhost'];
\OC_Config::setValues([
- 'dbhost' => $this->dbhost,
+ 'dbhost' => $this->dbHost,
'dbtablespace' => $this->dbtablespace,
]);
}
@@ -58,8 +58,8 @@ class OCI extends AbstractDatabase {
}
public function setupDatabase($username) {
- $e_host = addslashes($this->dbhost);
- $e_dbname = addslashes($this->dbname);
+ $e_host = addslashes($this->dbHost);
+ $e_dbname = addslashes($this->dbName);
//check if the database user has admin right
if ($e_host == '') {
$easy_connect_string = $e_dbname; // use dbname as easy connect name
@@ -67,7 +67,7 @@ class OCI extends AbstractDatabase {
$easy_connect_string = '//'.$e_host.'/'.$e_dbname;
}
\OCP\Util::writeLog('setup oracle', 'connect string: ' . $easy_connect_string, \OCP\Util::DEBUG);
- $connection = @oci_connect($this->dbuser, $this->dbpassword, $easy_connect_string);
+ $connection = @oci_connect($this->dbUser, $this->dbPassword, $easy_connect_string);
if(!$connection) {
$errorMessage = $this->getLastError();
if ($errorMessage) {
@@ -103,23 +103,23 @@ class OCI extends AbstractDatabase {
//use the admin login data for the new database user
//add prefix to the oracle user name to prevent collisions
- $this->dbuser='oc_'.$username;
+ $this->dbUser='oc_'.$username;
//create a new password so we don't need to store the admin config in the config file
- $this->dbpassword=\OC_Util::generateRandomBytes(30);
+ $this->dbPassword=\OC_Util::generateRandomBytes(30);
//oracle passwords are treated as identifiers:
// must start with alphanumeric char
// needs to be shortened to 30 bytes, as the two " needed to escape the identifier count towards the identifier length.
- $this->dbpassword=substr($this->dbpassword, 0, 30);
+ $this->dbPassword=substr($this->dbPassword, 0, 30);
$this->createDBUser($connection);
}
}
\OC_Config::setValues([
- 'dbuser' => $this->dbuser,
- 'dbname' => $this->dbname,
- 'dbpassword' => $this->dbpassword,
+ 'dbuser' => $this->dbUser,
+ 'dbname' => $this->dbName,
+ 'dbpassword' => $this->dbPassword,
]);
//create the database not necessary, oracle implies user = schema
@@ -131,26 +131,26 @@ class OCI extends AbstractDatabase {
oci_close($connection);
// connect to the oracle database (schema=$this->dbuser) an check if the schema needs to be filled
- $this->dbuser = \OC_Config::getValue('dbuser');
+ $this->dbUser = \OC_Config::getValue('dbuser');
//$this->dbname = \OC_Config::getValue('dbname');
- $this->dbpassword = \OC_Config::getValue('dbpassword');
+ $this->dbPassword = \OC_Config::getValue('dbpassword');
- $e_host = addslashes($this->dbhost);
- $e_dbname = addslashes($this->dbname);
+ $e_host = addslashes($this->dbHost);
+ $e_dbname = addslashes($this->dbName);
if ($e_host == '') {
$easy_connect_string = $e_dbname; // use dbname as easy connect name
} else {
$easy_connect_string = '//'.$e_host.'/'.$e_dbname;
}
- $connection = @oci_connect($this->dbuser, $this->dbpassword, $easy_connect_string);
+ $connection = @oci_connect($this->dbUser, $this->dbPassword, $easy_connect_string);
if(!$connection) {
throw new \OC\DatabaseSetupException($this->trans->t('Oracle username and/or password not valid'),
$this->trans->t('You need to enter either an existing account or the administrator.'));
}
$query = "SELECT count(*) FROM user_tables WHERE table_name = :un";
$stmt = oci_parse($connection, $query);
- $un = $this->tableprefix.'users';
+ $un = $this->tablePrefix.'users';
oci_bind_by_name($stmt, ':un', $un);
if (!$stmt) {
$entry = $this->trans->t('DB Error: "%s"', array($this->getLastError($connection))) . '<br />';
@@ -171,8 +171,8 @@ class OCI extends AbstractDatabase {
* @param resource $connection
*/
private function createDBUser($connection) {
- $name = $this->dbuser;
- $password = $this->dbpassword;
+ $name = $this->dbUser;
+ $password = $this->dbPassword;
$query = "SELECT * FROM all_users WHERE USERNAME = :un";
$stmt = oci_parse($connection, $query);
if (!$stmt) {
diff --git a/lib/private/setup/postgresql.php b/lib/private/setup/postgresql.php
index c8fd3b98fe4..319b6676ef8 100644
--- a/lib/private/setup/postgresql.php
+++ b/lib/private/setup/postgresql.php
@@ -27,9 +27,9 @@ class PostgreSQL extends AbstractDatabase {
public $dbprettyname = 'PostgreSQL';
public function setupDatabase($username) {
- $e_host = addslashes($this->dbhost);
- $e_user = addslashes($this->dbuser);
- $e_password = addslashes($this->dbpassword);
+ $e_host = addslashes($this->dbHost);
+ $e_user = addslashes($this->dbUser);
+ $e_password = addslashes($this->dbPassword);
// Fix database with port connection
if(strpos($e_host, ':')) {
@@ -43,7 +43,7 @@ class PostgreSQL extends AbstractDatabase {
$connection = @pg_connect($connection_string);
if(!$connection) {
// Try if we can connect to the DB with the specified name
- $e_dbname = addslashes($this->dbname);
+ $e_dbname = addslashes($this->dbName);
$connection_string = "host='$e_host' dbname='$e_dbname' user='$e_user' port='$port' password='$e_password'";
$connection = @pg_connect($connection_string);
@@ -51,7 +51,7 @@ class PostgreSQL extends AbstractDatabase {
throw new \OC\DatabaseSetupException($this->trans->t('PostgreSQL username and/or password not valid'),
$this->trans->t('You need to enter either an existing account or the administrator.'));
}
- $e_user = pg_escape_string($this->dbuser);
+ $e_user = pg_escape_string($this->dbUser);
//check for roles creation rights in postgresql
$query="SELECT 1 FROM pg_roles WHERE rolcreaterole=TRUE AND rolname='$e_user'";
$result = pg_query($connection, $query);
@@ -59,16 +59,16 @@ class PostgreSQL extends AbstractDatabase {
//use the admin login data for the new database user
//add prefix to the postgresql user name to prevent collisions
- $this->dbuser='oc_'.$username;
+ $this->dbUser='oc_'.$username;
//create a new password so we don't need to store the admin config in the config file
- $this->dbpassword=\OC_Util::generateRandomBytes(30);
+ $this->dbPassword=\OC_Util::generateRandomBytes(30);
$this->createDBUser($connection);
}
\OC_Config::setValues([
- 'dbuser' => $this->dbuser,
- 'dbpassword' => $this->dbpassword,
+ 'dbuser' => $this->dbUser,
+ 'dbpassword' => $this->dbPassword,
]);
//create the database
@@ -78,13 +78,13 @@ class PostgreSQL extends AbstractDatabase {
pg_close($connection);
// connect to the ownCloud database (dbname=$this->dbname) and check if it needs to be filled
- $this->dbuser = \OC_Config::getValue('dbuser');
- $this->dbpassword = \OC_Config::getValue('dbpassword');
+ $this->dbUser = \OC_Config::getValue('dbuser');
+ $this->dbPassword = \OC_Config::getValue('dbpassword');
- $e_host = addslashes($this->dbhost);
- $e_dbname = addslashes($this->dbname);
- $e_user = addslashes($this->dbuser);
- $e_password = addslashes($this->dbpassword);
+ $e_host = addslashes($this->dbHost);
+ $e_dbname = addslashes($this->dbName);
+ $e_user = addslashes($this->dbUser);
+ $e_password = addslashes($this->dbPassword);
// Fix database with port connection
if(strpos($e_host, ':')) {
@@ -99,7 +99,7 @@ class PostgreSQL extends AbstractDatabase {
throw new \OC\DatabaseSetupException($this->trans->t('PostgreSQL username and/or password not valid'),
$this->trans->t('You need to enter either an existing account or the administrator.'));
}
- $query = "select count(*) FROM pg_class WHERE relname='".$this->tableprefix."users' limit 1";
+ $query = "select count(*) FROM pg_class WHERE relname='".$this->tablePrefix."users' limit 1";
$result = pg_query($connection, $query);
if($result) {
$row = pg_fetch_row($result);
@@ -111,8 +111,8 @@ class PostgreSQL extends AbstractDatabase {
private function createDatabase($connection) {
//we cant use OC_BD functions here because we need to connect as the administrative user.
- $e_name = pg_escape_string($this->dbname);
- $e_user = pg_escape_string($this->dbuser);
+ $e_name = pg_escape_string($this->dbName);
+ $e_user = pg_escape_string($this->dbUser);
$query = "select datname from pg_database where datname = '$e_name'";
$result = pg_query($connection, $query);
if(!$result) {
@@ -137,8 +137,8 @@ class PostgreSQL extends AbstractDatabase {
}
private function createDBUser($connection) {
- $e_name = pg_escape_string($this->dbuser);
- $e_password = pg_escape_string($this->dbpassword);
+ $e_name = pg_escape_string($this->dbUser);
+ $e_password = pg_escape_string($this->dbPassword);
$query = "select * from pg_roles where rolname='$e_name';";
$result = pg_query($connection, $query);
if(!$result) {
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index 40fcc59f219..9aea4677b5b 100644
--- a/lib/private/share/share.php
+++ b/lib/private/share/share.php
@@ -1218,7 +1218,7 @@ class Share extends Constants {
$qb = $connection->getQueryBuilder();
$qb->select('uid_owner')
- ->from('*PREFIX*share')
+ ->from('share')
->where($qb->expr()->eq('id', $qb->createParameter('shareId')))
->setParameter(':shareId', $shareId);
$result = $qb->execute();
@@ -1269,7 +1269,7 @@ class Share extends Constants {
self::verifyPassword($password);
$qb = $connection->getQueryBuilder();
- $qb->update('*PREFIX*share')
+ $qb->update('share')
->set('share_with', $qb->createParameter('pass'))
->where($qb->expr()->eq('id', $qb->createParameter('shareId')))
->setParameter(':pass', is_null($password) ? null : \OC::$server->getHasher()->hash($password))
diff --git a/lib/private/template.php b/lib/private/template.php
index ca689729f80..e7acc778de3 100644
--- a/lib/private/template.php
+++ b/lib/private/template.php
@@ -222,9 +222,9 @@ class OC_Template extends \OC\Template\Base {
/**
* print error page using Exception details
- * @param Exception $exception
+ * @param Exception|Error $exception
*/
- public static function printExceptionErrorPage(Exception $exception) {
+ public static function printExceptionErrorPage($exception) {
$request = \OC::$server->getRequest();
$content = new \OC_Template('', 'exception', 'error', false);
$content->assign('errorClass', get_class($exception));
diff --git a/lib/private/util.php b/lib/private/util.php
index 39d64952dc6..501dbf5c4c5 100644
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -143,6 +143,14 @@ class OC_Util {
return $storage;
});
+ // install storage availability wrapper, before most other wrappers
+ \OC\Files\Filesystem::addStorageWrapper('oc_availability', function ($mountPoint, $storage) {
+ if (!$storage->isLocal()) {
+ return new \OC\Files\Storage\Wrapper\Availability(['storage' => $storage]);
+ }
+ return $storage;
+ });
+
\OC\Files\Filesystem::addStorageWrapper('oc_quota', function ($mountPoint, $storage) {
// set up quota for home storages, even for other users
// which can happen when using sharing
@@ -567,7 +575,8 @@ class OC_Util {
}
$webServerRestart = false;
- $setup = new \OC\Setup($config, \OC::$server->getIniWrapper(), \OC::$server->getL10N('lib'), new \OC_Defaults());
+ $setup = new \OC\Setup($config, \OC::$server->getIniWrapper(), \OC::$server->getL10N('lib'),
+ new \OC_Defaults(), \OC::$server->getLogger(), \OC::$server->getSecureRandom());
$availableDatabases = $setup->getSupportedDatabases();
if (empty($availableDatabases)) {
$errors[] = array(