Completed
Push — master ( a080c4...d2b9b7 )
by Blizzz
19:39
created
lib/private/Authentication/TwoFactorAuth/Manager.php 1 patch
Indentation   +328 added lines, -328 removed lines patch added patch discarded remove patch
@@ -46,336 +46,336 @@
 block discarded – undo
46 46
 
47 47
 class Manager {
48 48
 
49
-	const SESSION_UID_KEY = 'two_factor_auth_uid';
50
-	const SESSION_UID_DONE = 'two_factor_auth_passed';
51
-	const REMEMBER_LOGIN = 'two_factor_remember_login';
52
-	const BACKUP_CODES_PROVIDER_ID = 'backup_codes';
53
-
54
-	/** @var ProviderLoader */
55
-	private $providerLoader;
56
-
57
-	/** @var IRegistry */
58
-	private $providerRegistry;
59
-
60
-	/** @var ISession */
61
-	private $session;
62
-
63
-	/** @var IConfig */
64
-	private $config;
65
-
66
-	/** @var IManager */
67
-	private $activityManager;
68
-
69
-	/** @var ILogger */
70
-	private $logger;
71
-
72
-	/** @var TokenProvider */
73
-	private $tokenProvider;
74
-
75
-	/** @var ITimeFactory */
76
-	private $timeFactory;
77
-
78
-	/** @var EventDispatcherInterface */
79
-	private $dispatcher;
80
-
81
-	public function __construct(ProviderLoader $providerLoader,
82
-								IRegistry $providerRegistry, ISession $session, IConfig $config,
83
-								IManager $activityManager, ILogger $logger, TokenProvider $tokenProvider,
84
-								ITimeFactory $timeFactory, EventDispatcherInterface $eventDispatcher) {
85
-		$this->providerLoader = $providerLoader;
86
-		$this->session = $session;
87
-		$this->config = $config;
88
-		$this->activityManager = $activityManager;
89
-		$this->logger = $logger;
90
-		$this->tokenProvider = $tokenProvider;
91
-		$this->timeFactory = $timeFactory;
92
-		$this->dispatcher = $eventDispatcher;
93
-		$this->providerRegistry = $providerRegistry;
94
-	}
95
-
96
-	/**
97
-	 * Determine whether the user must provide a second factor challenge
98
-	 *
99
-	 * @param IUser $user
100
-	 * @return boolean
101
-	 */
102
-	public function isTwoFactorAuthenticated(IUser $user): bool {
103
-		$twoFactorEnabled = ((int) $this->config->getUserValue($user->getUID(), 'core', 'two_factor_auth_disabled', 0)) === 0;
104
-
105
-		if (!$twoFactorEnabled) {
106
-			return false;
107
-		}
108
-
109
-		$providerStates = $this->providerRegistry->getProviderStates($user);
110
-		$providers = $this->providerLoader->getProviders($user);
111
-		$fixedStates = $this->fixMissingProviderStates($providerStates, $providers, $user);
112
-		$enabled = array_filter($fixedStates);
113
-		$providerIds = array_keys($enabled);
114
-		$providerIdsWithoutBackupCodes = array_diff($providerIds, [self::BACKUP_CODES_PROVIDER_ID]);
115
-
116
-		return $twoFactorEnabled && !empty($providerIdsWithoutBackupCodes);
117
-	}
118
-
119
-	/**
120
-	 * Disable 2FA checks for the given user
121
-	 *
122
-	 * @param IUser $user
123
-	 */
124
-	public function disableTwoFactorAuthentication(IUser $user) {
125
-		$this->config->setUserValue($user->getUID(), 'core', 'two_factor_auth_disabled', 1);
126
-	}
127
-
128
-	/**
129
-	 * Enable all 2FA checks for the given user
130
-	 *
131
-	 * @param IUser $user
132
-	 */
133
-	public function enableTwoFactorAuthentication(IUser $user) {
134
-		$this->config->deleteUserValue($user->getUID(), 'core', 'two_factor_auth_disabled');
135
-	}
136
-
137
-	/**
138
-	 * Get a 2FA provider by its ID
139
-	 *
140
-	 * @param IUser $user
141
-	 * @param string $challengeProviderId
142
-	 * @return IProvider|null
143
-	 */
144
-	public function getProvider(IUser $user, string $challengeProviderId) {
145
-		$providers = $this->getProviderSet($user)->getProviders();
146
-		return $providers[$challengeProviderId] ?? null;
147
-	}
148
-
149
-	/**
150
-	 * Check if the persistant mapping of enabled/disabled state of each available
151
-	 * provider is missing an entry and add it to the registry in that case.
152
-	 *
153
-	 * @todo remove in Nextcloud 17 as by then all providers should have been updated
154
-	 *
155
-	 * @param string[] $providerStates
156
-	 * @param IProvider[] $providers
157
-	 * @param IUser $user
158
-	 * @return string[] the updated $providerStates variable
159
-	 */
160
-	private function fixMissingProviderStates(array $providerStates,
161
-		array $providers, IUser $user): array {
162
-
163
-		foreach ($providers as $provider) {
164
-			if (isset($providerStates[$provider->getId()])) {
165
-				// All good
166
-				continue;
167
-			}
168
-
169
-			$enabled = $provider->isTwoFactorAuthEnabledForUser($user);
170
-			if ($enabled) {
171
-				$this->providerRegistry->enableProviderFor($provider, $user);
172
-			} else {
173
-				$this->providerRegistry->disableProviderFor($provider, $user);
174
-			}
175
-			$providerStates[$provider->getId()] = $enabled;
176
-		}
177
-
178
-		return $providerStates;
179
-	}
180
-
181
-	/**
182
-	 * @param array $states
183
-	 * @param IProvider $providers
184
-	 */
185
-	private function isProviderMissing(array $states, array $providers): bool {
186
-		$indexed = [];
187
-		foreach ($providers as $provider) {
188
-			$indexed[$provider->getId()] = $provider;
189
-		}
190
-
191
-		$missing = [];
192
-		foreach ($states as $providerId => $enabled) {
193
-			if (!$enabled) {
194
-				// Don't care
195
-				continue;
196
-			}
197
-
198
-			if (!isset($indexed[$providerId])) {
199
-				$missing[] = $providerId;
200
-				$this->logger->alert("two-factor auth provider '$providerId' failed to load",
201
-					[
202
-					'app' => 'core',
203
-				]);
204
-			}
205
-		}
206
-
207
-		if (!empty($missing)) {
208
-			// There was at least one provider missing
209
-			$this->logger->alert(count($missing) . " two-factor auth providers failed to load", ['app' => 'core']);
210
-
211
-			return true;
212
-		}
213
-
214
-		// If we reach this, there was not a single provider missing
215
-		return false;
216
-	}
217
-
218
-	/**
219
-	 * Get the list of 2FA providers for the given user
220
-	 *
221
-	 * @param IUser $user
222
-	 * @throws Exception
223
-	 */
224
-	public function getProviderSet(IUser $user): ProviderSet {
225
-		$providerStates = $this->providerRegistry->getProviderStates($user);
226
-		$providers = $this->providerLoader->getProviders($user);
227
-
228
-		$fixedStates = $this->fixMissingProviderStates($providerStates, $providers, $user);
229
-		$isProviderMissing = $this->isProviderMissing($fixedStates, $providers);
230
-
231
-		$enabled = array_filter($providers, function (IProvider $provider) use ($fixedStates) {
232
-			return $fixedStates[$provider->getId()];
233
-		});
234
-		return new ProviderSet($enabled, $isProviderMissing);
235
-	}
236
-
237
-	/**
238
-	 * Verify the given challenge
239
-	 *
240
-	 * @param string $providerId
241
-	 * @param IUser $user
242
-	 * @param string $challenge
243
-	 * @return boolean
244
-	 */
245
-	public function verifyChallenge(string $providerId, IUser $user, string $challenge): bool {
246
-		$provider = $this->getProvider($user, $providerId);
247
-		if ($provider === null) {
248
-			return false;
249
-		}
250
-
251
-		$passed = $provider->verifyChallenge($user, $challenge);
252
-		if ($passed) {
253
-			if ($this->session->get(self::REMEMBER_LOGIN) === true) {
254
-				// TODO: resolve cyclic dependency and use DI
255
-				\OC::$server->getUserSession()->createRememberMeToken($user);
256
-			}
257
-			$this->session->remove(self::SESSION_UID_KEY);
258
-			$this->session->remove(self::REMEMBER_LOGIN);
259
-			$this->session->set(self::SESSION_UID_DONE, $user->getUID());
260
-
261
-			// Clear token from db
262
-			$sessionId = $this->session->getId();
263
-			$token = $this->tokenProvider->getToken($sessionId);
264
-			$tokenId = $token->getId();
265
-			$this->config->deleteUserValue($user->getUID(), 'login_token_2fa', $tokenId);
266
-
267
-			$dispatchEvent = new GenericEvent($user, ['provider' => $provider->getDisplayName()]);
268
-			$this->dispatcher->dispatch(IProvider::EVENT_SUCCESS, $dispatchEvent);
269
-
270
-			$this->publishEvent($user, 'twofactor_success', [
271
-				'provider' => $provider->getDisplayName(),
272
-			]);
273
-		} else {
274
-			$dispatchEvent = new GenericEvent($user, ['provider' => $provider->getDisplayName()]);
275
-			$this->dispatcher->dispatch(IProvider::EVENT_FAILED, $dispatchEvent);
276
-
277
-			$this->publishEvent($user, 'twofactor_failed', [
278
-				'provider' => $provider->getDisplayName(),
279
-			]);
280
-		}
281
-		return $passed;
282
-	}
283
-
284
-	/**
285
-	 * Push a 2fa event the user's activity stream
286
-	 *
287
-	 * @param IUser $user
288
-	 * @param string $event
289
-	 * @param array $params
290
-	 */
291
-	private function publishEvent(IUser $user, string $event, array $params) {
292
-		$activity = $this->activityManager->generateEvent();
293
-		$activity->setApp('core')
294
-			->setType('security')
295
-			->setAuthor($user->getUID())
296
-			->setAffectedUser($user->getUID())
297
-			->setSubject($event, $params);
298
-		try {
299
-			$this->activityManager->publish($activity);
300
-		} catch (BadMethodCallException $e) {
301
-			$this->logger->warning('could not publish activity', ['app' => 'core']);
302
-			$this->logger->logException($e, ['app' => 'core']);
303
-		}
304
-	}
305
-
306
-	/**
307
-	 * Check if the currently logged in user needs to pass 2FA
308
-	 *
309
-	 * @param IUser $user the currently logged in user
310
-	 * @return boolean
311
-	 */
312
-	public function needsSecondFactor(IUser $user = null): bool {
313
-		if ($user === null) {
314
-			return false;
315
-		}
316
-
317
-		// If we are authenticated using an app password skip all this
318
-		if ($this->session->exists('app_password')) {
319
-			return false;
320
-		}
321
-
322
-		// First check if the session tells us we should do 2FA (99% case)
323
-		if (!$this->session->exists(self::SESSION_UID_KEY)) {
324
-
325
-			// Check if the session tells us it is 2FA authenticated already
326
-			if ($this->session->exists(self::SESSION_UID_DONE) &&
327
-				$this->session->get(self::SESSION_UID_DONE) === $user->getUID()) {
328
-				return false;
329
-			}
330
-
331
-			/*
49
+    const SESSION_UID_KEY = 'two_factor_auth_uid';
50
+    const SESSION_UID_DONE = 'two_factor_auth_passed';
51
+    const REMEMBER_LOGIN = 'two_factor_remember_login';
52
+    const BACKUP_CODES_PROVIDER_ID = 'backup_codes';
53
+
54
+    /** @var ProviderLoader */
55
+    private $providerLoader;
56
+
57
+    /** @var IRegistry */
58
+    private $providerRegistry;
59
+
60
+    /** @var ISession */
61
+    private $session;
62
+
63
+    /** @var IConfig */
64
+    private $config;
65
+
66
+    /** @var IManager */
67
+    private $activityManager;
68
+
69
+    /** @var ILogger */
70
+    private $logger;
71
+
72
+    /** @var TokenProvider */
73
+    private $tokenProvider;
74
+
75
+    /** @var ITimeFactory */
76
+    private $timeFactory;
77
+
78
+    /** @var EventDispatcherInterface */
79
+    private $dispatcher;
80
+
81
+    public function __construct(ProviderLoader $providerLoader,
82
+                                IRegistry $providerRegistry, ISession $session, IConfig $config,
83
+                                IManager $activityManager, ILogger $logger, TokenProvider $tokenProvider,
84
+                                ITimeFactory $timeFactory, EventDispatcherInterface $eventDispatcher) {
85
+        $this->providerLoader = $providerLoader;
86
+        $this->session = $session;
87
+        $this->config = $config;
88
+        $this->activityManager = $activityManager;
89
+        $this->logger = $logger;
90
+        $this->tokenProvider = $tokenProvider;
91
+        $this->timeFactory = $timeFactory;
92
+        $this->dispatcher = $eventDispatcher;
93
+        $this->providerRegistry = $providerRegistry;
94
+    }
95
+
96
+    /**
97
+     * Determine whether the user must provide a second factor challenge
98
+     *
99
+     * @param IUser $user
100
+     * @return boolean
101
+     */
102
+    public function isTwoFactorAuthenticated(IUser $user): bool {
103
+        $twoFactorEnabled = ((int) $this->config->getUserValue($user->getUID(), 'core', 'two_factor_auth_disabled', 0)) === 0;
104
+
105
+        if (!$twoFactorEnabled) {
106
+            return false;
107
+        }
108
+
109
+        $providerStates = $this->providerRegistry->getProviderStates($user);
110
+        $providers = $this->providerLoader->getProviders($user);
111
+        $fixedStates = $this->fixMissingProviderStates($providerStates, $providers, $user);
112
+        $enabled = array_filter($fixedStates);
113
+        $providerIds = array_keys($enabled);
114
+        $providerIdsWithoutBackupCodes = array_diff($providerIds, [self::BACKUP_CODES_PROVIDER_ID]);
115
+
116
+        return $twoFactorEnabled && !empty($providerIdsWithoutBackupCodes);
117
+    }
118
+
119
+    /**
120
+     * Disable 2FA checks for the given user
121
+     *
122
+     * @param IUser $user
123
+     */
124
+    public function disableTwoFactorAuthentication(IUser $user) {
125
+        $this->config->setUserValue($user->getUID(), 'core', 'two_factor_auth_disabled', 1);
126
+    }
127
+
128
+    /**
129
+     * Enable all 2FA checks for the given user
130
+     *
131
+     * @param IUser $user
132
+     */
133
+    public function enableTwoFactorAuthentication(IUser $user) {
134
+        $this->config->deleteUserValue($user->getUID(), 'core', 'two_factor_auth_disabled');
135
+    }
136
+
137
+    /**
138
+     * Get a 2FA provider by its ID
139
+     *
140
+     * @param IUser $user
141
+     * @param string $challengeProviderId
142
+     * @return IProvider|null
143
+     */
144
+    public function getProvider(IUser $user, string $challengeProviderId) {
145
+        $providers = $this->getProviderSet($user)->getProviders();
146
+        return $providers[$challengeProviderId] ?? null;
147
+    }
148
+
149
+    /**
150
+     * Check if the persistant mapping of enabled/disabled state of each available
151
+     * provider is missing an entry and add it to the registry in that case.
152
+     *
153
+     * @todo remove in Nextcloud 17 as by then all providers should have been updated
154
+     *
155
+     * @param string[] $providerStates
156
+     * @param IProvider[] $providers
157
+     * @param IUser $user
158
+     * @return string[] the updated $providerStates variable
159
+     */
160
+    private function fixMissingProviderStates(array $providerStates,
161
+        array $providers, IUser $user): array {
162
+
163
+        foreach ($providers as $provider) {
164
+            if (isset($providerStates[$provider->getId()])) {
165
+                // All good
166
+                continue;
167
+            }
168
+
169
+            $enabled = $provider->isTwoFactorAuthEnabledForUser($user);
170
+            if ($enabled) {
171
+                $this->providerRegistry->enableProviderFor($provider, $user);
172
+            } else {
173
+                $this->providerRegistry->disableProviderFor($provider, $user);
174
+            }
175
+            $providerStates[$provider->getId()] = $enabled;
176
+        }
177
+
178
+        return $providerStates;
179
+    }
180
+
181
+    /**
182
+     * @param array $states
183
+     * @param IProvider $providers
184
+     */
185
+    private function isProviderMissing(array $states, array $providers): bool {
186
+        $indexed = [];
187
+        foreach ($providers as $provider) {
188
+            $indexed[$provider->getId()] = $provider;
189
+        }
190
+
191
+        $missing = [];
192
+        foreach ($states as $providerId => $enabled) {
193
+            if (!$enabled) {
194
+                // Don't care
195
+                continue;
196
+            }
197
+
198
+            if (!isset($indexed[$providerId])) {
199
+                $missing[] = $providerId;
200
+                $this->logger->alert("two-factor auth provider '$providerId' failed to load",
201
+                    [
202
+                    'app' => 'core',
203
+                ]);
204
+            }
205
+        }
206
+
207
+        if (!empty($missing)) {
208
+            // There was at least one provider missing
209
+            $this->logger->alert(count($missing) . " two-factor auth providers failed to load", ['app' => 'core']);
210
+
211
+            return true;
212
+        }
213
+
214
+        // If we reach this, there was not a single provider missing
215
+        return false;
216
+    }
217
+
218
+    /**
219
+     * Get the list of 2FA providers for the given user
220
+     *
221
+     * @param IUser $user
222
+     * @throws Exception
223
+     */
224
+    public function getProviderSet(IUser $user): ProviderSet {
225
+        $providerStates = $this->providerRegistry->getProviderStates($user);
226
+        $providers = $this->providerLoader->getProviders($user);
227
+
228
+        $fixedStates = $this->fixMissingProviderStates($providerStates, $providers, $user);
229
+        $isProviderMissing = $this->isProviderMissing($fixedStates, $providers);
230
+
231
+        $enabled = array_filter($providers, function (IProvider $provider) use ($fixedStates) {
232
+            return $fixedStates[$provider->getId()];
233
+        });
234
+        return new ProviderSet($enabled, $isProviderMissing);
235
+    }
236
+
237
+    /**
238
+     * Verify the given challenge
239
+     *
240
+     * @param string $providerId
241
+     * @param IUser $user
242
+     * @param string $challenge
243
+     * @return boolean
244
+     */
245
+    public function verifyChallenge(string $providerId, IUser $user, string $challenge): bool {
246
+        $provider = $this->getProvider($user, $providerId);
247
+        if ($provider === null) {
248
+            return false;
249
+        }
250
+
251
+        $passed = $provider->verifyChallenge($user, $challenge);
252
+        if ($passed) {
253
+            if ($this->session->get(self::REMEMBER_LOGIN) === true) {
254
+                // TODO: resolve cyclic dependency and use DI
255
+                \OC::$server->getUserSession()->createRememberMeToken($user);
256
+            }
257
+            $this->session->remove(self::SESSION_UID_KEY);
258
+            $this->session->remove(self::REMEMBER_LOGIN);
259
+            $this->session->set(self::SESSION_UID_DONE, $user->getUID());
260
+
261
+            // Clear token from db
262
+            $sessionId = $this->session->getId();
263
+            $token = $this->tokenProvider->getToken($sessionId);
264
+            $tokenId = $token->getId();
265
+            $this->config->deleteUserValue($user->getUID(), 'login_token_2fa', $tokenId);
266
+
267
+            $dispatchEvent = new GenericEvent($user, ['provider' => $provider->getDisplayName()]);
268
+            $this->dispatcher->dispatch(IProvider::EVENT_SUCCESS, $dispatchEvent);
269
+
270
+            $this->publishEvent($user, 'twofactor_success', [
271
+                'provider' => $provider->getDisplayName(),
272
+            ]);
273
+        } else {
274
+            $dispatchEvent = new GenericEvent($user, ['provider' => $provider->getDisplayName()]);
275
+            $this->dispatcher->dispatch(IProvider::EVENT_FAILED, $dispatchEvent);
276
+
277
+            $this->publishEvent($user, 'twofactor_failed', [
278
+                'provider' => $provider->getDisplayName(),
279
+            ]);
280
+        }
281
+        return $passed;
282
+    }
283
+
284
+    /**
285
+     * Push a 2fa event the user's activity stream
286
+     *
287
+     * @param IUser $user
288
+     * @param string $event
289
+     * @param array $params
290
+     */
291
+    private function publishEvent(IUser $user, string $event, array $params) {
292
+        $activity = $this->activityManager->generateEvent();
293
+        $activity->setApp('core')
294
+            ->setType('security')
295
+            ->setAuthor($user->getUID())
296
+            ->setAffectedUser($user->getUID())
297
+            ->setSubject($event, $params);
298
+        try {
299
+            $this->activityManager->publish($activity);
300
+        } catch (BadMethodCallException $e) {
301
+            $this->logger->warning('could not publish activity', ['app' => 'core']);
302
+            $this->logger->logException($e, ['app' => 'core']);
303
+        }
304
+    }
305
+
306
+    /**
307
+     * Check if the currently logged in user needs to pass 2FA
308
+     *
309
+     * @param IUser $user the currently logged in user
310
+     * @return boolean
311
+     */
312
+    public function needsSecondFactor(IUser $user = null): bool {
313
+        if ($user === null) {
314
+            return false;
315
+        }
316
+
317
+        // If we are authenticated using an app password skip all this
318
+        if ($this->session->exists('app_password')) {
319
+            return false;
320
+        }
321
+
322
+        // First check if the session tells us we should do 2FA (99% case)
323
+        if (!$this->session->exists(self::SESSION_UID_KEY)) {
324
+
325
+            // Check if the session tells us it is 2FA authenticated already
326
+            if ($this->session->exists(self::SESSION_UID_DONE) &&
327
+                $this->session->get(self::SESSION_UID_DONE) === $user->getUID()) {
328
+                return false;
329
+            }
330
+
331
+            /*
332 332
 			 * If the session is expired check if we are not logged in by a token
333 333
 			 * that still needs 2FA auth
334 334
 			 */
335
-			try {
336
-				$sessionId = $this->session->getId();
337
-				$token = $this->tokenProvider->getToken($sessionId);
338
-				$tokenId = $token->getId();
339
-				$tokensNeeding2FA = $this->config->getUserKeys($user->getUID(), 'login_token_2fa');
340
-
341
-				if (!\in_array($tokenId, $tokensNeeding2FA, true)) {
342
-					$this->session->set(self::SESSION_UID_DONE, $user->getUID());
343
-					return false;
344
-				}
345
-			} catch (InvalidTokenException $e) {
346
-			}
347
-		}
348
-
349
-		if (!$this->isTwoFactorAuthenticated($user)) {
350
-			// There is no second factor any more -> let the user pass
351
-			//   This prevents infinite redirect loops when a user is about
352
-			//   to solve the 2FA challenge, and the provider app is
353
-			//   disabled the same time
354
-			$this->session->remove(self::SESSION_UID_KEY);
355
-
356
-			$keys = $this->config->getUserKeys($user->getUID(), 'login_token_2fa');
357
-			foreach ($keys as $key) {
358
-				$this->config->deleteUserValue($user->getUID(), 'login_token_2fa', $key);
359
-			}
360
-			return false;
361
-		}
362
-
363
-		return true;
364
-	}
365
-
366
-	/**
367
-	 * Prepare the 2FA login
368
-	 *
369
-	 * @param IUser $user
370
-	 * @param boolean $rememberMe
371
-	 */
372
-	public function prepareTwoFactorLogin(IUser $user, bool $rememberMe) {
373
-		$this->session->set(self::SESSION_UID_KEY, $user->getUID());
374
-		$this->session->set(self::REMEMBER_LOGIN, $rememberMe);
375
-
376
-		$id = $this->session->getId();
377
-		$token = $this->tokenProvider->getToken($id);
378
-		$this->config->setUserValue($user->getUID(), 'login_token_2fa', $token->getId(), $this->timeFactory->getTime());
379
-	}
335
+            try {
336
+                $sessionId = $this->session->getId();
337
+                $token = $this->tokenProvider->getToken($sessionId);
338
+                $tokenId = $token->getId();
339
+                $tokensNeeding2FA = $this->config->getUserKeys($user->getUID(), 'login_token_2fa');
340
+
341
+                if (!\in_array($tokenId, $tokensNeeding2FA, true)) {
342
+                    $this->session->set(self::SESSION_UID_DONE, $user->getUID());
343
+                    return false;
344
+                }
345
+            } catch (InvalidTokenException $e) {
346
+            }
347
+        }
348
+
349
+        if (!$this->isTwoFactorAuthenticated($user)) {
350
+            // There is no second factor any more -> let the user pass
351
+            //   This prevents infinite redirect loops when a user is about
352
+            //   to solve the 2FA challenge, and the provider app is
353
+            //   disabled the same time
354
+            $this->session->remove(self::SESSION_UID_KEY);
355
+
356
+            $keys = $this->config->getUserKeys($user->getUID(), 'login_token_2fa');
357
+            foreach ($keys as $key) {
358
+                $this->config->deleteUserValue($user->getUID(), 'login_token_2fa', $key);
359
+            }
360
+            return false;
361
+        }
362
+
363
+        return true;
364
+    }
365
+
366
+    /**
367
+     * Prepare the 2FA login
368
+     *
369
+     * @param IUser $user
370
+     * @param boolean $rememberMe
371
+     */
372
+    public function prepareTwoFactorLogin(IUser $user, bool $rememberMe) {
373
+        $this->session->set(self::SESSION_UID_KEY, $user->getUID());
374
+        $this->session->set(self::REMEMBER_LOGIN, $rememberMe);
375
+
376
+        $id = $this->session->getId();
377
+        $token = $this->tokenProvider->getToken($id);
378
+        $this->config->setUserValue($user->getUID(), 'login_token_2fa', $token->getId(), $this->timeFactory->getTime());
379
+    }
380 380
 
381 381
 }
Please login to merge, or discard this patch.