// SPDX-License-Identifier: GPL-3.0-or-later namespace Icinga\Authentication; use Icinga\Application\Hook\TwoFactorHook; use Icinga\User; use ipl\Html\FormElement\FieldsetElement; /** * Contract for a two-factor authentication method */ interface TwoFactor { /** * Get the unique machine-readable identifier for this 2FA method * * Used as a stable key to look up the implementation by name, e.g. via {@see TwoFactorHook::fromName()}. * * @return string Lowercase identifier for this method, e.g. 'totp' */ public function getName(): string; /** * Get the human-readable name for this 2FA method shown in the UI * * @return string Human-readable name for this method, e.g. 'TOTP' */ public function getDisplayName(): string; /** * Check whether a user is enrolled in this 2FA method * * Implementations typically query the database for a stored credential (secret, key, ...). * * @param ?User $user The user to check for. If null, the currently * authenticated user is resolved via {@see Auth::getUser()} * * @return bool True if enrolled, false if not enrolled or if the * credential lookup fails */ public function isEnrolled(?User $user = null): bool; /** * Verify a 2FA token provided by the user * * Called during login to verify the two-factor challenge. Implementations should * call this from within {@see enroll()} to confirm the credential works. * * @param string $token The raw token string entered by the user, e.g. a 6-digit TOTP code * * @return bool True if the token is valid, false otherwise */ public function verify(string $token): bool; /** * Verify the submitted credential and persist it for the currently authenticated user * * Called from {@see TwoFactorEnrollmentForm::onSuccess()} when the enroll * button is pressed. Read the method-specific values from $fieldset, verify * that the credential works, and store it on success. * * @param FieldsetElement $fieldset The method-specific fieldset containing the submitted * credential elements * * @return bool True if the credential was verified and stored, false if verification * failed. On failure, attach a user-visible error to the relevant element in * $fieldset via {@see FieldsetElement::addMessage()}. */ public function enroll(FieldsetElement $fieldset): bool; /** * Remove the stored credential for the currently authenticated user * * Called from {@see TwoFactorEnrollmentForm::onSuccess()} when the unenroll button is pressed. * * @return void */ public function unenroll(): void; /** * Add the method-specific elements to the enrollment config fieldset * * Called from {@see TwoFactorEnrollmentForm::assemble()}. * * @param FieldsetElement $fieldset The method-specific fieldset to add elements to * * @return void */ public function assembleEnrollmentFormElements(FieldsetElement $fieldset): void; }