Passed
Push — master ( 0857d9...f9d30b )
by Roeland
18:19 queued 03:38
created

AppPasswordController::deleteAppPassword()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 9
nc 3
nop 0
dl 0
loc 15
rs 9.9666
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
/**
4
 * @copyright Copyright (c) 2018, Roeland Jago Douma <[email protected]>
5
 *
6
 * @author Roeland Jago Douma <[email protected]>
7
 *
8
 * @license GNU AGPL version 3 or any later version
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU Affero General Public License as
12
 * published by the Free Software Foundation, either version 3 of the
13
 * License, or (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 *
23
 */
24
25
namespace OC\Core\Controller;
26
27
use OC\Authentication\Exceptions\InvalidTokenException;
28
use OC\Authentication\Token\IProvider;
29
use OC\Authentication\Token\IToken;
30
use OCP\AppFramework\Http\DataResponse;
31
use OCP\AppFramework\OCS\OCSForbiddenException;
32
use OCP\Authentication\Exceptions\CredentialsUnavailableException;
33
use OCP\Authentication\Exceptions\PasswordUnavailableException;
34
use OCP\Authentication\LoginCredentials\IStore;
35
use OCP\IRequest;
36
use OCP\ISession;
37
use OCP\Security\ISecureRandom;
38
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
39
use Symfony\Component\EventDispatcher\GenericEvent;
40
41
class AppPasswordController extends \OCP\AppFramework\OCSController {
42
43
	/** @var ISession */
44
	private $session;
45
46
	/** @var ISecureRandom */
47
	private $random;
48
49
	/** @var IProvider */
50
	private $tokenProvider;
51
52
	/** @var IStore */
53
	private $credentialStore;
54
55
	/** @var EventDispatcherInterface */
56
	private $eventDispatcher;
57
58
	public function __construct(string $appName,
59
								IRequest $request,
60
								ISession $session,
61
								ISecureRandom $random,
62
								IProvider $tokenProvider,
63
								IStore $credentialStore,
64
								EventDispatcherInterface $eventDispatcher) {
65
		parent::__construct($appName, $request);
66
67
		$this->session = $session;
68
		$this->random = $random;
69
		$this->tokenProvider = $tokenProvider;
70
		$this->credentialStore = $credentialStore;
71
		$this->eventDispatcher = $eventDispatcher;
72
	}
73
74
	/**
75
	 * @NoAdminRequired
76
	 *
77
	 * @return DataResponse
78
	 * @throws OCSForbiddenException
79
	 */
80
	public function getAppPassword(): DataResponse {
81
		// We do not allow the creation of new tokens if this is an app password
82
		if ($this->session->exists('app_password')) {
83
			throw new OCSForbiddenException('You cannot request an new apppassword with an apppassword');
84
		}
85
86
		try {
87
			$credentials = $this->credentialStore->getLoginCredentials();
88
		} catch (CredentialsUnavailableException $e) {
89
			throw new OCSForbiddenException();
90
		}
91
92
		try {
93
			$password = $credentials->getPassword();
94
		} catch (PasswordUnavailableException $e) {
95
			$password = null;
96
		}
97
98
		$userAgent = $this->request->getHeader('USER_AGENT');
99
100
		$token = $this->random->generate(72, ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_DIGITS);
101
102
		$generatedToken = $this->tokenProvider->generateToken(
103
			$token,
104
			$credentials->getUID(),
105
			$credentials->getLoginName(),
106
			$password,
107
			$userAgent,
108
			IToken::PERMANENT_TOKEN,
109
			IToken::DO_NOT_REMEMBER
110
		);
111
112
		$event = new GenericEvent($generatedToken);
113
		$this->eventDispatcher->dispatch('app_password_created', $event);
114
115
		return new DataResponse([
116
			'apppassword' => $token
117
		]);
118
	}
119
120
	/**
121
	 * @NoAdminRequired
122
	 *
123
	 * @return DataResponse
124
	 */
125
	public function deleteAppPassword() {
126
		if (!$this->session->exists('app_password')) {
127
			throw new OCSForbiddenException('no app password in use');
128
		}
129
130
		$appPassword = $this->session->get('app_password');
131
132
		try {
133
			$token = $this->tokenProvider->getToken($appPassword);
134
		} catch (InvalidTokenException $e) {
135
			throw new OCSForbiddenException('could not remove apptoken');
136
		}
137
138
		$this->tokenProvider->invalidateTokenById($token->getUID(), $token->getId());
139
		return new DataResponse();
140
	}
141
}
142