aboutsummaryrefslogtreecommitdiffstats
path: root/apps/provisioning_api/lib/Controller/AppsController.php
blob: fa0f2597e7fde4f5c4d24b776717c1a61011e68d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?php

declare(strict_types=1);

/**
 * @copyright Copyright (c) 2016, ownCloud, Inc.
 *
 * @author Christoph Wurst <christoph@winzerhof-wurst.at>
 * @author Joas Schilling <coding@schilljs.com>
 * @author Lukas Reschke <lukas@statuscode.ch>
 * @author Roeland Jago Douma <roeland@famdouma.nl>
 * @author Tom Needham <tom@owncloud.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/>
 *
 */
namespace OCA\Provisioning_API\Controller;

use OC_App;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCS\OCSException;
use OCP\AppFramework\OCSController;
use OCP\IRequest;

class AppsController extends OCSController {
	/** @var IAppManager */
	private $appManager;

	public function __construct(
		string $appName,
		IRequest $request,
		IAppManager $appManager
	) {
		parent::__construct($appName, $request);

		$this->appManager = $appManager;
	}

	/**
	 * @param string|null $filter
	 * @return DataResponse
	 * @throws OCSException
	 */
	public function getApps(string $filter = null): DataResponse {
		$apps = (new OC_App())->listAllApps();
		$list = [];
		foreach ($apps as $app) {
			$list[] = $app['id'];
		}
		if ($filter) {
			switch ($filter) {
				case 'enabled':
					return new DataResponse(['apps' => \OC_App::getEnabledApps()]);
					break;
				case 'disabled':
					$enabled = OC_App::getEnabledApps();
					return new DataResponse(['apps' => array_diff($list, $enabled)]);
					break;
				default:
					// Invalid filter variable
					throw new OCSException('', 101);
			}
		} else {
			return new DataResponse(['apps' => $list]);
		}
	}

	/**
	 * @param string $app
	 * @return DataResponse
	 * @throws OCSException
	 */
	public function getAppInfo(string $app): DataResponse {
		$info = $this->appManager->getAppInfo($app);
		if (!is_null($info)) {
			return new DataResponse($info);
		}

		throw new OCSException('The request app was not found', OCSController::RESPOND_NOT_FOUND);
	}

	/**
	 * @PasswordConfirmationRequired
	 * @param string $app
	 * @return DataResponse
	 * @throws OCSException
	 */
	public function enable(string $app): DataResponse {
		try {
			$this->appManager->enableApp($app);
		} catch (AppPathNotFoundException $e) {
			throw new OCSException('The request app was not found', OCSController::RESPOND_NOT_FOUND);
		}
		return new DataResponse();
	}

	/**
	 * @PasswordConfirmationRequired
	 * @param string $app
	 * @return DataResponse
	 */
	public function disable(string $app): DataResponse {
		$this->appManager->disableApp($app);
		return new DataResponse();
	}
}
ontroller extends Controller { private TagService $tagService; private IManager $shareManager; private IPreview $previewManager; private IUserSession $userSession; private IConfig $config; private ?Folder $userFolder; private UserConfig $userConfig; private ViewConfig $viewConfig; public function __construct(string $appName, IRequest $request, IUserSession $userSession, TagService $tagService, IPreview $previewManager, IManager $shareManager, IConfig $config, ?Folder $userFolder, UserConfig $userConfig, ViewConfig $viewConfig) { parent::__construct($appName, $request); $this->userSession = $userSession; $this->tagService = $tagService; $this->previewManager = $previewManager; $this->shareManager = $shareManager; $this->config = $config; $this->userFolder = $userFolder; $this->userConfig = $userConfig; $this->viewConfig = $viewConfig; } /** * Gets a thumbnail of the specified file * * @since API version 1.0 * * @NoAdminRequired * @NoCSRFRequired * @StrictCookieRequired * * @param int $x Width of the thumbnail * @param int $y Height of the thumbnail * @param string $file URL-encoded filename * @return FileDisplayResponse<Http::STATUS_OK, array{Content-Type: string}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_NOT_FOUND, array{message?: string}, array{}> * * 200: Thumbnail returned * 400: Getting thumbnail is not possible * 404: File not found */ public function getThumbnail($x, $y, $file) { if ($x < 1 || $y < 1) { return new DataResponse(['message' => 'Requested size must be numeric and a positive value.'], Http::STATUS_BAD_REQUEST); } try { $file = $this->userFolder->get($file); if ($file instanceof Folder) { throw new NotFoundException(); } /** @var File $file */ $preview = $this->previewManager->getPreview($file, $x, $y, true); return new FileDisplayResponse($preview, Http::STATUS_OK, ['Content-Type' => $preview->getMimeType()]); } catch (NotFoundException $e) { return new DataResponse(['message' => 'File not found.'], Http::STATUS_NOT_FOUND); } catch (\Exception $e) { return new DataResponse([], Http::STATUS_BAD_REQUEST); } } /** * Updates the info of the specified file path * The passed tags are absolute, which means they will * replace the actual tag selection. * * @NoAdminRequired * * @param string $path path * @param array|string $tags array of tags * @return DataResponse */ public function updateFileTags($path, $tags = null) { $result = []; // if tags specified or empty array, update tags if (!is_null($tags)) { try { $this->tagService->updateFileTags($path, $tags); } catch (\OCP\Files\NotFoundException $e) { return new DataResponse([ 'message' => $e->getMessage() ], Http::STATUS_NOT_FOUND); } catch (\OCP\Files\StorageNotAvailableException $e) { return new DataResponse([ 'message' => $e->getMessage() ], Http::STATUS_SERVICE_UNAVAILABLE); } catch (\Exception $e) { return new DataResponse([ 'message' => $e->getMessage() ], Http::STATUS_NOT_FOUND); } $result['tags'] = $tags; } return new DataResponse($result); } /** * @param \OCP\Files\Node[] $nodes * @return array */ private function formatNodes(array $nodes) { $shareTypesForNodes = $this->getShareTypesForNodes($nodes); return array_values(array_map(function (Node $node) use ($shareTypesForNodes) { $shareTypes = $shareTypesForNodes[$node->getId()] ?? []; $file = \OCA\Files\Helper::formatFileInfo($node->getFileInfo()); $file['hasPreview'] = $this->previewManager->isAvailable($node); $parts = explode('/', dirname($node->getPath()), 4); if (isset($parts[3])) { $file['path'] = '/' . $parts[3]; } else { $file['path'] = '/'; } if (!empty($shareTypes)) { $file['shareTypes'] = $shareTypes; } return $file; }, $nodes)); } /** * Get the share types for each node * * @param \OCP\Files\Node[] $nodes * @return array<int, int[]> list of share types for each fileid */ private function getShareTypesForNodes(array $nodes): array { $userId = $this->userSession->getUser()->getUID(); $requestedShareTypes = [ IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_LINK, IShare::TYPE_REMOTE, IShare::TYPE_EMAIL, IShare::TYPE_ROOM, IShare::TYPE_DECK, IShare::TYPE_SCIENCEMESH, ]; $shareTypes = []; $nodeIds = array_map(function (Node $node) { return $node->getId(); }, $nodes); foreach ($requestedShareTypes as $shareType) { $nodesLeft = array_combine($nodeIds, array_fill(0, count($nodeIds), true)); $offset = 0; // fetch shares until we've either found shares for all nodes or there are no more shares left while (count($nodesLeft) > 0) { $shares = $this->shareManager->getSharesBy($userId, $shareType, null, false, 100, $offset); foreach ($shares as $share) { $fileId = $share->getNodeId(); if (isset($nodesLeft[$fileId])) { if (!isset($shareTypes[$fileId])) { $shareTypes[$fileId] = []; } $shareTypes[$fileId][] = $shareType; unset($nodesLeft[$fileId]); } } if (count($shares) < 100) { break; } else { $offset += count($shares); } } } return $shareTypes; } /** * Returns a list of recently modified files. * * @NoAdminRequired * * @return DataResponse */ public function getRecentFiles() { $nodes = $this->userFolder->getRecent(100); $files = $this->formatNodes($nodes); return new DataResponse(['files' => $files]); } /** * Returns the current logged-in user's storage stats. * * @NoAdminRequired * * @param ?string $dir the directory to get the storage stats from * @return JSONResponse */ public function getStorageStats($dir = '/'): JSONResponse { $storageInfo = \OC_Helper::getStorageInfo($dir ?: '/'); return new JSONResponse(['message' => 'ok', 'data' => $storageInfo]); } /** * Set a user view config * * @NoAdminRequired * * @param string $view * @param string $key * @param string|bool $value * @return JSONResponse */ public function setViewConfig(string $view, string $key, $value): JSONResponse { try { $this->viewConfig->setConfig($view, $key, (string)$value); } catch (\InvalidArgumentException $e) { return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_BAD_REQUEST); } return new JSONResponse(['message' => 'ok', 'data' => $this->viewConfig->getConfig($view)]); } /** * Get the user view config * * @NoAdminRequired * * @return JSONResponse */ public function getViewConfigs(): JSONResponse { return new JSONResponse(['message' => 'ok', 'data' => $this->viewConfig->getConfigs()]); } /** * Set a user config * * @NoAdminRequired * * @param string $key * @param string|bool $value * @return JSONResponse */ public function setConfig(string $key, $value): JSONResponse { try { $this->userConfig->setConfig($key, (string)$value); } catch (\InvalidArgumentException $e) { return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_BAD_REQUEST); } return new JSONResponse(['message' => 'ok', 'data' => ['key' => $key, 'value' => $value]]); } /** * Get the user config * * @NoAdminRequired * * @return JSONResponse */ public function getConfigs(): JSONResponse { return new JSONResponse(['message' => 'ok', 'data' => $this->userConfig->getConfigs()]); } /** * Toggle default for showing/hiding hidden files * * @NoAdminRequired * * @param bool $value * @return Response * @throws \OCP\PreConditionNotMetException */ public function showHiddenFiles(bool $value): Response { $this->config->setUserValue($this->userSession->getUser()->getUID(), 'files', 'show_hidden', $value ? '1' : '0'); return new Response(); } /** * Toggle default for cropping preview images * * @NoAdminRequired * * @param bool $value * @return Response * @throws \OCP\PreConditionNotMetException */ public function cropImagePreviews(bool $value): Response { $this->config->setUserValue($this->userSession->getUser()->getUID(), 'files', 'crop_image_previews', $value ? '1' : '0'); return new Response(); } /** * Toggle default for files grid view * * @NoAdminRequired * * @param bool $show * @return Response * @throws \OCP\PreConditionNotMetException */ public function showGridView(bool $show): Response { $this->config->setUserValue($this->userSession->getUser()->getUID(), 'files', 'show_grid', $show ? '1' : '0'); return new Response(); } /** * Get default settings for the grid view * * @NoAdminRequired */ public function getGridView() { $status = $this->config->getUserValue($this->userSession->getUser()->getUID(), 'files', 'show_grid', '0') === '1'; return new JSONResponse(['gridview' => $status]); } /** * @NoAdminRequired * @NoCSRFRequired * @PublicPage */ #[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)] public function serviceWorker(): StreamResponse { $response = new StreamResponse(__DIR__ . '/../../../../dist/preview-service-worker.js'); $response->setHeaders([ 'Content-Type' => 'application/javascript', 'Service-Worker-Allowed' => '/' ]); $policy = new ContentSecurityPolicy(); $policy->addAllowedWorkerSrcDomain("'self'"); $policy->addAllowedScriptDomain("'self'"); $policy->addAllowedConnectDomain("'self'"); $response->setContentSecurityPolicy($policy); return $response; } }