summaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/Activity/LegacyFilter.php110
-rw-r--r--lib/private/Activity/LegacySetting.php125
-rw-r--r--lib/private/Activity/Manager.php369
-rw-r--r--lib/private/AppFramework/DependencyInjection/DIContainer.php3
-rw-r--r--lib/private/AppFramework/Middleware/AdditionalScriptsMiddleware.php56
-rw-r--r--lib/private/AppFramework/Routing/RouteConfig.php148
-rw-r--r--lib/private/Authentication/TwoFactorAuth/Manager.php9
-rw-r--r--lib/private/Config.php6
-rw-r--r--lib/private/ContactsManager.php16
-rw-r--r--lib/private/Files/ObjectStore/S3ObjectTrait.php7
-rw-r--r--lib/private/Files/View.php8
-rw-r--r--lib/private/InitialStateService.php90
-rw-r--r--lib/private/Preview/TXT.php5
-rw-r--r--lib/private/Server.php10
-rw-r--r--lib/private/Settings/Personal/PersonalInfo.php2
-rw-r--r--lib/private/Share20/Manager.php23
-rw-r--r--lib/private/SubAdmin.php35
-rw-r--r--lib/private/TemplateLayout.php4
-rw-r--r--lib/private/User/Session.php9
-rw-r--r--lib/private/legacy/user.php8
-rw-r--r--lib/private/legacy/util.php72
21 files changed, 379 insertions, 736 deletions
diff --git a/lib/private/Activity/LegacyFilter.php b/lib/private/Activity/LegacyFilter.php
deleted file mode 100644
index 9beffc1f3a7..00000000000
--- a/lib/private/Activity/LegacyFilter.php
+++ /dev/null
@@ -1,110 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
- *
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-namespace OC\Activity;
-
-use OCP\Activity\IFilter;
-use OCP\Activity\IManager;
-
-class LegacyFilter implements IFilter {
-
- /** @var IManager */
- protected $manager;
- /** @var string */
- protected $identifier;
- /** @var string */
- protected $name;
- /** @var bool */
- protected $isTopFilter;
-
- /**
- * LegacySetting constructor.
- *
- * @param IManager $manager
- * @param string $identifier
- * @param string $name
- * @param bool $isTopFilter
- */
- public function __construct(IManager $manager,
- $identifier,
- $name,
- $isTopFilter) {
- $this->manager = $manager;
- $this->identifier = $identifier;
- $this->name = $name;
- $this->isTopFilter = $isTopFilter;
- }
-
- /**
- * @return string Lowercase a-z and underscore only identifier
- * @since 11.0.0
- */
- public function getIdentifier() {
- return $this->identifier;
- }
-
- /**
- * @return string A translated string
- * @since 11.0.0
- */
- public function getName() {
- return $this->name;
- }
-
- /**
- * @return int whether the filter should be rather on the top or bottom of
- * the admin section. The filters are arranged in ascending order of the
- * priority values. It is required to return a value between 0 and 100.
- * @since 11.0.0
- */
- public function getPriority() {
- return $this->isTopFilter ? 40 : 50;
- }
-
- /**
- * @return string Full URL to an icon, empty string when none is given
- * @since 11.0.0
- */
- public function getIcon() {
- // Old API was CSS class, so we can not use this...
- return '';
- }
-
- /**
- * @param string[] $types
- * @return string[] An array of allowed apps from which activities should be displayed
- * @since 11.0.0
- */
- public function filterTypes(array $types) {
- return $this->manager->filterNotificationTypes($types, $this->getIdentifier());
- }
-
- /**
- * @return string[] An array of allowed apps from which activities should be displayed
- * @since 11.0.0
- */
- public function allowedApps() {
- return [];
- }
-}
-
diff --git a/lib/private/Activity/LegacySetting.php b/lib/private/Activity/LegacySetting.php
deleted file mode 100644
index 7d08533aef5..00000000000
--- a/lib/private/Activity/LegacySetting.php
+++ /dev/null
@@ -1,125 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
- *
- * @author Joas Schilling <coding@schilljs.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-namespace OC\Activity;
-
-use OCP\Activity\ISetting;
-
-class LegacySetting implements ISetting {
-
- /** @var string */
- protected $identifier;
- /** @var string */
- protected $name;
- /** @var bool */
- protected $canChangeStream;
- /** @var bool */
- protected $isDefaultEnabledStream;
- /** @var bool */
- protected $canChangeMail;
- /** @var bool */
- protected $isDefaultEnabledMail;
-
- /**
- * LegacySetting constructor.
- *
- * @param string $identifier
- * @param string $name
- * @param bool $canChangeStream
- * @param bool $isDefaultEnabledStream
- * @param bool $canChangeMail
- * @param bool $isDefaultEnabledMail
- */
- public function __construct($identifier,
- $name,
- $canChangeStream,
- $isDefaultEnabledStream,
- $canChangeMail,
- $isDefaultEnabledMail) {
- $this->identifier = $identifier;
- $this->name = $name;
- $this->canChangeStream = $canChangeStream;
- $this->isDefaultEnabledStream = $isDefaultEnabledStream;
- $this->canChangeMail = $canChangeMail;
- $this->isDefaultEnabledMail = $isDefaultEnabledMail;
- }
-
- /**
- * @return string Lowercase a-z and underscore only identifier
- * @since 11.0.0
- */
- public function getIdentifier() {
- return $this->identifier;
- }
-
- /**
- * @return string A translated string
- * @since 11.0.0
- */
- public function getName() {
- return $this->name;
- }
-
- /**
- * @return int whether the filter should be rather on the top or bottom of
- * the admin section. The filters are arranged in ascending order of the
- * priority values. It is required to return a value between 0 and 100.
- * @since 11.0.0
- */
- public function getPriority() {
- return 70;
- }
-
- /**
- * @return bool True when the option can be changed for the stream
- * @since 11.0.0
- */
- public function canChangeStream() {
- return $this->canChangeStream;
- }
-
- /**
- * @return bool True when the option can be changed for the stream
- * @since 11.0.0
- */
- public function isDefaultEnabledStream() {
- return $this->isDefaultEnabledStream;
- }
-
- /**
- * @return bool True when the option can be changed for the mail
- * @since 11.0.0
- */
- public function canChangeMail() {
- return $this->canChangeMail;
- }
-
- /**
- * @return bool True when the option can be changed for the stream
- * @since 11.0.0
- */
- public function isDefaultEnabledMail() {
- return $this->isDefaultEnabledMail;
- }
-}
-
diff --git a/lib/private/Activity/Manager.php b/lib/private/Activity/Manager.php
index 9e70b6f465a..3381c23e31c 100644
--- a/lib/private/Activity/Manager.php
+++ b/lib/private/Activity/Manager.php
@@ -28,7 +28,6 @@ namespace OC\Activity;
use OCP\Activity\IConsumer;
use OCP\Activity\IEvent;
-use OCP\Activity\IExtension;
use OCP\Activity\IFilter;
use OCP\Activity\IManager;
use OCP\Activity\IProvider;
@@ -64,14 +63,6 @@ class Manager implements IManager {
/** @var string */
protected $currentUserId;
- /**
- * constructor of the controller
- *
- * @param IRequest $request
- * @param IUserSession $session
- * @param IConfig $config
- * @param IValidator $validator
- */
public function __construct(IRequest $request,
IUserSession $session,
IConfig $config,
@@ -88,29 +79,10 @@ class Manager implements IManager {
/** @var IConsumer[] */
private $consumers = array();
- /** @var \Closure[] */
- private $extensionsClosures = array();
-
- /** @var IExtension[] */
- private $extensions = array();
-
- /** @var array list of filters "name" => "is valid" */
- protected $validFilters = array(
- 'all' => true,
- 'by' => true,
- 'self' => true,
- );
-
- /** @var array list of type icons "type" => "css class" */
- protected $typeIcons = array();
-
- /** @var array list of special parameters "app" => ["text" => ["parameter" => "type"]] */
- protected $specialParameters = array();
-
/**
* @return \OCP\Activity\IConsumer[]
*/
- protected function getConsumers() {
+ protected function getConsumers(): array {
if (!empty($this->consumers)) {
return $this->consumers;
}
@@ -129,27 +101,6 @@ class Manager implements IManager {
}
/**
- * @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;
- }
-
- /**
* Generates a new IEvent object
*
* Make sure to call at least the following methods before sending it to the
@@ -161,7 +112,7 @@ class Manager implements IManager {
*
* @return IEvent
*/
- public function generateEvent() {
+ public function generateEvent(): IEvent {
return new Event($this->validator);
}
@@ -177,7 +128,7 @@ class Manager implements IManager {
* @param IEvent $event
* @throws \BadMethodCallException if required values have not been set
*/
- public function publish(IEvent $event) {
+ public function publish(IEvent $event): void {
if ($event->getAuthor() === '') {
if ($this->session->getUser() instanceof IUser) {
$event->setAuthor($this->session->getUser()->getUID());
@@ -205,38 +156,22 @@ class Manager implements IManager {
*
* @param \Closure $callable
*/
- public function registerConsumer(\Closure $callable) {
+ public function registerConsumer(\Closure $callable): void {
$this->consumersClosures[] = $callable;
$this->consumers = [];
}
- /**
- * In order to improve lazy loading a closure can be registered which will be called in case
- * activity consumers are actually requested
- *
- * $callable has to return an instance of OCA\Activity\IExtension
- *
- * @param \Closure $callable
- */
- public function registerExtension(\Closure $callable) {
- $this->extensionsClosures[] = $callable;
- $this->extensions = [];
- }
-
/** @var string[] */
protected $filterClasses = [];
/** @var IFilter[] */
protected $filters = [];
- /** @var bool */
- protected $loadedLegacyFilters = false;
-
/**
* @param string $filter Class must implement OCA\Activity\IFilter
* @return void
*/
- public function registerFilter($filter) {
+ public function registerFilter(string $filter): void {
$this->filterClasses[$filter] = false;
}
@@ -244,24 +179,7 @@ class Manager implements IManager {
* @return IFilter[]
* @throws \InvalidArgumentException
*/
- public function getFilters() {
- if (!$this->loadedLegacyFilters) {
- $legacyFilters = $this->getNavigation();
-
- foreach ($legacyFilters['top'] as $filter => $data) {
- $this->filters[$filter] = new LegacyFilter(
- $this, $filter, $data['name'], true
- );
- }
-
- foreach ($legacyFilters['apps'] as $filter => $data) {
- $this->filters[$filter] = new LegacyFilter(
- $this, $filter, $data['name'], false
- );
- }
- $this->loadedLegacyFilters = true;
- }
-
+ public function getFilters(): array {
foreach ($this->filterClasses as $class => $false) {
/** @var IFilter $filter */
$filter = \OC::$server->query($class);
@@ -283,7 +201,7 @@ class Manager implements IManager {
* @throws \InvalidArgumentException when the filter was not found
* @since 11.0.0
*/
- public function getFilterById($id) {
+ public function getFilterById(string $id): IFilter {
$filters = $this->getFilters();
if (isset($filters[$id])) {
@@ -303,7 +221,7 @@ class Manager implements IManager {
* @param string $provider Class must implement OCA\Activity\IProvider
* @return void
*/
- public function registerProvider($provider) {
+ public function registerProvider(string $provider): void {
$this->providerClasses[$provider] = false;
}
@@ -311,7 +229,7 @@ class Manager implements IManager {
* @return IProvider[]
* @throws \InvalidArgumentException
*/
- public function getProviders() {
+ public function getProviders(): array {
foreach ($this->providerClasses as $class => $false) {
/** @var IProvider $provider */
$provider = \OC::$server->query($class);
@@ -333,14 +251,11 @@ class Manager implements IManager {
/** @var ISetting[] */
protected $settings = [];
- /** @var bool */
- protected $loadedLegacyTypes = false;
-
/**
* @param string $setting Class must implement OCA\Activity\ISetting
* @return void
*/
- public function registerSetting($setting) {
+ public function registerSetting(string $setting): void {
$this->settingsClasses[$setting] = false;
}
@@ -348,32 +263,7 @@ class Manager implements IManager {
* @return ISetting[]
* @throws \InvalidArgumentException
*/
- public function getSettings() {
- if (!$this->loadedLegacyTypes) {
- $l = \OC::$server->getL10N('core');
- $legacyTypes = $this->getNotificationTypes($l->getLanguageCode());
- $streamTypes = $this->getDefaultTypes(IExtension::METHOD_STREAM);
- $mailTypes = $this->getDefaultTypes(IExtension::METHOD_MAIL);
- foreach ($legacyTypes as $type => $data) {
- if (is_string($data)) {
- $desc = $data;
- $canChangeStream = true;
- $canChangeMail = true;
- } else {
- $desc = $data['desc'];
- $canChangeStream = in_array(IExtension::METHOD_STREAM, $data['methods']);
- $canChangeMail = in_array(IExtension::METHOD_MAIL, $data['methods']);
- }
-
- $this->settings[$type] = new LegacySetting(
- $type, $desc,
- $canChangeStream, in_array($type, $streamTypes),
- $canChangeMail, in_array($type, $mailTypes)
- );
- }
- $this->loadedLegacyTypes = true;
- }
-
+ public function getSettings(): array {
foreach ($this->settingsClasses as $class => $false) {
/** @var ISetting $setting */
$setting = \OC::$server->query($class);
@@ -395,7 +285,7 @@ class Manager implements IManager {
* @throws \InvalidArgumentException when the setting was not found
* @since 11.0.0
*/
- public function getSettingById($id) {
+ public function getSettingById(string $id): ISetting {
$settings = $this->getSettings();
if (isset($settings[$id])) {
@@ -405,127 +295,46 @@ class Manager implements IManager {
throw new \InvalidArgumentException('Requested setting does not exist');
}
- /**
- * @param string $type
- * @return string
- */
- public function getTypeIcon($type) {
- if (isset($this->typeIcons[$type])) {
- return $this->typeIcons[$type];
- }
-
- foreach ($this->getExtensions() as $c) {
- $icon = $c->getTypeIcon($type);
- if (is_string($icon)) {
- $this->typeIcons[$type] = $icon;
- return $icon;
- }
- }
-
- $this->typeIcons[$type] = '';
- return '';
- }
/**
* @param string $type
- * @param string $id
+ * @param int $id
*/
- public function setFormattingObject($type, $id) {
+ public function setFormattingObject(string $type, int $id): void {
$this->formattingObjectType = $type;
- $this->formattingObjectId = (string) $id;
+ $this->formattingObjectId = $id;
}
/**
* @return bool
*/
- public function isFormattingFilteredObject() {
+ public function isFormattingFilteredObject(): bool {
return $this->formattingObjectType !== null && $this->formattingObjectId !== null
&& $this->formattingObjectType === $this->request->getParam('object_type')
- && $this->formattingObjectId === $this->request->getParam('object_id');
+ && $this->formattingObjectId === (int) $this->request->getParam('object_id');
}
/**
* @param bool $status Set to true, when parsing events should not use SVG icons
*/
- public function setRequirePNG($status) {
+ public function setRequirePNG(bool $status): void {
$this->requirePNG = $status;
}
/**
* @return bool
*/
- public function getRequirePNG() {
+ public function getRequirePNG(): bool {
return $this->requirePNG;
}
/**
- * @param string $app
- * @param string $text
- * @param array $params
- * @param boolean $stripPath
- * @param boolean $highlightParams
- * @param string $languageCode
- * @return string|false
- */
- public function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) {
- foreach ($this->getExtensions() as $c) {
- $translation = $c->translate($app, $text, $params, $stripPath, $highlightParams, $languageCode);
- if (is_string($translation)) {
- return $translation;
- }
- }
-
- return false;
- }
-
- /**
- * @param string $app
- * @param string $text
- * @return array|false
- */
- public function getSpecialParameterList($app, $text) {
- if (isset($this->specialParameters[$app][$text])) {
- return $this->specialParameters[$app][$text];
- }
-
- if (!isset($this->specialParameters[$app])) {
- $this->specialParameters[$app] = array();
- }
-
- foreach ($this->getExtensions() as $c) {
- $specialParameter = $c->getSpecialParameterList($app, $text);
- if (is_array($specialParameter)) {
- $this->specialParameters[$app][$text] = $specialParameter;
- return $specialParameter;
- }
- }
-
- $this->specialParameters[$app][$text] = false;
- return false;
- }
-
- /**
- * @param array $activity
- * @return integer|false
- */
- public function getGroupParameter($activity) {
- foreach ($this->getExtensions() as $c) {
- $parameter = $c->getGroupParameter($activity);
- if ($parameter !== false) {
- return $parameter;
- }
- }
-
- return false;
- }
-
- /**
* Set the user we need to use
*
* @param string|null $currentUserId
* @throws \UnexpectedValueException If the user is invalid
*/
- public function setCurrentUserId($currentUserId) {
+ public function setCurrentUserId(string $currentUserId = null): void {
if (!is_string($currentUserId) && $currentUserId !== null) {
throw new \UnexpectedValueException('The given current user is invalid');
}
@@ -540,14 +349,16 @@ class Manager implements IManager {
* @return string
* @throws \UnexpectedValueException If the token is invalid, does not exist or is not unique
*/
- public function getCurrentUserId() {
+ public function getCurrentUserId(): string {
if ($this->currentUserId !== null) {
return $this->currentUserId;
- } else if (!$this->session->isLoggedIn()) {
+ }
+
+ if (!$this->session->isLoggedIn()) {
return $this->getUserFromToken();
- } else {
- return $this->session->getUser()->getUID();
}
+
+ return $this->session->getUser()->getUID();
}
/**
@@ -556,7 +367,7 @@ class Manager implements IManager {
* @return string
* @throws \UnexpectedValueException If the token is invalid, does not exist or is not unique
*/
- protected function getUserFromToken() {
+ protected function getUserFromToken(): string {
$token = (string) $this->request->getParam('token', '');
if (strlen($token) !== 30) {
throw new \UnexpectedValueException('The token is invalid');
@@ -573,130 +384,4 @@ class Manager implements IManager {
return array_shift($users);
}
- /**
- * @return array
- * @deprecated 11.0.0 - Use getFilters() instead
- */
- public function getNavigation() {
- $entries = array(
- 'apps' => array(),
- 'top' => array(),
- );
- 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']);
- }
- }
-
- return $entries;
- }
-
- /**
- * @param string $filterValue
- * @return boolean
- * @deprecated 11.0.0 - Use getFilterById() instead
- */
- public function isFilterValid($filterValue) {
- if (isset($this->validFilters[$filterValue])) {
- return $this->validFilters[$filterValue];
- }
-
- foreach ($this->getExtensions() as $c) {
- if ($c->isFilterValid($filterValue) === true) {
- $this->validFilters[$filterValue] = true;
- return true;
- }
- }
-
- $this->validFilters[$filterValue] = false;
- return false;
- }
-
- /**
- * @param array $types
- * @param string $filter
- * @return array
- * @deprecated 11.0.0 - Use getFilterById()->filterTypes() instead
- */
- public function filterNotificationTypes($types, $filter) {
- if (!$this->isFilterValid($filter)) {
- return $types;
- }
-
- foreach ($this->getExtensions() as $c) {
- $result = $c->filterNotificationTypes($types, $filter);
- if (is_array($result)) {
- $types = $result;
- }
- }
- return $types;
- }
-
- /**
- * @param string $filter
- * @return array
- * @deprecated 11.0.0 - Use getFilterById() instead
- */
- public function getQueryForFilter($filter) {
- if (!$this->isFilterValid($filter)) {
- return [null, null];
- }
-
- $conditions = array();
- $parameters = array();
-
- 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);
- }
- }
- }
-
- if (empty($conditions)) {
- return array(null, null);
- }
-
- return array(' and ((' . implode(') or (', $conditions) . '))', $parameters);
- }
-
- /**
- * Will return additional notification types as specified by other apps
- *
- * @param string $languageCode
- * @return array
- * @deprecated 11.0.0 - Use getSettings() instead
- */
- public function getNotificationTypes($languageCode) {
- $notificationTypes = $sharingNotificationTypes = [];
- foreach ($this->getExtensions() as $c) {
- $result = $c->getNotificationTypes($languageCode);
- if (is_array($result)) {
- $notificationTypes = array_merge($notificationTypes, $result);
- }
- }
-
- return array_merge($sharingNotificationTypes, $notificationTypes);
- }
-
- /**
- * @param string $method
- * @return array
- * @deprecated 11.0.0 - Use getSettings()->isDefaulEnabled<method>() instead
- */
- public function getDefaultTypes($method) {
- $defaultTypes = array();
- foreach ($this->getExtensions() as $c) {
- $types = $c->getDefaultTypes($method);
- if (is_array($types)) {
- $defaultTypes = array_merge($types, $defaultTypes);
- }
- }
- return $defaultTypes;
- }
}
diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php
index 38857af0d39..de25f8fe4d3 100644
--- a/lib/private/AppFramework/DependencyInjection/DIContainer.php
+++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php
@@ -261,6 +261,9 @@ class DIContainer extends SimpleContainer implements IAppContainer {
$c->query(\OCP\IConfig::class)
)
);
+ $dispatcher->registerMiddleware(
+ $c->query(\OC\AppFramework\Middleware\AdditionalScriptsMiddleware::class)
+ );
foreach($this->middleWares as $middleWare) {
$dispatcher->registerMiddleware($c[$middleWare]);
diff --git a/lib/private/AppFramework/Middleware/AdditionalScriptsMiddleware.php b/lib/private/AppFramework/Middleware/AdditionalScriptsMiddleware.php
new file mode 100644
index 00000000000..de1a02026bf
--- /dev/null
+++ b/lib/private/AppFramework/Middleware/AdditionalScriptsMiddleware.php
@@ -0,0 +1,56 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\AppFramework\Middleware;
+
+use OCP\AppFramework\Http\Response;
+use OCP\AppFramework\Http\TemplateResponse;
+use OCP\AppFramework\Middleware;
+use OCP\IUserSession;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+class AdditionalScriptsMiddleware extends Middleware {
+ /** @var EventDispatcherInterface */
+ private $dispatcher;
+ /** @var IUserSession */
+ private $userSession;
+
+ public function __construct(EventDispatcherInterface $dispatcher, IUserSession $userSession) {
+ $this->dispatcher = $dispatcher;
+ $this->userSession = $userSession;
+ }
+
+ public function afterController($controller, $methodName, Response $response): Response {
+ if ($response instanceof TemplateResponse) {
+ $this->dispatcher->dispatch(TemplateResponse::EVENT_LOAD_ADDITIONAL_SCRIPTS);
+
+ if ($this->userSession->isLoggedIn()) {
+ $this->dispatcher->dispatch(TemplateResponse::EVENT_LOAD_ADDITIONAL_SCRIPTS_LOGGEDIN);
+ }
+ }
+
+ return $response;
+ }
+
+}
diff --git a/lib/private/AppFramework/Routing/RouteConfig.php b/lib/private/AppFramework/Routing/RouteConfig.php
index 70208725f46..0477f4dc209 100644
--- a/lib/private/AppFramework/Routing/RouteConfig.php
+++ b/lib/private/AppFramework/Routing/RouteConfig.php
@@ -1,4 +1,5 @@
<?php
+declare(strict_types=1);
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
@@ -79,47 +80,42 @@ class RouteConfig {
* OCS routes go into a different collection
*/
$oldCollection = $this->router->getCurrentCollection();
- $this->router->useCollection($oldCollection.'.ocs');
+ $this->router->useCollection($oldCollection . '.ocs');
// parse ocs simple routes
$this->processOCS($this->routes);
+ // parse ocs simple routes
+ $this->processOCSResources($this->routes);
+
$this->router->useCollection($oldCollection);
}
- private function processOCS(array $routes) {
- $ocsRoutes = isset($routes['ocs']) ? $routes['ocs'] : [];
+ private function processOCS(array $routes): void {
+ $ocsRoutes = $routes['ocs'] ?? [];
foreach ($ocsRoutes as $ocsRoute) {
$name = $ocsRoute['name'];
- $postfix = '';
-
- if (isset($ocsRoute['postfix'])) {
- $postfix = $ocsRoute['postfix'];
- }
-
- if (isset($ocsRoute['root'])) {
- $root = $ocsRoute['root'];
- } else {
- $root = '/apps/'.$this->appName;
- }
+ $postfix = $ocsRoute['postfix'] ?? '';
+ $root = $ocsRoute['root'] ?? '/apps/' . $this->appName;
$url = $root . $ocsRoute['url'];
- $verb = isset($ocsRoute['verb']) ? strtoupper($ocsRoute['verb']) : 'GET';
+ $verb = strtoupper($ocsRoute['verb'] ?? 'GET');
$split = explode('#', $name, 2);
- if (count($split) != 2) {
+ if (count($split) !== 2) {
throw new \UnexpectedValueException('Invalid route name');
}
- $controller = $split[0];
- $action = $split[1];
+ list($controller, $action) = $split;
$controllerName = $this->buildControllerName($controller);
$actionName = $this->buildActionName($action);
+ $routeName = 'ocs.' . $this->appName . '.' . $controller . '.' . $action . $postfix;
+
// register the route
$handler = new RouteActionHandler($this->container, $controllerName, $actionName);
- $router = $this->router->create('ocs.'.$this->appName.'.'.$controller.'.'.$action . $postfix, $url)
+ $router = $this->router->create($routeName, $url)
->method($verb)
->action($handler);
@@ -142,33 +138,29 @@ class RouteConfig {
* @param array $routes
* @throws \UnexpectedValueException
*/
- private function processSimpleRoutes($routes)
- {
- $simpleRoutes = isset($routes['routes']) ? $routes['routes'] : array();
+ private function processSimpleRoutes(array $routes): void {
+ $simpleRoutes = $routes['routes'] ?? [];
foreach ($simpleRoutes as $simpleRoute) {
$name = $simpleRoute['name'];
- $postfix = '';
-
- if (isset($simpleRoute['postfix'])) {
- $postfix = $simpleRoute['postfix'];
- }
+ $postfix = $simpleRoute['postfix'] ?? '';
$url = $simpleRoute['url'];
- $verb = isset($simpleRoute['verb']) ? strtoupper($simpleRoute['verb']) : 'GET';
+ $verb = strtoupper($simpleRoute['verb'] ?? 'GET');
$split = explode('#', $name, 2);
- if (count($split) != 2) {
+ if (count($split) !== 2) {
throw new \UnexpectedValueException('Invalid route name');
}
- $controller = $split[0];
- $action = $split[1];
+ list($controller, $action) = $split;
$controllerName = $this->buildControllerName($controller);
$actionName = $this->buildActionName($action);
+ $routeName = $this->appName . '.' . $controller . '.' . $action . $postfix;
+
// register the route
$handler = new RouteActionHandler($this->container, $controllerName, $actionName);
- $router = $this->router->create($this->appName.'.'.$controller.'.'.$action . $postfix, $url)
+ $router = $this->router->create($routeName, $url)
->method($verb)
->action($handler);
@@ -187,41 +179,90 @@ class RouteConfig {
}
/**
+ * For a given name and url restful OCS routes are created:
+ * - index
+ * - show
+ * - create
+ * - update
+ * - destroy
+ *
+ * @param array $routes
+ */
+ private function processOCSResources(array $routes): void {
+ // declaration of all restful actions
+ $actions = [
+ ['name' => 'index', 'verb' => 'GET', 'on-collection' => true],
+ ['name' => 'show', 'verb' => 'GET'],
+ ['name' => 'create', 'verb' => 'POST', 'on-collection' => true],
+ ['name' => 'update', 'verb' => 'PUT'],
+ ['name' => 'destroy', 'verb' => 'DELETE'],
+ ];
+
+ $resources = $routes['ocs-resources'] ?? [];
+ foreach ($resources as $resource => $config) {
+ $root = $config['root'] ?? '/apps/' . $this->appName;
+
+ // the url parameter used as id to the resource
+ foreach($actions as $action) {
+ $url = $root . $config['url'];
+ $method = $action['name'];
+ $verb = strtoupper($action['verb'] ?? 'GET');
+ $collectionAction = $action['on-collection'] ?? false;
+ if (!$collectionAction) {
+ $url .= '/{id}';
+ }
+ if (isset($action['url-postfix'])) {
+ $url .= '/' . $action['url-postfix'];
+ }
+
+ $controller = $resource;
+
+ $controllerName = $this->buildControllerName($controller);
+ $actionName = $this->buildActionName($method);
+
+ $routeName = 'ocs.' . $this->appName . '.' . strtolower($resource) . '.' . strtolower($method);
+
+ $this->router->create($routeName, $url)->method($verb)->action(
+ new RouteActionHandler($this->container, $controllerName, $actionName)
+ );
+ }
+ }
+ }
+
+ /**
* For a given name and url restful routes are created:
* - index
* - show
- * - new
* - create
* - update
* - destroy
*
* @param array $routes
*/
- private function processResources($routes)
- {
+ private function processResources(array $routes): void {
// declaration of all restful actions
- $actions = array(
- array('name' => 'index', 'verb' => 'GET', 'on-collection' => true),
- array('name' => 'show', 'verb' => 'GET'),
- array('name' => 'create', 'verb' => 'POST', 'on-collection' => true),
- array('name' => 'update', 'verb' => 'PUT'),
- array('name' => 'destroy', 'verb' => 'DELETE'),
- );
-
- $resources = isset($routes['resources']) ? $routes['resources'] : array();
+ $actions = [
+ ['name' => 'index', 'verb' => 'GET', 'on-collection' => true],
+ ['name' => 'show', 'verb' => 'GET'],
+ ['name' => 'create', 'verb' => 'POST', 'on-collection' => true],
+ ['name' => 'update', 'verb' => 'PUT'],
+ ['name' => 'destroy', 'verb' => 'DELETE'],
+ ];
+
+ $resources = $routes['resources'] ?? [];
foreach ($resources as $resource => $config) {
// the url parameter used as id to the resource
foreach($actions as $action) {
$url = $config['url'];
$method = $action['name'];
- $verb = isset($action['verb']) ? strtoupper($action['verb']) : 'GET';
- $collectionAction = isset($action['on-collection']) ? $action['on-collection'] : false;
+ $verb = strtoupper($action['verb'] ?? 'GET');
+ $collectionAction = $action['on-collection'] ?? false;
if (!$collectionAction) {
- $url = $url . '/{id}';
+ $url .= '/{id}';
}
if (isset($action['url-postfix'])) {
- $url = $url . '/' . $action['url-postfix'];
+ $url .= '/' . $action['url-postfix'];
}
$controller = $resource;
@@ -243,8 +284,7 @@ class RouteConfig {
* @param string $controller
* @return string
*/
- private function buildControllerName($controller)
- {
+ private function buildControllerName(string $controller): string {
if (!isset($this->controllerNameCache[$controller])) {
$this->controllerNameCache[$controller] = $this->underScoreToCamelCase(ucfirst($controller)) . 'Controller';
}
@@ -256,7 +296,7 @@ class RouteConfig {
* @param string $action
* @return string
*/
- private function buildActionName($action) {
+ private function buildActionName(string $action): string {
return $this->underScoreToCamelCase($action);
}
@@ -265,12 +305,12 @@ class RouteConfig {
* @param string $str
* @return string
*/
- private function underScoreToCamelCase($str) {
- $pattern = "/_[a-z]?/";
+ private function underScoreToCamelCase(string $str): string {
+ $pattern = '/_[a-z]?/';
return preg_replace_callback(
$pattern,
function ($matches) {
- return strtoupper(ltrim($matches[0], "_"));
+ return strtoupper(ltrim($matches[0], '_'));
},
$str);
}
diff --git a/lib/private/Authentication/TwoFactorAuth/Manager.php b/lib/private/Authentication/TwoFactorAuth/Manager.php
index 56fca8a745c..ef95184aba7 100644
--- a/lib/private/Authentication/TwoFactorAuth/Manager.php
+++ b/lib/private/Authentication/TwoFactorAuth/Manager.php
@@ -31,6 +31,7 @@ use function array_diff;
use function array_filter;
use BadMethodCallException;
use Exception;
+use OC\Authentication\Exceptions\ExpiredTokenException;
use OC\Authentication\Exceptions\InvalidTokenException;
use OC\Authentication\Token\IProvider as TokenProvider;
use OCP\Activity\IManager;
@@ -364,4 +365,12 @@ class Manager {
$this->config->setUserValue($user->getUID(), 'login_token_2fa', $token->getId(), $this->timeFactory->getTime());
}
+ public function clearTwoFactorPending(string $userId) {
+ $tokensNeeding2FA = $this->config->getUserKeys($userId, 'login_token_2fa');
+
+ foreach ($tokensNeeding2FA as $tokenId) {
+ $this->tokenProvider->invalidateTokenById($userId, $tokenId);
+ }
+ }
+
}
diff --git a/lib/private/Config.php b/lib/private/Config.php
index c881e485006..f462bebaf58 100644
--- a/lib/private/Config.php
+++ b/lib/private/Config.php
@@ -265,10 +265,8 @@ class Config {
flock($filePointer, LOCK_UN);
fclose($filePointer);
- // Try invalidating the opcache just for the file we wrote...
- if (!\OC_Util::deleteFromOpcodeCache($this->configFilePath)) {
- // But if that doesn't work, clear the whole cache.
- \OC_Util::clearOpcodeCache();
+ if (function_exists('opcache_invalidate')) {
+ @opcache_invalidate($this->configFilePath, true);
}
}
}
diff --git a/lib/private/ContactsManager.php b/lib/private/ContactsManager.php
index 6a83a718d41..e279997e634 100644
--- a/lib/private/ContactsManager.php
+++ b/lib/private/ContactsManager.php
@@ -119,7 +119,12 @@ namespace OC {
}
/**
+ * Return a list of the user's addressbooks display names
+ * ! The addressBook displayName are not unique, please use getUserAddressBooks
+ *
* @return array
+ * @since 6.0.0
+ * @deprecated 16.0.0 - Use `$this->getUserAddressBooks()` instead
*/
public function getAddressBooks() {
$this->loadAddressBooks();
@@ -132,6 +137,17 @@ namespace OC {
}
/**
+ * Return a list of the user's addressbooks
+ *
+ * @return IAddressBook[]
+ * @since 16.0.0
+ */
+ public function getUserAddressBooks(): Array {
+ $this->loadAddressBooks();
+ return $this->addressBooks;
+ }
+
+ /**
* removes all registered address book instances
*/
public function clear() {
diff --git a/lib/private/Files/ObjectStore/S3ObjectTrait.php b/lib/private/Files/ObjectStore/S3ObjectTrait.php
index a1110d87c8f..0b55c319ea8 100644
--- a/lib/private/Files/ObjectStore/S3ObjectTrait.php
+++ b/lib/private/Files/ObjectStore/S3ObjectTrait.php
@@ -23,6 +23,7 @@
namespace OC\Files\ObjectStore;
+use Aws\S3\MultipartUploader;
use Aws\S3\S3Client;
const S3_UPLOAD_PART_SIZE = 524288000; // 500MB
@@ -72,10 +73,12 @@ trait S3ObjectTrait {
* @since 7.0.0
*/
function writeObject($urn, $stream) {
- $this->getConnection()->upload($this->bucket, $urn, $stream, 'private', [
- 'mup_threshold' => S3_UPLOAD_PART_SIZE,
+ $uploader = new MultipartUploader($this->getConnection(), $stream, [
+ 'bucket' => $this->bucket,
+ 'key' => $urn,
'part_size' => S3_UPLOAD_PART_SIZE
]);
+ $uploader->upload();
}
/**
diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php
index 21df67cf557..6066aed411f 100644
--- a/lib/private/Files/View.php
+++ b/lib/private/Files/View.php
@@ -1137,7 +1137,13 @@ class View {
list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
if ($run and $storage) {
if (in_array('write', $hooks) || in_array('delete', $hooks)) {
- $this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE);
+ try {
+ $this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE);
+ } catch (LockedException $e) {
+ // release the shared lock we acquired before quiting
+ $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
+ throw $e;
+ }
}
try {
if (!is_null($extraParam)) {
diff --git a/lib/private/InitialStateService.php b/lib/private/InitialStateService.php
new file mode 100644
index 00000000000..6db264bb981
--- /dev/null
+++ b/lib/private/InitialStateService.php
@@ -0,0 +1,90 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC;
+
+use Closure;
+use OCP\IInitialStateService;
+use OCP\ILogger;
+
+class InitialStateService implements IInitialStateService {
+
+ /** @var ILogger */
+ private $logger;
+
+ /** @var string[][] */
+ private $states = [];
+
+ /** @var Closure[][] */
+ private $lazyStates = [];
+
+ public function __construct(ILogger $logger) {
+ $this->logger = $logger;
+ }
+
+ public function provideInitialState(string $appName, string $key, $data): void {
+ // Scalars and JsonSerializable are fine
+ if (is_scalar($data) || $data instanceof \JsonSerializable || is_array($data)) {
+ if (!isset($this->states[$appName])) {
+ $this->states[$appName] = [];
+ }
+ $this->states[$appName][$key] = json_encode($data);
+ return;
+ }
+
+ $this->logger->warning('Invalid data provided to provideInitialState by ' . $appName);
+ }
+
+ public function provideLazyInitialState(string $appName, string $key, Closure $closure): void {
+ if (!isset($this->lazyStates[$appName])) {
+ $this->lazyStates[$appName] = [];
+ }
+ $this->lazyStates[$appName][$key] = $closure;
+ }
+
+ /**
+ * Invoke all callbacks to populate the `states` property
+ */
+ private function invokeLazyStateCallbacks(): void {
+ foreach ($this->lazyStates as $app => $lazyStates) {
+ foreach ($lazyStates as $key => $lazyState) {
+ $this->provideInitialState($app, $key, $lazyState());
+ }
+ }
+ $this->lazyStates = [];
+ }
+
+ public function getInitialStates(): array {
+ $this->invokeLazyStateCallbacks();
+
+ $appStates = [];
+ foreach ($this->states as $app => $states) {
+ foreach ($states as $key => $value) {
+ $appStates["$app-$key"] = $value;
+ }
+ }
+ return $appStates;
+ }
+
+}
diff --git a/lib/private/Preview/TXT.php b/lib/private/Preview/TXT.php
index a5efb73010c..2bb121775d6 100644
--- a/lib/private/Preview/TXT.php
+++ b/lib/private/Preview/TXT.php
@@ -60,8 +60,9 @@ class TXT extends Provider {
$lines = preg_split("/\r\n|\n|\r/", $content);
- $fontSize = $maxX ? (int) ((5 / 32) * $maxX) : 5; //5px
- $lineSize = ceil($fontSize * 1.25);
+ // Define text size of text file preview
+ $fontSize = $maxX ? (int) ((2 / 32) * $maxX) : 5; //5px
+ $lineSize = ceil($fontSize * 1.5);
$image = imagecreate($maxX, $maxY);
imagecolorallocate($image, 255, 255, 255);
diff --git a/lib/private/Server.php b/lib/private/Server.php
index 03d115fe022..86d304af5ef 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -141,8 +141,10 @@ use OCP\Files\NotFoundException;
use OCP\Files\Storage\IStorageFactory;
use OCP\FullTextSearch\IFullTextSearchManager;
use OCP\GlobalScale\IConfig;
+use OCP\Group\ISubAdmin;
use OCP\ICacheFactory;
use OCP\IDBConnection;
+use OCP\IInitialStateService;
use OCP\IL10N;
use OCP\IServerContainer;
use OCP\ITempManager;
@@ -413,9 +415,9 @@ class Server extends ServerContainer implements IServerContainer {
$userSession->listen('\OC\User', 'preLogin', function ($uid, $password) {
\OC_Hook::emit('OC_User', 'pre_login', array('run' => true, 'uid' => $uid, 'password' => $password));
});
- $userSession->listen('\OC\User', 'postLogin', function ($user, $password) {
+ $userSession->listen('\OC\User', 'postLogin', function ($user, $password, $isTokenLogin) {
/** @var $user \OC\User\User */
- \OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password));
+ \OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'isTokenLogin' => $isTokenLogin));
});
$userSession->listen('\OC\User', 'postRememberedLogin', function ($user, $password) {
/** @var $user \OC\User\User */
@@ -1201,6 +1203,10 @@ class Server extends ServerContainer implements IServerContainer {
);
});
+ $this->registerAlias(ISubAdmin::class, SubAdmin::class);
+
+ $this->registerAlias(IInitialStateService::class, InitialStateService::class);
+
$this->connectDispatcher();
}
diff --git a/lib/private/Settings/Personal/PersonalInfo.php b/lib/private/Settings/Personal/PersonalInfo.php
index 8c1c8cb19b8..98991ce6d40 100644
--- a/lib/private/Settings/Personal/PersonalInfo.php
+++ b/lib/private/Settings/Personal/PersonalInfo.php
@@ -227,7 +227,7 @@ class PersonalInfo implements ISettings {
$uid = $user->getUID();
- $userLocaleString = $this->config->getUserValue($uid, 'core', 'locale', 'en_US');
+ $userLocaleString = $this->config->getUserValue($uid, 'core', 'locale', $this->l10nFactory->findLocale());
$userLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index e76269f9d86..b04f1acbd87 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -692,15 +692,15 @@ class Manager implements IManager {
$emailAddress,
$share->getExpirationDate()
);
- $this->logger->debug('Send share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
+ $this->logger->debug('Sent share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
} else {
- $this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
+ $this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
}
} else {
- $this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
+ $this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
}
} else {
- $this->logger->debug('Share notification not send because mailsend is false.', ['app' => 'share']);
+ $this->logger->debug('Share notification not sent because mailsend is false.', ['app' => 'share']);
}
}
@@ -708,13 +708,16 @@ class Manager implements IManager {
}
/**
+ * Send mail notifications
+ *
+ * This method will catch and log mail transmission errors
+ *
* @param IL10N $l Language of the recipient
* @param string $filename file/folder name
* @param string $link link to the file/folder
* @param string $initiator user ID of share sender
* @param string $shareWith email address of share receiver
* @param \DateTime|null $expiration
- * @throws \Exception If mail couldn't be sent
*/
protected function sendMailNotification(IL10N $l,
$filename,
@@ -773,7 +776,15 @@ class Manager implements IManager {
}
$message->useTemplate($emailTemplate);
- $this->mailer->send($message);
+ try {
+ $failedRecipients = $this->mailer->send($message);
+ if(!empty($failedRecipients)) {
+ $this->logger->error('Share notification mail could not be sent to: ' . implode(', ', $failedRecipients));
+ return;
+ }
+ } catch (\Exception $e) {
+ $this->logger->logException($e, ['message' => 'Share notification mail could not be sent']);
+ }
}
/**
diff --git a/lib/private/SubAdmin.php b/lib/private/SubAdmin.php
index 44d79d8994e..f79a0b1ae5a 100644
--- a/lib/private/SubAdmin.php
+++ b/lib/private/SubAdmin.php
@@ -29,13 +29,14 @@
namespace OC;
use OC\Hooks\PublicEmitter;
+use OCP\Group\ISubAdmin;
use OCP\IUser;
use OCP\IUserManager;
use OCP\IGroup;
use OCP\IGroupManager;
use OCP\IDBConnection;
-class SubAdmin extends PublicEmitter {
+class SubAdmin extends PublicEmitter implements ISubAdmin {
/** @var IUserManager */
private $userManager;
@@ -70,9 +71,8 @@ class SubAdmin extends PublicEmitter {
* add a SubAdmin
* @param IUser $user user to be SubAdmin
* @param IGroup $group group $user becomes subadmin of
- * @return bool
*/
- public function createSubAdmin(IUser $user, IGroup $group) {
+ public function createSubAdmin(IUser $user, IGroup $group): void {
$qb = $this->dbConn->getQueryBuilder();
$qb->insert('group_admin')
@@ -84,16 +84,14 @@ class SubAdmin extends PublicEmitter {
$this->emit('\OC\SubAdmin', 'postCreateSubAdmin', [$user, $group]);
\OC_Hook::emit("OC_SubAdmin", "post_createSubAdmin", ["gid" => $group->getGID()]);
- return true;
}
/**
* delete a SubAdmin
* @param IUser $user the user that is the SubAdmin
* @param IGroup $group the group
- * @return bool
*/
- public function deleteSubAdmin(IUser $user, IGroup $group) {
+ public function deleteSubAdmin(IUser $user, IGroup $group): void {
$qb = $this->dbConn->getQueryBuilder();
$qb->delete('group_admin')
@@ -103,7 +101,6 @@ class SubAdmin extends PublicEmitter {
$this->emit('\OC\SubAdmin', 'postDeleteSubAdmin', [$user, $group]);
\OC_Hook::emit("OC_SubAdmin", "post_deleteSubAdmin", ["gid" => $group->getGID()]);
- return true;
}
/**
@@ -111,7 +108,7 @@ class SubAdmin extends PublicEmitter {
* @param IUser $user the SubAdmin
* @return IGroup[]
*/
- public function getSubAdminsGroups(IUser $user) {
+ public function getSubAdminsGroups(IUser $user): array {
$qb = $this->dbConn->getQueryBuilder();
$result = $qb->select('gid')
@@ -136,7 +133,7 @@ class SubAdmin extends PublicEmitter {
* @param IUser $user
* @return array ['displayName' => displayname]
*/
- public function getSubAdminsGroupsName(IUser $user) {
+ public function getSubAdminsGroupsName(IUser $user): array {
return array_map(function($group) {
return array('displayName' => $group->getDisplayName());
}, $this->getSubAdminsGroups($user));
@@ -147,7 +144,7 @@ class SubAdmin extends PublicEmitter {
* @param IGroup $group the group
* @return IUser[]
*/
- public function getGroupsSubAdmins(IGroup $group) {
+ public function getGroupsSubAdmins(IGroup $group): array {
$qb = $this->dbConn->getQueryBuilder();
$result = $qb->select('uid')
@@ -171,7 +168,7 @@ class SubAdmin extends PublicEmitter {
* get all SubAdmins
* @return array
*/
- public function getAllSubAdmins() {
+ public function getAllSubAdmins(): array {
$qb = $this->dbConn->getQueryBuilder();
$result = $qb->select('*')
@@ -200,7 +197,7 @@ class SubAdmin extends PublicEmitter {
* @param IGroup $group
* @return bool
*/
- public function isSubAdminOfGroup(IUser $user, IGroup $group) {
+ public function isSubAdminOfGroup(IUser $user, IGroup $group): bool {
$qb = $this->dbConn->getQueryBuilder();
/*
@@ -224,7 +221,7 @@ class SubAdmin extends PublicEmitter {
* @param IUser $user
* @return bool
*/
- public function isSubAdmin(IUser $user) {
+ public function isSubAdmin(IUser $user): bool {
// Check if the user is already an admin
if ($this->groupManager->isAdmin($user->getUID())) {
return true;
@@ -250,7 +247,7 @@ class SubAdmin extends PublicEmitter {
* @param IUser $user
* @return bool
*/
- public function isUserAccessible($subadmin, $user) {
+ public function isUserAccessible(IUser $subadmin, IUser $user): bool {
if(!$this->isSubAdmin($subadmin)) {
return false;
}
@@ -269,30 +266,24 @@ class SubAdmin extends PublicEmitter {
/**
* delete all SubAdmins by $user
* @param IUser $user
- * @return boolean
*/
- private function post_deleteUser($user) {
+ private function post_deleteUser(IUser $user) {
$qb = $this->dbConn->getQueryBuilder();
$qb->delete('group_admin')
->where($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
->execute();
-
- return true;
}
/**
* delete all SubAdmins by $group
* @param IGroup $group
- * @return boolean
*/
- private function post_deleteGroup($group) {
+ private function post_deleteGroup(IGroup $group) {
$qb = $this->dbConn->getQueryBuilder();
$qb->delete('group_admin')
->where($qb->expr()->eq('gid', $qb->createNamedParameter($group->getGID())))
->execute();
-
- return true;
}
}
diff --git a/lib/private/TemplateLayout.php b/lib/private/TemplateLayout.php
index 284f14c5db4..e4a2724de67 100644
--- a/lib/private/TemplateLayout.php
+++ b/lib/private/TemplateLayout.php
@@ -220,6 +220,10 @@ class TemplateLayout extends \OC_Template {
}
}
+
+ /** @var InitialStateService $initialState */
+ $initialState = \OC::$server->query(InitialStateService::class);
+ $this->assign('initialStates', $initialState->getInitialStates());
}
/**
diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php
index a69aed3910b..45f9cbc260f 100644
--- a/lib/private/User/Session.php
+++ b/lib/private/User/Session.php
@@ -360,7 +360,8 @@ class Session implements IUserSession, Emitter {
$this->setUser($user);
$this->setLoginName($loginDetails['loginName']);
- if(isset($loginDetails['token']) && $loginDetails['token'] instanceof IToken) {
+ $isToken = isset($loginDetails['token']) && $loginDetails['token'] instanceof IToken;
+ if ($isToken) {
$this->setToken($loginDetails['token']->getId());
$this->lockdownManager->setToken($loginDetails['token']);
$firstTimeLogin = false;
@@ -368,7 +369,11 @@ class Session implements IUserSession, Emitter {
$this->setToken(null);
$firstTimeLogin = $user->updateLastLoginTimestamp();
}
- $this->manager->emit('\OC\User', 'postLogin', [$user, $loginDetails['password']]);
+ $this->manager->emit('\OC\User', 'postLogin', [
+ $user,
+ $loginDetails['password'],
+ $isToken,
+ ]);
if($this->isLoggedIn()) {
$this->prepareUserLogin($firstTimeLogin, $regenerateSessionId);
return true;
diff --git a/lib/private/legacy/user.php b/lib/private/legacy/user.php
index e006a59771a..3d4dc5cc982 100644
--- a/lib/private/legacy/user.php
+++ b/lib/private/legacy/user.php
@@ -269,12 +269,8 @@ class OC_User {
return $backend->getLogoutUrl();
}
- $logoutUrl = $urlGenerator->linkToRouteAbsolute(
- 'core.login.logout',
- [
- 'requesttoken' => \OCP\Util::callRegister(),
- ]
- );
+ $logoutUrl = $urlGenerator->linkToRouteAbsolute('core.login.logout');
+ $logoutUrl .= '?requesttoken=' . urlencode(\OCP\Util::callRegister());
return $logoutUrl;
}
diff --git a/lib/private/legacy/util.php b/lib/private/legacy/util.php
index a94ced8bb1f..9bada5bb733 100644
--- a/lib/private/legacy/util.php
+++ b/lib/private/legacy/util.php
@@ -43,6 +43,7 @@
* @author Victor Dubiniuk <dubiniuk@owncloud.com>
* @author Vincent Petry <pvince81@owncloud.com>
* @author Volkan Gezer <volkangezer@gmail.com>
+ * @author Robert Dailey <rcdailey@gmail.com>
*
* @license AGPL-3.0
*
@@ -789,13 +790,20 @@ class OC_Util {
];
}
} else if (!is_writable($CONFIG_DATADIRECTORY) or !is_readable($CONFIG_DATADIRECTORY)) {
- //common hint for all file permissions error messages
- $permissionsHint = $l->t('Permissions can usually be fixed by giving the webserver write access to the root directory. See %s.',
- [$urlGenerator->linkToDocs('admin-dir_permissions')]);
- $errors[] = [
- 'error' => 'Your data directory is not writable',
- 'hint' => $permissionsHint
- ];
+ // is_writable doesn't work for NFS mounts, so try to write a file and check if it exists.
+ $testFile = sprintf('%s/%s.tmp', $CONFIG_DATADIRECTORY, uniqid('data_dir_writability_test_'));
+ $handle = fopen($testFile, 'w');
+ if (!$handle || fwrite($handle, 'Test write operation') === FALSE) {
+ $permissionsHint = $l->t('Permissions can usually be fixed by giving the webserver write access to the root directory. See %s.',
+ [$urlGenerator->linkToDocs('admin-dir_permissions')]);
+ $errors[] = [
+ 'error' => 'Your data directory is not writable',
+ 'hint' => $permissionsHint
+ ];
+ } else {
+ fclose($handle);
+ unlink($testFile);
+ }
} else {
$errors = array_merge($errors, self::checkDataDirectoryPermissions($CONFIG_DATADIRECTORY));
}
@@ -1324,56 +1332,6 @@ class OC_Util {
}
/**
- * Clear a single file from the opcode cache
- * This is useful for writing to the config file
- * in case the opcode cache does not re-validate files
- * Returns true if successful, false if unsuccessful:
- * caller should fall back on clearing the entire cache
- * with clearOpcodeCache() if unsuccessful
- *
- * @param string $path the path of the file to clear from the cache
- * @return bool true if underlying function returns true, otherwise false
- */
- public static function deleteFromOpcodeCache($path) {
- $ret = false;
- if ($path) {
- // APC >= 3.1.1
- if (function_exists('apc_delete_file')) {
- $ret = @apc_delete_file($path);
- }
- // Zend OpCache >= 7.0.0, PHP >= 5.5.0
- if (function_exists('opcache_invalidate')) {
- $ret = @opcache_invalidate($path);
- }
- }
- return $ret;
- }
-
- /**
- * Clear the opcode cache if one exists
- * This is necessary for writing to the config file
- * in case the opcode cache does not re-validate files
- *
- * @return void
- * @suppress PhanDeprecatedFunction
- * @suppress PhanUndeclaredConstant
- */
- public static function clearOpcodeCache() {
- // APC
- if (function_exists('apc_clear_cache')) {
- apc_clear_cache();
- }
- // Zend Opcache
- if (function_exists('accelerator_reset')) {
- accelerator_reset();
- }
- // Opcache (PHP >= 5.5)
- if (function_exists('opcache_reset')) {
- @opcache_reset();
- }
- }
-
- /**
* Normalize a unicode string
*
* @param string $value a not normalized string