aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_external/lib
diff options
context:
space:
mode:
authorJohn Molakvoæ <skjnldsv@protonmail.com>2023-07-13 09:58:24 +0200
committerJohn Molakvoæ <skjnldsv@protonmail.com>2023-08-01 16:38:06 +0200
commit38480fda3cd1f10652bc1e854207b074921e66b8 (patch)
treec4c9112123f649802c9f86d056fe6da5e89be068 /apps/files_external/lib
parent385f987a28a535e8b6b0020693daa5347093c186 (diff)
downloadnextcloud-server-38480fda3cd1f10652bc1e854207b074921e66b8.tar.gz
nextcloud-server-38480fda3cd1f10652bc1e854207b074921e66b8.zip
feat(files_external): migrate to vue
Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
Diffstat (limited to 'apps/files_external/lib')
-rw-r--r--apps/files_external/lib/AppInfo/Application.php16
-rw-r--r--apps/files_external/lib/Controller/ApiController.php48
-rw-r--r--apps/files_external/lib/Controller/GlobalStoragesController.php4
-rw-r--r--apps/files_external/lib/Controller/StoragesController.php27
-rw-r--r--apps/files_external/lib/Controller/UserGlobalStoragesController.php15
-rw-r--r--apps/files_external/lib/Controller/UserStoragesController.php4
-rw-r--r--apps/files_external/lib/Lib/Auth/Password/SessionCredentials.php4
-rw-r--r--apps/files_external/lib/Lib/StorageConfig.php23
-rw-r--r--apps/files_external/lib/Listener/LoadAdditionalListener.php55
-rw-r--r--apps/files_external/lib/ResponseDefinitions.php1
10 files changed, 135 insertions, 62 deletions
diff --git a/apps/files_external/lib/AppInfo/Application.php b/apps/files_external/lib/AppInfo/Application.php
index 6f8018746b3..fc6a5d64e7c 100644
--- a/apps/files_external/lib/AppInfo/Application.php
+++ b/apps/files_external/lib/AppInfo/Application.php
@@ -29,6 +29,7 @@
*/
namespace OCA\Files_External\AppInfo;
+use OCA\Files\Event\LoadAdditionalScriptsEvent;
use OCA\Files_External\Config\ConfigAdapter;
use OCA\Files_External\Config\UserPlaceholderHandler;
use OCA\Files_External\Lib\Auth\AmazonS3\AccessKey;
@@ -62,6 +63,7 @@ use OCA\Files_External\Lib\Backend\Swift;
use OCA\Files_External\Lib\Config\IAuthMechanismProvider;
use OCA\Files_External\Lib\Config\IBackendProvider;
use OCA\Files_External\Listener\GroupDeletedListener;
+use OCA\Files_External\Listener\LoadAdditionalListener;
use OCA\Files_External\Listener\UserDeletedListener;
use OCA\Files_External\Service\BackendService;
use OCP\AppFramework\App;
@@ -78,6 +80,7 @@ require_once __DIR__ . '/../../3rdparty/autoload.php';
* @package OCA\Files_External\AppInfo
*/
class Application extends App implements IBackendProvider, IAuthMechanismProvider, IBootstrap {
+ public const APP_ID = 'files_external';
/**
* Application constructor.
@@ -85,28 +88,19 @@ class Application extends App implements IBackendProvider, IAuthMechanismProvide
* @throws \OCP\AppFramework\QueryException
*/
public function __construct(array $urlParams = []) {
- parent::__construct('files_external', $urlParams);
+ parent::__construct(self::APP_ID, $urlParams);
}
public function register(IRegistrationContext $context): void {
$context->registerEventListener(UserDeletedEvent::class, UserDeletedListener::class);
$context->registerEventListener(GroupDeletedEvent::class, GroupDeletedListener::class);
+ $context->registerEventListener(LoadAdditionalScriptsEvent::class, LoadAdditionalListener::class);
}
public function boot(IBootContext $context): void {
$context->injectFn(function (IMountProviderCollection $mountProviderCollection, ConfigAdapter $configAdapter) {
$mountProviderCollection->registerProvider($configAdapter);
});
- \OCA\Files\App::getNavigationManager()->add(function () {
- $l = \OC::$server->getL10N('files_external');
- return [
- 'id' => 'extstoragemounts',
- 'appname' => 'files_external',
- 'script' => 'list.php',
- 'order' => 30,
- 'name' => $l->t('External storage'),
- ];
- });
$context->injectFn(function (BackendService $backendService, UserPlaceholderHandler $userConfigHandler) {
$backendService->registerBackendProvider($this);
$backendService->registerAuthMechanismProvider($this);
diff --git a/apps/files_external/lib/Controller/ApiController.php b/apps/files_external/lib/Controller/ApiController.php
index ed54837a9bd..1276dde91c6 100644
--- a/apps/files_external/lib/Controller/ApiController.php
+++ b/apps/files_external/lib/Controller/ApiController.php
@@ -37,30 +37,22 @@ use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\IRequest;
-use OCP\IUserSession;
/**
* @psalm-import-type FilesExternalMount from ResponseDefinitions
*/
class ApiController extends OCSController {
- /** @var IUserSession */
- private $userSession;
- /** @var UserGlobalStoragesService */
- private $userGlobalStoragesService;
- /** @var UserStoragesService */
- private $userStoragesService;
+ private UserGlobalStoragesService $userGlobalStoragesService;
+ private UserStoragesService $userStoragesService;
public function __construct(
string $appName,
IRequest $request,
- IUserSession $userSession,
UserGlobalStoragesService $userGlobalStorageService,
UserStoragesService $userStorageService
) {
parent::__construct($appName, $request);
-
- $this->userSession = $userSession;
$this->userGlobalStoragesService = $userGlobalStorageService;
$this->userStoragesService = $userStorageService;
}
@@ -89,14 +81,15 @@ class ApiController extends OCSController {
}
$entry = [
+ 'id' => $mountConfig->getId(),
+ 'type' => 'dir',
'name' => basename($mountPoint),
'path' => $path,
- 'type' => 'dir',
- 'backend' => $mountConfig->getBackend()->getText(),
- 'scope' => $isSystemMount ? 'system' : 'personal',
'permissions' => $permissions,
- 'id' => $mountConfig->getId(),
+ 'scope' => $isSystemMount ? 'system' : 'personal',
+ 'backend' => $mountConfig->getBackend()->getText(),
'class' => $mountConfig->getBackend()->getIdentifier(),
+ 'config' => $mountConfig->jsonSerialize(true),
];
return $entry;
}
@@ -127,4 +120,31 @@ class ApiController extends OCSController {
return new DataResponse($entries);
}
+
+ /**
+ * @NoAdminRequired
+ *
+ * Ask for credentials using a browser's native basic auth prompt
+ * Then returns it if provided
+ */
+ public function askNativeAuth(): DataResponse {
+ if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) {
+ $response = new DataResponse([], Http::STATUS_UNAUTHORIZED);
+ $response->addHeader('WWW-Authenticate', 'Basic realm="Storage authentification needed"');
+ return $response;
+ }
+
+ $user = $_SERVER['PHP_AUTH_USER'];
+ $password = $_SERVER['PHP_AUTH_PW'];
+
+ // Reset auth
+ unset($_SERVER['PHP_AUTH_USER']);
+ unset($_SERVER['PHP_AUTH_PW']);
+
+ // Using 401 again to ensure we clear any cached Authorization
+ return new DataResponse([
+ 'user' => $user,
+ 'password' => $password,
+ ], Http::STATUS_UNAUTHORIZED);
+ }
}
diff --git a/apps/files_external/lib/Controller/GlobalStoragesController.php b/apps/files_external/lib/Controller/GlobalStoragesController.php
index ce45bf3307c..cb785695647 100644
--- a/apps/files_external/lib/Controller/GlobalStoragesController.php
+++ b/apps/files_external/lib/Controller/GlobalStoragesController.php
@@ -134,7 +134,7 @@ class GlobalStoragesController extends StoragesController {
$this->updateStorageStatus($newStorage);
return new DataResponse(
- $this->formatStorageForUI($newStorage),
+ $newStorage->jsonSerialize(true),
Http::STATUS_CREATED
);
}
@@ -201,7 +201,7 @@ class GlobalStoragesController extends StoragesController {
$this->updateStorageStatus($storage, $testOnly);
return new DataResponse(
- $this->formatStorageForUI($storage),
+ $storage->jsonSerialize(true),
Http::STATUS_OK
);
}
diff --git a/apps/files_external/lib/Controller/StoragesController.php b/apps/files_external/lib/Controller/StoragesController.php
index 6b8e9574d6f..ead6aa9663a 100644
--- a/apps/files_external/lib/Controller/StoragesController.php
+++ b/apps/files_external/lib/Controller/StoragesController.php
@@ -276,7 +276,7 @@ abstract class StoragesController extends Controller {
* @return DataResponse
*/
public function index() {
- $storages = $this->formatStoragesForUI($this->service->getStorages());
+ $storages = array_map(static fn ($storage) => $storage->jsonSerialize(true), $this->service->getStorages());
return new DataResponse(
$storages,
@@ -284,29 +284,6 @@ abstract class StoragesController extends Controller {
);
}
- protected function formatStoragesForUI(array $storages): array {
- return array_map(function ($storage) {
- return $this->formatStorageForUI($storage);
- }, $storages);
- }
-
- protected function formatStorageForUI(StorageConfig $storage): StorageConfig {
- /** @var DefinitionParameter[] $parameters */
- $parameters = array_merge($storage->getBackend()->getParameters(), $storage->getAuthMechanism()->getParameters());
-
- $options = $storage->getBackendOptions();
- foreach ($options as $key => $value) {
- foreach ($parameters as $parameter) {
- if ($parameter->getName() === $key && $parameter->getType() === DefinitionParameter::VALUE_PASSWORD) {
- $storage->setBackendOption($key, DefinitionParameter::UNMODIFIED_PLACEHOLDER);
- break;
- }
- }
- }
-
- return $storage;
- }
-
/**
* Get an external storage entry.
*
@@ -329,7 +306,7 @@ abstract class StoragesController extends Controller {
);
}
- $data = $this->formatStorageForUI($storage)->jsonSerialize();
+ $data = $storage->jsonSerialize(true);
$isAdmin = $this->groupManager->isAdmin($this->userSession->getUser()->getUID());
$data['can_edit'] = $storage->getType() === StorageConfig::MOUNT_TYPE_PERSONAl || $isAdmin;
diff --git a/apps/files_external/lib/Controller/UserGlobalStoragesController.php b/apps/files_external/lib/Controller/UserGlobalStoragesController.php
index 91bc1701372..ba15afb2bdf 100644
--- a/apps/files_external/lib/Controller/UserGlobalStoragesController.php
+++ b/apps/files_external/lib/Controller/UserGlobalStoragesController.php
@@ -88,12 +88,13 @@ class UserGlobalStoragesController extends StoragesController {
* @NoAdminRequired
*/
public function index() {
- $storages = $this->formatStoragesForUI($this->service->getUniqueStorages());
-
- // remove configuration data, this must be kept private
- foreach ($storages as $storage) {
+ /** @var UserGlobalStoragesService */
+ $service = $this->service;
+ $storages = array_map(function ($storage) {
+ // remove configuration data, this must be kept private
$this->sanitizeStorage($storage);
- }
+ return $storage->jsonSerialize(true);
+ }, $service->getUniqueStorages());
return new DataResponse(
$storages,
@@ -135,7 +136,7 @@ class UserGlobalStoragesController extends StoragesController {
$this->sanitizeStorage($storage);
- $data = $this->formatStorageForUI($storage)->jsonSerialize();
+ $data = $storage->jsonSerialize(true);
$isAdmin = $this->groupManager->isAdmin($this->userSession->getUser()->getUID());
$data['can_edit'] = $storage->getType() === StorageConfig::MOUNT_TYPE_PERSONAl || $isAdmin;
@@ -189,7 +190,7 @@ class UserGlobalStoragesController extends StoragesController {
$this->sanitizeStorage($storage);
return new DataResponse(
- $this->formatStorageForUI($storage),
+ $storage->jsonSerialize(true),
Http::STATUS_OK
);
}
diff --git a/apps/files_external/lib/Controller/UserStoragesController.php b/apps/files_external/lib/Controller/UserStoragesController.php
index a875f7c2dcb..7c141afcb30 100644
--- a/apps/files_external/lib/Controller/UserStoragesController.php
+++ b/apps/files_external/lib/Controller/UserStoragesController.php
@@ -159,7 +159,7 @@ class UserStoragesController extends StoragesController {
$this->updateStorageStatus($newStorage);
return new DataResponse(
- $this->formatStorageForUI($newStorage),
+ $newStorage->jsonSerialize(true),
Http::STATUS_CREATED
);
}
@@ -219,7 +219,7 @@ class UserStoragesController extends StoragesController {
$this->updateStorageStatus($storage, $testOnly);
return new DataResponse(
- $this->formatStorageForUI($storage),
+ $storage->jsonSerialize(true),
Http::STATUS_OK
);
}
diff --git a/apps/files_external/lib/Lib/Auth/Password/SessionCredentials.php b/apps/files_external/lib/Lib/Auth/Password/SessionCredentials.php
index 228366db204..a1add7c870f 100644
--- a/apps/files_external/lib/Lib/Auth/Password/SessionCredentials.php
+++ b/apps/files_external/lib/Lib/Auth/Password/SessionCredentials.php
@@ -58,6 +58,10 @@ class SessionCredentials extends AuthMechanism {
throw new InsufficientDataForMeaningfulAnswerException('No session credentials saved');
}
+ if ($user === null) {
+ throw new StorageAuthException('Session unavailable');
+ }
+
if ($credentials->getUID() !== $user->getUID()) {
throw new StorageAuthException('Session credentials for storage owner not available');
}
diff --git a/apps/files_external/lib/Lib/StorageConfig.php b/apps/files_external/lib/Lib/StorageConfig.php
index be61d2982c0..8cb59f70892 100644
--- a/apps/files_external/lib/Lib/StorageConfig.php
+++ b/apps/files_external/lib/Lib/StorageConfig.php
@@ -397,11 +397,17 @@ class StorageConfig implements \JsonSerializable {
/**
* Serialize config to JSON
*/
- public function jsonSerialize(): array {
+ public function jsonSerialize(bool $obfuscate = false): array {
$result = [];
if (!is_null($this->id)) {
$result['id'] = $this->id;
}
+
+ // obfuscate sensitive data if requested
+ if ($obfuscate) {
+ $this->formatStorageForUI();
+ }
+
$result['mountPoint'] = $this->mountPoint;
$result['backend'] = $this->backend->getIdentifier();
$result['authMechanism'] = $this->authMechanism->getIdentifier();
@@ -428,4 +434,19 @@ class StorageConfig implements \JsonSerializable {
$result['type'] = ($this->getType() === self::MOUNT_TYPE_PERSONAl) ? 'personal': 'system';
return $result;
}
+
+ protected function formatStorageForUI(): void {
+ /** @var DefinitionParameter[] $parameters */
+ $parameters = array_merge($this->getBackend()->getParameters(), $this->getAuthMechanism()->getParameters());
+
+ $options = $this->getBackendOptions();
+ foreach ($options as $key => $value) {
+ foreach ($parameters as $parameter) {
+ if ($parameter->getName() === $key && $parameter->getType() === DefinitionParameter::VALUE_PASSWORD) {
+ $this->setBackendOption($key, DefinitionParameter::UNMODIFIED_PLACEHOLDER);
+ break;
+ }
+ }
+ }
+ }
}
diff --git a/apps/files_external/lib/Listener/LoadAdditionalListener.php b/apps/files_external/lib/Listener/LoadAdditionalListener.php
new file mode 100644
index 00000000000..e5cb5e96d0a
--- /dev/null
+++ b/apps/files_external/lib/Listener/LoadAdditionalListener.php
@@ -0,0 +1,55 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OCA\Files_External\Listener;
+
+use OCA\Files_External\AppInfo\Application;
+use OCA\Files\Event\LoadAdditionalScriptsEvent;
+use OCP\AppFramework\Services\IInitialState;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\IConfig;
+use OCP\Util;
+
+/**
+ * @template-implements IEventListener<Event|LoadAdditionalScriptsEvent>
+ */
+class LoadAdditionalListener implements IEventListener {
+
+ public function __construct(
+ private IConfig $config,
+ private IInitialState $initialState,
+ ) {}
+
+ public function handle(Event $event): void {
+ if (!($event instanceof LoadAdditionalScriptsEvent)) {
+ return;
+ }
+
+ $allowUserMounting = $this->config->getAppValue('files_external', 'allow_user_mounting', 'no') === 'yes';
+ $this->initialState->provideInitialState('allowUserMounting', $allowUserMounting);
+ Util::addScript(Application::APP_ID, 'main', 'files');
+ }
+}
diff --git a/apps/files_external/lib/ResponseDefinitions.php b/apps/files_external/lib/ResponseDefinitions.php
index d26d05a36f4..bae29085361 100644
--- a/apps/files_external/lib/ResponseDefinitions.php
+++ b/apps/files_external/lib/ResponseDefinitions.php
@@ -35,6 +35,7 @@ namespace OCA\Files_External;
* permissions: int,
* id: int,
* class: string,
+ * config: array<array-key, mixed>,
* }
*/
class ResponseDefinitions {