diff options
author | MichaIng <micha@dietpi.com> | 2021-06-20 13:20:10 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-20 13:20:10 +0300 |
commit | 4f47bec782c90d89a501e7ed5ed43c2816a8ce81 (patch) | |
tree | ad5bac61b7a005a92f234a44531354ff6ab24032 /core/Controller | |
parent | 4d51ed3918032c44df612fad6b2c12b0e9eff693 (diff) | |
parent | 61a31dcdd73aae9a728551421116c5947e5b3089 (diff) |
Merge branch 'master' into improve-contributing-docsimprove-contributing-docs
Diffstat (limited to 'core/Controller')
29 files changed, 581 insertions, 206 deletions
diff --git a/core/Controller/AppPasswordController.php b/core/Controller/AppPasswordController.php index 2f8c1184def..41f0f6e4f27 100644 --- a/core/Controller/AppPasswordController.php +++ b/core/Controller/AppPasswordController.php @@ -5,6 +5,7 @@ declare(strict_types=1); /** * @copyright Copyright (c) 2018, Roeland Jago Douma <roeland@famdouma.nl> * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Daniel Kesselberg <mail@danielkesselberg.de> * @author Roeland Jago Douma <roeland@famdouma.nl> * @@ -17,16 +18,16 @@ declare(strict_types=1); * * 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 + * 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\Core\Controller; +use OC\Authentication\Events\AppPasswordCreatedEvent; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Token\IProvider; use OC\Authentication\Token\IToken; @@ -35,11 +36,10 @@ use OCP\AppFramework\OCS\OCSForbiddenException; use OCP\Authentication\Exceptions\CredentialsUnavailableException; use OCP\Authentication\Exceptions\PasswordUnavailableException; use OCP\Authentication\LoginCredentials\IStore; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IRequest; use OCP\ISession; use OCP\Security\ISecureRandom; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\EventDispatcher\GenericEvent; class AppPasswordController extends \OCP\AppFramework\OCSController { @@ -55,7 +55,7 @@ class AppPasswordController extends \OCP\AppFramework\OCSController { /** @var IStore */ private $credentialStore; - /** @var EventDispatcherInterface */ + /** @var IEventDispatcher */ private $eventDispatcher; public function __construct(string $appName, @@ -64,7 +64,7 @@ class AppPasswordController extends \OCP\AppFramework\OCSController { ISecureRandom $random, IProvider $tokenProvider, IStore $credentialStore, - EventDispatcherInterface $eventDispatcher) { + IEventDispatcher $eventDispatcher) { parent::__construct($appName, $request); $this->session = $session; @@ -112,8 +112,9 @@ class AppPasswordController extends \OCP\AppFramework\OCSController { IToken::DO_NOT_REMEMBER ); - $event = new GenericEvent($generatedToken); - $this->eventDispatcher->dispatch('app_password_created', $event); + $this->eventDispatcher->dispatchTyped( + new AppPasswordCreatedEvent($generatedToken) + ); return new DataResponse([ 'apppassword' => $token diff --git a/core/Controller/AutoCompleteController.php b/core/Controller/AutoCompleteController.php index 12414b50f30..6cbca91ec0f 100644 --- a/core/Controller/AutoCompleteController.php +++ b/core/Controller/AutoCompleteController.php @@ -6,7 +6,9 @@ declare(strict_types=1); * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> * * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Joas Schilling <coding@schilljs.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * @author Roeland Jago Douma <roeland@famdouma.nl> * * @license GNU AGPL version 3 or any later version @@ -18,14 +20,13 @@ declare(strict_types=1); * * 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 + * 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\Core\Controller; use OCP\AppFramework\Http\DataResponse; @@ -33,25 +34,25 @@ use OCP\AppFramework\OCSController as Controller; use OCP\Collaboration\AutoComplete\AutoCompleteEvent; use OCP\Collaboration\AutoComplete\IManager; use OCP\Collaboration\Collaborators\ISearch; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IRequest; -use OCP\Share; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use OCP\Share\IShare; class AutoCompleteController extends Controller { /** @var ISearch */ private $collaboratorSearch; + /** @var IManager */ private $autoCompleteManager; - /** @var EventDispatcherInterface */ + + /** @var IEventDispatcher */ private $dispatcher; - public function __construct( - string $appName, - IRequest $request, - ISearch $collaboratorSearch, - IManager $autoCompleteManager, - EventDispatcherInterface $dispatcher - ) { + public function __construct(string $appName, + IRequest $request, + ISearch $collaboratorSearch, + IManager $autoCompleteManager, + IEventDispatcher $dispatcher) { parent::__construct($appName, $request); $this->collaboratorSearch = $collaboratorSearch; @@ -70,7 +71,7 @@ class AutoCompleteController extends Controller { * @param int $limit * @return DataResponse */ - public function get($search, $itemType, $itemId, $sorter = null, $shareTypes = [Share::SHARE_TYPE_USER], $limit = 10): DataResponse { + public function get($search, $itemType, $itemId, $sorter = null, $shareTypes = [IShare::TYPE_USER], $limit = 10): DataResponse { // if enumeration/user listings are disabled, we'll receive an empty // result from search() – thus nothing else to do here. [$results,] = $this->collaboratorSearch->search($search, $shareTypes, false, $limit, 0); @@ -91,7 +92,7 @@ class AutoCompleteController extends Controller { unset($results['exact']); $results = array_merge_recursive($exactMatches, $results); - if($sorter !== null) { + if ($sorter !== null) { $sorters = array_reverse(explode('|', $sorter)); $this->autoCompleteManager->runSorters($sorters, $results, [ 'itemType' => $itemType, @@ -113,7 +114,10 @@ class AutoCompleteController extends Controller { $output[] = [ 'id' => (string) $result['value']['shareWith'], 'label' => $result['label'], + 'icon' => $result['icon'] ?? '', 'source' => $type, + 'status' => $result['status'] ?? '', + 'subline' => $result['subline'] ?? '', ]; } } diff --git a/core/Controller/AvatarController.php b/core/Controller/AvatarController.php index ac07129a04f..3b87bf15b2f 100644 --- a/core/Controller/AvatarController.php +++ b/core/Controller/AvatarController.php @@ -2,13 +2,16 @@ /** * @copyright Copyright (c) 2016, ownCloud, Inc. * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> + * @author Daniel Kesselberg <mail@danielkesselberg.de> * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> + * @author Julien Veyssier <eneiluj@posteo.net> * @author Lukas Reschke <lukas@statuscode.ch> * @author Morris Jobke <hey@morrisjobke.de> * @author Roeland Jago Douma <roeland@famdouma.nl> * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Vincent Petry <pvince81@owncloud.com> + * @author Vincent Petry <vincent@nextcloud.com> * * @license AGPL-3.0 * @@ -25,11 +28,9 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OC\Core\Controller; use OC\AppFramework\Utility\TimeFactory; -use OCP\Accounts\IAccountManager; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataDisplayResponse; @@ -78,8 +79,6 @@ class AvatarController extends Controller { /** @var TimeFactory */ protected $timeFactory; - /** @var IAccountManager */ - private $accountManager; public function __construct($appName, IRequest $request, @@ -90,8 +89,7 @@ class AvatarController extends Controller { IRootFolder $rootFolder, ILogger $logger, $userId, - TimeFactory $timeFactory, - IAccountManager $accountManager) { + TimeFactory $timeFactory) { parent::__construct($appName, $request); $this->avatarManager = $avatarManager; @@ -102,7 +100,6 @@ class AvatarController extends Controller { $this->logger = $logger; $this->userId = $userId; $this->timeFactory = $timeFactory; - $this->accountManager = $accountManager; } @@ -124,21 +121,6 @@ class AvatarController extends Controller { $size = 64; } - $user = $this->userManager->get($userId); - if ($user === null) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); - } - - $account = $this->accountManager->getAccount($user); - $scope = $account->getProperty(IAccountManager::PROPERTY_AVATAR)->getScope(); - - if ($scope !== IAccountManager::VISIBILITY_PUBLIC && $this->userId === null) { - // Public avatar access is not allowed - $response = new JSONResponse([], Http::STATUS_NOT_FOUND); - $response->cacheFor(1800); - return $response; - } - try { $avatar = $this->avatarManager->getAvatar($userId); $avatarFile = $avatar->getFile($size); @@ -151,8 +133,8 @@ class AvatarController extends Controller { return new JSONResponse([], Http::STATUS_NOT_FOUND); } - // Cache for 30 minutes - $response->cacheFor(1800); + // Cache for 1 day + $response->cacheFor(60 * 60 * 24); return $response; } @@ -173,7 +155,7 @@ class AvatarController extends Controller { if (!($node instanceof File)) { return new JSONResponse(['data' => ['message' => $this->l->t('Please select a file.')]]); } - if ($node->getSize() > 20*1024*1024) { + if ($node->getSize() > 20 * 1024 * 1024) { return new JSONResponse( ['data' => ['message' => $this->l->t('File is too big')]], Http::STATUS_BAD_REQUEST @@ -201,7 +183,7 @@ class AvatarController extends Controller { is_uploaded_file($files['tmp_name'][0]) && !\OC\Files\Filesystem::isFileBlacklisted($files['tmp_name'][0]) ) { - if ($files['size'][0] > 20*1024*1024) { + if ($files['size'][0] > 20 * 1024 * 1024) { return new JSONResponse( ['data' => ['message' => $this->l->t('File is too big')]], Http::STATUS_BAD_REQUEST @@ -211,8 +193,20 @@ class AvatarController extends Controller { $content = $this->cache->get('avatar_upload'); unlink($files['tmp_name'][0]); } else { + $phpFileUploadErrors = [ + UPLOAD_ERR_OK => $this->l->t('The file was uploaded'), + UPLOAD_ERR_INI_SIZE => $this->l->t('The uploaded file exceeds the upload_max_filesize directive in php.ini'), + UPLOAD_ERR_FORM_SIZE => $this->l->t('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form'), + UPLOAD_ERR_PARTIAL => $this->l->t('The file was only partially uploaded'), + UPLOAD_ERR_NO_FILE => $this->l->t('No file was uploaded'), + UPLOAD_ERR_NO_TMP_DIR => $this->l->t('Missing a temporary folder'), + UPLOAD_ERR_CANT_WRITE => $this->l->t('Could not write file to disk'), + UPLOAD_ERR_EXTENSION => $this->l->t('A PHP extension stopped the file upload'), + ]; + $message = $phpFileUploadErrors[$files['error'][0]] ?? $this->l->t('Invalid file provided'); + $this->logger->warning($message, ['app' => 'core']); return new JSONResponse( - ['data' => ['message' => $this->l->t('Invalid file provided')]], + ['data' => ['message' => $message]], Http::STATUS_BAD_REQUEST ); } @@ -258,7 +252,7 @@ class AvatarController extends Controller { /** * @NoAdminRequired - * + * * @return JSONResponse */ public function deleteAvatar() { @@ -281,8 +275,8 @@ class AvatarController extends Controller { $tmpAvatar = $this->cache->get('tmpAvatar'); if (is_null($tmpAvatar)) { return new JSONResponse(['data' => [ - 'message' => $this->l->t("No temporary profile picture available, try again") - ]], + 'message' => $this->l->t("No temporary profile picture available, try again") + ]], Http::STATUS_NOT_FOUND); } @@ -319,8 +313,8 @@ class AvatarController extends Controller { $tmpAvatar = $this->cache->get('tmpAvatar'); if (is_null($tmpAvatar)) { return new JSONResponse(['data' => [ - 'message' => $this->l->t("No temporary profile picture available, try again") - ]], + 'message' => $this->l->t("No temporary profile picture available, try again") + ]], Http::STATUS_BAD_REQUEST); } diff --git a/core/Controller/CSRFTokenController.php b/core/Controller/CSRFTokenController.php index b120acbcd5f..510d5e64d9f 100644 --- a/core/Controller/CSRFTokenController.php +++ b/core/Controller/CSRFTokenController.php @@ -17,14 +17,13 @@ declare(strict_types=1); * * 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 + * 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\Core\Controller; use OC\Security\CSRF\CsrfTokenManager; @@ -66,5 +65,4 @@ class CSRFTokenController extends Controller { 'token' => $requestToken->getEncryptedValue(), ]); } - } diff --git a/core/Controller/ClientFlowLoginController.php b/core/Controller/ClientFlowLoginController.php index ffdfd9f9f0a..2ba26deb0e7 100644 --- a/core/Controller/ClientFlowLoginController.php +++ b/core/Controller/ClientFlowLoginController.php @@ -3,7 +3,9 @@ * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch> * * @author Bjoern Schiessle <bjoern@schiessle.org> + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Daniel Kesselberg <mail@danielkesselberg.de> + * @author Joas Schilling <coding@schilljs.com> * @author Lukas Reschke <lukas@statuscode.ch> * @author Mario Danic <mario@lovelyhq.com> * @author Morris Jobke <hey@morrisjobke.de> @@ -20,16 +22,16 @@ * * 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 + * 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\Core\Controller; +use OC\Authentication\Events\AppPasswordCreatedEvent; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\PasswordlessTokenException; use OC\Authentication\Token\IProvider; @@ -42,6 +44,7 @@ use OCP\AppFramework\Http; use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\StandaloneTemplateResponse; use OCP\Defaults; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IL10N; use OCP\IRequest; use OCP\ISession; @@ -50,8 +53,6 @@ use OCP\IUserSession; use OCP\Security\ICrypto; use OCP\Security\ISecureRandom; use OCP\Session\Exceptions\SessionNotAvailableException; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\EventDispatcher\GenericEvent; class ClientFlowLoginController extends Controller { /** @var IUserSession */ @@ -74,10 +75,10 @@ class ClientFlowLoginController extends Controller { private $accessTokenMapper; /** @var ICrypto */ private $crypto; - /** @var EventDispatcherInterface */ + /** @var IEventDispatcher */ private $eventDispatcher; - const stateName = 'client.flow.state.token'; + public const STATE_NAME = 'client.flow.state.token'; /** * @param string $appName @@ -92,7 +93,7 @@ class ClientFlowLoginController extends Controller { * @param ClientMapper $clientMapper * @param AccessTokenMapper $accessTokenMapper * @param ICrypto $crypto - * @param EventDispatcherInterface $eventDispatcher + * @param IEventDispatcher $eventDispatcher */ public function __construct($appName, IRequest $request, @@ -106,7 +107,7 @@ class ClientFlowLoginController extends Controller { ClientMapper $clientMapper, AccessTokenMapper $accessTokenMapper, ICrypto $crypto, - EventDispatcherInterface $eventDispatcher) { + IEventDispatcher $eventDispatcher) { parent::__construct($appName, $request); $this->userSession = $userSession; $this->l10n = $l10n; @@ -134,8 +135,8 @@ class ClientFlowLoginController extends Controller { * @return bool */ private function isValidToken($stateToken) { - $currentToken = $this->session->get(self::stateName); - if(!is_string($stateToken) || !is_string($currentToken)) { + $currentToken = $this->session->get(self::STATE_NAME); + if (!is_string($stateToken) || !is_string($currentToken)) { return false; } return hash_equals($currentToken, $stateToken); @@ -169,7 +170,7 @@ class ClientFlowLoginController extends Controller { public function showAuthPickerPage($clientIdentifier = '') { $clientName = $this->getClientName(); $client = null; - if($clientIdentifier !== '') { + if ($clientIdentifier !== '') { $client = $this->clientMapper->getByIdentifier($clientIdentifier); $clientName = $client->getName(); } @@ -197,7 +198,7 @@ class ClientFlowLoginController extends Controller { 64, ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_DIGITS ); - $this->session->set(self::stateName, $stateToken); + $this->session->set(self::STATE_NAME, $stateToken); $csp = new Http\ContentSecurityPolicy(); if ($client) { @@ -237,13 +238,13 @@ class ClientFlowLoginController extends Controller { */ public function grantPage($stateToken = '', $clientIdentifier = '') { - if(!$this->isValidToken($stateToken)) { + if (!$this->isValidToken($stateToken)) { return $this->stateTokenForbiddenResponse(); } $clientName = $this->getClientName(); $client = null; - if($clientIdentifier !== '') { + if ($clientIdentifier !== '') { $client = $this->clientMapper->getByIdentifier($clientIdentifier); $clientName = $client->getName(); } @@ -284,12 +285,12 @@ class ClientFlowLoginController extends Controller { */ public function generateAppPassword($stateToken, $clientIdentifier = '') { - if(!$this->isValidToken($stateToken)) { - $this->session->remove(self::stateName); + if (!$this->isValidToken($stateToken)) { + $this->session->remove(self::STATE_NAME); return $this->stateTokenForbiddenResponse(); } - $this->session->remove(self::stateName); + $this->session->remove(self::STATE_NAME); try { $sessionId = $this->session->getId(); @@ -315,7 +316,7 @@ class ClientFlowLoginController extends Controller { $clientName = $this->getClientName(); $client = false; - if($clientIdentifier !== '') { + if ($clientIdentifier !== '') { $client = $this->clientMapper->getByIdentifier($clientIdentifier); $clientName = $client->getName(); } @@ -332,7 +333,7 @@ class ClientFlowLoginController extends Controller { IToken::DO_NOT_REMEMBER ); - if($client) { + if ($client) { $code = $this->random->generate(128, ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_DIGITS); $accessToken = new AccessToken(); $accessToken->setClientId($client->getId()); @@ -342,7 +343,7 @@ class ClientFlowLoginController extends Controller { $this->accessTokenMapper->insert($accessToken); $redirectUri = $client->getRedirectUri(); - + if (parse_url($redirectUri, PHP_URL_QUERY)) { $redirectUri .= '&'; } else { @@ -362,8 +363,9 @@ class ClientFlowLoginController extends Controller { $this->tokenProvider->invalidateToken($sessionId); } - $event = new GenericEvent($generatedToken); - $this->eventDispatcher->dispatch('app_password_created', $event); + $this->eventDispatcher->dispatchTyped( + new AppPasswordCreatedEvent($generatedToken) + ); return new Http\RedirectResponse($redirectUri); } @@ -376,6 +378,24 @@ class ClientFlowLoginController extends Controller { return $this->stateTokenForbiddenResponse(); } + try { + $token = $this->tokenProvider->getToken($password); + if ($token->getLoginName() !== $user) { + throw new InvalidTokenException('login name does not match'); + } + } catch (InvalidTokenException $e) { + $response = new StandaloneTemplateResponse( + $this->appName, + '403', + [ + 'message' => $this->l10n->t('Invalid app password'), + ], + 'guest' + ); + $response->setStatus(Http::STATUS_FORBIDDEN); + return $response; + } + $redirectUri = 'nc://login/server:' . $this->getServerPath() . '&user:' . urlencode($user) . '&password:' . urlencode($password); return new Http\RedirectResponse($redirectUri); } @@ -385,7 +405,7 @@ class ClientFlowLoginController extends Controller { if (strpos($this->request->getRequestUri(), '/index.php') !== false) { $serverPostfix = substr($this->request->getRequestUri(), 0, strpos($this->request->getRequestUri(), '/index.php')); - } else if (strpos($this->request->getRequestUri(), '/login/flow') !== false) { + } elseif (strpos($this->request->getRequestUri(), '/login/flow') !== false) { $serverPostfix = substr($this->request->getRequestUri(), 0, strpos($this->request->getRequestUri(), '/login/flow')); } diff --git a/core/Controller/ClientFlowLoginV2Controller.php b/core/Controller/ClientFlowLoginV2Controller.php index 836606d301b..205c1ff8a1c 100644 --- a/core/Controller/ClientFlowLoginV2Controller.php +++ b/core/Controller/ClientFlowLoginV2Controller.php @@ -5,6 +5,8 @@ declare(strict_types=1); /** * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl> * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> + * @author Joas Schilling <coding@schilljs.com> * @author Roeland Jago Douma <roeland@famdouma.nl> * * @license GNU AGPL version 3 or any later version @@ -16,14 +18,13 @@ declare(strict_types=1); * * 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 + * 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\Core\Controller; use OC\Core\Db\LoginFlowV2; @@ -43,9 +44,8 @@ use OCP\IURLGenerator; use OCP\Security\ISecureRandom; class ClientFlowLoginV2Controller extends Controller { - - private const tokenName = 'client.flow.v2.login.token'; - private const stateName = 'client.flow.v2.state.token'; + public const TOKEN_NAME = 'client.flow.v2.login.token'; + public const STATE_NAME = 'client.flow.v2.state.token'; /** @var LoginFlowV2Service */ private $loginFlowV2Service; @@ -105,7 +105,7 @@ class ClientFlowLoginV2Controller extends Controller { return $this->loginTokenForbiddenResponse(); } - $this->session->set(self::tokenName, $token); + $this->session->set(self::TOKEN_NAME, $token); return new RedirectResponse( $this->urlGenerator->linkToRouteAbsolute('core.ClientFlowLoginV2.showAuthPickerPage') @@ -128,7 +128,7 @@ class ClientFlowLoginV2Controller extends Controller { 64, ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_DIGITS ); - $this->session->set(self::stateName, $stateToken); + $this->session->set(self::STATE_NAME, $stateToken); return new StandaloneTemplateResponse( $this->appName, @@ -150,7 +150,7 @@ class ClientFlowLoginV2Controller extends Controller { * @NoSameSiteCookieRequired */ public function grantPage(string $stateToken): StandaloneTemplateResponse { - if(!$this->isValidStateToken($stateToken)) { + if (!$this->isValidStateToken($stateToken)) { return $this->stateTokenForbiddenResponse(); } @@ -178,7 +178,7 @@ class ClientFlowLoginV2Controller extends Controller { * @UseSession */ public function generateAppPassword(string $stateToken): Response { - if(!$this->isValidStateToken($stateToken)) { + if (!$this->isValidStateToken($stateToken)) { return $this->stateTokenForbiddenResponse(); } @@ -188,11 +188,11 @@ class ClientFlowLoginV2Controller extends Controller { return $this->loginTokenForbiddenResponse(); } - $loginToken = $this->session->get(self::tokenName); + $loginToken = $this->session->get(self::TOKEN_NAME); // Clear session variables - $this->session->remove(self::tokenName); - $this->session->remove(self::stateName); + $this->session->remove(self::TOKEN_NAME); + $this->session->remove(self::STATE_NAME); $sessionId = $this->session->getId(); $result = $this->loginFlowV2Service->flowDone($loginToken, $sessionId, $this->getServerPath(), $this->userId); @@ -240,8 +240,8 @@ class ClientFlowLoginV2Controller extends Controller { } private function isValidStateToken(string $stateToken): bool { - $currentToken = $this->session->get(self::stateName); - if(!is_string($stateToken) || !is_string($currentToken)) { + $currentToken = $this->session->get(self::STATE_NAME); + if (!is_string($stateToken) || !is_string($currentToken)) { return false; } return hash_equals($currentToken, $stateToken); @@ -265,8 +265,8 @@ class ClientFlowLoginV2Controller extends Controller { * @throws LoginFlowV2NotFoundException */ private function getFlowByLoginToken(): LoginFlowV2 { - $currentToken = $this->session->get(self::tokenName); - if(!is_string($currentToken)) { + $currentToken = $this->session->get(self::TOKEN_NAME); + if (!is_string($currentToken)) { throw new LoginFlowV2NotFoundException('Login token not set in session'); } @@ -291,7 +291,7 @@ class ClientFlowLoginV2Controller extends Controller { if (strpos($this->request->getRequestUri(), '/index.php') !== false) { $serverPostfix = substr($this->request->getRequestUri(), 0, strpos($this->request->getRequestUri(), '/index.php')); - } else if (strpos($this->request->getRequestUri(), '/login/v2') !== false) { + } elseif (strpos($this->request->getRequestUri(), '/login/v2') !== false) { $serverPostfix = substr($this->request->getRequestUri(), 0, strpos($this->request->getRequestUri(), '/login/v2')); } diff --git a/core/Controller/CollaborationResourcesController.php b/core/Controller/CollaborationResourcesController.php index 72bcf351db0..114423e1a2f 100644 --- a/core/Controller/CollaborationResourcesController.php +++ b/core/Controller/CollaborationResourcesController.php @@ -18,14 +18,13 @@ declare(strict_types=1); * * 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 + * 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\Core\Controller; use Exception; diff --git a/core/Controller/ContactsMenuController.php b/core/Controller/ContactsMenuController.php index 8b7962f97ef..6c967e7e019 100644 --- a/core/Controller/ContactsMenuController.php +++ b/core/Controller/ContactsMenuController.php @@ -15,14 +15,13 @@ * * 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 + * 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\Core\Controller; use OC\Contacts\ContactsMenu\Manager; diff --git a/core/Controller/CssController.php b/core/Controller/CssController.php index 3e7215966bc..e1d7d5178cd 100644 --- a/core/Controller/CssController.php +++ b/core/Controller/CssController.php @@ -5,11 +5,12 @@ declare(strict_types=1); /** * @copyright Copyright (c) 2016, John Molakvoæ (skjnldsv@protonmail.com) * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * @author Morris Jobke <hey@morrisjobke.de> * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Thomas Citharel <tcit@tcit.fr> + * @author Thomas Citharel <nextcloud@tcit.fr> * * @license GNU AGPL version 3 or any later version * @@ -20,14 +21,13 @@ declare(strict_types=1); * * 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 + * 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\Core\Controller; use OC\Files\AppData\Factory; @@ -75,7 +75,7 @@ class CssController extends Controller { $folder = $this->appData->getFolder($appName); $gzip = false; $file = $this->getFile($folder, $fileName, $gzip); - } catch(NotFoundException $e) { + } catch (NotFoundException $e) { return new NotFoundResponse(); } diff --git a/core/Controller/GuestAvatarController.php b/core/Controller/GuestAvatarController.php index 38b5cfd2941..57900af810d 100644 --- a/core/Controller/GuestAvatarController.php +++ b/core/Controller/GuestAvatarController.php @@ -13,14 +13,13 @@ * * 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 + * 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\Core\Controller; use OCP\AppFramework\Controller; diff --git a/core/Controller/JsController.php b/core/Controller/JsController.php index f2accc21b45..937df073e81 100644 --- a/core/Controller/JsController.php +++ b/core/Controller/JsController.php @@ -5,11 +5,12 @@ declare(strict_types=1); /** * @copyright 2017, Roeland Jago Douma <roeland@famdouma.nl> * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * @author Morris Jobke <hey@morrisjobke.de> * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Thomas Citharel <tcit@tcit.fr> + * @author Thomas Citharel <nextcloud@tcit.fr> * * @license GNU AGPL version 3 or any later version * @@ -20,14 +21,13 @@ declare(strict_types=1); * * 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 + * 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\Core\Controller; use OC\Files\AppData\Factory; @@ -72,7 +72,7 @@ class JsController extends Controller { $folder = $this->appData->getFolder($appName); $gzip = false; $file = $this->getFile($folder, $fileName, $gzip); - } catch(NotFoundException $e) { + } catch (NotFoundException $e) { return new NotFoundResponse(); } diff --git a/core/Controller/LoginController.php b/core/Controller/LoginController.php index 13aef8f67ab..8a96db97c9e 100644 --- a/core/Controller/LoginController.php +++ b/core/Controller/LoginController.php @@ -7,6 +7,7 @@ * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Daniel Kesselberg <mail@danielkesselberg.de> * @author Joas Schilling <coding@schilljs.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * @author Julius Härtl <jus@bitgrid.net> * @author Lukas Reschke <lukas@statuscode.ch> * @author Michael Weimann <mail@michael-weimann.eu> @@ -28,12 +29,12 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OC\Core\Controller; use OC\AppFramework\Http\Request; use OC\Authentication\Login\Chain; use OC\Authentication\Login\LoginData; +use OC\Authentication\WebAuthn\Manager as WebAuthnManager; use OC\Security\Bruteforce\Throttler; use OC\User\Session; use OC_App; @@ -56,9 +57,8 @@ use OCP\IUserSession; use OCP\Util; class LoginController extends Controller { - - const LOGIN_MSG_INVALIDPASSWORD = 'invalidpassword'; - const LOGIN_MSG_USERDISABLED = 'userdisabled'; + public const LOGIN_MSG_INVALIDPASSWORD = 'invalidpassword'; + public const LOGIN_MSG_USERDISABLED = 'userdisabled'; /** @var IUserManager */ private $userManager; @@ -80,6 +80,8 @@ class LoginController extends Controller { private $loginChain; /** @var IInitialStateService */ private $initialStateService; + /** @var WebAuthnManager */ + private $webAuthnManager; public function __construct(?string $appName, IRequest $request, @@ -92,7 +94,8 @@ class LoginController extends Controller { Defaults $defaults, Throttler $throttler, Chain $loginChain, - IInitialStateService $initialStateService) { + IInitialStateService $initialStateService, + WebAuthnManager $webAuthnManager) { parent::__construct($appName, $request); $this->userManager = $userManager; $this->config = $config; @@ -104,6 +107,7 @@ class LoginController extends Controller { $this->throttler = $throttler; $this->loginChain = $loginChain; $this->initialStateService = $initialStateService; + $this->webAuthnManager = $webAuthnManager; } /** @@ -151,7 +155,7 @@ class LoginController extends Controller { $loginMessages = $this->session->get('loginMessages'); if (is_array($loginMessages)) { - list($errors, $messages) = $loginMessages; + [$errors, $messages] = $loginMessages; $this->initialStateService->provideInitialState('core', 'loginMessages', $messages); $this->initialStateService->provideInitialState('core', 'loginErrors', $errors); } @@ -170,7 +174,10 @@ class LoginController extends Controller { ); if (!empty($redirect_url)) { - $this->initialStateService->provideInitialState('core', 'loginRedirectUrl', $redirect_url); + [$url, ] = explode('?', $redirect_url); + if ($url !== $this->urlGenerator->linkToRoute('core.login.logout')) { + $this->initialStateService->provideInitialState('core', 'loginRedirectUrl', $redirect_url); + } } $this->initialStateService->provideInitialState( @@ -181,6 +188,10 @@ class LoginController extends Controller { $this->setPasswordResetInitialState($user); + $this->initialStateService->provideInitialState('core', 'webauthn-available', $this->webAuthnManager->isWebAuthnAvailable()); + + $this->initialStateService->provideInitialState('core', 'hideLoginForm', $this->config->getSystemValueBool('hide_login_form', false)); + // OpenGraph Support: http://ogp.me/ Util::addHeader('meta', ['property' => 'og:title', 'content' => Util::sanitizeHTML($this->defaults->getName())]); Util::addHeader('meta', ['property' => 'og:description', 'content' => Util::sanitizeHTML($this->defaults->getSlogan())]); @@ -192,6 +203,9 @@ class LoginController extends Controller { $parameters = [ 'alt_login' => OC_App::getAlternativeLogIns(), ]; + + $this->initialStateService->provideInitialState('core', 'countAlternativeLogins', count($parameters['alt_login'])); + return new TemplateResponse( $this->appName, 'login', $parameters, 'guest' ); @@ -253,7 +267,7 @@ class LoginController extends Controller { private function generateRedirect(?string $redirectUrl): RedirectResponse { if ($redirectUrl !== null && $this->userSession->isLoggedIn()) { - $location = $this->urlGenerator->getAbsoluteURL(urldecode($redirectUrl)); + $location = $this->urlGenerator->getAbsoluteURL($redirectUrl); // Deny the redirect if the URL contains a @ // This prevents unvalidated redirects like ?redirect_url=:user@domain.com if (strpos($location, '@') === false) { @@ -327,7 +341,7 @@ class LoginController extends Controller { $user, $originalUser, $redirect_url, string $loginMessage) { // Read current user and append if possible we need to // return the unmodified user otherwise we will leak the login name - $args = $user !== null ? ['user' => $originalUser] : []; + $args = $user !== null ? ['user' => $originalUser, 'direct' => 1] : []; if ($redirect_url !== null) { $args['redirect_url'] = $redirect_url; } diff --git a/core/Controller/LostController.php b/core/Controller/LostController.php index cdeec469e04..99427132f5e 100644 --- a/core/Controller/LostController.php +++ b/core/Controller/LostController.php @@ -5,7 +5,7 @@ * @author Arthur Schiwon <blizzz@arthur-schiwon.de> * @author Bernhard Posselt <dev@bernhard-posselt.com> * @author Bjoern Schiessle <bjoern@schiessle.org> - * @author Björn Schießle <bjoern@schiessle.org> + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Daniel Kesselberg <mail@danielkesselberg.de> * @author Joas Schilling <coding@schilljs.com> * @author Julius Haertl <jus@bitgrid.net> @@ -33,7 +33,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OC\Core\Controller; use function array_filter; @@ -159,8 +158,8 @@ class LostController extends Controller { public function resetform($token, $userId) { if ($this->config->getSystemValue('lost_password_link', '') !== '') { return new TemplateResponse('core', 'error', [ - 'errors' => [['error' => $this->l10n->t('Password reset is disabled')]] - ], + 'errors' => [['error' => $this->l10n->t('Password reset is disabled')]] + ], 'guest' ); } @@ -195,7 +194,7 @@ class LostController extends Controller { */ protected function checkPasswordResetToken($token, $userId) { $user = $this->userManager->get($userId); - if($user === null || !$user->isEnabled()) { + if ($user === null || !$user->isEnabled()) { throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid')); } @@ -212,11 +211,11 @@ class LostController extends Controller { } $splittedToken = explode(':', $decryptedToken); - if(count($splittedToken) !== 2) { + if (count($splittedToken) !== 2) { throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid')); } - if ($splittedToken[0] < ($this->timeFactory->getTime() - 60*60*24*7) || + if ($splittedToken[0] < ($this->timeFactory->getTime() - 60 * 60 * 24 * 7) || $user->getLastLogin() > $splittedToken[0]) { throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is expired')); } @@ -231,7 +230,7 @@ class LostController extends Controller { * @param array $additional * @return array */ - private function error($message, array $additional=[]) { + private function error($message, array $additional = []) { return array_merge(['status' => 'error', 'msg' => $message], $additional); } @@ -240,7 +239,7 @@ class LostController extends Controller { * @return array */ private function success($data = []) { - return array_merge($data, ['status'=>'success']); + return array_merge($data, ['status' => 'success']); } /** @@ -251,7 +250,7 @@ class LostController extends Controller { * @param string $user * @return JSONResponse */ - public function email($user){ + public function email($user) { if ($this->config->getSystemValue('lost_password_link', '') !== '') { return new JSONResponse($this->error($this->l10n->t('Password reset is disabled'))); } @@ -318,9 +317,9 @@ class LostController extends Controller { $this->config->deleteUserValue($userId, 'core', 'lostpassword'); @\OC::$server->getUserSession()->unsetMagicInCookie(); - } catch (HintException $e){ + } catch (HintException $e) { return $this->error($e->getHint()); - } catch (\Exception $e){ + } catch (\Exception $e) { return $this->error($e->getMessage()); } @@ -378,7 +377,7 @@ class LostController extends Controller { try { $message = $this->mailer->createMessage(); - $message->setTo([$email => $user->getUID()]); + $message->setTo([$email => $user->getDisplayName()]); $message->setFrom([$this->from => $this->defaults->getName()]); $message->useTemplate($emailTemplate); $this->mailer->send($message); diff --git a/core/Controller/NavigationController.php b/core/Controller/NavigationController.php index ad88985ce76..9d0565145c3 100644 --- a/core/Controller/NavigationController.php +++ b/core/Controller/NavigationController.php @@ -3,7 +3,6 @@ * @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net> * * @author Julius Härtl <jus@bitgrid.net> - * @author Roeland Jago Douma <roeland@famdouma.nl> * * @license GNU AGPL version 3 or any later version * @@ -14,14 +13,13 @@ * * 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 + * 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\Core\Controller; use OCP\AppFramework\Http; diff --git a/core/Controller/OCJSController.php b/core/Controller/OCJSController.php index 617f6b25236..71f0941b46c 100644 --- a/core/Controller/OCJSController.php +++ b/core/Controller/OCJSController.php @@ -4,6 +4,7 @@ * * @author Bjoern Schiessle <bjoern@schiessle.org> * @author Joas Schilling <coding@schilljs.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * @author Lukas Reschke <lukas@statuscode.ch> * @author Morris Jobke <hey@morrisjobke.de> * @author Roeland Jago Douma <roeland@famdouma.nl> @@ -17,14 +18,13 @@ * * 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 + * 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\Core\Controller; use bantu\IniGetWrapper\IniGetWrapper; @@ -37,6 +37,7 @@ use OCP\AppFramework\Http\DataDisplayResponse; use OCP\Defaults; use OCP\IConfig; use OCP\IGroupManager; +use OCP\IInitialStateService; use OCP\IRequest; use OCP\ISession; use OCP\IURLGenerator; @@ -63,6 +64,7 @@ class OCJSController extends Controller { * @param IniGetWrapper $iniWrapper * @param IURLGenerator $urlGenerator * @param CapabilitiesManager $capabilitiesManager + * @param IInitialStateService $initialStateService */ public function __construct($appName, IRequest $request, @@ -75,7 +77,8 @@ class OCJSController extends Controller { IGroupManager $groupManager, IniGetWrapper $iniWrapper, IURLGenerator $urlGenerator, - CapabilitiesManager $capabilitiesManager) { + CapabilitiesManager $capabilitiesManager, + IInitialStateService $initialStateService) { parent::__construct($appName, $request); $this->helper = new JSConfigHelper( @@ -88,7 +91,8 @@ class OCJSController extends Controller { $groupManager, $iniWrapper, $urlGenerator, - $capabilitiesManager + $capabilitiesManager, + $initialStateService ); } diff --git a/core/Controller/OCSController.php b/core/Controller/OCSController.php index 60ea12f017c..63a25591ef0 100644 --- a/core/Controller/OCSController.php +++ b/core/Controller/OCSController.php @@ -1,7 +1,9 @@ <?php /** + * @copyright Copyright (c) 2016 Roeland Jago Douma <roeland@famdouma.nl> * - * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> + * @author Daniel Kesselberg <mail@danielkesselberg.de> * @author Joas Schilling <coding@schilljs.com> * @author Julius Härtl <jus@bitgrid.net> * @author Lukas Reschke <lukas@statuscode.ch> @@ -16,14 +18,13 @@ * * 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 + * 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\Core\Controller; use OC\CapabilitiesManager; @@ -91,7 +92,7 @@ class OCSController extends \OCP\AppFramework\OCSController { */ public function getCapabilities() { $result = []; - list($major, $minor, $micro) = \OCP\Util::getVersion(); + [$major, $minor, $micro] = \OCP\Util::getVersion(); $result['version'] = [ 'major' => $major, 'minor' => $minor, @@ -101,13 +102,15 @@ class OCSController extends \OCP\AppFramework\OCSController { 'extendedSupport' => \OCP\Util::hasExtendedSupport() ]; - if($this->userSession->isLoggedIn()) { + if ($this->userSession->isLoggedIn()) { $result['capabilities'] = $this->capabilitiesManager->getCapabilities(); } else { $result['capabilities'] = $this->capabilitiesManager->getCapabilities(true); } - return new DataResponse($result); + $response = new DataResponse($result); + $response->setETag(md5(json_encode($result))); + return $response; } /** @@ -144,7 +147,7 @@ class OCSController extends \OCP\AppFramework\OCSController { public function getIdentityProof($cloudId) { $userObject = $this->userManager->get($cloudId); - if($userObject !== null) { + if ($userObject !== null) { $key = $this->keyManager->getKey($userObject); $data = [ 'public' => $key->getPublic(), diff --git a/core/Controller/PreviewController.php b/core/Controller/PreviewController.php index 3fd1ce2c868..1224ea39877 100644 --- a/core/Controller/PreviewController.php +++ b/core/Controller/PreviewController.php @@ -5,6 +5,7 @@ declare(strict_types=1); /** * @copyright Copyright (c) 2016, Roeland Jago Douma <roeland@famdouma.nl> * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Morris Jobke <hey@morrisjobke.de> * @author Roeland Jago Douma <roeland@famdouma.nl> * @@ -17,14 +18,13 @@ declare(strict_types=1); * * 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 + * 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\Core\Controller; use OCP\AppFramework\Controller; @@ -85,14 +85,13 @@ class PreviewController extends Controller { * @param string $mode * @return DataResponse|FileDisplayResponse */ - public function getPreview ( + public function getPreview( string $file = '', int $x = 32, int $y = 32, bool $a = false, bool $forceIcon = true, string $mode = 'fill'): Http\Response { - if ($file === '' || $x === 0 || $y === 0) { return new DataResponse([], Http::STATUS_BAD_REQUEST); } @@ -127,7 +126,6 @@ class PreviewController extends Controller { bool $a = false, bool $forceIcon = true, string $mode = 'fill') { - if ($fileId === -1 || $x === 0 || $y === 0) { return new DataResponse([], Http::STATUS_BAD_REQUEST); } @@ -157,10 +155,9 @@ class PreviewController extends Controller { Node $node, int $x, int $y, - bool $a = false, - bool $forceIcon = true, + bool $a, + bool $forceIcon, string $mode) : Http\Response { - if (!($node instanceof File) || (!$forceIcon && !$this->preview->isAvailable($node))) { return new DataResponse([], Http::STATUS_NOT_FOUND); } @@ -178,6 +175,5 @@ class PreviewController extends Controller { } catch (\InvalidArgumentException $e) { return new DataResponse([], Http::STATUS_BAD_REQUEST); } - } } diff --git a/core/Controller/RecommendedAppsController.php b/core/Controller/RecommendedAppsController.php index fe3435d9be8..1b6650ed902 100644 --- a/core/Controller/RecommendedAppsController.php +++ b/core/Controller/RecommendedAppsController.php @@ -16,14 +16,13 @@ declare(strict_types=1); * * 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 + * 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\Core\Controller; use OCP\AppFramework\Controller; @@ -51,5 +50,4 @@ class RecommendedAppsController extends Controller { $this->initialStateService->provideInitialState('core', 'defaultPageUrl', \OC_Util::getDefaultPageUrl()); return new StandaloneTemplateResponse($this->appName, 'recommendedapps', [], 'guest'); } - } diff --git a/core/Controller/SearchController.php b/core/Controller/SearchController.php index 8d3a6f623b7..95d100a393d 100644 --- a/core/Controller/SearchController.php +++ b/core/Controller/SearchController.php @@ -5,6 +5,7 @@ declare(strict_types=1); /** * @copyright 2018, Roeland Jago Douma <roeland@famdouma.nl> * + * @author Robin Appelman <robin@icewind.nl> * @author Roeland Jago Douma <roeland@famdouma.nl> * * @license GNU AGPL version 3 or any later version @@ -16,32 +17,39 @@ declare(strict_types=1); * * 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 + * 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\Core\Controller; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\JSONResponse; +use OCP\ILogger; use OCP\IRequest; use OCP\ISearch; +use OCP\Search\Result; class SearchController extends Controller { /** @var ISearch */ private $searcher; + /** @var ILogger */ + private $logger; - public function __construct(string $appName, - IRequest $request, - ISearch $search) { + public function __construct( + string $appName, + IRequest $request, + ISearch $search, + ILogger $logger + ) { parent::__construct($appName, $request); $this->searcher = $search; + $this->logger = $logger; } /** @@ -50,6 +58,15 @@ class SearchController extends Controller { public function search(string $query, array $inApps = [], int $page = 1, int $size = 30): JSONResponse { $results = $this->searcher->searchPaged($query, $inApps, $page, $size); + $results = array_filter($results, function (Result $result) { + if (json_encode($result, JSON_HEX_TAG) === false) { + $this->logger->warning("Skipping search result due to invalid encoding: {type: " . $result->type . ", id: " . $result->id . "}"); + return false; + } else { + return true; + } + }); + return new JSONResponse($results); } } diff --git a/core/Controller/SetupController.php b/core/Controller/SetupController.php index 7449717831b..704a2507b5a 100644 --- a/core/Controller/SetupController.php +++ b/core/Controller/SetupController.php @@ -29,7 +29,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OC\Core\Controller; use OC\Setup; @@ -44,7 +43,7 @@ class SetupController { /** * @param Setup $setupHelper */ - function __construct(Setup $setupHelper) { + public function __construct(Setup $setupHelper) { $this->autoConfigFile = \OC::$configDir.'autoconfig.php'; $this->setupHelper = $setupHelper; } @@ -70,12 +69,12 @@ class SetupController { return; } - if(isset($post['install']) AND $post['install']=='true') { + if (isset($post['install']) and $post['install'] == 'true') { // We have to launch the installation process : $e = $this->setupHelper->install($post); $errors = ['errors' => $e]; - if(count($e) > 0) { + if (count($e) > 0) { $options = array_merge($opts, $post, $errors); $this->display($options); } else { @@ -104,12 +103,11 @@ class SetupController { ]; $parameters = array_merge($defaults, $post); - \OC_Util::addScript('setup'); \OC_Template::printGuestPage('', 'installation', $parameters); } private function finishSetup(bool $installRecommended) { - if( file_exists( $this->autoConfigFile )) { + if (file_exists($this->autoConfigFile)) { unlink($this->autoConfigFile); } \OC::$server->getIntegrityCodeChecker()->runInstanceVerification(); @@ -130,18 +128,18 @@ class SetupController { } public function loadAutoConfig($post) { - if( file_exists($this->autoConfigFile)) { + if (file_exists($this->autoConfigFile)) { \OCP\Util::writeLog('core', 'Autoconfig file found, setting up Nextcloud…', ILogger::INFO); $AUTOCONFIG = []; include $this->autoConfigFile; - $post = array_merge ($post, $AUTOCONFIG); + $post = array_merge($post, $AUTOCONFIG); } $dbIsSet = isset($post['dbtype']); $directoryIsSet = isset($post['directory']); $adminAccountIsSet = isset($post['adminlogin']); - if ($dbIsSet AND $directoryIsSet AND $adminAccountIsSet) { + if ($dbIsSet and $directoryIsSet and $adminAccountIsSet) { $post['install'] = 'true'; } $post['dbIsSet'] = $dbIsSet; diff --git a/core/Controller/SvgController.php b/core/Controller/SvgController.php index 63105e1c0f1..ea73ba118d9 100644 --- a/core/Controller/SvgController.php +++ b/core/Controller/SvgController.php @@ -5,12 +5,13 @@ declare(strict_types=1); /** * @copyright Copyright (c) 2018, John Molakvoæ (skjnldsv@protonmail.com) * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> + * @author Daniel Kesselberg <mail@danielkesselberg.de> * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> * @author Julius Härtl <jus@bitgrid.net> - * @author Michael Weimann <mail@michael-weimann.eu> * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Thomas Citharel <tcit@tcit.fr> + * @author Thomas Citharel <nextcloud@tcit.fr> * * @license GNU AGPL version 3 or any later version * @@ -21,17 +22,17 @@ declare(strict_types=1); * * 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 + * 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\Core\Controller; use OC\Template\IconsCacher; +use OCP\App\AppPathNotFoundException; use OCP\App\IAppManager; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; @@ -61,7 +62,7 @@ class SvgController extends Controller { IconsCacher $iconsCacher) { parent::__construct($appName, $request); - $this->serverRoot = \OC::$SERVERROOT; + $this->serverRoot = \OC::$SERVERROOT; $this->timeFactory = $timeFactory; $this->appManager = $appManager; $this->iconsCacher = $iconsCacher; @@ -97,13 +98,13 @@ class SvgController extends Controller { * @return DataDisplayResponse|NotFoundResponse */ public function getSvgFromApp(string $app, string $fileName, string $color = 'ffffff') { - $appRootPath = $this->appManager->getAppPath($app); - $appPath = substr($appRootPath, strlen($this->serverRoot)); - - if (!$appPath) { + try { + $appPath = $this->appManager->getAppPath($app); + } catch (AppPathNotFoundException $e) { return new NotFoundResponse(); } - $path = $this->serverRoot . $appPath ."/img/$fileName.svg"; + + $path = $appPath . "/img/$fileName.svg"; return $this->getSvg($path, $color, $fileName); } diff --git a/core/Controller/TwoFactorChallengeController.php b/core/Controller/TwoFactorChallengeController.php index 4209e48e648..e08454caea6 100644 --- a/core/Controller/TwoFactorChallengeController.php +++ b/core/Controller/TwoFactorChallengeController.php @@ -23,7 +23,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OC\Core\Controller; use OC\Authentication\TwoFactorAuth\Manager; @@ -108,7 +107,7 @@ class TwoFactorChallengeController extends Controller { $user = $this->userSession->getUser(); $providerSet = $this->twoFactorManager->getProviderSet($user); $allProviders = $providerSet->getProviders(); - list($providers, $backupProvider) = $this->splitProvidersAndBackupCodes($allProviders); + [$providers, $backupProvider] = $this->splitProvidersAndBackupCodes($allProviders); $setupProviders = $this->twoFactorManager->getLoginSetupProviders($user); $data = [ @@ -278,5 +277,4 @@ class TwoFactorChallengeController extends Controller { ] )); } - } diff --git a/core/Controller/UnifiedSearchController.php b/core/Controller/UnifiedSearchController.php new file mode 100644 index 00000000000..93fbb323ee5 --- /dev/null +++ b/core/Controller/UnifiedSearchController.php @@ -0,0 +1,153 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> + * @author Joas Schilling <coding@schilljs.com> + * @author John Molakvoæ <skjnldsv@protonmail.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OC\Core\Controller; + +use OC\Search\SearchComposer; +use OC\Search\SearchQuery; +use OCP\AppFramework\OCSController; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\DataResponse; +use OCP\IRequest; +use OCP\IUserSession; +use OCP\Route\IRouter; +use OCP\Search\ISearchQuery; +use Symfony\Component\Routing\Exception\ResourceNotFoundException; + +class UnifiedSearchController extends OCSController { + + /** @var SearchComposer */ + private $composer; + + /** @var IUserSession */ + private $userSession; + + /** @var IRouter */ + private $router; + + public function __construct(IRequest $request, + IUserSession $userSession, + SearchComposer $composer, + IRouter $router) { + parent::__construct('core', $request); + + $this->composer = $composer; + $this->userSession = $userSession; + $this->router = $router; + } + + /** + * @NoAdminRequired + * @NoCSRFRequired + * + * @param string $from the url the user is currently at + * + * @return DataResponse + */ + public function getProviders(string $from = ''): DataResponse { + [$route, $parameters] = $this->getRouteInformation($from); + + $result = $this->composer->getProviders($route, $parameters); + $response = new DataResponse($result); + $response->setETag(md5(json_encode($result))); + return $response; + } + + /** + * @NoAdminRequired + * @NoCSRFRequired + * + * @param string $providerId + * @param string $term + * @param int|null $sortOrder + * @param int|null $limit + * @param int|string|null $cursor + * @param string $from + * + * @return DataResponse + */ + public function search(string $providerId, + string $term = '', + ?int $sortOrder = null, + ?int $limit = null, + $cursor = null, + string $from = ''): DataResponse { + if (empty(trim($term))) { + return new DataResponse(null, Http::STATUS_BAD_REQUEST); + } + [$route, $routeParameters] = $this->getRouteInformation($from); + + return new DataResponse( + $this->composer->search( + $this->userSession->getUser(), + $providerId, + new SearchQuery( + $term, + $sortOrder ?? ISearchQuery::SORT_DATE_DESC, + $limit ?? SearchQuery::LIMIT_DEFAULT, + $cursor, + $route, + $routeParameters + ) + ) + ); + } + + protected function getRouteInformation(string $url): array { + $routeStr = ''; + $parameters = []; + + if ($url !== '') { + $urlParts = parse_url($url); + + try { + $parameters = $this->router->findMatchingRoute($urlParts['path']); + + // contacts.PageController.index => contacts.Page.index + $route = $parameters['caller']; + if (substr($route[1], -10) === 'Controller') { + $route[1] = substr($route[1], 0, -10); + } + $routeStr = implode('.', $route); + + // cleanup + unset($parameters['_route'], $parameters['action'], $parameters['caller']); + } catch (ResourceNotFoundException $exception) { + } + + if (isset($urlParts['query'])) { + parse_str($urlParts['query'], $queryParameters); + $parameters = array_merge($parameters, $queryParameters); + } + } + + return [ + $routeStr, + $parameters, + ]; + } +} diff --git a/core/Controller/UserController.php b/core/Controller/UserController.php index 54c5202a59f..6d50348c2a5 100644 --- a/core/Controller/UserController.php +++ b/core/Controller/UserController.php @@ -2,6 +2,7 @@ /** * @copyright Copyright (c) 2016, ownCloud, Inc. * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Lukas Reschke <lukas@statuscode.ch> * @author Morris Jobke <hey@morrisjobke.de> * @author Roeland Jago Douma <roeland@famdouma.nl> @@ -21,7 +22,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ - namespace OC\Core\Controller; use OCP\AppFramework\Controller; @@ -70,6 +70,5 @@ class UserController extends Controller { ]; return new JSONResponse($json); - } } diff --git a/core/Controller/WalledGardenController.php b/core/Controller/WalledGardenController.php index 5bd66225076..4aff72beb44 100644 --- a/core/Controller/WalledGardenController.php +++ b/core/Controller/WalledGardenController.php @@ -2,6 +2,7 @@ /** * @copyright 2017, Roeland Jago Douma <roeland@famdouma.nl> * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Roeland Jago Douma <roeland@famdouma.nl> * * @license GNU AGPL version 3 or any later version @@ -13,14 +14,13 @@ * * 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 + * 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\Core\Controller; use OCP\AppFramework\Controller; @@ -35,7 +35,7 @@ class WalledGardenController extends Controller { * * @return Response */ - function get() { + public function get() { $resp = new Response(); $resp->setStatus(Http::STATUS_NO_CONTENT); return $resp; diff --git a/core/Controller/WebAuthnController.php b/core/Controller/WebAuthnController.php new file mode 100644 index 00000000000..1aab505f16a --- /dev/null +++ b/core/Controller/WebAuthnController.php @@ -0,0 +1,118 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2020, Roeland Jago Douma <roeland@famdouma.nl> + * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> + * @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\Core\Controller; + +use OC\Authentication\Login\LoginData; +use OC\Authentication\Login\WebAuthnChain; +use OC\Authentication\WebAuthn\Manager; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\JSONResponse; +use OCP\ILogger; +use OCP\IRequest; +use OCP\ISession; +use OCP\Util; +use Webauthn\PublicKeyCredentialRequestOptions; + +class WebAuthnController extends Controller { + private const WEBAUTHN_LOGIN = 'webauthn_login'; + private const WEBAUTHN_LOGIN_UID = 'webauthn_login_uid'; + + /** @var Manager */ + private $webAuthnManger; + + /** @var ISession */ + private $session; + + /** @var ILogger */ + private $logger; + + /** @var WebAuthnChain */ + private $webAuthnChain; + + public function __construct($appName, IRequest $request, Manager $webAuthnManger, ISession $session, ILogger $logger, WebAuthnChain $webAuthnChain) { + parent::__construct($appName, $request); + + $this->webAuthnManger = $webAuthnManger; + $this->session = $session; + $this->logger = $logger; + $this->webAuthnChain = $webAuthnChain; + } + + /** + * @NoAdminRequired + * @PublicPage + * @UseSession + */ + public function startAuthentication(string $loginName): JSONResponse { + $this->logger->debug('Starting WebAuthn login'); + + $this->logger->debug('Converting login name to UID'); + $uid = $loginName; + Util::emitHook( + '\OCA\Files_Sharing\API\Server2Server', + 'preLoginNameUsedAsUserName', + ['uid' => &$uid] + ); + $this->logger->debug('Got UID: ' . $uid); + + $publicKeyCredentialRequestOptions = $this->webAuthnManger->startAuthentication($uid, $this->request->getServerHost()); + $this->session->set(self::WEBAUTHN_LOGIN, json_encode($publicKeyCredentialRequestOptions)); + $this->session->set(self::WEBAUTHN_LOGIN_UID, $uid); + + return new JSONResponse($publicKeyCredentialRequestOptions); + } + + /** + * @NoAdminRequired + * @PublicPage + * @UseSession + */ + public function finishAuthentication(string $data): JSONResponse { + $this->logger->debug('Validating WebAuthn login'); + + if (!$this->session->exists(self::WEBAUTHN_LOGIN) || !$this->session->exists(self::WEBAUTHN_LOGIN_UID)) { + $this->logger->debug('Trying to finish WebAuthn login without session data'); + return new JSONResponse([], Http::STATUS_BAD_REQUEST); + } + + // Obtain the publicKeyCredentialOptions from when we started the registration + $publicKeyCredentialRequestOptions = PublicKeyCredentialRequestOptions::createFromString($this->session->get(self::WEBAUTHN_LOGIN)); + $uid = $this->session->get(self::WEBAUTHN_LOGIN_UID); + $this->webAuthnManger->finishAuthentication($publicKeyCredentialRequestOptions, $data, $uid); + + //TODO: add other parameters + $loginData = new LoginData( + $this->request, + $uid, + '' + ); + $this->webAuthnChain->process($loginData); + + return new JSONResponse([]); + } +} diff --git a/core/Controller/WellKnownController.php b/core/Controller/WellKnownController.php new file mode 100644 index 00000000000..12384b6f9ad --- /dev/null +++ b/core/Controller/WellKnownController.php @@ -0,0 +1,67 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @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\Core\Controller; + +use OC\Http\WellKnown\RequestManager; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\Http\Response; +use OCP\IRequest; + +class WellKnownController extends Controller { + + /** @var RequestManager */ + private $requestManager; + + public function __construct(IRequest $request, + RequestManager $wellKnownManager) { + parent::__construct('core', $request); + $this->requestManager = $wellKnownManager; + } + + /** + * @PublicPage + * @NoCSRFRequired + * + * @return Response + */ + public function handle(string $service): Response { + $response = $this->requestManager->process( + $service, + $this->request + ); + + if ($response === null) { + $httpResponse = new JSONResponse(["message" => "$service not supported"], Http::STATUS_NOT_FOUND); + } else { + $httpResponse = $response->toHttpResponse(); + } + + // We add a custom header so that setup checks can detect if their requests are answered by this controller + return $httpResponse->addHeader('X-NEXTCLOUD-WELL-KNOWN', '1'); + } +} diff --git a/core/Controller/WhatsNewController.php b/core/Controller/WhatsNewController.php index 159e88e1474..12024dec030 100644 --- a/core/Controller/WhatsNewController.php +++ b/core/Controller/WhatsNewController.php @@ -3,6 +3,7 @@ * @copyright Copyright (c) 2018 Arthur Schiwon <blizzz@arthur-schiwon.de> * * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * * @license GNU AGPL version 3 or any later version * @@ -13,14 +14,13 @@ * * 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 + * 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\Core\Controller; use OC\CapabilitiesManager; @@ -74,13 +74,13 @@ class WhatsNewController extends OCSController { */ public function get():DataResponse { $user = $this->userSession->getUser(); - if($user === null) { + if ($user === null) { throw new \RuntimeException("Acting user cannot be resolved"); } $lastRead = $this->config->getUserValue($user->getUID(), 'core', 'whatsNewLastRead', 0); $currentVersion = $this->whatsNewService->normalizeVersion($this->config->getSystemValue('version')); - if(version_compare($lastRead, $currentVersion, '>=')) { + if (version_compare($lastRead, $currentVersion, '>=')) { return new DataResponse([], Http::STATUS_NO_CONTENT); } @@ -89,12 +89,12 @@ class WhatsNewController extends OCSController { $whatsNew = $this->whatsNewService->getChangesForVersion($currentVersion); $resultData = [ 'changelogURL' => $whatsNew['changelogURL'], - 'product' => $this->defaults->getName(), + 'product' => $this->defaults->getProductName(), 'version' => $currentVersion, ]; do { $lang = $iterator->current(); - if(isset($whatsNew['whatsNew'][$lang])) { + if (isset($whatsNew['whatsNew'][$lang])) { $resultData['whatsNew'] = $whatsNew['whatsNew'][$lang]; break; } @@ -114,7 +114,7 @@ class WhatsNewController extends OCSController { */ public function dismiss(string $version):DataResponse { $user = $this->userSession->getUser(); - if($user === null) { + if ($user === null) { throw new \RuntimeException("Acting user cannot be resolved"); } $version = $this->whatsNewService->normalizeVersion($version); diff --git a/core/Controller/WipeController.php b/core/Controller/WipeController.php index 378fb112850..5eef03b129f 100644 --- a/core/Controller/WipeController.php +++ b/core/Controller/WipeController.php @@ -16,14 +16,13 @@ declare(strict_types=1); * * 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 + * 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\Core\Controller; use OC\Authentication\Exceptions\InvalidTokenException; @@ -94,5 +93,4 @@ class WipeController extends Controller { return new JSONResponse([], Http::STATUS_NOT_FOUND); } } - } |