Passed
Pull Request — master (#92)
by Christoph
03:17
created

AProvider::getTemplate()   A

Complexity

Conditions 2
Paths 3

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 13
dl 0
loc 19
rs 9.8333
c 0
b 0
f 0
cc 2
nc 3
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * @author Christoph Wurst <[email protected]>
7
 *
8
 * Nextcloud - Two-factor Gateway
9
 *
10
 * This code is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU Affero General Public License, version 3,
12
 * as published by the Free Software Foundation.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License, version 3,
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
21
 *
22
 */
23
24
namespace OCA\TwoFactorGateway\Provider;
25
26
use OCA\TwoFactorGateway\PhoneNumberMask;
27
use OCA\TwoFactorGateway\Service\Gateway\IGateway;
28
use OCA\TwoFactorGateway\Service\StateStorage;
29
use OCP\Authentication\TwoFactorAuth\IProvider;
30
use OCP\IL10N;
31
use OCP\ISession;
32
use OCP\IUser;
33
use OCP\Security\ISecureRandom;
34
use OCP\Template;
35
36
abstract class AProvider implements IProvider {
37
38
	const STATE_DISABLED = 0;
39
	const STATE_START_VERIFICATION = 1;
40
	const STATE_VERIFYING = 2;
41
	const STATE_ENABLED = 3;
42
43
	/** @var string */
44
	protected $gatewayName;
45
46
	/** @var IGateway */
47
	protected $gateway;
48
49
	/** @var StateStorage */
50
	protected $stateStorage;
51
52
	/** @var ISession */
53
	protected $session;
54
55
	/** @var ISecureRandom */
56
	protected $secureRandom;
57
58
	/** @var IL10N */
59
	protected $l10n;
60
61
	private function getSessionKey() {
62
		return "twofactor_gateway_$this->gatewayId_secret";
0 ignored issues
show
Bug introduced by
The property gatewayId_secret does not exist on OCA\TwoFactorGateway\Provider\AProvider. Did you mean gateway?
Loading history...
63
	}
64
65
	public function __construct(string $gatewayId,
66
								IGateway $gateway,
67
								StateStorage $stateStorage,
68
								ISession $session,
69
								ISecureRandom $secureRandom,
70
								IL10N $l10n) {
71
		$this->gateway = $gateway;
72
		$this->gatewayName = $gatewayId;
73
		$this->stateStorage = $stateStorage;
74
		$this->session = $session;
75
		$this->secureRandom = $secureRandom;
76
		$this->l10n = $l10n;
77
	}
78
79
	/**
80
	 * Get unique identifier of this 2FA provider
81
	 */
82
	public function getId(): string {
83
		return "gateway_$this->gatewayName";
84
	}
85
86
	private function getSecret(): string {
87
		if ($this->session->exists($this->getSessionKey())) {
88
			return $this->session->get($this->getSessionKey());
89
		}
90
91
		$secret = $this->secureRandom->generate(6, ISecureRandom::CHAR_DIGITS);
92
		$this->session->set($this->getSessionKey(), $secret);
93
94
		return $secret;
95
	}
96
97
	/**
98
	 * Get the template for rending the 2FA provider view
99
	 */
100
	public function getTemplate(IUser $user): Template {
101
		$secret = $this->getSecret();
102
103
		try {
104
			$identifier = $this->stateStorage->get($user, $this->gatewayName)->getIdentifier();
105
			$this->gateway->send(
106
				$user,
107
				$identifier,
108
				$this->l10n->t('%s is your Nextcloud authentication code', [
109
					$secret
110
				])
111
			);
112
		} catch (SmsTransmissionException $ex) {
0 ignored issues
show
Bug introduced by
The type OCA\TwoFactorGateway\Pro...msTransmissionException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
113
			return new Template('twofactor_gateway', 'error');
114
		}
115
116
		$tmpl = new Template('twofactor_gateway', 'challenge');
117
		$tmpl->assign('phone', PhoneNumberMask::maskNumber($identifier));
118
		return $tmpl;
119
	}
120
121
	/**
122
	 * Verify the given challenge
123
	 */
124
	public function verifyChallenge(IUser $user, string $challenge): bool {
125
		$valid = $this->session->exists($this->getSessionKey())
126
			&& $this->session->get($this->getSessionKey()) === $challenge;
127
128
		if ($valid) {
129
			$this->session->remove($this->getSessionKey());
130
		}
131
132
		return $valid;
133
	}
134
135
	/**
136
	 * Decides whether 2FA is enabled for the given user
137
	 */
138
	public function isTwoFactorAuthEnabledForUser(IUser $user): bool {
139
		return $this->stateStorage->get($user, $this->gatewayName)->getState() === self::STATE_ENABLED;
140
	}
141
142
}
143