diff options
Diffstat (limited to 'lib/private/Template/JSConfigHelper.php')
-rw-r--r-- | lib/private/Template/JSConfigHelper.php | 261 |
1 files changed, 124 insertions, 137 deletions
diff --git a/lib/private/Template/JSConfigHelper.php b/lib/private/Template/JSConfigHelper.php index b228cae6ffb..044fa8147a0 100644 --- a/lib/private/Template/JSConfigHelper.php +++ b/lib/private/Template/JSConfigHelper.php @@ -1,134 +1,80 @@ <?php + +declare(strict_types=1); /** - * @copyright Copyright (c) 2016, Roeland Jago Douma <roeland@famdouma.nl> - * - * @author Abijeet <abijeetpatro@gmail.com> - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * @author Bjoern Schiessle <bjoern@schiessle.org> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Joas Schilling <coding@schilljs.com> - * @author Julius Härtl <jus@bitgrid.net> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.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/>. - * + * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ - namespace OC\Template; use bantu\IniGetWrapper\IniGetWrapper; +use OC\Authentication\Token\IProvider; use OC\CapabilitiesManager; +use OC\Core\AppInfo\ConfigLexicon; +use OC\Files\FilenameValidator; +use OC\Share\Share; +use OCA\Provisioning_API\Controller\AUserDataOCSController; +use OCP\App\AppPathNotFoundException; use OCP\App\IAppManager; +use OCP\Authentication\Exceptions\ExpiredTokenException; +use OCP\Authentication\Exceptions\InvalidTokenException; +use OCP\Authentication\Exceptions\WipeTokenException; +use OCP\Authentication\Token\IToken; use OCP\Constants; use OCP\Defaults; +use OCP\Files\FileInfo; +use OCP\IAppConfig; use OCP\IConfig; use OCP\IGroupManager; use OCP\IInitialStateService; use OCP\IL10N; +use OCP\ILogger; use OCP\ISession; use OCP\IURLGenerator; use OCP\IUser; +use OCP\Server; +use OCP\ServerVersion; +use OCP\Session\Exceptions\SessionNotAvailableException; +use OCP\Share\IManager as IShareManager; use OCP\User\Backend\IPasswordConfirmationBackend; +use OCP\Util; class JSConfigHelper { - /** @var IL10N */ - private $l; - - /** @var Defaults */ - private $defaults; - - /** @var IAppManager */ - private $appManager; - - /** @var ISession */ - private $session; - - /** @var IUser|null */ - private $currentUser; - - /** @var IConfig */ - private $config; - - /** @var IGroupManager */ - private $groupManager; - - /** @var IniGetWrapper */ - private $iniWrapper; - - /** @var IURLGenerator */ - private $urlGenerator; - - /** @var CapabilitiesManager */ - private $capabilitiesManager; - - /** @var IInitialStateService */ - private $initialStateService; - /** @var array user back-ends excluded from password verification */ private $excludedUserBackEnds = ['user_saml' => true, 'user_globalsiteselector' => true]; - /** - * @param IL10N $l - * @param Defaults $defaults - * @param IAppManager $appManager - * @param ISession $session - * @param IUser|null $currentUser - * @param IConfig $config - * @param IGroupManager $groupManager - * @param IniGetWrapper $iniWrapper - * @param IURLGenerator $urlGenerator - * @param CapabilitiesManager $capabilitiesManager - */ - public function __construct(IL10N $l, - Defaults $defaults, - IAppManager $appManager, - ISession $session, - $currentUser, - IConfig $config, - IGroupManager $groupManager, - IniGetWrapper $iniWrapper, - IURLGenerator $urlGenerator, - CapabilitiesManager $capabilitiesManager, - IInitialStateService $initialStateService) { - $this->l = $l; - $this->defaults = $defaults; - $this->appManager = $appManager; - $this->session = $session; - $this->currentUser = $currentUser; - $this->config = $config; - $this->groupManager = $groupManager; - $this->iniWrapper = $iniWrapper; - $this->urlGenerator = $urlGenerator; - $this->capabilitiesManager = $capabilitiesManager; - $this->initialStateService = $initialStateService; + public function __construct( + protected ServerVersion $serverVersion, + protected IL10N $l, + protected Defaults $defaults, + protected IAppManager $appManager, + protected ISession $session, + protected ?IUser $currentUser, + protected IConfig $config, + protected readonly IAppConfig $appConfig, + protected IGroupManager $groupManager, + protected IniGetWrapper $iniWrapper, + protected IURLGenerator $urlGenerator, + protected CapabilitiesManager $capabilitiesManager, + protected IInitialStateService $initialStateService, + protected IProvider $tokenProvider, + protected FilenameValidator $filenameValidator, + ) { } - public function getConfig() { + public function getConfig(): string { $userBackendAllowsPasswordConfirmation = true; if ($this->currentUser !== null) { $uid = $this->currentUser->getUID(); $backend = $this->currentUser->getBackend(); if ($backend instanceof IPasswordConfirmationBackend) { - $userBackendAllowsPasswordConfirmation = $backend->canConfirmPassword($uid); + $userBackendAllowsPasswordConfirmation = $backend->canConfirmPassword($uid) && $this->canUserValidatePassword(); } elseif (isset($this->excludedUserBackEnds[$this->currentUser->getBackendClassName()])) { $userBackendAllowsPasswordConfirmation = false; + } else { + $userBackendAllowsPasswordConfirmation = $this->canUserValidatePassword(); } } else { $uid = null; @@ -138,18 +84,20 @@ class JSConfigHelper { $apps_paths = []; if ($this->currentUser === null) { - $apps = $this->appManager->getInstalledApps(); + $apps = $this->appManager->getEnabledApps(); } else { $apps = $this->appManager->getEnabledAppsForUser($this->currentUser); } foreach ($apps as $app) { - $apps_paths[$app] = \OC_App::getAppWebPath($app); + try { + $apps_paths[$app] = $this->appManager->getAppWebPath($app); + } catch (AppPathNotFoundException $e) { + $apps_paths[$app] = false; + } } - - $enableLinkPasswordByDefault = $this->config->getAppValue('core', 'shareapi_enable_link_password_by_default', 'no'); - $enableLinkPasswordByDefault = $enableLinkPasswordByDefault === 'yes'; + $enableLinkPasswordByDefault = $this->appConfig->getValueBool('core', ConfigLexicon::SHARE_LINK_PASSWORD_DEFAULT); $defaultExpireDateEnabled = $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes'; $defaultExpireDate = $enforceDefaultExpireDate = null; if ($defaultExpireDateEnabled) { @@ -165,48 +113,72 @@ class JSConfigHelper { $defaultInternalExpireDateEnforced = $this->config->getAppValue('core', 'shareapi_enforce_internal_expire_date', 'no') === 'yes'; } + $defaultRemoteExpireDateEnabled = $this->config->getAppValue('core', 'shareapi_default_remote_expire_date', 'no') === 'yes'; + $defaultRemoteExpireDate = $defaultRemoteExpireDateEnforced = null; + if ($defaultRemoteExpireDateEnabled) { + $defaultRemoteExpireDate = (int)$this->config->getAppValue('core', 'shareapi_remote_expire_after_n_days', '7'); + $defaultRemoteExpireDateEnforced = $this->config->getAppValue('core', 'shareapi_enforce_remote_expire_date', 'no') === 'yes'; + } + $countOfDataLocation = 0; $dataLocation = str_replace(\OC::$SERVERROOT . '/', '', $this->config->getSystemValue('datadirectory', ''), $countOfDataLocation); - if ($countOfDataLocation !== 1 || !$this->groupManager->isAdmin($uid)) { + if ($countOfDataLocation !== 1 || $uid === null || !$this->groupManager->isAdmin($uid)) { $dataLocation = false; } if ($this->currentUser instanceof IUser) { - $lastConfirmTimestamp = $this->session->get('last-password-confirm'); - if (!is_int($lastConfirmTimestamp)) { - $lastConfirmTimestamp = 0; + if ($this->canUserValidatePassword()) { + $lastConfirmTimestamp = $this->session->get('last-password-confirm'); + if (!is_int($lastConfirmTimestamp)) { + $lastConfirmTimestamp = 0; + } + } else { + $lastConfirmTimestamp = PHP_INT_MAX; } } else { $lastConfirmTimestamp = 0; } - $capabilities = $this->capabilitiesManager->getCapabilities(); + $capabilities = $this->capabilitiesManager->getCapabilities(false, true); + + $userFirstDay = $this->config->getUserValue($uid, 'core', AUserDataOCSController::USER_FIELD_FIRST_DAY_OF_WEEK, null); + $firstDay = (int)($userFirstDay ?? $this->l->l('firstday', null)); $config = [ - 'session_lifetime' => min($this->config->getSystemValue('session_lifetime', $this->iniWrapper->getNumeric('session.gc_maxlifetime')), $this->iniWrapper->getNumeric('session.gc_maxlifetime')), - 'session_keepalive' => $this->config->getSystemValue('session_keepalive', true), + /** @deprecated 30.0.0 - use files capabilities instead */ + 'blacklist_files_regex' => FileInfo::BLACKLIST_FILES_REGEX, + /** @deprecated 30.0.0 - use files capabilities instead */ + 'forbidden_filename_characters' => $this->filenameValidator->getForbiddenCharacters(), + 'auto_logout' => $this->config->getSystemValue('auto_logout', false), - 'version' => implode('.', \OCP\Util::getVersion()), - 'versionstring' => \OC_Util::getVersionString(), - 'enable_avatars' => true, // here for legacy reasons - to not crash existing code that relies on this value + 'loglevel' => $this->config->getSystemValue('loglevel_frontend', + $this->config->getSystemValue('loglevel', ILogger::WARN) + ), 'lost_password_link' => $this->config->getSystemValue('lost_password_link', null), 'modRewriteWorking' => $this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true', + 'no_unsupported_browser_warning' => $this->config->getSystemValue('no_unsupported_browser_warning', false), + 'session_keepalive' => $this->config->getSystemValue('session_keepalive', true), + 'session_lifetime' => min($this->config->getSystemValue('session_lifetime', $this->iniWrapper->getNumeric('session.gc_maxlifetime')), $this->iniWrapper->getNumeric('session.gc_maxlifetime')), 'sharing.maxAutocompleteResults' => max(0, $this->config->getSystemValueInt('sharing.maxAutocompleteResults', Constants::SHARING_MAX_AUTOCOMPLETE_RESULTS_DEFAULT)), 'sharing.minSearchStringLength' => $this->config->getSystemValueInt('sharing.minSearchStringLength', 0), - 'blacklist_files_regex' => \OCP\Files\FileInfo::BLACKLIST_FILES_REGEX, + 'version' => implode('.', $this->serverVersion->getVersion()), + 'versionstring' => $this->serverVersion->getVersionString(), + 'enable_non-accessible_features' => $this->config->getSystemValueBool('enable_non-accessible_features', true), ]; + $shareManager = Server::get(IShareManager::class); + $array = [ - "_oc_debug" => $this->config->getSystemValue('debug', false) ? 'true' : 'false', - "_oc_isadmin" => $this->groupManager->isAdmin($uid) ? 'true' : 'false', - "backendAllowsPasswordConfirmation" => $userBackendAllowsPasswordConfirmation ? 'true' : 'false', - "oc_dataURL" => is_string($dataLocation) ? "\"" . $dataLocation . "\"" : 'false', - "_oc_webroot" => "\"" . \OC::$WEBROOT . "\"", - "_oc_appswebroots" => str_replace('\\/', '/', json_encode($apps_paths)), // Ugly unescape slashes waiting for better solution - "datepickerFormatDate" => json_encode($this->l->l('jsdate', null)), + '_oc_debug' => $this->config->getSystemValue('debug', false) ? 'true' : 'false', + '_oc_isadmin' => $uid !== null && $this->groupManager->isAdmin($uid) ? 'true' : 'false', + 'backendAllowsPasswordConfirmation' => $userBackendAllowsPasswordConfirmation ? 'true' : 'false', + 'oc_dataURL' => is_string($dataLocation) ? '"' . $dataLocation . '"' : 'false', + '_oc_webroot' => '"' . \OC::$WEBROOT . '"', + '_oc_appswebroots' => str_replace('\\/', '/', json_encode($apps_paths)), // Ugly unescape slashes waiting for better solution + 'datepickerFormatDate' => json_encode($this->l->l('jsdate', null)), 'nc_lastLogin' => $lastConfirmTimestamp, 'nc_pageLoad' => time(), - "dayNames" => json_encode([ + 'dayNames' => json_encode([ $this->l->t('Sunday'), $this->l->t('Monday'), $this->l->t('Tuesday'), @@ -215,7 +187,7 @@ class JSConfigHelper { $this->l->t('Friday'), $this->l->t('Saturday') ]), - "dayNamesShort" => json_encode([ + 'dayNamesShort' => json_encode([ $this->l->t('Sun.'), $this->l->t('Mon.'), $this->l->t('Tue.'), @@ -224,7 +196,7 @@ class JSConfigHelper { $this->l->t('Fri.'), $this->l->t('Sat.') ]), - "dayNamesMin" => json_encode([ + 'dayNamesMin' => json_encode([ $this->l->t('Su'), $this->l->t('Mo'), $this->l->t('Tu'), @@ -233,7 +205,7 @@ class JSConfigHelper { $this->l->t('Fr'), $this->l->t('Sa') ]), - "monthNames" => json_encode([ + 'monthNames' => json_encode([ $this->l->t('January'), $this->l->t('February'), $this->l->t('March'), @@ -247,7 +219,7 @@ class JSConfigHelper { $this->l->t('November'), $this->l->t('December') ]), - "monthNamesShort" => json_encode([ + 'monthNamesShort' => json_encode([ $this->l->t('Jan.'), $this->l->t('Feb.'), $this->l->t('Mar.'), @@ -261,28 +233,32 @@ class JSConfigHelper { $this->l->t('Nov.'), $this->l->t('Dec.') ]), - "firstDay" => json_encode($this->l->l('firstday', null)), - "_oc_config" => json_encode($config), - "oc_appconfig" => json_encode([ + 'firstDay' => json_encode($firstDay), + '_oc_config' => json_encode($config), + 'oc_appconfig' => json_encode([ 'core' => [ 'defaultExpireDateEnabled' => $defaultExpireDateEnabled, 'defaultExpireDate' => $defaultExpireDate, 'defaultExpireDateEnforced' => $enforceDefaultExpireDate, - 'enforcePasswordForPublicLink' => \OCP\Util::isPublicLinkPasswordRequired(), + 'enforcePasswordForPublicLink' => Util::isPublicLinkPasswordRequired(), 'enableLinkPasswordByDefault' => $enableLinkPasswordByDefault, - 'sharingDisabledForUser' => \OCP\Util::isSharingDisabledForUser(), - 'resharingAllowed' => \OC\Share\Share::isResharingAllowed(), + 'sharingDisabledForUser' => $shareManager->sharingDisabledForUser($uid), + 'resharingAllowed' => Share::isResharingAllowed(), 'remoteShareAllowed' => $outgoingServer2serverShareEnabled, 'federatedCloudShareDoc' => $this->urlGenerator->linkToDocs('user-sharing-federated'), - 'allowGroupSharing' => \OC::$server->getShareManager()->allowGroupSharing(), + 'allowGroupSharing' => $shareManager->allowGroupSharing(), 'defaultInternalExpireDateEnabled' => $defaultInternalExpireDateEnabled, 'defaultInternalExpireDate' => $defaultInternalExpireDate, 'defaultInternalExpireDateEnforced' => $defaultInternalExpireDateEnforced, + 'defaultRemoteExpireDateEnabled' => $defaultRemoteExpireDateEnabled, + 'defaultRemoteExpireDate' => $defaultRemoteExpireDate, + 'defaultRemoteExpireDateEnforced' => $defaultRemoteExpireDateEnforced, ] ]), - "_theme" => json_encode([ + '_theme' => json_encode([ 'entity' => $this->defaults->getEntity(), 'name' => $this->defaults->getName(), + 'productName' => $this->defaults->getProductName(), 'title' => $this->defaults->getTitle(), 'baseUrl' => $this->defaults->getBaseUrl(), 'syncClientUrl' => $this->defaults->getSyncClientUrl(), @@ -290,8 +266,6 @@ class JSConfigHelper { 'docPlaceholderUrl' => $this->defaults->buildDocLinkToKey('PLACEHOLDER'), 'slogan' => $this->defaults->getSlogan(), 'logoClaim' => '', - 'shortFooter' => $this->defaults->getShortFooter(), - 'longFooter' => $this->defaults->getLongFooter(), 'folder' => \OC_Util::getTheme(), ]), ]; @@ -305,6 +279,8 @@ class JSConfigHelper { ]); } + $this->initialStateService->provideInitialState('core', 'projects_enabled', $this->config->getSystemValueBool('projects.enabled', false)); + $this->initialStateService->provideInitialState('core', 'config', $config); $this->initialStateService->provideInitialState('core', 'capabilities', $capabilities); @@ -314,10 +290,21 @@ class JSConfigHelper { $result = ''; // Echo it - foreach ($array as $setting => $value) { - $result .= 'var '. $setting . '='. $value . ';' . PHP_EOL; + foreach ($array as $setting => $value) { + $result .= 'var ' . $setting . '=' . $value . ';' . PHP_EOL; } return $result; } + + protected function canUserValidatePassword(): bool { + try { + $token = $this->tokenProvider->getToken($this->session->getId()); + } catch (ExpiredTokenException|WipeTokenException|InvalidTokenException|SessionNotAvailableException) { + // actually we do not know, so we fall back to this statement + return true; + } + $scope = $token->getScopeAsArray(); + return !isset($scope[IToken::SCOPE_SKIP_PASSWORD_VALIDATION]) || $scope[IToken::SCOPE_SKIP_PASSWORD_VALIDATION] === false; + } } |