diff options
Diffstat (limited to 'apps/files_external/lib/Lib')
63 files changed, 841 insertions, 1994 deletions
diff --git a/apps/files_external/lib/Lib/Auth/AmazonS3/AccessKey.php b/apps/files_external/lib/Lib/Auth/AmazonS3/AccessKey.php index 7185fb511f5..c86c88a13d7 100644 --- a/apps/files_external/lib/Lib/Auth/AmazonS3/AccessKey.php +++ b/apps/files_external/lib/Lib/Auth/AmazonS3/AccessKey.php @@ -1,26 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Auth\AmazonS3; diff --git a/apps/files_external/lib/Lib/Auth/AuthMechanism.php b/apps/files_external/lib/Lib/Auth/AuthMechanism.php index 5ef5f78acd9..7b0544100fb 100644 --- a/apps/files_external/lib/Lib/Auth/AuthMechanism.php +++ b/apps/files_external/lib/Lib/Auth/AuthMechanism.php @@ -1,26 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Auth; @@ -57,7 +40,6 @@ class AuthMechanism implements \JsonSerializable, IIdentifier, IFrontendDefiniti public const SCHEME_NULL = 'null'; public const SCHEME_BUILTIN = 'builtin'; public const SCHEME_PASSWORD = 'password'; - public const SCHEME_OAUTH1 = 'oauth1'; public const SCHEME_OAUTH2 = 'oauth2'; public const SCHEME_PUBLICKEY = 'publickey'; public const SCHEME_OPENSTACK = 'openstack'; diff --git a/apps/files_external/lib/Lib/Auth/Builtin.php b/apps/files_external/lib/Lib/Auth/Builtin.php index 91428156c75..8e12a6daca6 100644 --- a/apps/files_external/lib/Lib/Auth/Builtin.php +++ b/apps/files_external/lib/Lib/Auth/Builtin.php @@ -1,24 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Auth; diff --git a/apps/files_external/lib/Lib/Auth/IUserProvided.php b/apps/files_external/lib/Lib/Auth/IUserProvided.php index f913e8e3ab5..2350d7f6db4 100644 --- a/apps/files_external/lib/Lib/Auth/IUserProvided.php +++ b/apps/files_external/lib/Lib/Auth/IUserProvided.php @@ -1,23 +1,8 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Robin Appelman <robin@icewind.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Auth; diff --git a/apps/files_external/lib/Lib/Auth/InvalidAuth.php b/apps/files_external/lib/Lib/Auth/InvalidAuth.php index 1d2953b11cd..2af24f1ea07 100644 --- a/apps/files_external/lib/Lib/Auth/InvalidAuth.php +++ b/apps/files_external/lib/Lib/Auth/InvalidAuth.php @@ -1,23 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud GmbH. - * - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud GmbH. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Auth; diff --git a/apps/files_external/lib/Lib/Auth/NullMechanism.php b/apps/files_external/lib/Lib/Auth/NullMechanism.php index 05b73b92fc1..8e2e5b656b2 100644 --- a/apps/files_external/lib/Lib/Auth/NullMechanism.php +++ b/apps/files_external/lib/Lib/Auth/NullMechanism.php @@ -1,24 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Auth; diff --git a/apps/files_external/lib/Lib/Auth/OAuth1/OAuth1.php b/apps/files_external/lib/Lib/Auth/OAuth1/OAuth1.php deleted file mode 100644 index 44cdcf79523..00000000000 --- a/apps/files_external/lib/Lib/Auth/OAuth1/OAuth1.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -/** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ -namespace OCA\Files_External\Lib\Auth\OAuth1; - -use OCA\Files_External\Lib\Auth\AuthMechanism; -use OCA\Files_External\Lib\DefinitionParameter; -use OCP\IL10N; - -/** - * OAuth1 authentication - */ -class OAuth1 extends AuthMechanism { - public function __construct(IL10N $l) { - $this - ->setIdentifier('oauth1::oauth1') - ->setScheme(self::SCHEME_OAUTH1) - ->setText($l->t('OAuth1')) - ->addParameters([ - (new DefinitionParameter('configured', 'configured')) - ->setType(DefinitionParameter::VALUE_HIDDEN), - new DefinitionParameter('app_key', $l->t('App key')), - (new DefinitionParameter('app_secret', $l->t('App secret'))) - ->setType(DefinitionParameter::VALUE_PASSWORD), - (new DefinitionParameter('token', 'token')) - ->setType(DefinitionParameter::VALUE_HIDDEN), - (new DefinitionParameter('token_secret', 'token_secret')) - ->setType(DefinitionParameter::VALUE_HIDDEN), - ]) - ->addCustomJs('oauth1') - ; - } -} diff --git a/apps/files_external/lib/Lib/Auth/OAuth2/OAuth2.php b/apps/files_external/lib/Lib/Auth/OAuth2/OAuth2.php index 4dc2b23035a..beaf73c2344 100644 --- a/apps/files_external/lib/Lib/Auth/OAuth2/OAuth2.php +++ b/apps/files_external/lib/Lib/Auth/OAuth2/OAuth2.php @@ -1,25 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Auth\OAuth2; @@ -38,12 +22,14 @@ class OAuth2 extends AuthMechanism { ->setText($l->t('OAuth2')) ->addParameters([ (new DefinitionParameter('configured', 'configured')) - ->setType(DefinitionParameter::VALUE_HIDDEN), + ->setType(DefinitionParameter::VALUE_TEXT) + ->setFlag(DefinitionParameter::FLAG_HIDDEN), new DefinitionParameter('client_id', $l->t('Client ID')), (new DefinitionParameter('client_secret', $l->t('Client secret'))) ->setType(DefinitionParameter::VALUE_PASSWORD), (new DefinitionParameter('token', 'token')) - ->setType(DefinitionParameter::VALUE_HIDDEN), + ->setType(DefinitionParameter::VALUE_PASSWORD) + ->setFlag(DefinitionParameter::FLAG_HIDDEN), ]) ->addCustomJs('oauth2') ; diff --git a/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV2.php b/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV2.php index a36a86afce4..3b1c9f123af 100644 --- a/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV2.php +++ b/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV2.php @@ -1,26 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Auth\OpenStack; diff --git a/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV3.php b/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV3.php index 090a54596bc..b5d185fd374 100644 --- a/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV3.php +++ b/apps/files_external/lib/Lib/Auth/OpenStack/OpenStackV3.php @@ -3,28 +3,8 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl> - * - * @author Julien Lutran <julien.lutran@corp.ovh.com> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @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: 2018 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Files_External\Lib\Auth\OpenStack; diff --git a/apps/files_external/lib/Lib/Auth/OpenStack/Rackspace.php b/apps/files_external/lib/Lib/Auth/OpenStack/Rackspace.php index 2ec0b8b035e..b1d1068e586 100644 --- a/apps/files_external/lib/Lib/Auth/OpenStack/Rackspace.php +++ b/apps/files_external/lib/Lib/Auth/OpenStack/Rackspace.php @@ -1,25 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Auth\OpenStack; diff --git a/apps/files_external/lib/Lib/Auth/Password/GlobalAuth.php b/apps/files_external/lib/Lib/Auth/Password/GlobalAuth.php index 174efd96e3c..916b496b506 100644 --- a/apps/files_external/lib/Lib/Auth/Password/GlobalAuth.php +++ b/apps/files_external/lib/Lib/Auth/Password/GlobalAuth.php @@ -1,26 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2015, ownCloud, Inc. - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2015 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Auth\Password; @@ -37,13 +20,12 @@ use OCP\Security\ICredentialsManager; */ class GlobalAuth extends AuthMechanism { public const CREDENTIALS_IDENTIFIER = 'password::global'; + private const PWD_PLACEHOLDER = '************************'; - /** @var ICredentialsManager */ - protected $credentialsManager; - - public function __construct(IL10N $l, ICredentialsManager $credentialsManager) { - $this->credentialsManager = $credentialsManager; - + public function __construct( + IL10N $l, + protected ICredentialsManager $credentialsManager, + ) { $this ->setIdentifier('password::global') ->setVisibility(BackendService::VISIBILITY_DEFAULT) @@ -59,11 +41,18 @@ class GlobalAuth extends AuthMechanism { 'password' => '' ]; } else { + $auth['password'] = self::PWD_PLACEHOLDER; return $auth; } } public function saveAuth($uid, $user, $password) { + // Use old password if it has not changed. + if ($password === self::PWD_PLACEHOLDER) { + $auth = $this->credentialsManager->retrieve($uid, self::CREDENTIALS_IDENTIFIER); + $password = $auth['password']; + } + $this->credentialsManager->store($uid, self::CREDENTIALS_IDENTIFIER, [ 'user' => $user, 'password' => $password diff --git a/apps/files_external/lib/Lib/Auth/Password/LoginCredentials.php b/apps/files_external/lib/Lib/Auth/Password/LoginCredentials.php index 5dc290d3548..ce38140b6ee 100644 --- a/apps/files_external/lib/Lib/Auth/Password/LoginCredentials.php +++ b/apps/files_external/lib/Lib/Auth/Password/LoginCredentials.php @@ -1,33 +1,14 @@ <?php + /** - * @copyright Copyright (c) 2015, ownCloud, Inc. - * - * @author blizzz <blizzz@arthur-schiwon.de> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Joas Schilling <coding@schilljs.com> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2015 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Auth\Password; use OCA\Files_External\Lib\Auth\AuthMechanism; +use OCA\Files_External\Lib\DefinitionParameter; use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException; use OCA\Files_External\Lib\StorageConfig; use OCA\Files_External\Listener\StorePasswordListener; @@ -49,36 +30,23 @@ use OCP\User\Events\UserLoggedInEvent; class LoginCredentials extends AuthMechanism { public const CREDENTIALS_IDENTIFIER = 'password::logincredentials/credentials'; - /** @var ISession */ - protected $session; - - /** @var ICredentialsManager */ - protected $credentialsManager; - - /** @var CredentialsStore */ - private $credentialsStore; - - /** @var ILDAPProviderFactory */ - private $ldapFactory; - public function __construct( IL10N $l, - ISession $session, - ICredentialsManager $credentialsManager, - CredentialsStore $credentialsStore, + protected ISession $session, + protected ICredentialsManager $credentialsManager, + private CredentialsStore $credentialsStore, IEventDispatcher $eventDispatcher, - ILDAPProviderFactory $ldapFactory + private ILDAPProviderFactory $ldapFactory, ) { - $this->session = $session; - $this->credentialsManager = $credentialsManager; - $this->credentialsStore = $credentialsStore; - $this->ldapFactory = $ldapFactory; - $this ->setIdentifier('password::logincredentials') ->setScheme(self::SCHEME_PASSWORD) ->setText($l->t('Log-in credentials, save in database')) ->addParameters([ + (new DefinitionParameter('password', $l->t('Password'))) + ->setType(DefinitionParameter::VALUE_PASSWORD) + ->setFlag(DefinitionParameter::FLAG_HIDDEN) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), ]); $eventDispatcher->addServiceListener(UserLoggedInEvent::class, StorePasswordListener::class); @@ -121,7 +89,7 @@ class LoginCredentials extends AuthMechanism { } $credentials = $this->getCredentials($user); - $loginKey = $storage->getBackendOption("login_ldap_attr"); + $loginKey = $storage->getBackendOption('login_ldap_attr'); if ($loginKey) { $backend = $user->getBackend(); if ($backend instanceof IUserBackend && $backend->getBackendName() === 'LDAP') { diff --git a/apps/files_external/lib/Lib/Auth/Password/Password.php b/apps/files_external/lib/Lib/Auth/Password/Password.php index 3435ebbb1de..d4291148e3e 100644 --- a/apps/files_external/lib/Lib/Auth/Password/Password.php +++ b/apps/files_external/lib/Lib/Auth/Password/Password.php @@ -1,25 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Auth\Password; diff --git a/apps/files_external/lib/Lib/Auth/Password/SessionCredentials.php b/apps/files_external/lib/Lib/Auth/Password/SessionCredentials.php index d2587991a96..8f161073771 100644 --- a/apps/files_external/lib/Lib/Auth/Password/SessionCredentials.php +++ b/apps/files_external/lib/Lib/Auth/Password/SessionCredentials.php @@ -1,35 +1,20 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Auth\Password; use OCA\Files_External\Lib\Auth\AuthMechanism; +use OCA\Files_External\Lib\DefinitionParameter; use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException; use OCA\Files_External\Lib\SessionStorageWrapper; use OCA\Files_External\Lib\StorageConfig; use OCP\Authentication\Exceptions\CredentialsUnavailableException; use OCP\Authentication\LoginCredentials\IStore as CredentialsStore; -use OCP\Files\Storage; +use OCP\Files\Storage\IStorage; use OCP\Files\StorageAuthException; use OCP\IL10N; use OCP\IUser; @@ -39,16 +24,19 @@ use OCP\IUser; */ class SessionCredentials extends AuthMechanism { - /** @var CredentialsStore */ - private $credentialsStore; - - public function __construct(IL10N $l, CredentialsStore $credentialsStore) { - $this->credentialsStore = $credentialsStore; - + public function __construct( + IL10N $l, + private CredentialsStore $credentialsStore, + ) { $this->setIdentifier('password::sessioncredentials') ->setScheme(self::SCHEME_PASSWORD) ->setText($l->t('Log-in credentials, save in session')) - ->addParameters([]); + ->addParameters([ + (new DefinitionParameter('password', $l->t('Password'))) + ->setType(DefinitionParameter::VALUE_PASSWORD) + ->setFlag(DefinitionParameter::FLAG_HIDDEN) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), + ]); } /** @@ -73,7 +61,7 @@ class SessionCredentials extends AuthMechanism { $storage->setBackendOption('password', $credentials->getPassword()); } - public function wrapStorage(Storage $storage) { + public function wrapStorage(IStorage $storage): IStorage { return new SessionStorageWrapper(['storage' => $storage]); } } diff --git a/apps/files_external/lib/Lib/Auth/Password/UserGlobalAuth.php b/apps/files_external/lib/Lib/Auth/Password/UserGlobalAuth.php index d43c4327b6b..cb7165261ac 100644 --- a/apps/files_external/lib/Lib/Auth/Password/UserGlobalAuth.php +++ b/apps/files_external/lib/Lib/Auth/Password/UserGlobalAuth.php @@ -3,32 +3,13 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2019 Robin Appelman <robin@icewind.nl> - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @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: 2019 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Files_External\Lib\Auth\Password; use OCA\Files_External\Lib\Auth\AuthMechanism; +use OCA\Files_External\Lib\DefinitionParameter; use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException; use OCA\Files_External\Lib\StorageConfig; use OCA\Files_External\Service\BackendService; @@ -42,12 +23,10 @@ use OCP\Security\ICredentialsManager; class UserGlobalAuth extends AuthMechanism { private const CREDENTIALS_IDENTIFIER = 'password::global'; - /** @var ICredentialsManager */ - protected $credentialsManager; - - public function __construct(IL10N $l, ICredentialsManager $credentialsManager) { - $this->credentialsManager = $credentialsManager; - + public function __construct( + IL10N $l, + protected ICredentialsManager $credentialsManager, + ) { $this ->setIdentifier('password::global::user') ->setVisibility(BackendService::VISIBILITY_DEFAULT) @@ -61,6 +40,12 @@ class UserGlobalAuth extends AuthMechanism { if (!isset($backendOptions['user']) && !isset($backendOptions['password'])) { return; } + + if ($backendOptions['password'] === DefinitionParameter::UNMODIFIED_PLACEHOLDER) { + $oldCredentials = $this->credentialsManager->retrieve($user->getUID(), self::CREDENTIALS_IDENTIFIER); + $backendOptions['password'] = $oldCredentials['password']; + } + // make sure we're not setting any unexpected keys $credentials = [ 'user' => $backendOptions['user'], diff --git a/apps/files_external/lib/Lib/Auth/Password/UserProvided.php b/apps/files_external/lib/Lib/Auth/Password/UserProvided.php index 7fcbdb38336..b158392f6eb 100644 --- a/apps/files_external/lib/Lib/Auth/Password/UserProvided.php +++ b/apps/files_external/lib/Lib/Auth/Password/UserProvided.php @@ -1,26 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2015, 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> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2015 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Auth\Password; @@ -40,12 +23,10 @@ use OCP\Security\ICredentialsManager; class UserProvided extends AuthMechanism implements IUserProvided { public const CREDENTIALS_IDENTIFIER_PREFIX = 'password::userprovided/'; - /** @var ICredentialsManager */ - protected $credentialsManager; - - public function __construct(IL10N $l, ICredentialsManager $credentialsManager) { - $this->credentialsManager = $credentialsManager; - + public function __construct( + IL10N $l, + protected ICredentialsManager $credentialsManager, + ) { $this ->setIdentifier('password::userprovided') ->setVisibility(BackendService::VISIBILITY_ADMIN) @@ -65,6 +46,11 @@ class UserProvided extends AuthMechanism implements IUserProvided { } public function saveBackendOptions(IUser $user, $mountId, array $options) { + if ($options['password'] === DefinitionParameter::UNMODIFIED_PLACEHOLDER) { + $oldCredentials = $this->credentialsManager->retrieve($user->getUID(), $this->getCredentialsIdentifier($mountId)); + $options['password'] = $oldCredentials['password']; + } + $this->credentialsManager->store($user->getUID(), $this->getCredentialsIdentifier($mountId), [ 'user' => $options['user'], // explicitly copy the fields we want instead of just passing the entire $options array 'password' => $options['password'] // this way we prevent users from being able to modify any other field diff --git a/apps/files_external/lib/Lib/Auth/PublicKey/RSA.php b/apps/files_external/lib/Lib/Auth/PublicKey/RSA.php index 67259ffc5b3..ad95c743d2d 100644 --- a/apps/files_external/lib/Lib/Auth/PublicKey/RSA.php +++ b/apps/files_external/lib/Lib/Auth/PublicKey/RSA.php @@ -1,25 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Auth\PublicKey; @@ -36,12 +20,10 @@ use phpseclib\Crypt\RSA as RSACrypt; */ class RSA extends AuthMechanism { - /** @var IConfig */ - private $config; - - public function __construct(IL10N $l, IConfig $config) { - $this->config = $config; - + public function __construct( + IL10N $l, + private IConfig $config, + ) { $this ->setIdentifier('publickey::rsa') ->setScheme(self::SCHEME_PUBLICKEY) @@ -50,7 +32,8 @@ class RSA extends AuthMechanism { new DefinitionParameter('user', $l->t('Login')), new DefinitionParameter('public_key', $l->t('Public key')), (new DefinitionParameter('private_key', 'private_key')) - ->setType(DefinitionParameter::VALUE_HIDDEN), + ->setType(DefinitionParameter::VALUE_PASSWORD) + ->setFlag(DefinitionParameter::FLAG_HIDDEN), ]) ->addCustomJs('public_key') ; diff --git a/apps/files_external/lib/Lib/Auth/PublicKey/RSAPrivateKey.php b/apps/files_external/lib/Lib/Auth/PublicKey/RSAPrivateKey.php index 30ff5dd2a4c..8f58b71d5ac 100644 --- a/apps/files_external/lib/Lib/Auth/PublicKey/RSAPrivateKey.php +++ b/apps/files_external/lib/Lib/Auth/PublicKey/RSAPrivateKey.php @@ -1,24 +1,8 @@ <?php + /** - * @copyright 2018, 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/>. - * + * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Files_External\Lib\Auth\PublicKey; @@ -35,12 +19,10 @@ use phpseclib\Crypt\RSA as RSACrypt; */ class RSAPrivateKey extends AuthMechanism { - /** @var IConfig */ - private $config; - - public function __construct(IL10N $l, IConfig $config) { - $this->config = $config; - + public function __construct( + IL10N $l, + private IConfig $config, + ) { $this ->setIdentifier('publickey::rsa_private') ->setScheme(self::SCHEME_PUBLICKEY) diff --git a/apps/files_external/lib/Lib/Auth/SMB/KerberosApacheAuth.php b/apps/files_external/lib/Lib/Auth/SMB/KerberosApacheAuth.php index 17492280275..26671110294 100644 --- a/apps/files_external/lib/Lib/Auth/SMB/KerberosApacheAuth.php +++ b/apps/files_external/lib/Lib/Auth/SMB/KerberosApacheAuth.php @@ -1,25 +1,8 @@ <?php /** - * @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl> - * - * @author Robin Appelman <robin@icewind.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: 2018 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Files_External\Lib\Auth\SMB; @@ -30,10 +13,10 @@ use OCP\Authentication\LoginCredentials\IStore; use OCP\IL10N; class KerberosApacheAuth extends AuthMechanism { - /** @var IStore */ - private $credentialsStore; - - public function __construct(IL10N $l, IStore $credentialsStore) { + public function __construct( + IL10N $l, + private IStore $credentialsStore, + ) { $realm = new DefinitionParameter('default_realm', 'Default realm'); $realm ->setType(DefinitionParameter::VALUE_TEXT) @@ -44,7 +27,6 @@ class KerberosApacheAuth extends AuthMechanism { ->setScheme(self::SCHEME_SMB) ->setText($l->t('Kerberos ticket Apache mode')) ->addParameter($realm); - $this->credentialsStore = $credentialsStore; } public function getCredentialsStore(): IStore { diff --git a/apps/files_external/lib/Lib/Auth/SMB/KerberosAuth.php b/apps/files_external/lib/Lib/Auth/SMB/KerberosAuth.php index 44956c57ada..9210209192a 100644 --- a/apps/files_external/lib/Lib/Auth/SMB/KerberosAuth.php +++ b/apps/files_external/lib/Lib/Auth/SMB/KerberosAuth.php @@ -1,24 +1,8 @@ <?php + /** - * @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl> - * - * @author Robin Appelman <robin@icewind.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: 2018 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Files_External\Lib\Auth\SMB; diff --git a/apps/files_external/lib/Lib/Backend/AmazonS3.php b/apps/files_external/lib/Lib/Backend/AmazonS3.php index 11479c70c8e..464b03b55e0 100644 --- a/apps/files_external/lib/Lib/Backend/AmazonS3.php +++ b/apps/files_external/lib/Lib/Backend/AmazonS3.php @@ -1,26 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Backend; @@ -59,6 +42,9 @@ class AmazonS3 extends Backend { (new DefinitionParameter('useMultipartCopy', $l->t('Enable multipart copy'))) ->setType(DefinitionParameter::VALUE_BOOLEAN) ->setDefaultValue(true), + (new DefinitionParameter('sse_c_key', $l->t('SSE-C encryption key'))) + ->setType(DefinitionParameter::VALUE_PASSWORD) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), ]) ->addAuthScheme(AccessKey::SCHEME_AMAZONS3_ACCESSKEY) ->addAuthScheme(AuthMechanism::SCHEME_NULL) diff --git a/apps/files_external/lib/Lib/Backend/Backend.php b/apps/files_external/lib/Lib/Backend/Backend.php index 48f46b8f55a..f7500ee24a4 100644 --- a/apps/files_external/lib/Lib/Backend/Backend.php +++ b/apps/files_external/lib/Lib/Backend/Backend.php @@ -1,24 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Backend; diff --git a/apps/files_external/lib/Lib/Backend/DAV.php b/apps/files_external/lib/Lib/Backend/DAV.php index 71c97e639ff..dea9e7c5e77 100644 --- a/apps/files_external/lib/Lib/Backend/DAV.php +++ b/apps/files_external/lib/Lib/Backend/DAV.php @@ -1,25 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Backend; diff --git a/apps/files_external/lib/Lib/Backend/FTP.php b/apps/files_external/lib/Lib/Backend/FTP.php index d7c6e3bebd6..72a8184c9b9 100644 --- a/apps/files_external/lib/Lib/Backend/FTP.php +++ b/apps/files_external/lib/Lib/Backend/FTP.php @@ -1,25 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Backend; @@ -40,6 +24,8 @@ class FTP extends Backend { ->setText($l->t('FTP')) ->addParameters([ new DefinitionParameter('host', $l->t('Host')), + (new DefinitionParameter('port', $l->t('Port'))) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), (new DefinitionParameter('root', $l->t('Remote subfolder'))) ->setFlag(DefinitionParameter::FLAG_OPTIONAL), (new DefinitionParameter('secure', $l->t('Secure ftps://'))) diff --git a/apps/files_external/lib/Lib/Backend/InvalidBackend.php b/apps/files_external/lib/Lib/Backend/InvalidBackend.php index 88c73470279..48912c0e49e 100644 --- a/apps/files_external/lib/Lib/Backend/InvalidBackend.php +++ b/apps/files_external/lib/Lib/Backend/InvalidBackend.php @@ -1,26 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud GmbH. - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud GmbH. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Backend; @@ -34,21 +17,19 @@ use OCP\IUser; */ class InvalidBackend extends Backend { - /** @var string Invalid backend id */ - private $invalidId; - /** * Constructs a new InvalidBackend with the id of the invalid backend * for display purposes * * @param string $invalidId id of the backend that did not exist */ - public function __construct($invalidId) { - $this->invalidId = $invalidId; + public function __construct( + private $invalidId, + ) { $this - ->setIdentifier($invalidId) + ->setIdentifier($this->invalidId) ->setStorageClass('\OC\Files\Storage\FailedStorage') - ->setText('Unknown storage backend ' . $invalidId); + ->setText('Unknown storage backend ' . $this->invalidId); } /** diff --git a/apps/files_external/lib/Lib/Backend/LegacyBackend.php b/apps/files_external/lib/Lib/Backend/LegacyBackend.php index 86c21f03434..9c7e5b01bc3 100644 --- a/apps/files_external/lib/Lib/Backend/LegacyBackend.php +++ b/apps/files_external/lib/Lib/Backend/LegacyBackend.php @@ -1,25 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Backend; @@ -69,10 +53,6 @@ class LegacyBackend extends Backend { $type = DefinitionParameter::VALUE_PASSWORD; $placeholder = substr($placeholder, 1); break; - case '#': - $type = DefinitionParameter::VALUE_HIDDEN; - $placeholder = substr($placeholder, 1); - break; } $this->addParameter((new DefinitionParameter($name, $placeholder)) ->setType($type) diff --git a/apps/files_external/lib/Lib/Backend/Local.php b/apps/files_external/lib/Lib/Backend/Local.php index 41b8e2fbad7..56940b8e83b 100644 --- a/apps/files_external/lib/Lib/Backend/Local.php +++ b/apps/files_external/lib/Lib/Backend/Local.php @@ -1,25 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Backend; diff --git a/apps/files_external/lib/Lib/Backend/OwnCloud.php b/apps/files_external/lib/Lib/Backend/OwnCloud.php index 97297b6a977..0c0e2c6d300 100644 --- a/apps/files_external/lib/Lib/Backend/OwnCloud.php +++ b/apps/files_external/lib/Lib/Backend/OwnCloud.php @@ -1,26 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Backend; diff --git a/apps/files_external/lib/Lib/Backend/SFTP.php b/apps/files_external/lib/Lib/Backend/SFTP.php index c65720ea1ae..0926cf7fd93 100644 --- a/apps/files_external/lib/Lib/Backend/SFTP.php +++ b/apps/files_external/lib/Lib/Backend/SFTP.php @@ -1,25 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Backend; @@ -37,6 +21,8 @@ class SFTP extends Backend { ->setText($l->t('SFTP')) ->addParameters([ new DefinitionParameter('host', $l->t('Host')), + (new DefinitionParameter('port', $l->t('Port'))) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL), (new DefinitionParameter('root', $l->t('Root'))) ->setFlag(DefinitionParameter::FLAG_OPTIONAL), ]) diff --git a/apps/files_external/lib/Lib/Backend/SFTP_Key.php b/apps/files_external/lib/Lib/Backend/SFTP_Key.php index e9a64407ce2..278fae3fba7 100644 --- a/apps/files_external/lib/Lib/Backend/SFTP_Key.php +++ b/apps/files_external/lib/Lib/Backend/SFTP_Key.php @@ -1,25 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Backend; diff --git a/apps/files_external/lib/Lib/Backend/SMB.php b/apps/files_external/lib/Lib/Backend/SMB.php index 29f6c727a10..e86ad98880c 100644 --- a/apps/files_external/lib/Lib/Backend/SMB.php +++ b/apps/files_external/lib/Lib/Backend/SMB.php @@ -1,48 +1,30 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Daniel Kesselberg <mail@danielkesselberg.de> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Valdnet <47037905+Valdnet@users.noreply.github.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Backend; use Icewind\SMB\BasicAuth; -use Icewind\SMB\KerberosApacheAuth; use Icewind\SMB\KerberosAuth; +use Icewind\SMB\KerberosTicket; +use Icewind\SMB\Native\NativeServer; +use Icewind\SMB\Wrapped\Server; use OCA\Files_External\Lib\Auth\AuthMechanism; use OCA\Files_External\Lib\Auth\Password\Password; use OCA\Files_External\Lib\Auth\SMB\KerberosApacheAuth as KerberosApacheAuthMechanism; use OCA\Files_External\Lib\DefinitionParameter; use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException; -use OCA\Files_External\Lib\LegacyDependencyCheckPolyfill; +use OCA\Files_External\Lib\MissingDependency; +use OCA\Files_External\Lib\Storage\SystemBridge; use OCA\Files_External\Lib\StorageConfig; use OCP\IL10N; use OCP\IUser; class SMB extends Backend { - use LegacyDependencyCheckPolyfill; - public function __construct(IL10N $l, Password $legacyAuth) { $this ->setIdentifier('smb') @@ -69,18 +51,16 @@ class SMB extends Backend { ->setFlag(DefinitionParameter::FLAG_OPTIONAL) ->setTooltip($l->t("Check the ACL's of each file or folder inside a directory to filter out items where the account has no read permissions, comes with a performance penalty")), (new DefinitionParameter('timeout', $l->t('Timeout'))) - ->setType(DefinitionParameter::VALUE_HIDDEN) - ->setFlag(DefinitionParameter::FLAG_OPTIONAL), + ->setType(DefinitionParameter::VALUE_TEXT) + ->setFlag(DefinitionParameter::FLAG_OPTIONAL) + ->setFlag(DefinitionParameter::FLAG_HIDDEN), ]) ->addAuthScheme(AuthMechanism::SCHEME_PASSWORD) ->addAuthScheme(AuthMechanism::SCHEME_SMB) ->setLegacyAuthMechanism($legacyAuth); } - /** - * @return void - */ - public function manipulateStorageConfig(StorageConfig &$storage, ?IUser $user = null) { + public function manipulateStorageConfig(StorageConfig &$storage, ?IUser $user = null): void { $auth = $storage->getAuthMechanism(); if ($auth->getScheme() === AuthMechanism::SCHEME_PASSWORD) { if (!is_string($storage->getBackendOption('user')) || !is_string($storage->getBackendOption('password'))) { @@ -102,33 +82,33 @@ class SMB extends Backend { throw new \InvalidArgumentException('invalid authentication backend'); } $credentialsStore = $auth->getCredentialsStore(); - $kerbAuth = new KerberosApacheAuth(); + $kerbAuth = new KerberosAuth(); + $kerbAuth->setTicket(KerberosTicket::fromEnv()); // check if a kerberos ticket is available, else fallback to session credentials - if ($kerbAuth->checkTicket()) { + if ($kerbAuth->getTicket()?->isValid()) { $smbAuth = $kerbAuth; } else { try { $credentials = $credentialsStore->getLoginCredentials(); - $user = $credentials->getLoginName(); + $loginName = $credentials->getLoginName(); $pass = $credentials->getPassword(); - preg_match('/(.*)@(.*)/', $user, $matches); + preg_match('/(.*)@(.*)/', $loginName, $matches); $realm = $storage->getBackendOption('default_realm'); if (empty($realm)) { $realm = 'WORKGROUP'; } if (count($matches) === 0) { - $username = $user; + $username = $loginName; $workgroup = $realm; } else { - $username = $matches[1]; - $workgroup = $matches[2]; + [, $username, $workgroup] = $matches; } $smbAuth = new BasicAuth( $username, $workgroup, $pass ); - } catch (\Exception $e) { + } catch (\Exception) { throw new InsufficientDataForMeaningfulAnswerException('No session credentials saved'); } } @@ -141,4 +121,20 @@ class SMB extends Backend { $storage->setBackendOption('auth', $smbAuth); } + + public function checkDependencies(): array { + $system = \OCP\Server::get(SystemBridge::class); + if (NativeServer::available($system)) { + return []; + } elseif (Server::available($system)) { + $missing = new MissingDependency('php-smbclient'); + $missing->setOptional(true); + $missing->setMessage('The php-smbclient library provides improved compatibility and performance for SMB storages.'); + return [$missing]; + } else { + $missing = new MissingDependency('php-smbclient'); + $missing->setMessage('Either the php-smbclient library (preferred) or the smbclient binary is required for SMB storages.'); + return [$missing, new MissingDependency('smbclient')]; + } + } } diff --git a/apps/files_external/lib/Lib/Backend/SMB_OC.php b/apps/files_external/lib/Lib/Backend/SMB_OC.php index 5f1ed3b8334..bcb8d0fbf16 100644 --- a/apps/files_external/lib/Lib/Backend/SMB_OC.php +++ b/apps/files_external/lib/Lib/Backend/SMB_OC.php @@ -1,26 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Valdnet <47037905+Valdnet@users.noreply.github.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Backend; diff --git a/apps/files_external/lib/Lib/Backend/Swift.php b/apps/files_external/lib/Lib/Backend/Swift.php index 8450af5f19c..37527ba3dbb 100644 --- a/apps/files_external/lib/Lib/Backend/Swift.php +++ b/apps/files_external/lib/Lib/Backend/Swift.php @@ -1,28 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Julien Lutran <julien.lutran@corp.ovh.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Backend; diff --git a/apps/files_external/lib/Lib/Config/IAuthMechanismProvider.php b/apps/files_external/lib/Lib/Config/IAuthMechanismProvider.php index 4358b7abc4f..0c2e90a243c 100644 --- a/apps/files_external/lib/Lib/Config/IAuthMechanismProvider.php +++ b/apps/files_external/lib/Lib/Config/IAuthMechanismProvider.php @@ -1,24 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Config; diff --git a/apps/files_external/lib/Lib/Config/IBackendProvider.php b/apps/files_external/lib/Lib/Config/IBackendProvider.php index e2b04e78c10..44c460c3138 100644 --- a/apps/files_external/lib/Lib/Config/IBackendProvider.php +++ b/apps/files_external/lib/Lib/Config/IBackendProvider.php @@ -1,24 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Config; diff --git a/apps/files_external/lib/Lib/DefinitionParameter.php b/apps/files_external/lib/Lib/DefinitionParameter.php index ce0a37b4e9b..a73dd2df967 100644 --- a/apps/files_external/lib/Lib/DefinitionParameter.php +++ b/apps/files_external/lib/Lib/DefinitionParameter.php @@ -1,25 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib; @@ -35,18 +19,12 @@ class DefinitionParameter implements \JsonSerializable { public const VALUE_TEXT = 0; public const VALUE_BOOLEAN = 1; public const VALUE_PASSWORD = 2; - public const VALUE_HIDDEN = 3; /** Flag constants */ public const FLAG_NONE = 0; public const FLAG_OPTIONAL = 1; public const FLAG_USER_PROVIDED = 2; - - /** @var string name of parameter */ - private string $name; - - /** @var string human-readable parameter text */ - private string $text; + public const FLAG_HIDDEN = 4; /** @var string human-readable parameter tooltip */ private string $tooltip = ''; @@ -57,18 +35,16 @@ class DefinitionParameter implements \JsonSerializable { /** @var int flags, see self::FLAG_* constants */ private int $flags = self::FLAG_NONE; - /** @var mixed */ - private $defaultValue; - /** * @param string $name parameter name * @param string $text parameter description * @param mixed $defaultValue default value */ - public function __construct(string $name, string $text, $defaultValue = null) { - $this->name = $name; - $this->text = $text; - $this->defaultValue = $defaultValue; + public function __construct( + private string $name, + private string $text, + private $defaultValue = null, + ) { } /** diff --git a/apps/files_external/lib/Lib/DependencyTrait.php b/apps/files_external/lib/Lib/DependencyTrait.php index 135f5ade296..644132b82bc 100644 --- a/apps/files_external/lib/Lib/DependencyTrait.php +++ b/apps/files_external/lib/Lib/DependencyTrait.php @@ -1,23 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Robin McCorkell <robin@mccorkell.me.uk> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib; diff --git a/apps/files_external/lib/Lib/FrontendDefinitionTrait.php b/apps/files_external/lib/Lib/FrontendDefinitionTrait.php index fd72b2fa7aa..0f280d1d486 100644 --- a/apps/files_external/lib/Lib/FrontendDefinitionTrait.php +++ b/apps/files_external/lib/Lib/FrontendDefinitionTrait.php @@ -1,25 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib; @@ -29,7 +13,7 @@ namespace OCA\Files_External\Lib; trait FrontendDefinitionTrait { /** @var string human-readable mechanism name */ - private string $text = ""; + private string $text = ''; /** @var array<string, DefinitionParameter> parameters for mechanism */ private array $parameters = []; diff --git a/apps/files_external/lib/Lib/IFrontendDefinition.php b/apps/files_external/lib/Lib/IFrontendDefinition.php index 3c625c21c15..c8b06a1c30b 100644 --- a/apps/files_external/lib/Lib/IFrontendDefinition.php +++ b/apps/files_external/lib/Lib/IFrontendDefinition.php @@ -1,21 +1,8 @@ <?php + /** - * @copyright 2022 Carl Schwan <carl@carlschwan.eu> - * - * @license AGPL-3.0-or-later - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Files_External\Lib; diff --git a/apps/files_external/lib/Lib/IIdentifier.php b/apps/files_external/lib/Lib/IIdentifier.php index b410f5333d5..0677409a3cf 100644 --- a/apps/files_external/lib/Lib/IIdentifier.php +++ b/apps/files_external/lib/Lib/IIdentifier.php @@ -1,21 +1,8 @@ <?php + /** - * @copyright 2022 Carl Schwan <carl@carlschwan.eu> - * - * @license AGPL-3.0-or-later - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Files_External\Lib; diff --git a/apps/files_external/lib/Lib/IdentifierTrait.php b/apps/files_external/lib/Lib/IdentifierTrait.php index 52eff147a02..f5ffde32307 100644 --- a/apps/files_external/lib/Lib/IdentifierTrait.php +++ b/apps/files_external/lib/Lib/IdentifierTrait.php @@ -1,24 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib; diff --git a/apps/files_external/lib/Lib/InsufficientDataForMeaningfulAnswerException.php b/apps/files_external/lib/Lib/InsufficientDataForMeaningfulAnswerException.php index 0e5c0be069c..1e872b35072 100644 --- a/apps/files_external/lib/Lib/InsufficientDataForMeaningfulAnswerException.php +++ b/apps/files_external/lib/Lib/InsufficientDataForMeaningfulAnswerException.php @@ -1,26 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib; diff --git a/apps/files_external/lib/Lib/LegacyDependencyCheckPolyfill.php b/apps/files_external/lib/Lib/LegacyDependencyCheckPolyfill.php index 42a72e960ea..f6311fae83e 100644 --- a/apps/files_external/lib/Lib/LegacyDependencyCheckPolyfill.php +++ b/apps/files_external/lib/Lib/LegacyDependencyCheckPolyfill.php @@ -1,23 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Robin McCorkell <robin@mccorkell.me.uk> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib; diff --git a/apps/files_external/lib/Lib/MissingDependency.php b/apps/files_external/lib/Lib/MissingDependency.php index a8e9f9ecc45..c2da7fcadbf 100644 --- a/apps/files_external/lib/Lib/MissingDependency.php +++ b/apps/files_external/lib/Lib/MissingDependency.php @@ -1,23 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Robin McCorkell <robin@mccorkell.me.uk> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib; @@ -26,17 +12,16 @@ namespace OCA\Files_External\Lib; */ class MissingDependency { - /** @var string */ - private $dependency; - /** @var string|null Custom message */ - private $message = null; + private ?string $message = null; + private bool $optional = false; /** * @param string $dependency */ - public function __construct($dependency) { - $this->dependency = $dependency; + public function __construct( + private readonly string $dependency, + ) { } public function getDependency(): string { @@ -55,4 +40,12 @@ class MissingDependency { $this->message = $message; return $this; } + + public function isOptional(): bool { + return $this->optional; + } + + public function setOptional(bool $optional): void { + $this->optional = $optional; + } } diff --git a/apps/files_external/lib/Lib/Notify/SMBNotifyHandler.php b/apps/files_external/lib/Lib/Notify/SMBNotifyHandler.php index 66567b397f2..2812df6ad6a 100644 --- a/apps/files_external/lib/Lib/Notify/SMBNotifyHandler.php +++ b/apps/files_external/lib/Lib/Notify/SMBNotifyHandler.php @@ -1,26 +1,8 @@ <?php + /** - * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl> - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Julius Härtl <jus@bitgrid.net> - * @author Robin Appelman <robin@icewind.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: 2017 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Files_External\Lib\Notify; @@ -31,11 +13,6 @@ use OCP\Files\Notify\INotifyHandler; class SMBNotifyHandler implements INotifyHandler { /** - * @var \Icewind\SMB\INotifyHandler - */ - private $shareNotifyHandler; - - /** * @var string */ private $root; @@ -48,8 +25,10 @@ class SMBNotifyHandler implements INotifyHandler { * @param \Icewind\SMB\INotifyHandler $shareNotifyHandler * @param string $root */ - public function __construct(\Icewind\SMB\INotifyHandler $shareNotifyHandler, $root) { - $this->shareNotifyHandler = $shareNotifyHandler; + public function __construct( + private \Icewind\SMB\INotifyHandler $shareNotifyHandler, + $root, + ) { $this->root = str_replace('\\', '/', $root); } diff --git a/apps/files_external/lib/Lib/PersonalMount.php b/apps/files_external/lib/Lib/PersonalMount.php index b0487494635..d9dbddd1449 100644 --- a/apps/files_external/lib/Lib/PersonalMount.php +++ b/apps/files_external/lib/Lib/PersonalMount.php @@ -1,26 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Julius Härtl <jus@bitgrid.net> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib; @@ -28,40 +11,35 @@ use OC\Files\Mount\MoveableMount; use OCA\Files_External\Config\ExternalMountPoint; use OCA\Files_External\Service\UserStoragesService; use OCP\Files\Storage\IStorage; +use OCP\Files\Storage\IStorageFactory; /** * Person mount points can be moved by the user */ class PersonalMount extends ExternalMountPoint implements MoveableMount { - /** @var UserStoragesService */ - protected $storagesService; - - /** @var int id of the external storage (mount) (not the numeric id of the resulting storage!) */ - protected $numericExternalStorageId; - /** * @param UserStoragesService $storagesService * @param int $storageId * @param IStorage $storage * @param string $mountpoint * @param array $arguments (optional) configuration for the storage backend - * @param \OCP\Files\Storage\IStorageFactory $loader + * @param IStorageFactory $loader * @param array $mountOptions mount specific options + * @param int $externalStorageId */ public function __construct( - UserStoragesService $storagesService, + protected UserStoragesService $storagesService, StorageConfig $storageConfig, - $externalStorageId, + /** @var int id of the external storage (mount) (not the numeric id of the resulting storage!) */ + protected $numericExternalStorageId, $storage, $mountpoint, $arguments = null, $loader = null, $mountOptions = null, - $mountId = null + $mountId = null, ) { parent::__construct($storageConfig, $storage, $mountpoint, $arguments, $loader, $mountOptions, $mountId); - $this->storagesService = $storagesService; - $this->numericExternalStorageId = $externalStorageId; } /** diff --git a/apps/files_external/lib/Lib/PriorityTrait.php b/apps/files_external/lib/Lib/PriorityTrait.php index 299d25c9b40..fad2c07e58c 100644 --- a/apps/files_external/lib/Lib/PriorityTrait.php +++ b/apps/files_external/lib/Lib/PriorityTrait.php @@ -1,24 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib; diff --git a/apps/files_external/lib/Lib/SessionStorageWrapper.php b/apps/files_external/lib/Lib/SessionStorageWrapper.php index 386ab4a73af..8754041b2fa 100644 --- a/apps/files_external/lib/Lib/SessionStorageWrapper.php +++ b/apps/files_external/lib/Lib/SessionStorageWrapper.php @@ -1,24 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib; @@ -29,13 +14,12 @@ use OCP\Constants; * Wrap Storage in PermissionsMask for session ephemeral use */ class SessionStorageWrapper extends PermissionsMask { - /** - * @param array $arguments ['storage' => $storage] + * @param array $parameters ['storage' => $storage] */ - public function __construct($arguments) { + public function __construct(array $parameters) { // disable sharing permission - $arguments['mask'] = Constants::PERMISSION_ALL & ~Constants::PERMISSION_SHARE; - parent::__construct($arguments); + $parameters['mask'] = Constants::PERMISSION_ALL & ~Constants::PERMISSION_SHARE; + parent::__construct($parameters); } } diff --git a/apps/files_external/lib/Lib/Storage/AmazonS3.php b/apps/files_external/lib/Lib/Storage/AmazonS3.php index e5fa98313d5..5dc9e114532 100644 --- a/apps/files_external/lib/Lib/Storage/AmazonS3.php +++ b/apps/files_external/lib/Lib/Storage/AmazonS3.php @@ -1,66 +1,37 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author André Gaul <gaul@web-yard.de> - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * @author Christian Berendt <berendt@b1-systems.de> - * @author Christopher T. Johnson <ctjctj@gmail.com> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Daniel Kesselberg <mail@danielkesselberg.de> - * @author enoch <lanxenet@hotmail.com> - * @author Johan Björk <johanimon@gmail.com> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Julius Härtl <jus@bitgrid.net> - * @author Martin Mattel <martin.mattel@diemattels.at> - * @author Michael Gapczynski <GapczynskiM@gmail.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Philipp Kapfer <philipp.kapfer@gmx.at> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Storage; use Aws\S3\Exception\S3Exception; use Icewind\Streams\CallbackWrapper; +use Icewind\Streams\CountWrapper; use Icewind\Streams\IteratorDirectory; use OC\Files\Cache\CacheEntry; use OC\Files\ObjectStore\S3ConnectionTrait; use OC\Files\ObjectStore\S3ObjectTrait; +use OC\Files\Storage\Common; use OCP\Cache\CappedMemoryCache; use OCP\Constants; use OCP\Files\FileInfo; use OCP\Files\IMimeTypeDetector; use OCP\ICache; use OCP\ICacheFactory; +use OCP\ITempManager; use OCP\Server; use Psr\Log\LoggerInterface; -class AmazonS3 extends \OC\Files\Storage\Common { +class AmazonS3 extends Common { use S3ConnectionTrait; use S3ObjectTrait; private LoggerInterface $logger; - public function needsPartFile() { + public function needsPartFile(): bool { return false; } @@ -77,7 +48,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { private ?bool $versioningEnabled = null; private ICache $memCache; - public function __construct($parameters) { + public function __construct(array $parameters) { parent::__construct($parameters); $this->parseParams($parameters); $this->id = 'amazon::external::' . md5($this->params['hostname'] . ':' . $this->params['bucket'] . ':' . $this->params['key']); @@ -91,11 +62,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { $this->logger = Server::get(LoggerInterface::class); } - /** - * @param string $path - * @return string correctly encoded path - */ - private function normalizePath($path) { + private function normalizePath(string $path): string { $path = trim($path, '/'); if (!$path) { @@ -105,24 +72,24 @@ class AmazonS3 extends \OC\Files\Storage\Common { return $path; } - private function isRoot($path) { + private function isRoot(string $path): bool { return $path === '.'; } - private function cleanKey($path) { + private function cleanKey(string $path): string { if ($this->isRoot($path)) { return '/'; } return $path; } - private function clearCache() { + private function clearCache(): void { $this->objectCache = new CappedMemoryCache(); $this->directoryCache = new CappedMemoryCache(); $this->filesCache = new CappedMemoryCache(); } - private function invalidateCache($key) { + private function invalidateCache(string $key): void { unset($this->objectCache[$key]); $keys = array_keys($this->objectCache->getData()); $keyLength = strlen($key); @@ -142,16 +109,13 @@ class AmazonS3 extends \OC\Files\Storage\Common { unset($this->directoryCache[$key]); } - /** - * @return array|false - */ - private function headObject(string $key) { + private function headObject(string $key): array|false { if (!isset($this->objectCache[$key])) { try { $this->objectCache[$key] = $this->getConnection()->headObject([ 'Bucket' => $this->bucket, 'Key' => $key - ])->toArray(); + ] + $this->getSSECParameters())->toArray(); } catch (S3Exception $e) { if ($e->getStatusCode() >= 500) { throw $e; @@ -160,9 +124,9 @@ class AmazonS3 extends \OC\Files\Storage\Common { } } - if (is_array($this->objectCache[$key]) && !isset($this->objectCache[$key]["Key"])) { + if (is_array($this->objectCache[$key]) && !isset($this->objectCache[$key]['Key'])) { /** @psalm-suppress InvalidArgument Psalm doesn't understand nested arrays well */ - $this->objectCache[$key]["Key"] = $key; + $this->objectCache[$key]['Key'] = $key; } return $this->objectCache[$key]; } @@ -176,11 +140,9 @@ class AmazonS3 extends \OC\Files\Storage\Common { * Implementation from flysystem-aws-s3-v3: * https://github.com/thephpleague/flysystem-aws-s3-v3/blob/8241e9cc5b28f981e0d24cdaf9867f14c7498ae4/src/AwsS3Adapter.php#L670-L694 * - * @param $path - * @return bool * @throws \Exception */ - private function doesDirectoryExist($path) { + private function doesDirectoryExist(string $path): bool { if ($path === '.' || $path === '') { return true; } @@ -222,13 +184,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { return false; } - /** - * Remove a file or folder - * - * @param string $path - * @return bool - */ - protected function remove($path) { + protected function remove(string $path): bool { // remember fileType to reduce http calls $fileType = $this->filetype($path); if ($fileType === 'dir') { @@ -240,7 +196,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { } } - public function mkdir($path) { + public function mkdir(string $path): bool { $path = $this->normalizePath($path); if ($this->is_dir($path)) { @@ -253,7 +209,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { 'Key' => $path . '/', 'Body' => '', 'ContentType' => FileInfo::MIMETYPE_FOLDER - ]); + ] + $this->getSSECParameters()); $this->testTimeout(); } catch (S3Exception $e) { $this->logger->error($e->getMessage(), [ @@ -268,12 +224,12 @@ class AmazonS3 extends \OC\Files\Storage\Common { return true; } - public function file_exists($path) { + public function file_exists(string $path): bool { return $this->filetype($path) !== false; } - public function rmdir($path) { + public function rmdir(string $path): bool { $path = $this->normalizePath($path); if ($this->isRoot($path)) { @@ -288,12 +244,12 @@ class AmazonS3 extends \OC\Files\Storage\Common { return $this->batchDelete($path); } - protected function clearBucket() { + protected function clearBucket(): bool { $this->clearCache(); return $this->batchDelete(); } - private function batchDelete($path = null) { + private function batchDelete(?string $path = null): bool { // TODO explore using https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.S3.BatchDelete.html $params = [ 'Bucket' => $this->bucket @@ -333,7 +289,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { return true; } - public function opendir($path) { + public function opendir(string $path) { try { $content = iterator_to_array($this->getDirectoryContent($path)); return IteratorDirectory::wrap(array_map(function (array $item) { @@ -344,7 +300,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { } } - public function stat($path) { + public function stat(string $path): array|false { $path = $this->normalizePath($path); if ($this->is_dir($path)) { @@ -366,11 +322,8 @@ class AmazonS3 extends \OC\Files\Storage\Common { * * When the information is already present (e.g. opendir has been called before) * this value is return. Otherwise a headObject is emitted. - * - * @param $path - * @return int|mixed */ - private function getContentLength($path) { + private function getContentLength(string $path): int { if (isset($this->filesCache[$path])) { return (int)$this->filesCache[$path]['ContentLength']; } @@ -388,11 +341,8 @@ class AmazonS3 extends \OC\Files\Storage\Common { * * When the information is already present (e.g. opendir has been called before) * this value is return. Otherwise a headObject is emitted. - * - * @param $path - * @return mixed|string */ - private function getLastModified($path) { + private function getLastModified(string $path): string { if (isset($this->filesCache[$path])) { return $this->filesCache[$path]['LastModified']; } @@ -405,7 +355,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { return 'now'; } - public function is_dir($path) { + public function is_dir(string $path): bool { $path = $this->normalizePath($path); if (isset($this->filesCache[$path])) { @@ -423,7 +373,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { } } - public function filetype($path) { + public function filetype(string $path): string|false { $path = $this->normalizePath($path); if ($this->isRoot($path)) { @@ -451,7 +401,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { return false; } - public function getPermissions($path) { + public function getPermissions(string $path): int { $type = $this->filetype($path); if (!$type) { return 0; @@ -459,7 +409,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { return $type === 'dir' ? Constants::PERMISSION_ALL : Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE; } - public function unlink($path) { + public function unlink(string $path): bool { $path = $this->normalizePath($path); if ($this->is_dir($path)) { @@ -480,7 +430,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { return true; } - public function fopen($path, $mode) { + public function fopen(string $path, string $mode) { $path = $this->normalizePath($path); switch ($mode) { @@ -503,10 +453,10 @@ class AmazonS3 extends \OC\Files\Storage\Common { } case 'w': case 'wb': - $tmpFile = \OC::$server->getTempManager()->getTemporaryFile(); + $tmpFile = Server::get(ITempManager::class)->getTemporaryFile(); $handle = fopen($tmpFile, 'w'); - return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) { + return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile): void { $this->writeBack($tmpFile, $path); }); case 'a': @@ -524,21 +474,21 @@ class AmazonS3 extends \OC\Files\Storage\Common { } else { $ext = ''; } - $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext); + $tmpFile = Server::get(ITempManager::class)->getTemporaryFile($ext); if ($this->file_exists($path)) { $source = $this->readObject($path); file_put_contents($tmpFile, $source); } $handle = fopen($tmpFile, $mode); - return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) { + return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile): void { $this->writeBack($tmpFile, $path); }); } return false; } - public function touch($path, $mtime = null) { + public function touch(string $path, ?int $mtime = null): bool { if (is_null($mtime)) { $mtime = time(); } @@ -559,7 +509,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { 'Body' => '', 'ContentType' => $mimeType, 'MetadataDirective' => 'REPLACE', - ]); + ] + $this->getSSECParameters()); $this->testTimeout(); } catch (S3Exception $e) { $this->logger->error($e->getMessage(), [ @@ -573,7 +523,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { return true; } - public function copy($source, $target, $isFile = null) { + public function copy(string $source, string $target, ?bool $isFile = null): bool { $source = $this->normalizePath($source); $target = $this->normalizePath($target); @@ -616,7 +566,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { return true; } - public function rename($source, $target) { + public function rename(string $source, string $target): bool { $source = $this->normalizePath($source); $target = $this->normalizePath($target); @@ -643,18 +593,18 @@ class AmazonS3 extends \OC\Files\Storage\Common { return true; } - public function test() { + public function test(): bool { $this->getConnection()->headBucket([ 'Bucket' => $this->bucket ]); return true; } - public function getId() { + public function getId(): string { return $this->id; } - public function writeBack($tmpFile, $path) { + public function writeBack(string $tmpFile, string $path): bool { try { $source = fopen($tmpFile, 'r'); $this->writeObject($path, $source, $this->mimeDetector->detectPath($path)); @@ -674,11 +624,11 @@ class AmazonS3 extends \OC\Files\Storage\Common { /** * check if curl is installed */ - public static function checkDependencies() { + public static function checkDependencies(): bool { return true; } - public function getDirectoryContent($directory): \Traversable { + public function getDirectoryContent(string $directory): \Traversable { $path = $this->normalizePath($directory); if ($this->isRoot($path)) { @@ -775,7 +725,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { } } - public function hasUpdated($path, $time) { + public function hasUpdated(string $path, int $time): bool { // for files we can get the proper mtime if ($path !== '' && $object = $this->headObject($path)) { $stat = $this->objectToMetaData($object); @@ -787,4 +737,24 @@ class AmazonS3 extends \OC\Files\Storage\Common { return true; } } + + public function writeStream(string $path, $stream, ?int $size = null): int { + if ($size === null) { + $size = 0; + // track the number of bytes read from the input stream to return as the number of written bytes. + $stream = CountWrapper::wrap($stream, function (int $writtenSize) use (&$size): void { + $size = $writtenSize; + }); + } + + if (!is_resource($stream)) { + throw new \InvalidArgumentException('Invalid stream provided'); + } + + $path = $this->normalizePath($path); + $this->writeObject($path, $stream, $this->mimeDetector->detectPath($path)); + $this->invalidateCache($path); + + return $size; + } } diff --git a/apps/files_external/lib/Lib/Storage/FTP.php b/apps/files_external/lib/Lib/Storage/FTP.php index 544ebc2c529..944964de7a6 100644 --- a/apps/files_external/lib/Lib/Storage/FTP.php +++ b/apps/files_external/lib/Lib/Storage/FTP.php @@ -1,23 +1,8 @@ <?php + /** - * @copyright Copyright (c) 2021 Robin Appelman <robin@icewind.nl> - * - * @author Robin Appelman <robin@icewind.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Storage; @@ -28,7 +13,10 @@ use OC\Files\Storage\Common; use OC\Files\Storage\PolyFill\CopyDirectory; use OCP\Constants; use OCP\Files\FileInfo; +use OCP\Files\IMimeTypeDetector; use OCP\Files\StorageNotAvailableException; +use OCP\ITempManager; +use OCP\Server; use Psr\Log\LoggerInterface; class FTP extends Common { @@ -45,23 +33,23 @@ class FTP extends Common { /** @var FtpConnection|null */ private $connection; - public function __construct($params) { - if (isset($params['host']) && isset($params['user']) && isset($params['password'])) { - $this->host = $params['host']; - $this->username = $params['user']; - $this->password = $params['password']; - if (isset($params['secure'])) { - if (is_string($params['secure'])) { - $this->secure = ($params['secure'] === 'true'); + public function __construct(array $parameters) { + if (isset($parameters['host']) && isset($parameters['user']) && isset($parameters['password'])) { + $this->host = $parameters['host']; + $this->username = $parameters['user']; + $this->password = $parameters['password']; + if (isset($parameters['secure'])) { + if (is_string($parameters['secure'])) { + $this->secure = ($parameters['secure'] === 'true'); } else { - $this->secure = (bool)$params['secure']; + $this->secure = (bool)$parameters['secure']; } } else { $this->secure = false; } - $this->root = isset($params['root']) ? '/' . ltrim($params['root']) : '/'; - $this->port = $params['port'] ?? 21; - $this->utf8Mode = isset($params['utf8']) && $params['utf8']; + $this->root = isset($parameters['root']) ? '/' . ltrim($parameters['root']) : '/'; + $this->port = $parameters['port'] ?? 21; + $this->utf8Mode = isset($parameters['utf8']) && $parameters['utf8']; } else { throw new \Exception('Creating ' . self::class . ' storage failed, required parameters not set'); } @@ -82,11 +70,11 @@ class FTP extends Common { $this->password ); } catch (\Exception $e) { - throw new StorageNotAvailableException("Failed to create ftp connection", 0, $e); + throw new StorageNotAvailableException('Failed to create ftp connection', 0, $e); } if ($this->utf8Mode) { if (!$this->connection->setUtf8Mode()) { - throw new StorageNotAvailableException("Could not set UTF-8 mode"); + throw new StorageNotAvailableException('Could not set UTF-8 mode'); } } } @@ -94,15 +82,15 @@ class FTP extends Common { return $this->connection; } - public function getId() { + public function getId(): string { return 'ftp::' . $this->username . '@' . $this->host . '/' . $this->root; } - protected function buildPath($path) { + protected function buildPath(string $path): string { return rtrim($this->root . '/' . $path, '/'); } - public static function checkDependencies() { + public static function checkDependencies(): array|bool { if (function_exists('ftp_login')) { return true; } else { @@ -110,14 +98,14 @@ class FTP extends Common { } } - public function filemtime($path) { + public function filemtime(string $path): int|false { $result = $this->getConnection()->mdtm($this->buildPath($path)); if ($result === -1) { if ($this->is_dir($path)) { $list = $this->getConnection()->mlsd($this->buildPath($path)); if (!$list) { - \OC::$server->get(LoggerInterface::class)->warning("Unable to get last modified date for ftp folder ($path), failed to list folder contents"); + Server::get(LoggerInterface::class)->warning("Unable to get last modified date for ftp folder ($path), failed to list folder contents"); return time(); } $currentDir = current(array_filter($list, function ($item) { @@ -131,7 +119,7 @@ class FTP extends Common { } return $time->getTimestamp(); } else { - \OC::$server->get(LoggerInterface::class)->warning("Unable to get last modified date for ftp folder ($path), folder contents doesn't include current folder"); + Server::get(LoggerInterface::class)->warning("Unable to get last modified date for ftp folder ($path), folder contents doesn't include current folder"); return time(); } } else { @@ -142,7 +130,7 @@ class FTP extends Common { } } - public function filesize($path): false|int|float { + public function filesize(string $path): false|int|float { $result = $this->getConnection()->size($this->buildPath($path)); if ($result === -1) { return false; @@ -151,7 +139,7 @@ class FTP extends Common { } } - public function rmdir($path) { + public function rmdir(string $path): bool { if ($this->is_dir($path)) { $result = $this->getConnection()->rmdir($this->buildPath($path)); // recursive rmdir support depends on the ftp server @@ -167,11 +155,7 @@ class FTP extends Common { } } - /** - * @param string $path - * @return bool - */ - private function recursiveRmDir($path): bool { + private function recursiveRmDir(string $path): bool { $contents = $this->getDirectoryContent($path); $result = true; foreach ($contents as $content) { @@ -186,7 +170,7 @@ class FTP extends Common { return $result; } - public function test() { + public function test(): bool { try { return $this->getConnection()->systype() !== false; } catch (\Exception $e) { @@ -194,7 +178,7 @@ class FTP extends Common { } } - public function stat($path) { + public function stat(string $path): array|false { if (!$this->file_exists($path)) { return false; } @@ -204,14 +188,14 @@ class FTP extends Common { ]; } - public function file_exists($path) { + public function file_exists(string $path): bool { if ($path === '' || $path === '.' || $path === '/') { return true; } return $this->filetype($path) !== false; } - public function unlink($path) { + public function unlink(string $path): bool { switch ($this->filetype($path)) { case 'dir': return $this->rmdir($path); @@ -222,20 +206,20 @@ class FTP extends Common { } } - public function opendir($path) { + public function opendir(string $path) { $files = $this->getConnection()->nlist($this->buildPath($path)); return IteratorDirectory::wrap($files); } - public function mkdir($path) { + public function mkdir(string $path): bool { if ($this->is_dir($path)) { return false; } return $this->getConnection()->mkdir($this->buildPath($path)) !== false; } - public function is_dir($path) { - if ($path === "") { + public function is_dir(string $path): bool { + if ($path === '') { return true; } if ($this->getConnection()->chdir($this->buildPath($path)) === true) { @@ -246,11 +230,11 @@ class FTP extends Common { } } - public function is_file($path) { + public function is_file(string $path): bool { return $this->filesize($path) !== false; } - public function filetype($path) { + public function filetype(string $path): string|false { if ($this->is_dir($path)) { return 'dir'; } elseif ($this->is_file($path)) { @@ -260,7 +244,7 @@ class FTP extends Common { } } - public function fopen($path, $mode) { + public function fopen(string $path, string $mode) { $useExisting = true; switch ($mode) { case 'r': @@ -290,10 +274,10 @@ class FTP extends Common { if (!$this->isCreatable(dirname($path))) { return false; } - $tmpFile = \OC::$server->getTempManager()->getTemporaryFile(); + $tmpFile = Server::get(ITempManager::class)->getTemporaryFile(); } $source = fopen($tmpFile, $mode); - return CallbackWrapper::wrap($source, null, null, function () use ($tmpFile, $path) { + return CallbackWrapper::wrap($source, null, null, function () use ($tmpFile, $path): void { $this->writeStream($path, fopen($tmpFile, 'r')); unlink($tmpFile); }); @@ -303,7 +287,7 @@ class FTP extends Common { public function writeStream(string $path, $stream, ?int $size = null): int { if ($size === null) { - $stream = CountWrapper::wrap($stream, function ($writtenSize) use (&$size) { + $stream = CountWrapper::wrap($stream, function ($writtenSize) use (&$size): void { $size = $writtenSize; }); } @@ -326,7 +310,7 @@ class FTP extends Common { return $stream; } - public function touch($path, $mtime = null) { + public function touch(string $path, ?int $mtime = null): bool { if ($this->file_exists($path)) { return false; } else { @@ -335,14 +319,14 @@ class FTP extends Common { } } - public function rename($source, $target) { + public function rename(string $source, string $target): bool { $this->unlink($target); return $this->getConnection()->rename($this->buildPath($source), $this->buildPath($target)); } - public function getDirectoryContent($directory): \Traversable { + public function getDirectoryContent(string $directory): \Traversable { $files = $this->getConnection()->mlsd($this->buildPath($directory)); - $mimeTypeDetector = \OC::$server->getMimeTypeDetector(); + $mimeTypeDetector = Server::get(IMimeTypeDetector::class); foreach ($files as $file) { $name = $file['name']; diff --git a/apps/files_external/lib/Lib/Storage/FtpConnection.php b/apps/files_external/lib/Lib/Storage/FtpConnection.php index 0b6c1108d1c..a064bf9b100 100644 --- a/apps/files_external/lib/Lib/Storage/FtpConnection.php +++ b/apps/files_external/lib/Lib/Storage/FtpConnection.php @@ -3,23 +3,8 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2020 Robin Appelman <robin@icewind.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: 2020 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Files_External\Lib\Storage; @@ -38,11 +23,11 @@ class FtpConnection { } if ($connection === false) { - throw new \Exception("Failed to connect to ftp"); + throw new \Exception('Failed to connect to ftp'); } if (ftp_login($connection, $username, $password) === false) { - throw new \Exception("Failed to connect to login to ftp"); + throw new \Exception('Failed to connect to login to ftp'); } ftp_pasv($connection, true); @@ -54,7 +39,7 @@ class FtpConnection { } public function setUtf8Mode(): bool { - $response = ftp_raw($this->connection, "OPTS UTF8 ON"); + $response = ftp_raw($this->connection, 'OPTS UTF8 ON'); return substr($response[0], 0, 3) === '200'; } @@ -90,8 +75,8 @@ class FtpConnection { $result = @ftp_mdtm($this->connection, $path); // filezilla doesn't like empty path with mdtm - if ($result === -1 && $path === "") { - $result = @ftp_mdtm($this->connection, "/"); + if ($result === -1 && $path === '') { + $result = @ftp_mdtm($this->connection, '/'); } return $result; } @@ -165,13 +150,13 @@ class FtpConnection { $parsedDate = (new \DateTime()) ->setTimestamp(strtotime("$month $day $time")); - $tomorrow = (new \DateTime())->add(new \DateInterval("P1D")); + $tomorrow = (new \DateTime())->add(new \DateInterval('P1D')); // since the provided date doesn't include the year, we either set it to the correct year // or when the date would otherwise be in the future (by more then 1 day to account for timezone errors) // we use last year if ($parsedDate > $tomorrow) { - $parsedDate = $parsedDate->sub(new \DateInterval("P1Y")); + $parsedDate = $parsedDate->sub(new \DateInterval('P1Y')); } $formattedDate = $parsedDate diff --git a/apps/files_external/lib/Lib/Storage/OwnCloud.php b/apps/files_external/lib/Lib/Storage/OwnCloud.php index ba7ae1c36a9..12c305de750 100644 --- a/apps/files_external/lib/Lib/Storage/OwnCloud.php +++ b/apps/files_external/lib/Lib/Storage/OwnCloud.php @@ -1,33 +1,13 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Joas Schilling <coding@schilljs.com> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Storage; +use OC\Files\Storage\DAV; use OCP\Files\Storage\IDisableEncryptionStorage; use Sabre\DAV\Client; @@ -38,20 +18,20 @@ use Sabre\DAV\Client; * http://%host/%context/remote.php/webdav/%root * */ -class OwnCloud extends \OC\Files\Storage\DAV implements IDisableEncryptionStorage { +class OwnCloud extends DAV implements IDisableEncryptionStorage { public const OC_URL_SUFFIX = 'remote.php/webdav'; - public function __construct($params) { + public function __construct(array $parameters) { // extract context path from host if specified // (owncloud install path on host) - $host = $params['host']; + $host = $parameters['host']; // strip protocol - if (substr($host, 0, 8) === "https://") { + if (substr($host, 0, 8) === 'https://') { $host = substr($host, 8); - $params['secure'] = true; - } elseif (substr($host, 0, 7) === "http://") { + $parameters['secure'] = true; + } elseif (substr($host, 0, 7) === 'http://') { $host = substr($host, 7); - $params['secure'] = false; + $parameters['secure'] = false; } $contextPath = ''; $hostSlashPos = strpos($host, '/'); @@ -64,20 +44,20 @@ class OwnCloud extends \OC\Files\Storage\DAV implements IDisableEncryptionStorag $contextPath .= '/'; } - if (isset($params['root'])) { - $root = '/' . ltrim($params['root'], '/'); + if (isset($parameters['root'])) { + $root = '/' . ltrim($parameters['root'], '/'); } else { $root = '/'; } - $params['host'] = $host; - $params['root'] = $contextPath . self::OC_URL_SUFFIX . $root; - $params['authType'] = Client::AUTH_BASIC; + $parameters['host'] = $host; + $parameters['root'] = $contextPath . self::OC_URL_SUFFIX . $root; + $parameters['authType'] = Client::AUTH_BASIC; - parent::__construct($params); + parent::__construct($parameters); } - public function needsPartFile() { + public function needsPartFile(): bool { return false; } } diff --git a/apps/files_external/lib/Lib/Storage/SFTP.php b/apps/files_external/lib/Lib/Storage/SFTP.php index e6fc5dd3e22..a2f5bafcca1 100644 --- a/apps/files_external/lib/Lib/Storage/SFTP.php +++ b/apps/files_external/lib/Lib/Storage/SFTP.php @@ -1,48 +1,23 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Andreas Fischer <bantu@owncloud.com> - * @author Bart Visscher <bartv@thisnet.nl> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author hkjolhede <hkjolhede@gmail.com> - * @author Joas Schilling <coding@schilljs.com> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Lennart Rosam <lennart.rosam@medien-systempartner.de> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Ross Nicoll <jrn@jrn.me.uk> - * @author SA <stephen@mthosting.net> - * @author Senorsen <senorsen.zhang@gmail.com> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Storage; +use Icewind\Streams\CallbackWrapper; use Icewind\Streams\CountWrapper; use Icewind\Streams\IteratorDirectory; use Icewind\Streams\RetryWrapper; use OC\Files\Storage\Common; +use OC\Files\View; +use OCP\Cache\CappedMemoryCache; use OCP\Constants; use OCP\Files\FileInfo; use OCP\Files\IMimeTypeDetector; +use OCP\Server; use phpseclib\Net\SFTP\Stream; /** @@ -61,6 +36,8 @@ class SFTP extends Common { * @var \phpseclib\Net\SFTP */ protected $client; + private CappedMemoryCache $knownMTimes; + private IMimeTypeDetector $mimeTypeDetector; public const COPY_CHUNK_SIZE = 8 * 1024 * 1024; @@ -69,7 +46,7 @@ class SFTP extends Common { * @param string $host protocol://server:port * @return array [$server, $port] */ - private function splitHost($host) { + private function splitHost(string $host): array { $input = $host; if (!str_contains($host, '://')) { // add a protocol to fix parse_url behavior with ipv6 @@ -86,28 +63,25 @@ class SFTP extends Common { } } - /** - * {@inheritdoc} - */ - public function __construct($params) { + public function __construct(array $parameters) { // Register sftp:// Stream::register(); - $parsedHost = $this->splitHost($params['host']); + $parsedHost = $this->splitHost($parameters['host']); $this->host = $parsedHost[0]; $this->port = $parsedHost[1]; - if (!isset($params['user'])) { + if (!isset($parameters['user'])) { throw new \UnexpectedValueException('no authentication parameters specified'); } - $this->user = $params['user']; + $this->user = $parameters['user']; - if (isset($params['public_key_auth'])) { - $this->auth[] = $params['public_key_auth']; + if (isset($parameters['public_key_auth'])) { + $this->auth[] = $parameters['public_key_auth']; } - if (isset($params['password']) && $params['password'] !== '') { - $this->auth[] = $params['password']; + if (isset($parameters['password']) && $parameters['password'] !== '') { + $this->auth[] = $parameters['password']; } if ($this->auth === []) { @@ -115,11 +89,14 @@ class SFTP extends Common { } $this->root - = isset($params['root']) ? $this->cleanPath($params['root']) : '/'; + = isset($parameters['root']) ? $this->cleanPath($parameters['root']) : '/'; $this->root = '/' . ltrim($this->root, '/'); $this->root = rtrim($this->root, '/') . '/'; - $this->mimeTypeDetector = \OC::$server->get(IMimeTypeDetector::class); + + $this->knownMTimes = new CappedMemoryCache(); + + $this->mimeTypeDetector = Server::get(IMimeTypeDetector::class); } /** @@ -128,7 +105,7 @@ class SFTP extends Common { * @return \phpseclib\Net\SFTP connected client instance * @throws \Exception when the connection failed */ - public function getConnection() { + public function getConnection(): \phpseclib\Net\SFTP { if (!is_null($this->client)) { return $this->client; } @@ -162,10 +139,7 @@ class SFTP extends Common { return $this->client; } - /** - * {@inheritdoc} - */ - public function test() { + public function test(): bool { if ( !isset($this->host) || !isset($this->user) @@ -175,10 +149,7 @@ class SFTP extends Common { return $this->getConnection()->nlist() !== false; } - /** - * {@inheritdoc} - */ - public function getId() { + public function getId(): string { $id = 'sftp::' . $this->user . '@' . $this->host; if ($this->port !== 22) { $id .= ':' . $this->port; @@ -190,56 +161,38 @@ class SFTP extends Common { return $id; } - /** - * @return string - */ - public function getHost() { + public function getHost(): string { return $this->host; } - /** - * @return string - */ - public function getRoot() { + public function getRoot(): string { return $this->root; } - /** - * @return mixed - */ - public function getUser() { + public function getUser(): string { return $this->user; } - /** - * @param string $path - * @return string - */ - private function absPath($path) { + private function absPath(string $path): string { return $this->root . $this->cleanPath($path); } - /** - * @return string|false - */ - private function hostKeysPath() { + private function hostKeysPath(): string|false { try { - $storage_view = \OCP\Files::getStorage('files_external'); - if ($storage_view) { - return \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . - $storage_view->getAbsolutePath('') . - 'ssh_hostKeys'; + $userId = \OC_User::getUser(); + if ($userId === false) { + return false; } + + $view = new View('/' . $userId . '/files_external'); + + return $view->getLocalFile('ssh_hostKeys'); } catch (\Exception $e) { } return false; } - /** - * @param $keys - * @return bool - */ - protected function writeHostKeys($keys) { + protected function writeHostKeys(array $keys): bool { try { $keyPath = $this->hostKeysPath(); if ($keyPath && file_exists($keyPath)) { @@ -255,10 +208,7 @@ class SFTP extends Common { return false; } - /** - * @return array - */ - protected function readHostKeys() { + protected function readHostKeys(): array { try { $keyPath = $this->hostKeysPath(); if (file_exists($keyPath)) { @@ -267,7 +217,7 @@ class SFTP extends Common { $lines = file($keyPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines) { foreach ($lines as $line) { - $hostKeyArray = explode("::", $line, 2); + $hostKeyArray = explode('::', $line, 2); if (count($hostKeyArray) === 2) { $hosts[] = $hostKeyArray[0]; $keys[] = $hostKeyArray[1]; @@ -281,10 +231,7 @@ class SFTP extends Common { return []; } - /** - * {@inheritdoc} - */ - public function mkdir($path) { + public function mkdir(string $path): bool { try { return $this->getConnection()->mkdir($this->absPath($path)); } catch (\Exception $e) { @@ -292,10 +239,7 @@ class SFTP extends Common { } } - /** - * {@inheritdoc} - */ - public function rmdir($path) { + public function rmdir(string $path): bool { try { $result = $this->getConnection()->delete($this->absPath($path), true); // workaround: stray stat cache entry when deleting empty folders @@ -307,10 +251,7 @@ class SFTP extends Common { } } - /** - * {@inheritdoc} - */ - public function opendir($path) { + public function opendir(string $path) { try { $list = $this->getConnection()->nlist($this->absPath($path)); if ($list === false) { @@ -330,20 +271,17 @@ class SFTP extends Common { } } - /** - * {@inheritdoc} - */ - public function filetype($path) { + public function filetype(string $path): string|false { try { $stat = $this->getConnection()->stat($this->absPath($path)); if (!is_array($stat) || !array_key_exists('type', $stat)) { return false; } - if ((int) $stat['type'] === NET_SFTP_TYPE_REGULAR) { + if ((int)$stat['type'] === NET_SFTP_TYPE_REGULAR) { return 'file'; } - if ((int) $stat['type'] === NET_SFTP_TYPE_DIRECTORY) { + if ((int)$stat['type'] === NET_SFTP_TYPE_DIRECTORY) { return 'dir'; } } catch (\Exception $e) { @@ -351,10 +289,7 @@ class SFTP extends Common { return false; } - /** - * {@inheritdoc} - */ - public function file_exists($path) { + public function file_exists(string $path): bool { try { return $this->getConnection()->stat($this->absPath($path)) !== false; } catch (\Exception $e) { @@ -362,10 +297,7 @@ class SFTP extends Common { } } - /** - * {@inheritdoc} - */ - public function unlink($path) { + public function unlink(string $path): bool { try { return $this->getConnection()->delete($this->absPath($path), true); } catch (\Exception $e) { @@ -373,10 +305,8 @@ class SFTP extends Common { } } - /** - * {@inheritdoc} - */ - public function fopen($path, $mode) { + public function fopen(string $path, string $mode) { + $path = $this->cleanPath($path); try { $absPath = $this->absPath($path); $connection = $this->getConnection(); @@ -397,7 +327,13 @@ class SFTP extends Common { // the SFTPWriteStream doesn't go through the "normal" methods so it doesn't clear the stat cache. $connection->_remove_from_stat_cache($absPath); $context = stream_context_create(['sftp' => ['session' => $connection]]); - return fopen('sftpwrite://' . trim($absPath, '/'), 'w', false, $context); + $fh = fopen('sftpwrite://' . trim($absPath, '/'), 'w', false, $context); + if ($fh) { + $fh = CallbackWrapper::wrap($fh, null, null, function () use ($path): void { + $this->knownMTimes->set($path, time()); + }); + } + return $fh; case 'a': case 'ab': case 'r+': @@ -417,38 +353,29 @@ class SFTP extends Common { return false; } - /** - * {@inheritdoc} - */ - public function touch($path, $mtime = null) { + public function touch(string $path, ?int $mtime = null): bool { try { if (!is_null($mtime)) { return false; } if (!$this->file_exists($path)) { - $this->getConnection()->put($this->absPath($path), ''); + return $this->getConnection()->put($this->absPath($path), ''); } else { return false; } } catch (\Exception $e) { return false; } - return true; } /** - * @param string $path - * @param string $target * @throws \Exception */ - public function getFile($path, $target) { + public function getFile(string $path, string $target): void { $this->getConnection()->get($path, $target); } - /** - * {@inheritdoc} - */ - public function rename($source, $target) { + public function rename(string $source, string $target): bool { try { if ($this->file_exists($target)) { $this->unlink($target); @@ -465,24 +392,30 @@ class SFTP extends Common { /** * @return array{mtime: int, size: int, ctime: int}|false */ - public function stat($path) { + public function stat(string $path): array|false { try { + $path = $this->cleanPath($path); $stat = $this->getConnection()->stat($this->absPath($path)); - $mtime = $stat ? (int)$stat['mtime'] : -1; - $size = $stat ? (int)$stat['size'] : 0; + $mtime = isset($stat['mtime']) ? (int)$stat['mtime'] : -1; + $size = isset($stat['size']) ? (int)$stat['size'] : 0; + + // the mtime can't be less than when we last touched it + if ($knownMTime = $this->knownMTimes->get($path)) { + $mtime = max($mtime, $knownMTime); + } - return ['mtime' => $mtime, 'size' => $size, 'ctime' => -1]; + return [ + 'mtime' => $mtime, + 'size' => $size, + 'ctime' => -1 + ]; } catch (\Exception $e) { return false; } } - /** - * @param string $path - * @return string - */ - public function constructUrl($path) { + public function constructUrl(string $path): string { // Do not pass the password here. We want to use the Net_SFTP object // supplied via stream context or fail. We only supply username and // hostname because this might show up in logs (they are not used). @@ -490,7 +423,7 @@ class SFTP extends Common { return $url; } - public function file_put_contents($path, $data) { + public function file_put_contents(string $path, mixed $data): int|float|false { /** @psalm-suppress InternalMethod */ $result = $this->getConnection()->put($this->absPath($path), $data); if ($result) { @@ -502,24 +435,27 @@ class SFTP extends Common { public function writeStream(string $path, $stream, ?int $size = null): int { if ($size === null) { - $stream = CountWrapper::wrap($stream, function (int $writtenSize) use (&$size) { + $stream = CountWrapper::wrap($stream, function (int $writtenSize) use (&$size): void { $size = $writtenSize; }); if (!$stream) { - throw new \Exception("Failed to wrap stream"); + throw new \Exception('Failed to wrap stream'); } } /** @psalm-suppress InternalMethod */ $result = $this->getConnection()->put($this->absPath($path), $stream); fclose($stream); if ($result) { + if ($size === null) { + throw new \Exception('Failed to get written size from sftp storage wrapper'); + } return $size; } else { - throw new \Exception("Failed to write steam to sftp storage"); + throw new \Exception('Failed to write steam to sftp storage'); } } - public function copy($source, $target) { + public function copy(string $source, string $target): bool { if ($this->is_dir($source) || $this->is_dir($target)) { return parent::copy($source, $target); } else { @@ -546,7 +482,7 @@ class SFTP extends Common { } } - public function getPermissions($path) { + public function getPermissions(string $path): int { $stat = $this->getConnection()->stat($this->absPath($path)); if (!$stat) { return 0; @@ -558,7 +494,7 @@ class SFTP extends Common { } } - public function getMetaData($path) { + public function getMetaData(string $path): ?array { $stat = $this->getConnection()->stat($this->absPath($path)); if (!$stat) { return null; diff --git a/apps/files_external/lib/Lib/Storage/SFTPReadStream.php b/apps/files_external/lib/Lib/Storage/SFTPReadStream.php index 7a98c6b2a6d..7dedbd7035a 100644 --- a/apps/files_external/lib/Lib/Storage/SFTPReadStream.php +++ b/apps/files_external/lib/Lib/Storage/SFTPReadStream.php @@ -3,26 +3,8 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2020 Robin Appelman <robin@icewind.nl> - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Robin Appelman <robin@icewind.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: 2020 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Files_External\Lib\Storage; @@ -62,10 +44,9 @@ class SFTPReadStream implements File { /** * Load the source from the stream context and return the context options * - * @param string $name * @throws \BadMethodCallException */ - protected function loadContext($name) { + protected function loadContext(string $name) { $context = stream_context_get_options($this->context); if (isset($context[$name])) { $context = $context[$name]; @@ -164,7 +145,7 @@ class SFTPReadStream implements File { return $data; } - private function request_chunk($size) { + private function request_chunk(int $size) { if ($this->pendingRead) { $this->sftp->_get_sftp_packet(); } diff --git a/apps/files_external/lib/Lib/Storage/SFTPWriteStream.php b/apps/files_external/lib/Lib/Storage/SFTPWriteStream.php index 6682a49d8f6..d64e89b5462 100644 --- a/apps/files_external/lib/Lib/Storage/SFTPWriteStream.php +++ b/apps/files_external/lib/Lib/Storage/SFTPWriteStream.php @@ -3,26 +3,8 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2020 Robin Appelman <robin@icewind.nl> - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Robin Appelman <robin@icewind.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: 2020 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Files_External\Lib\Storage; @@ -60,10 +42,9 @@ class SFTPWriteStream implements File { /** * Load the source from the stream context and return the context options * - * @param string $name * @throws \BadMethodCallException */ - protected function loadContext($name) { + protected function loadContext(string $name) { $context = stream_context_get_options($this->context); if (isset($context[$name])) { $context = $context[$name]; diff --git a/apps/files_external/lib/Lib/Storage/SMB.php b/apps/files_external/lib/Lib/Storage/SMB.php index c7324db01e4..8f8750864e1 100644 --- a/apps/files_external/lib/Lib/Storage/SMB.php +++ b/apps/files_external/lib/Lib/Storage/SMB.php @@ -1,39 +1,11 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Jesús Macias <jmacias@solidgear.es> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Juan Pablo Villafañez <jvillafanez@solidgear.es> - * @author Juan Pablo Villafáñez <jvillafanez@solidgear.es> - * @author Julius Härtl <jus@bitgrid.net> - * @author Michael Gapczynski <GapczynskiM@gmail.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Philipp Kapfer <philipp.kapfer@gmx.at> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Roland Tapken <roland@bitarbeiter.net> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ + namespace OCA\Files_External\Lib\Storage; use Icewind\SMB\ACL; @@ -51,7 +23,7 @@ use Icewind\SMB\IFileInfo; use Icewind\SMB\Native\NativeServer; use Icewind\SMB\Options; use Icewind\SMB\ServerFactory; -use Icewind\SMB\System; +use Icewind\SMB\Wrapped\Server; use Icewind\Streams\CallbackWrapper; use Icewind\Streams\IteratorDirectory; use OC\Files\Filesystem; @@ -60,12 +32,14 @@ use OCA\Files_External\Lib\Notify\SMBNotifyHandler; use OCP\Cache\CappedMemoryCache; use OCP\Constants; use OCP\Files\EntityTooLargeException; +use OCP\Files\IMimeTypeDetector; use OCP\Files\Notify\IChange; use OCP\Files\Notify\IRenameChange; use OCP\Files\NotPermittedException; use OCP\Files\Storage\INotifyStorage; use OCP\Files\StorageAuthException; use OCP\Files\StorageNotAvailableException; +use OCP\ITempManager; use Psr\Log\LoggerInterface; class SMB extends Common implements INotifyStorage { @@ -98,57 +72,58 @@ class SMB extends Common implements INotifyStorage { /** @var bool */ protected $checkAcl; - public function __construct($params) { - if (!isset($params['host'])) { + public function __construct(array $parameters) { + if (!isset($parameters['host'])) { throw new \Exception('Invalid configuration, no host provided'); } - if (isset($params['auth'])) { - $auth = $params['auth']; - } elseif (isset($params['user']) && isset($params['password']) && isset($params['share'])) { - [$workgroup, $user] = $this->splitUser($params['user']); - $auth = new BasicAuth($user, $workgroup, $params['password']); + if (isset($parameters['auth'])) { + $auth = $parameters['auth']; + } elseif (isset($parameters['user']) && isset($parameters['password']) && isset($parameters['share'])) { + [$workgroup, $user] = $this->splitUser($parameters['user']); + $auth = new BasicAuth($user, $workgroup, $parameters['password']); } else { throw new \Exception('Invalid configuration, no credentials provided'); } - if (isset($params['logger'])) { - if (!$params['logger'] instanceof LoggerInterface) { + if (isset($parameters['logger'])) { + if (!$parameters['logger'] instanceof LoggerInterface) { throw new \Exception( 'Invalid logger. Got ' - . get_class($params['logger']) + . get_class($parameters['logger']) . ' Expected ' . LoggerInterface::class ); } - $this->logger = $params['logger']; + $this->logger = $parameters['logger']; } else { - $this->logger = \OC::$server->get(LoggerInterface::class); + $this->logger = \OCP\Server::get(LoggerInterface::class); } $options = new Options(); - if (isset($params['timeout'])) { - $timeout = (int)$params['timeout']; + if (isset($parameters['timeout'])) { + $timeout = (int)$parameters['timeout']; if ($timeout > 0) { $options->setTimeout($timeout); } } - $serverFactory = new ServerFactory($options); - $this->server = $serverFactory->createServer($params['host'], $auth); - $this->share = $this->server->getShare(trim($params['share'], '/')); + $system = \OCP\Server::get(SystemBridge::class); + $serverFactory = new ServerFactory($options, $system); + $this->server = $serverFactory->createServer($parameters['host'], $auth); + $this->share = $this->server->getShare(trim($parameters['share'], '/')); - $this->root = $params['root'] ?? '/'; + $this->root = $parameters['root'] ?? '/'; $this->root = '/' . ltrim($this->root, '/'); $this->root = rtrim($this->root, '/') . '/'; - $this->showHidden = isset($params['show_hidden']) && $params['show_hidden']; - $this->caseSensitive = (bool) ($params['case_sensitive'] ?? true); - $this->checkAcl = isset($params['check_acl']) && $params['check_acl']; + $this->showHidden = isset($parameters['show_hidden']) && $parameters['show_hidden']; + $this->caseSensitive = (bool)($parameters['case_sensitive'] ?? true); + $this->checkAcl = isset($parameters['check_acl']) && $parameters['check_acl']; $this->statCache = new CappedMemoryCache(); - parent::__construct($params); + parent::__construct($parameters); } - private function splitUser($user) { + private function splitUser(string $user): array { if (str_contains($user, '/')) { return explode('/', $user, 2); } elseif (str_contains($user, '\\')) { @@ -158,25 +133,18 @@ class SMB extends Common implements INotifyStorage { return [null, $user]; } - /** - * @return string - */ - public function getId() { + public function getId(): string { // FIXME: double slash to keep compatible with the old storage ids, // failure to do so will lead to creation of a new storage id and // loss of shares from the storage return 'smb::' . $this->server->getAuth()->getUsername() . '@' . $this->server->getHost() . '//' . $this->share->getName() . '/' . $this->root; } - /** - * @param string $path - * @return string - */ - protected function buildPath($path) { + protected function buildPath(string $path): string { return Filesystem::normalizePath($this->root . '/' . $path, true, false, true); } - protected function relativePath($fullPath) { + protected function relativePath(string $fullPath): ?string { if ($fullPath === $this->root) { return ''; } elseif (substr($fullPath, 0, strlen($this->root)) === $this->root) { @@ -187,11 +155,11 @@ class SMB extends Common implements INotifyStorage { } /** - * @param string $path - * @return IFileInfo * @throws StorageAuthException + * @throws \OCP\Files\NotFoundException + * @throws \OCP\Files\ForbiddenException */ - protected function getFileInfo($path) { + protected function getFileInfo(string $path): IFileInfo { try { $path = $this->buildPath($path); $cached = $this->statCache[$path] ?? null; @@ -217,23 +185,23 @@ class SMB extends Common implements INotifyStorage { } /** - * @param \Exception $e - * @return never * @throws StorageAuthException */ - protected function throwUnavailable(\Exception $e) { + protected function throwUnavailable(\Exception $e): never { $this->logger->error('Error while getting file info', ['exception' => $e]); throw new StorageAuthException($e->getMessage(), $e); } /** * get the acl from fileinfo that is relevant for the configured user - * - * @param IFileInfo $file - * @return ACL|null */ private function getACL(IFileInfo $file): ?ACL { - $acls = $file->getAcls(); + try { + $acls = $file->getAcls(); + } catch (Exception $e) { + $this->logger->warning('Error while getting file acls', ['exception' => $e]); + return null; + } foreach ($acls as $user => $acl) { [, $user] = $this->splitUser($user); // strip domain if ($user === $this->server->getAuth()->getUsername()) { @@ -245,11 +213,10 @@ class SMB extends Common implements INotifyStorage { } /** - * @param string $path * @return \Generator<IFileInfo> * @throws StorageNotAvailableException */ - protected function getFolderContents($path): iterable { + protected function getFolderContents(string $path): iterable { try { $path = ltrim($this->buildPath($path), '/'); try { @@ -300,11 +267,7 @@ class SMB extends Common implements INotifyStorage { } } - /** - * @param IFileInfo $info - * @return array - */ - protected function formatInfo($info) { + protected function formatInfo(IFileInfo $info): array { $result = [ 'size' => $info->getSize(), 'mtime' => $info->getMTime(), @@ -322,9 +285,8 @@ class SMB extends Common implements INotifyStorage { * * @param string $source the old name of the path * @param string $target the new name of the path - * @return bool true if the rename is successful, false otherwise */ - public function rename($source, $target, $retry = true): bool { + public function rename(string $source, string $target, bool $retry = true): bool { if ($this->isRootDir($source) || $this->isRootDir($target)) { return false; } @@ -363,10 +325,10 @@ class SMB extends Common implements INotifyStorage { return $result; } - public function stat($path, $retry = true) { + public function stat(string $path, bool $retry = true): array|false { try { $result = $this->formatInfo($this->getFileInfo($path)); - } catch (ForbiddenException $e) { + } catch (\OCP\Files\ForbiddenException $e) { return false; } catch (\OCP\Files\NotFoundException $e) { return false; @@ -374,7 +336,7 @@ class SMB extends Common implements INotifyStorage { if ($retry) { return $this->stat($path, false); } else { - throw $e; + throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e); } } if ($this->remoteIsShare() && $this->isRootDir($path)) { @@ -385,10 +347,8 @@ class SMB extends Common implements INotifyStorage { /** * get the best guess for the modification time of the share - * - * @return int */ - private function shareMTime() { + private function shareMTime(): int { $highestMTime = 0; $files = $this->share->dir($this->root); foreach ($files as $fileInfo) { @@ -407,28 +367,19 @@ class SMB extends Common implements INotifyStorage { /** * Check if the path is our root dir (not the smb one) - * - * @param string $path the path - * @return bool */ - private function isRootDir($path) { + private function isRootDir(string $path): bool { return $path === '' || $path === '/' || $path === '.'; } /** * Check if our root points to a smb share - * - * @return bool true if our root points to a share false otherwise */ - private function remoteIsShare() { + private function remoteIsShare(): bool { return $this->share->getName() && (!$this->root || $this->root === '/'); } - /** - * @param string $path - * @return bool - */ - public function unlink($path) { + public function unlink(string $path): bool { if ($this->isRootDir($path)) { return false; } @@ -454,41 +405,36 @@ class SMB extends Common implements INotifyStorage { /** * check if a file or folder has been updated since $time - * - * @param string $path - * @param int $time - * @return bool */ - public function hasUpdated($path, $time) { + public function hasUpdated(string $path, int $time): bool { if (!$path and $this->root === '/') { // mtime doesn't work for shares, but giving the nature of the backend, // doing a full update is still just fast enough return true; } else { $actualTime = $this->filemtime($path); - return $actualTime > $time; + return $actualTime > $time || $actualTime === 0; } } /** - * @param string $path - * @param string $mode - * @return resource|bool + * @return resource|false */ - public function fopen($path, $mode) { + public function fopen(string $path, string $mode) { $fullPath = $this->buildPath($path); try { switch ($mode) { case 'r': case 'rb': if (!$this->file_exists($path)) { + $this->logger->warning('Failed to open ' . $path . ' on ' . $this->getId() . ', file doesn\'t exist.'); return false; } return $this->share->read($fullPath); case 'w': case 'wb': $source = $this->share->write($fullPath); - return CallBackWrapper::wrap($source, null, null, function () use ($fullPath) { + return CallBackWrapper::wrap($source, null, null, function () use ($fullPath): void { unset($this->statCache[$fullPath]); }); case 'a': @@ -509,18 +455,20 @@ class SMB extends Common implements INotifyStorage { } if ($this->file_exists($path)) { if (!$this->isUpdatable($path)) { + $this->logger->warning('Failed to open ' . $path . ' on ' . $this->getId() . ', file not updatable.'); return false; } $tmpFile = $this->getCachedFile($path); } else { if (!$this->isCreatable(dirname($path))) { + $this->logger->warning('Failed to open ' . $path . ' on ' . $this->getId() . ', parent directory not writable.'); return false; } - $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext); + $tmpFile = \OCP\Server::get(ITempManager::class)->getTemporaryFile($ext); } $source = fopen($tmpFile, $mode); $share = $this->share; - return CallbackWrapper::wrap($source, null, null, function () use ($tmpFile, $fullPath, $share) { + return CallbackWrapper::wrap($source, null, null, function () use ($tmpFile, $fullPath, $share): void { unset($this->statCache[$fullPath]); $share->put($tmpFile, $fullPath); unlink($tmpFile); @@ -528,18 +476,21 @@ class SMB extends Common implements INotifyStorage { } return false; } catch (NotFoundException $e) { + $this->logger->warning('Failed to open ' . $path . ' on ' . $this->getId() . ', not found.', ['exception' => $e]); return false; } catch (ForbiddenException $e) { + $this->logger->warning('Failed to open ' . $path . ' on ' . $this->getId() . ', forbidden.', ['exception' => $e]); return false; } catch (OutOfSpaceException $e) { - throw new EntityTooLargeException("not enough available space to create file", 0, $e); + $this->logger->warning('Failed to open ' . $path . ' on ' . $this->getId() . ', out of space.', ['exception' => $e]); + throw new EntityTooLargeException('not enough available space to create file', 0, $e); } catch (ConnectException $e) { - $this->logger->error('Error while opening file', ['exception' => $e]); + $this->logger->error('Error while opening file ' . $path . ' on ' . $this->getId(), ['exception' => $e]); throw new StorageNotAvailableException($e->getMessage(), (int)$e->getCode(), $e); } } - public function rmdir($path) { + public function rmdir(string $path): bool { if ($this->isRootDir($path)) { return false; } @@ -566,7 +517,7 @@ class SMB extends Common implements INotifyStorage { } } - public function touch($path, $mtime = null) { + public function touch(string $path, ?int $mtime = null): bool { try { if (!$this->file_exists($path)) { $fh = $this->share->write($this->buildPath($path)); @@ -575,29 +526,26 @@ class SMB extends Common implements INotifyStorage { } return false; } catch (OutOfSpaceException $e) { - throw new EntityTooLargeException("not enough available space to create file", 0, $e); + throw new EntityTooLargeException('not enough available space to create file', 0, $e); } catch (ConnectException $e) { $this->logger->error('Error while creating file', ['exception' => $e]); throw new StorageNotAvailableException($e->getMessage(), (int)$e->getCode(), $e); } } - public function getMetaData($path) { + public function getMetaData(string $path): ?array { try { $fileInfo = $this->getFileInfo($path); } catch (\OCP\Files\NotFoundException $e) { return null; - } catch (ForbiddenException $e) { - return null; - } - if (!$fileInfo) { + } catch (\OCP\Files\ForbiddenException $e) { return null; } return $this->getMetaDataFromFileInfo($fileInfo); } - private function getMetaDataFromFileInfo(IFileInfo $fileInfo) { + private function getMetaDataFromFileInfo(IFileInfo $fileInfo): array { $permissions = Constants::PERMISSION_READ + Constants::PERMISSION_SHARE; if ( @@ -614,7 +562,7 @@ class SMB extends Common implements INotifyStorage { if ($fileInfo->isDirectory()) { $data['mimetype'] = 'httpd/unix-directory'; } else { - $data['mimetype'] = \OC::$server->getMimeTypeDetector()->detectPath($fileInfo->getPath()); + $data['mimetype'] = \OCP\Server::get(IMimeTypeDetector::class)->detectPath($fileInfo->getPath()); } $data['mtime'] = $fileInfo->getMTime(); if ($fileInfo->isDirectory()) { @@ -630,7 +578,7 @@ class SMB extends Common implements INotifyStorage { return $data; } - public function opendir($path) { + public function opendir(string $path) { try { $files = $this->getFolderContents($path); } catch (NotFoundException $e) { @@ -645,7 +593,7 @@ class SMB extends Common implements INotifyStorage { return IteratorDirectory::wrap($names); } - public function getDirectoryContent($directory): \Traversable { + public function getDirectoryContent(string $directory): \Traversable { try { $files = $this->getFolderContents($directory); foreach ($files as $file) { @@ -658,17 +606,17 @@ class SMB extends Common implements INotifyStorage { } } - public function filetype($path) { + public function filetype(string $path): string|false { try { return $this->getFileInfo($path)->isDirectory() ? 'dir' : 'file'; } catch (\OCP\Files\NotFoundException $e) { return false; - } catch (ForbiddenException $e) { + } catch (\OCP\Files\ForbiddenException $e) { return false; } } - public function mkdir($path) { + public function mkdir(string $path): bool { $path = $this->buildPath($path); try { $this->share->mkdir($path); @@ -681,12 +629,12 @@ class SMB extends Common implements INotifyStorage { } } - public function file_exists($path) { + public function file_exists(string $path): bool { try { // Case sensitive filesystem doesn't matter for root directory if ($this->caseSensitive === false && $path !== '') { $filename = basename($path); - $siblings = $this->getDirectoryContent(dirname($this->buildPath($path))); + $siblings = $this->getDirectoryContent(dirname($path)); foreach ($siblings as $sibling) { if ($sibling['name'] === $filename) { return true; @@ -698,25 +646,25 @@ class SMB extends Common implements INotifyStorage { return true; } catch (\OCP\Files\NotFoundException $e) { return false; - } catch (ForbiddenException $e) { + } catch (\OCP\Files\ForbiddenException $e) { return false; } catch (ConnectException $e) { throw new StorageNotAvailableException($e->getMessage(), (int)$e->getCode(), $e); } } - public function isReadable($path) { + public function isReadable(string $path): bool { try { $info = $this->getFileInfo($path); return $this->showHidden || !$info->isHidden(); } catch (\OCP\Files\NotFoundException $e) { return false; - } catch (ForbiddenException $e) { + } catch (\OCP\Files\ForbiddenException $e) { return false; } } - public function isUpdatable($path) { + public function isUpdatable(string $path): bool { try { $info = $this->getFileInfo($path); // following windows behaviour for read-only folders: they can be written into @@ -724,18 +672,18 @@ class SMB extends Common implements INotifyStorage { return ($this->showHidden || !$info->isHidden()) && (!$info->isReadOnly() || $info->isDirectory()); } catch (\OCP\Files\NotFoundException $e) { return false; - } catch (ForbiddenException $e) { + } catch (\OCP\Files\ForbiddenException $e) { return false; } } - public function isDeletable($path) { + public function isDeletable(string $path): bool { try { $info = $this->getFileInfo($path); return ($this->showHidden || !$info->isHidden()) && !$info->isReadOnly(); } catch (\OCP\Files\NotFoundException $e) { return false; - } catch (ForbiddenException $e) { + } catch (\OCP\Files\ForbiddenException $e) { return false; } } @@ -743,19 +691,12 @@ class SMB extends Common implements INotifyStorage { /** * check if smbclient is installed */ - public static function checkDependencies() { - return ( - (bool)\OC_Helper::findBinaryPath('smbclient') - || NativeServer::available(new System()) - ) ? true : ['smbclient']; + public static function checkDependencies(): array|bool { + $system = \OCP\Server::get(SystemBridge::class); + return Server::available($system) || NativeServer::available($system) ?: ['smbclient']; } - /** - * Test a storage for availability - * - * @return bool - */ - public function test() { + public function test(): bool { try { return parent::test(); } catch (StorageAuthException $e) { @@ -768,7 +709,7 @@ class SMB extends Common implements INotifyStorage { } } - public function listen($path, callable $callback) { + public function listen(string $path, callable $callback): void { $this->notify($path)->listen(function (IChange $change) use ($callback) { if ($change instanceof IRenameChange) { return $callback($change->getType(), $change->getPath(), $change->getTargetPath()); @@ -778,7 +719,7 @@ class SMB extends Common implements INotifyStorage { }); } - public function notify($path) { + public function notify(string $path): SMBNotifyHandler { $path = '/' . ltrim($path, '/'); $shareNotifyHandler = $this->share->notify($this->buildPath($path)); return new SMBNotifyHandler($shareNotifyHandler, $this->root); diff --git a/apps/files_external/lib/Lib/Storage/StreamWrapper.php b/apps/files_external/lib/Lib/Storage/StreamWrapper.php index 79387e14cf6..1272b9d4d8a 100644 --- a/apps/files_external/lib/Lib/Storage/StreamWrapper.php +++ b/apps/files_external/lib/Lib/Storage/StreamWrapper.php @@ -1,44 +1,23 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Bart Visscher <bartv@thisnet.nl> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2020-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Storage; -abstract class StreamWrapper extends \OC\Files\Storage\Common { +use OC\Files\Storage\Common; + +abstract class StreamWrapper extends Common { - /** - * @param string $path - * @return string|null - */ - abstract public function constructUrl($path); + abstract public function constructUrl(string $path): ?string; - public function mkdir($path) { + public function mkdir(string $path): bool { return mkdir($this->constructUrl($path)); } - public function rmdir($path) { + public function rmdir(string $path): bool { if ($this->is_dir($path) && $this->isDeletable($path)) { $dh = $this->opendir($path); if (!is_resource($dh)) { @@ -60,19 +39,19 @@ abstract class StreamWrapper extends \OC\Files\Storage\Common { } } - public function opendir($path) { + public function opendir(string $path) { return opendir($this->constructUrl($path)); } - public function filetype($path) { + public function filetype(string $path): string|false { return @filetype($this->constructUrl($path)); } - public function file_exists($path) { + public function file_exists(string $path): bool { return file_exists($this->constructUrl($path)); } - public function unlink($path) { + public function unlink(string $path): bool { $url = $this->constructUrl($path); $success = unlink($url); // normally unlink() is supposed to do this implicitly, @@ -81,11 +60,11 @@ abstract class StreamWrapper extends \OC\Files\Storage\Common { return $success; } - public function fopen($path, $mode) { + public function fopen(string $path, string $mode) { return fopen($this->constructUrl($path), $mode); } - public function touch($path, $mtime = null) { + public function touch(string $path, ?int $mtime = null): bool { if ($this->file_exists($path)) { if (is_null($mtime)) { $fh = $this->fopen($path, 'a'); @@ -102,26 +81,19 @@ abstract class StreamWrapper extends \OC\Files\Storage\Common { } } - /** - * @param string $path - * @param string $target - */ - public function getFile($path, $target) { + public function getFile(string $path, string $target): bool { return copy($this->constructUrl($path), $target); } - /** - * @param string $target - */ - public function uploadFile($path, $target) { + public function uploadFile(string $path, string $target): bool { return copy($path, $this->constructUrl($target)); } - public function rename($source, $target) { + public function rename(string $source, string $target): bool { return rename($this->constructUrl($source), $this->constructUrl($target)); } - public function stat($path) { + public function stat(string $path): array|false { return stat($this->constructUrl($path)); } } diff --git a/apps/files_external/lib/Lib/Storage/Swift.php b/apps/files_external/lib/Lib/Storage/Swift.php index 7283e5ae7b1..e80570f14ba 100644 --- a/apps/files_external/lib/Lib/Storage/Swift.php +++ b/apps/files_external/lib/Lib/Storage/Swift.php @@ -3,60 +3,37 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * @author Bart Visscher <bartv@thisnet.nl> - * @author Benjamin Liles <benliles@arch.tamu.edu> - * @author Christian Berendt <berendt@b1-systems.de> - * @author Christopher Bartz <bartz@dkrz.de> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Felix Moeller <mail@felixmoeller.de> - * @author Joas Schilling <coding@schilljs.com> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Martin Mattel <martin.mattel@diemattels.at> - * @author Michael Zamot <michael@zamot.io> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Philipp Kapfer <philipp.kapfer@gmx.at> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Tim Dettrick <t.dettrick@uq.edu.au> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib\Storage; use GuzzleHttp\Psr7\Uri; use Icewind\Streams\CallbackWrapper; use Icewind\Streams\IteratorDirectory; +use OC\Files\Filesystem; use OC\Files\ObjectStore\SwiftFactory; +use OC\Files\Storage\Common; +use OCP\Cache\CappedMemoryCache; use OCP\Files\IMimeTypeDetector; +use OCP\Files\StorageAuthException; use OCP\Files\StorageBadConfigException; +use OCP\Files\StorageNotAvailableException; +use OCP\ICache; +use OCP\ICacheFactory; +use OCP\ITempManager; +use OCP\Server; use OpenStack\Common\Error\BadResponseError; +use OpenStack\ObjectStore\v1\Models\Container; use OpenStack\ObjectStore\v1\Models\StorageObject; use Psr\Log\LoggerInterface; -class Swift extends \OC\Files\Storage\Common { +class Swift extends Common { /** @var SwiftFactory */ private $connectionFactory; /** - * @var \OpenStack\ObjectStore\v1\Models\Container + * @var Container */ private $container; /** @@ -84,15 +61,11 @@ class Swift extends \OC\Files\Storage\Common { * \OpenCloud\OpenStack\ObjectStorage\Resource\DataObject for existing * paths and path to false for not existing paths. * - * @var \OCP\ICache + * @var ICache */ private $objectCache; - /** - * @param string $path - * @return mixed|string - */ - private function normalizePath(string $path) { + private function normalizePath(string $path): string { $path = trim($path, '/'); if (!$path) { @@ -107,25 +80,17 @@ class Swift extends \OC\Files\Storage\Common { public const SUBCONTAINER_FILE = '.subcontainers'; /** - * translate directory path to container name - * - * @param string $path - * @return string - */ - - /** * Fetches an object from the API. * If the object is cached already or a * failed "doesn't exist" response was cached, * that one will be returned. * - * @param string $path - * @return StorageObject|bool object - * or false if the object did not exist - * @throws \OCP\Files\StorageAuthException - * @throws \OCP\Files\StorageNotAvailableException + * @return StorageObject|false object + * or false if the object did not exist + * @throws StorageAuthException + * @throws StorageNotAvailableException */ - private function fetchObject(string $path) { + private function fetchObject(string $path): StorageObject|false { $cached = $this->objectCache->get($path); if ($cached !== null) { // might be "false" if object did not exist from last check @@ -139,7 +104,7 @@ class Swift extends \OC\Files\Storage\Common { } catch (BadResponseError $e) { // Expected response is "404 Not Found", so only log if it isn't if ($e->getResponse()->getStatusCode() !== 404) { - \OC::$server->get(LoggerInterface::class)->error($e->getMessage(), [ + Server::get(LoggerInterface::class)->error($e->getMessage(), [ 'exception' => $e, 'app' => 'files_external', ]); @@ -152,67 +117,65 @@ class Swift extends \OC\Files\Storage\Common { /** * Returns whether the given path exists. * - * @param string $path - * * @return bool true if the object exist, false otherwise - * @throws \OCP\Files\StorageAuthException - * @throws \OCP\Files\StorageNotAvailableException + * @throws StorageAuthException + * @throws StorageNotAvailableException */ - private function doesObjectExist($path) { + private function doesObjectExist(string $path): bool { return $this->fetchObject($path) !== false; } - public function __construct($params) { - if ((empty($params['key']) and empty($params['password'])) - or (empty($params['user']) && empty($params['userid'])) or empty($params['bucket']) - or empty($params['region']) + public function __construct(array $parameters) { + if ((empty($parameters['key']) and empty($parameters['password'])) + or (empty($parameters['user']) && empty($parameters['userid'])) or empty($parameters['bucket']) + or empty($parameters['region']) ) { - throw new StorageBadConfigException("API Key or password, Login, Bucket and Region have to be configured."); + throw new StorageBadConfigException('API Key or password, Login, Bucket and Region have to be configured.'); } - $user = $params['user']; - $this->id = 'swift::' . $user . md5($params['bucket']); + $user = $parameters['user']; + $this->id = 'swift::' . $user . md5($parameters['bucket']); - $bucketUrl = new Uri($params['bucket']); + $bucketUrl = new Uri($parameters['bucket']); if ($bucketUrl->getHost()) { - $params['bucket'] = basename($bucketUrl->getPath()); - $params['endpoint_url'] = (string)$bucketUrl->withPath(dirname($bucketUrl->getPath())); + $parameters['bucket'] = basename($bucketUrl->getPath()); + $parameters['endpoint_url'] = (string)$bucketUrl->withPath(dirname($bucketUrl->getPath())); } - if (empty($params['url'])) { - $params['url'] = 'https://identity.api.rackspacecloud.com/v2.0/'; + if (empty($parameters['url'])) { + $parameters['url'] = 'https://identity.api.rackspacecloud.com/v2.0/'; } - if (empty($params['service_name'])) { - $params['service_name'] = 'cloudFiles'; + if (empty($parameters['service_name'])) { + $parameters['service_name'] = 'cloudFiles'; } - $params['autocreate'] = true; + $parameters['autocreate'] = true; - if (isset($params['domain'])) { - $params['user'] = [ - 'name' => $params['user'], - 'password' => $params['password'], + if (isset($parameters['domain'])) { + $parameters['user'] = [ + 'name' => $parameters['user'], + 'password' => $parameters['password'], 'domain' => [ - 'name' => $params['domain'], + 'name' => $parameters['domain'], ] ]; } - $this->params = $params; + $this->params = $parameters; // FIXME: private class... - $this->objectCache = new \OCP\Cache\CappedMemoryCache(); + $this->objectCache = new CappedMemoryCache(); $this->connectionFactory = new SwiftFactory( - \OC::$server->getMemCacheFactory()->createDistributed('swift/'), + Server::get(ICacheFactory::class)->createDistributed('swift/'), $this->params, - \OC::$server->get(LoggerInterface::class) + Server::get(LoggerInterface::class) ); $this->objectStore = new \OC\Files\ObjectStore\Swift($this->params, $this->connectionFactory); - $this->bucket = $params['bucket']; - $this->mimeDetector = \OC::$server->get(IMimeTypeDetector::class); + $this->bucket = $parameters['bucket']; + $this->mimeDetector = Server::get(IMimeTypeDetector::class); } - public function mkdir($path) { + public function mkdir(string $path): bool { $path = $this->normalizePath($path); if ($this->is_dir($path)) { @@ -233,7 +196,7 @@ class Swift extends \OC\Files\Storage\Common { // with all properties $this->objectCache->remove($path); } catch (BadResponseError $e) { - \OC::$server->get(LoggerInterface::class)->error($e->getMessage(), [ + Server::get(LoggerInterface::class)->error($e->getMessage(), [ 'exception' => $e, 'app' => 'files_external', ]); @@ -243,7 +206,7 @@ class Swift extends \OC\Files\Storage\Common { return true; } - public function file_exists($path) { + public function file_exists(string $path): bool { $path = $this->normalizePath($path); if ($path !== '.' && $this->is_dir($path)) { @@ -253,7 +216,7 @@ class Swift extends \OC\Files\Storage\Common { return $this->doesObjectExist($path); } - public function rmdir($path) { + public function rmdir(string $path): bool { $path = $this->normalizePath($path); if (!$this->is_dir($path) || !$this->isDeletable($path)) { @@ -261,8 +224,8 @@ class Swift extends \OC\Files\Storage\Common { } $dh = $this->opendir($path); - while ($file = readdir($dh)) { - if (\OC\Files\Filesystem::isIgnoredDir($file)) { + while (($file = readdir($dh)) !== false) { + if (Filesystem::isIgnoredDir($file)) { continue; } @@ -277,7 +240,7 @@ class Swift extends \OC\Files\Storage\Common { $this->objectStore->deleteObject($path . '/'); $this->objectCache->remove($path . '/'); } catch (BadResponseError $e) { - \OC::$server->get(LoggerInterface::class)->error($e->getMessage(), [ + Server::get(LoggerInterface::class)->error($e->getMessage(), [ 'exception' => $e, 'app' => 'files_external', ]); @@ -287,7 +250,7 @@ class Swift extends \OC\Files\Storage\Common { return true; } - public function opendir($path) { + public function opendir(string $path) { $path = $this->normalizePath($path); if ($path === '.') { @@ -315,7 +278,7 @@ class Swift extends \OC\Files\Storage\Common { return IteratorDirectory::wrap($files); } catch (\Exception $e) { - \OC::$server->get(LoggerInterface::class)->error($e->getMessage(), [ + Server::get(LoggerInterface::class)->error($e->getMessage(), [ 'exception' => $e, 'app' => 'files_external', ]); @@ -323,9 +286,8 @@ class Swift extends \OC\Files\Storage\Common { } } - public function stat($path) { + public function stat(string $path): array|false { $path = $this->normalizePath($path); - if ($path === '.') { $path = ''; } elseif ($this->is_dir($path)) { @@ -338,32 +300,33 @@ class Swift extends \OC\Files\Storage\Common { return false; } } catch (BadResponseError $e) { - \OC::$server->get(LoggerInterface::class)->error($e->getMessage(), [ + Server::get(LoggerInterface::class)->error($e->getMessage(), [ 'exception' => $e, 'app' => 'files_external', ]); return false; } - $dateTime = $object->lastModified ? \DateTime::createFromFormat(\DateTime::RFC1123, $object->lastModified) : false; - $mtime = $dateTime ? $dateTime->getTimestamp() : null; - $objectMetadata = $object->getMetadata(); - if (isset($objectMetadata['timestamp'])) { - $mtime = $objectMetadata['timestamp']; + $mtime = null; + if (!empty($object->lastModified)) { + $dateTime = \DateTime::createFromFormat(\DateTime::RFC1123, $object->lastModified); + if ($dateTime !== false) { + $mtime = $dateTime->getTimestamp(); + } } - if (!empty($mtime)) { - $mtime = floor($mtime); + if (is_numeric($object->getMetadata()['timestamp'] ?? null)) { + $mtime = (float)$object->getMetadata()['timestamp']; } - $stat = []; - $stat['size'] = (int)$object->contentLength; - $stat['mtime'] = $mtime; - $stat['atime'] = time(); - return $stat; + return [ + 'size' => (int)$object->contentLength, + 'mtime' => isset($mtime) ? (int)floor($mtime) : null, + 'atime' => time(), + ]; } - public function filetype($path) { + public function filetype(string $path) { $path = $this->normalizePath($path); if ($path !== '.' && $this->doesObjectExist($path)) { @@ -379,7 +342,7 @@ class Swift extends \OC\Files\Storage\Common { } } - public function unlink($path) { + public function unlink(string $path): bool { $path = $this->normalizePath($path); if ($this->is_dir($path)) { @@ -392,7 +355,7 @@ class Swift extends \OC\Files\Storage\Common { $this->objectCache->remove($path . '/'); } catch (BadResponseError $e) { if ($e->getResponse()->getStatusCode() !== 404) { - \OC::$server->get(LoggerInterface::class)->error($e->getMessage(), [ + Server::get(LoggerInterface::class)->error($e->getMessage(), [ 'exception' => $e, 'app' => 'files_external', ]); @@ -403,7 +366,7 @@ class Swift extends \OC\Files\Storage\Common { return true; } - public function fopen($path, $mode) { + public function fopen(string $path, string $mode) { $path = $this->normalizePath($path); switch ($mode) { @@ -416,7 +379,7 @@ class Swift extends \OC\Files\Storage\Common { try { return $this->objectStore->readObject($path); } catch (BadResponseError $e) { - \OC::$server->get(LoggerInterface::class)->error($e->getMessage(), [ + Server::get(LoggerInterface::class)->error($e->getMessage(), [ 'exception' => $e, 'app' => 'files_external', ]); @@ -436,7 +399,7 @@ class Swift extends \OC\Files\Storage\Common { } else { $ext = ''; } - $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext); + $tmpFile = Server::get(ITempManager::class)->getTemporaryFile($ext); // Fetch existing file if required if ($mode[0] !== 'w' && $this->file_exists($path)) { if ($mode[0] === 'x') { @@ -447,13 +410,13 @@ class Swift extends \OC\Files\Storage\Common { file_put_contents($tmpFile, $source); } $handle = fopen($tmpFile, $mode); - return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) { + return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile): void { $this->writeBack($tmpFile, $path); }); } } - public function touch($path, $mtime = null) { + public function touch(string $path, ?int $mtime = null): bool { $path = $this->normalizePath($path); if (is_null($mtime)) { $mtime = time(); @@ -483,7 +446,7 @@ class Swift extends \OC\Files\Storage\Common { } } - public function copy($source, $target) { + public function copy(string $source, string $target): bool { $source = $this->normalizePath($source); $target = $this->normalizePath($target); @@ -503,7 +466,7 @@ class Swift extends \OC\Files\Storage\Common { $this->objectCache->remove($target); $this->objectCache->remove($target . '/'); } catch (BadResponseError $e) { - \OC::$server->get(LoggerInterface::class)->error($e->getMessage(), [ + Server::get(LoggerInterface::class)->error($e->getMessage(), [ 'exception' => $e, 'app' => 'files_external', ]); @@ -519,7 +482,7 @@ class Swift extends \OC\Files\Storage\Common { $this->objectCache->remove($target); $this->objectCache->remove($target . '/'); } catch (BadResponseError $e) { - \OC::$server->get(LoggerInterface::class)->error($e->getMessage(), [ + Server::get(LoggerInterface::class)->error($e->getMessage(), [ 'exception' => $e, 'app' => 'files_external', ]); @@ -527,8 +490,8 @@ class Swift extends \OC\Files\Storage\Common { } $dh = $this->opendir($source); - while ($file = readdir($dh)) { - if (\OC\Files\Filesystem::isIgnoredDir($file)) { + while (($file = readdir($dh)) !== false) { + if (Filesystem::isIgnoredDir($file)) { continue; } @@ -544,7 +507,7 @@ class Swift extends \OC\Files\Storage\Common { return true; } - public function rename($source, $target) { + public function rename(string $source, string $target): bool { $source = $this->normalizePath($source); $target = $this->normalizePath($target); @@ -569,18 +532,18 @@ class Swift extends \OC\Files\Storage\Common { return false; } - public function getId() { + public function getId(): string { return $this->id; } /** * Returns the initialized object store container. * - * @return \OpenStack\ObjectStore\v1\Models\Container - * @throws \OCP\Files\StorageAuthException - * @throws \OCP\Files\StorageNotAvailableException + * @return Container + * @throws StorageAuthException + * @throws StorageNotAvailableException */ - public function getContainer() { + public function getContainer(): Container { if (is_null($this->container)) { $this->container = $this->connectionFactory->getContainer(); @@ -591,7 +554,7 @@ class Swift extends \OC\Files\Storage\Common { return $this->container; } - public function writeBack($tmpFile, $path) { + public function writeBack(string $tmpFile, string $path): void { $fileData = fopen($tmpFile, 'r'); $this->objectStore->writeObject($path, $fileData, $this->mimeDetector->detectPath($path)); // invalidate target object to force repopulation on fetch @@ -599,7 +562,7 @@ class Swift extends \OC\Files\Storage\Common { unlink($tmpFile); } - public function hasUpdated($path, $time) { + public function hasUpdated(string $path, int $time): bool { if ($this->is_file($path)) { return parent::hasUpdated($path, $time); } @@ -624,7 +587,7 @@ class Swift extends \OC\Files\Storage\Common { /** * check if curl is installed */ - public static function checkDependencies() { + public static function checkDependencies(): bool { return true; } } diff --git a/apps/files_external/lib/Lib/Storage/SystemBridge.php b/apps/files_external/lib/Lib/Storage/SystemBridge.php new file mode 100644 index 00000000000..80449b2744b --- /dev/null +++ b/apps/files_external/lib/Lib/Storage/SystemBridge.php @@ -0,0 +1,27 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2024 Robin Appelman <robin@icewind.nl> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCA\Files_External\Lib\Storage; + +use Icewind\SMB\System; +use OCP\IBinaryFinder; + +/** + * Bridge the NC and SMB binary finding logic + */ +class SystemBridge extends System { + public function __construct( + private IBinaryFinder $binaryFinder, + ) { + } + + protected function getBinaryPath(string $binary): ?string { + $path = $this->binaryFinder->findBinaryPath($binary); + return $path !== false ? $path : null; + } +} diff --git a/apps/files_external/lib/Lib/StorageConfig.php b/apps/files_external/lib/Lib/StorageConfig.php index 2d7d0687635..2cb82d3790a 100644 --- a/apps/files_external/lib/Lib/StorageConfig.php +++ b/apps/files_external/lib/Lib/StorageConfig.php @@ -1,33 +1,13 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Jesús Macias <jmacias@solidgear.es> - * @author Joas Schilling <coding@schilljs.com> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Robin Appelman <robin@icewind.nl> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib; +use OC\Files\Filesystem; use OCA\Files_External\Lib\Auth\AuthMechanism; use OCA\Files_External\Lib\Auth\IUserProvided; use OCA\Files_External\Lib\Backend\Backend; @@ -103,14 +83,14 @@ class StorageConfig implements \JsonSerializable { /** * List of users who have access to this storage * - * @var string[] + * @var list<string> */ private $applicableUsers = []; /** * List of groups that have access to this storage * - * @var string[] + * @var list<string> */ private $applicableGroups = []; @@ -174,7 +154,7 @@ class StorageConfig implements \JsonSerializable { * @param string $mountPoint path */ public function setMountPoint($mountPoint) { - $this->mountPoint = \OC\Files\Filesystem::normalizePath($mountPoint); + $this->mountPoint = Filesystem::normalizePath($mountPoint); } /** @@ -225,7 +205,7 @@ class StorageConfig implements \JsonSerializable { foreach ($backendOptions as $key => $value) { if (isset($parameters[$key])) { switch ($parameters[$key]->getType()) { - case \OCA\Files_External\Lib\DefinitionParameter::VALUE_BOOLEAN: + case DefinitionParameter::VALUE_BOOLEAN: $value = (bool)$value; break; } @@ -277,7 +257,7 @@ class StorageConfig implements \JsonSerializable { /** * Returns the users for which to mount this storage * - * @return string[] applicable users + * @return list<string> applicable users */ public function getApplicableUsers() { return $this->applicableUsers; @@ -286,7 +266,7 @@ class StorageConfig implements \JsonSerializable { /** * Sets the users for which to mount this storage * - * @param string[]|null $applicableUsers applicable users + * @param list<string>|null $applicableUsers applicable users */ public function setApplicableUsers($applicableUsers) { if (is_null($applicableUsers)) { @@ -298,7 +278,7 @@ class StorageConfig implements \JsonSerializable { /** * Returns the groups for which to mount this storage * - * @return string[] applicable groups + * @return list<string> applicable groups */ public function getApplicableGroups() { return $this->applicableGroups; @@ -307,7 +287,7 @@ class StorageConfig implements \JsonSerializable { /** * Sets the groups for which to mount this storage * - * @param string[]|null $applicableGroups applicable groups + * @param list<string>|null $applicableGroups applicable groups */ public function setApplicableGroups($applicableGroups) { if (is_null($applicableGroups)) { diff --git a/apps/files_external/lib/Lib/StorageModifierTrait.php b/apps/files_external/lib/Lib/StorageModifierTrait.php index 096e091576e..4062ff1635e 100644 --- a/apps/files_external/lib/Lib/StorageModifierTrait.php +++ b/apps/files_external/lib/Lib/StorageModifierTrait.php @@ -1,28 +1,13 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib; -use OCP\Files\Storage; +use OCP\Files\Storage\IStorage; use OCP\Files\StorageNotAvailableException; use OCP\IUser; @@ -44,8 +29,8 @@ trait StorageModifierTrait { /** * Modify a StorageConfig parameters * - * @param StorageConfig $storage - * @param IUser $user User the storage is being used as + * @param StorageConfig &$storage + * @param ?IUser $user User the storage is being used as * @return void * @throws InsufficientDataForMeaningfulAnswerException * @throws StorageNotAvailableException @@ -54,14 +39,12 @@ trait StorageModifierTrait { } /** - * Wrap a Storage if necessary + * Wrap a storage if necessary * - * @param Storage $storage - * @return Storage * @throws InsufficientDataForMeaningfulAnswerException * @throws StorageNotAvailableException */ - public function wrapStorage(Storage $storage) { + public function wrapStorage(IStorage $storage): IStorage { return $storage; } } diff --git a/apps/files_external/lib/Lib/VisibilityTrait.php b/apps/files_external/lib/Lib/VisibilityTrait.php index db616900b8e..62b26f3edb1 100644 --- a/apps/files_external/lib/Lib/VisibilityTrait.php +++ b/apps/files_external/lib/Lib/VisibilityTrait.php @@ -1,24 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_External\Lib; |