Passed
Push — master ( 47b10c...1d2707 )
by Morris
33:30 queued 20:10
created

TwoFactor::shouldShow()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 27
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 14
nc 6
nop 0
dl 0
loc 27
rs 8.8333
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * @copyright Copyright (c) 2019, Roeland Jago Douma <[email protected]>
7
 *
8
 * @author Roeland Jago Douma <[email protected]>
9
 *
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
namespace OCA\Settings\Settings\Personal\Security;
28
29
use Exception;
30
use OC\Authentication\TwoFactorAuth\MandatoryTwoFactor;
31
use OCA\TwoFactorBackupCodes\Provider\BackupCodesProvider;
32
use function array_filter;
33
use function array_map;
34
use function is_null;
35
use OC\Authentication\TwoFactorAuth\ProviderLoader;
36
use OCP\AppFramework\Http\TemplateResponse;
37
use OCP\Authentication\TwoFactorAuth\IProvider;
38
use OCP\Authentication\TwoFactorAuth\IProvidesPersonalSettings;
39
use OCP\IConfig;
40
use OCP\IUserSession;
41
use OCP\Settings\ISettings;
42
43
class TwoFactor implements ISettings {
44
45
	/** @var ProviderLoader */
46
	private $providerLoader;
47
48
	/** @var MandatoryTwoFactor */
49
	private $mandatoryTwoFactor;
50
51
	/** @var IUserSession */
52
	private $userSession;
53
54
	/** @var string|null */
55
	private $uid;
56
57
	/** @var IConfig */
58
	private $config;
59
60
	public function __construct(ProviderLoader $providerLoader,
61
								MandatoryTwoFactor $mandatoryTwoFactor,
62
								IUserSession $userSession,
63
								IConfig $config,
64
								?string $UserId) {
65
		$this->providerLoader = $providerLoader;
66
		$this->mandatoryTwoFactor = $mandatoryTwoFactor;
67
		$this->userSession = $userSession;
68
		$this->uid = $UserId;
69
		$this->config = $config;
70
	}
71
72
	public function getForm(): TemplateResponse {
73
		return new TemplateResponse('settings', 'settings/personal/security/twofactor', [
74
			'twoFactorProviderData' => $this->getTwoFactorProviderData(),
75
			'themedark' => $this->config->getUserValue($this->uid, 'accessibility', 'theme', false)
76
		]);
77
	}
78
79
	public function getSection(): ?string {
80
		if (!$this->shouldShow()) {
81
			return null;
82
		}
83
		return 'security';
84
	}
85
86
	public function getPriority(): int {
87
		return 15;
88
	}
89
90
	private function shouldShow(): bool {
91
		$user = $this->userSession->getUser();
92
		if (is_null($user)) {
93
			// Actually impossible, but still …
94
			return false;
95
		}
96
97
		// Anyone who's supposed to use 2FA should see 2FA settings
98
		if ($this->mandatoryTwoFactor->isEnforcedFor($user)) {
99
			return true;
100
		}
101
102
		// If there is at least one provider with personal settings but it's not
103
		// the backup codes provider, then these settings should show.
104
		try {
105
			$providers = $this->providerLoader->getProviders($user);
106
		} catch (Exception $e) {
107
			// Let's hope for the best
108
			return true;
109
		}
110
		foreach ($providers as $provider) {
111
			if ($provider instanceof IProvidesPersonalSettings
112
				&& !($provider instanceof BackupCodesProvider)) {
113
				return true;
114
			}
115
		}
116
		return false;
117
	}
118
119
	private function getTwoFactorProviderData(): array {
120
		$user = $this->userSession->getUser();
121
		if (is_null($user)) {
122
			// Actually impossible, but still …
123
			return [];
124
		}
125
126
		return [
127
			'providers' => array_map(function (IProvidesPersonalSettings $provider) use ($user) {
128
				return [
129
					'provider' => $provider,
130
					'settings' => $provider->getPersonalSettings($user)
131
				];
132
			}, array_filter($this->providerLoader->getProviders($user), function (IProvider $provider) {
133
				return $provider instanceof IProvidesPersonalSettings;
134
			}))
135
		];
136
	}
137
}
138