Passed
Push — master ( b39fb5...590849 )
by Roeland
11:59 queued 10s
created

WebAuthnController   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 77
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 37
c 1
b 0
f 0
dl 0
loc 77
rs 10
wmc 5

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A startAuthentication() 0 17 1
A finishAuthentication() 0 22 3
1
<?php
2
declare(strict_types=1);
3
/**
4
 * @copyright Copyright (c) 2020, 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\Login\LoginData;
28
use OC\Authentication\Login\WebAuthnChain;
29
use OC\Authentication\WebAuthn\Manager;
30
use OCP\AppFramework\Controller;
31
use OCP\AppFramework\Http;
32
use OCP\AppFramework\Http\JSONResponse;
33
use OCP\ILogger;
34
use OCP\IRequest;
35
use OCP\ISession;
36
use OCP\Util;
37
use Webauthn\PublicKeyCredentialRequestOptions;
38
39
class WebAuthnController extends Controller {
40
41
	private const WEBAUTHN_LOGIN = 'webauthn_login';
42
	private const WEBAUTHN_LOGIN_UID = 'webauthn_login_uid';
43
44
	/** @var Manager */
45
	private $webAuthnManger;
46
47
	/** @var ISession */
48
	private $session;
49
50
	/** @var ILogger */
51
	private $logger;
52
53
	/** @var WebAuthnChain */
54
	private $webAuthnChain;
55
56
	public function __construct($appName, IRequest $request, Manager $webAuthnManger, ISession $session, ILogger $logger, WebAuthnChain $webAuthnChain) {
57
		parent::__construct($appName, $request);
58
59
		$this->webAuthnManger = $webAuthnManger;
60
		$this->session = $session;
61
		$this->logger = $logger;
62
		$this->webAuthnChain = $webAuthnChain;
63
	}
64
65
	/**
66
	 * @NoAdminRequired
67
	 * @PublicPage
68
	 * @UseSession
69
	 */
70
	public function startAuthentication(string $loginName): JSONResponse {
71
		$this->logger->debug('Starting WebAuthn login');
72
73
		$this->logger->debug('Converting login name to UID');
74
		$uid = $loginName;
75
		Util::emitHook(
76
			'\OCA\Files_Sharing\API\Server2Server',
77
			'preLoginNameUsedAsUserName',
78
			array('uid' => &$uid)
79
		);
80
		$this->logger->debug('Got UID: ' . $uid);
81
82
		$publicKeyCredentialRequestOptions = $this->webAuthnManger->startAuthentication($uid, $this->request->getServerHost());
83
		$this->session->set(self::WEBAUTHN_LOGIN, json_encode($publicKeyCredentialRequestOptions));
84
		$this->session->set(self::WEBAUTHN_LOGIN_UID, $uid);
85
86
		return new JSONResponse($publicKeyCredentialRequestOptions);
87
	}
88
89
	/**
90
	 * @NoAdminRequired
91
	 * @PublicPage
92
	 * @UseSession
93
	 */
94
	public function finishAuthentication(string $data): JSONResponse {
95
		$this->logger->debug('Validating WebAuthn login');
96
97
		if (!$this->session->exists(self::WEBAUTHN_LOGIN) || !$this->session->exists(self::WEBAUTHN_LOGIN_UID)) {
98
			$this->logger->debug('Trying to finish WebAuthn login without session data');
99
			return new JSONResponse([], Http::STATUS_BAD_REQUEST);
100
		}
101
102
		// Obtain the publicKeyCredentialOptions from when we started the registration
103
		$publicKeyCredentialRequestOptions = PublicKeyCredentialRequestOptions::createFromString($this->session->get(self::WEBAUTHN_LOGIN));
104
		$uid = $this->session->get(self::WEBAUTHN_LOGIN_UID);
105
		$this->webAuthnManger->finishAuthentication($publicKeyCredentialRequestOptions, $data, $uid);
106
107
		//TODO: add other parameters
108
		$loginData = new LoginData(
109
			$this->request,
110
			$uid,
111
			''
112
		);
113
		$this->webAuthnChain->process($loginData);
114
115
		return new JSONResponse([]);
116
	}
117
}
118