Passed
Push — master ( 51f739...732353 )
by Pauli
02:31
created

SettingController::enableScanMetadata()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php declare(strict_types=1);
2
3
/**
4
 * ownCloud - Music app
5
 *
6
 * This file is licensed under the Affero General Public License version 3 or
7
 * later. See the COPYING file.
8
 *
9
 * @author Morris Jobke <[email protected]>
10
 * @author Pauli Järvinen <[email protected]>
11
 * @copyright Morris Jobke 2013, 2014
12
 * @copyright Pauli Järvinen 2017 - 2021
13
 */
14
15
namespace OCA\Music\Controller;
16
17
use OCP\AppFramework\Controller;
18
use OCP\AppFramework\Http;
19
use OCP\AppFramework\Http\JSONResponse;
20
use OCP\IRequest;
21
use OCP\IURLGenerator;
22
use OCP\Security\ISecureRandom;
23
24
use OCA\Music\AppFramework\Core\Logger;
25
use OCA\Music\Db\AmpacheUserMapper;
26
use OCA\Music\Http\ErrorResponse;
27
use OCA\Music\Utility\LibrarySettings;
28
use OCA\Music\Utility\Scanner;
29
use OCA\Music\Utility\Util;
30
31
class SettingController extends Controller {
32
	const DEFAULT_PASSWORD_LENGTH = 10;
33
34
	private $ampacheUserMapper;
35
	private $scanner;
36
	private $userId;
37
	private $librarySettings;
38
	private $secureRandom;
39
	private $urlGenerator;
40
	private $logger;
41
42
	public function __construct(string $appName,
43
								IRequest $request,
44
								AmpacheUserMapper $ampacheUserMapper,
45
								Scanner $scanner,
46
								?string $userId,
47
								LibrarySettings $librarySettings,
48
								ISecureRandom $secureRandom,
49
								IURLGenerator $urlGenerator,
50
								Logger $logger) {
51
		parent::__construct($appName, $request);
52
53
		$this->ampacheUserMapper = $ampacheUserMapper;
54
		$this->scanner = $scanner;
55
		$this->userId = $userId ?? ''; // ensure non-null to satisfy Scrutinizer; the null case should happen only when the user has already logged out
56
		$this->librarySettings = $librarySettings;
57
		$this->secureRandom = $secureRandom;
58
		$this->urlGenerator = $urlGenerator;
59
		$this->logger = $logger;
60
	}
61
62
	/**
63
	 * @NoAdminRequired
64
	 * @UseSession to keep the session reserved while execution in progress
65
	 */
66
	public function userPath(string $value) {
67
		$prevPath = $this->librarySettings->getPath($this->userId);
68
		$success = $this->librarySettings->setPath($this->userId, $value);
69
70
		if ($success) {
71
			$this->scanner->updatePath($prevPath, $value, $this->userId);
72
		}
73
74
		return new JSONResponse(['success' => $success]);
75
	}
76
77
	/**
78
	 * @NoAdminRequired
79
	 */
80
	public function userExcludedPaths(array $value) {
81
		$success = $this->librarySettings->setExcludedPaths($this->userId, $value);
82
		return new JSONResponse(['success' => $success]);
83
	}
84
85
	/**
86
	 * @NoAdminRequired
87
	 */
88
	public function enableScanMetadata(bool $value) {
89
		$this->librarySettings->setScanMetadataEnabled($this->userId, $value);
90
		return new JSONResponse(['success' => true]);
91
	}
92
93
	/**
94
	 * @NoAdminRequired
95
	 */
96
	public function getAll() {
97
		return [
98
			'path' => $this->librarySettings->getPath($this->userId),
99
			'excludedPaths' => $this->librarySettings->getExcludedPaths($this->userId),
100
			'scanMetadata' => $this->librarySettings->getScanMetadataEnabled($this->userId),
101
			'ampacheUrl' => $this->getAmpacheUrl(),
102
			'subsonicUrl' => $this->getSubsonicUrl(),
103
			'ampacheKeys' => $this->getAmpacheKeys(),
104
			'appVersion' => $this->getAppVersion(),
105
			'user' => $this->userId
106
		];
107
	}
108
109
	private function getAmpacheUrl() {
110
		return \str_replace('/server/xml.server.php', '',
111
				$this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkToRoute('music.ampache.xmlApi')));
112
	}
113
114
	private function getSubsonicUrl() {
115
		return \str_replace('/rest/dummy', '',
116
				$this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkToRoute(
117
						'music.subsonic.handleRequest', ['method' => 'dummy'])));
118
	}
119
120
	private function getAmpacheKeys() {
121
		return $this->ampacheUserMapper->getAll($this->userId);
122
	}
123
124
	private function getAppVersion() {
125
		// Note: the following in deprecated since NC14 but the replacement
126
		// \OCP\App\IAppManager::getAppVersion is not available before NC14.
127
		return \OCP\App::getAppVersion($this->appName);
128
	}
129
130
	private function storeUserKey($description, $password) {
131
		$hash = \hash('sha256', $password);
132
		$description = Util::truncate($description, 64); // some DB setups can't truncate automatically to column max size
133
		return $this->ampacheUserMapper->addUserKey($this->userId, $hash, $description);
134
	}
135
136
	/**
137
	 * @NoAdminRequired
138
	 */
139
	public function addUserKey($description, $password) {
140
		$id = $this->storeUserKey($description, $password);
141
		$success = ($id !== null);
142
		return new JSONResponse(['success' => $success, 'id' => $id]);
143
	}
144
145
	/**
146
	 * @NoAdminRequired
147
	 * @NoCSRFRequired
148
	 * @CORS
149
	 */
150
	public function generateUserKey($length, $description) {
151
		if ($description == null) {
152
			return new ErrorResponse(Http::STATUS_BAD_REQUEST, 'Please provide a description');
153
		}
154
155
		if ($length == null || $length < self::DEFAULT_PASSWORD_LENGTH) {
156
			$length = self::DEFAULT_PASSWORD_LENGTH;
157
		}
158
159
		$password = $this->secureRandom->generate(
160
			$length,
161
			ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS);
162
163
		$id = $this->storeUserKey($description, $password);
164
165
		if ($id === null) {
166
			return new ErrorResponse(Http::STATUS_INTERNAL_SERVER_ERROR, 'Error while saving the credentials');
167
		}
168
169
		return new JSONResponse(['id' => $id, 'password' => $password, 'description' => $description], Http::STATUS_CREATED);
170
	}
171
172
	/**
173
	 * @NoAdminRequired
174
	 */
175
	public function removeUserKey($id) {
176
		$this->ampacheUserMapper->removeUserKey($this->userId, (int)$id);
177
		return new JSONResponse(['success' => true]);
178
	}
179
}
180