diff --git a/l10n/de.js b/l10n/de.js index 46823807c0b0529486c65f7bea7209d478e71645..47243d093f3c4b81b18aa2ca6be4fa179bb907f2 100644 --- a/l10n/de.js +++ b/l10n/de.js @@ -38,6 +38,8 @@ OC.L10N.register( "Here is the list of currently available beta features:": "Hier ist die Liste der derzeit verfügbaren Beta-Funktionen:", "A subscription is active in this account. Please cancel it or let it expire before deleting your account.": "Für dieses Konto ist ein Abonnement aktiv. Bitte kündigen Sie es oder lassen Sie es auslaufen, bevor Sie Ihr Konto löschen.", "Loading...": "Laden...", - "Temporary error contacting murena.com; please try again later!": "Vorübergehender Fehler bei der Kontaktaufnahme mit murena.com; bitte versuchen Sie es später noch einmal!" + "Temporary error contacting murena.com; please try again later!": "Vorübergehender Fehler bei der Kontaktaufnahme mit murena.com; bitte versuchen Sie es später noch einmal!", + "Murena Cloud 2FA": "Murena Cloud 2FA" + }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/de.json b/l10n/de.json index b94ac70996e19245b316afeb864ec612ae964f0b..d70e6d9c48b8c7b5eae7f582a3f34c565ba4caf8 100644 --- a/l10n/de.json +++ b/l10n/de.json @@ -37,7 +37,8 @@ "Here is the list of currently available beta features:": "Hier ist die Liste der derzeit verfügbaren Beta-Funktionen:", "A subscription is active in this account. Please cancel it or let it expire before deleting your account.": "Für dieses Konto ist ein Abonnement aktiv. Bitte kündigen Sie es oder lassen Sie es auslaufen, bevor Sie Ihr Konto löschen.", "Loading...": "Laden...", - "Temporary error contacting murena.com; please try again later!": "Vorübergehender Fehler bei der Kontaktaufnahme mit murena.com; bitte versuchen Sie es später noch einmal!" + "Temporary error contacting murena.com; please try again later!": "Vorübergehender Fehler bei der Kontaktaufnahme mit murena.com; bitte versuchen Sie es später noch einmal!", + "Murena Cloud 2FA": "Murena Cloud 2FA" }, "pluralForm": "nplurals=2; plural=(n != 1);" } diff --git a/l10n/en.js b/l10n/en.js index bc284754685fa5b3591900c770a0c11c91665552..422054cf050c82973efbe9ff477421bcf45e3e78 100644 --- a/l10n/en.js +++ b/l10n/en.js @@ -40,6 +40,7 @@ OC.L10N.register( "Here is the list of currently available beta features:": "Here is the list of currently available beta features:", "A subscription is active in this account. Please cancel it or let it expire before deleting your account.": "A subscription is active in this account. Please cancel it or let it expire before deleting your account.", "Loading...": "Loading...", - "Temporary error contacting murena.com; please try again later!": "Temporary error contacting murena.com; please try again later!" + "Temporary error contacting murena.com; please try again later!": "Temporary error contacting murena.com; please try again later!", + "Murena Cloud 2FA": "Murena Cloud 2FA" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/en.json b/l10n/en.json index bdcda7af86cadb8db63f08a1eea23a796363dd22..83db6b42ebd09872e59fa0184ad360b3886fa76d 100644 --- a/l10n/en.json +++ b/l10n/en.json @@ -37,7 +37,8 @@ "Here is the list of currently available beta features:": "Here is the list of currently available beta features:", "A subscription is active in this account. Please cancel it or let it expire before deleting your account.": "A subscription is active in this account. Please cancel it or let it expire before deleting your account.", "Loading...": "Loading...", - "Temporary error contacting murena.com; please try again later!": "Temporary error contacting murena.com; please try again later!" + "Temporary error contacting murena.com; please try again later!": "Temporary error contacting murena.com; please try again later!", + "Murena Cloud 2FA": "Murena Cloud 2FA" }, "pluralForm": "nplurals=2; plural=(n != 1);" } diff --git a/l10n/es.js b/l10n/es.js index 713bffb6b47943bdb3fe6a9ba3078147e457b977..3a081dd1f065b26659ffbe20f81e80cd92e5dc03 100644 --- a/l10n/es.js +++ b/l10n/es.js @@ -39,6 +39,7 @@ OC.L10N.register( "Here is the list of currently available beta features:": "Esta es la lista de funciones de la versión beta disponibles actualmente:", "A subscription is active in this account. Please cancel it or let it expire before deleting your account.": "Hay una suscripción activa en esta cuenta. Por favor, cancélala o deja que expire antes de eliminar tu cuenta.", "Loading...": "Cargando...", - "Temporary error contacting murena.com; please try again later!": "Error temporal al contactar con murena.com; ¡por favor, inténtalo más tarde!" + "Temporary error contacting murena.com; please try again later!": "Error temporal al contactar con murena.com; ¡por favor, inténtalo más tarde!", + "Murena Cloud 2FA": "Nube Murena A2F" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/es.json b/l10n/es.json index fc0959d3b69ec60265984a7d2bfe05800cb99480..b85948651e29e601a4e765f2a30317a0abeadf6b 100644 --- a/l10n/es.json +++ b/l10n/es.json @@ -37,7 +37,8 @@ "Here is the list of currently available beta features:": "Esta es la lista de funciones de la versión beta disponibles actualmente:", "A subscription is active in this account. Please cancel it or let it expire before deleting your account.": "Hay una suscripción activa en esta cuenta. Por favor, cancélala o deja que expire antes de eliminar tu cuenta.", "Loading...": "Cargando...", - "Temporary error contacting murena.com; please try again later!": "Error temporal al contactar con murena.com; ¡por favor, inténtalo más tarde!" + "Temporary error contacting murena.com; please try again later!": "Error temporal al contactar con murena.com; ¡por favor, inténtalo más tarde!", + "Murena Cloud 2FA": "Nube Murena A2F" }, "pluralForm": "nplurals=2; plural=(n != 1);" } diff --git a/l10n/fr.js b/l10n/fr.js index 11002b93d2fc29910ad7fbf29ff325971dd1539c..1f668c1fe41989b17f237785be77526930d9fba4 100644 --- a/l10n/fr.js +++ b/l10n/fr.js @@ -38,6 +38,7 @@ OC.L10N.register( "Here is the list of currently available beta features:": "Voici la liste des fonctionnalités de la version bêta actuellement disponibles :", "A subscription is active in this account. Please cancel it or let it expire before deleting your account.": "Un abonnement est actif dans ce compte. Veuillez l'annuler ou le laisser expirer avant de supprimer votre compte.", "Loading...": "Chargement...", - "Temporary error contacting murena.com; please try again later!": "Erreur temporaire en contactant murena.com ; veuillez réessayer plus tard !" + "Temporary error contacting murena.com; please try again later!": "Erreur temporaire en contactant murena.com ; veuillez réessayer plus tard !", + "Murena Cloud 2FA": "Authentification à 2 facteurs Murena Cloud" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/fr.json b/l10n/fr.json index 1a3e3ae4a6f6b88d19f67fd2bbe13e1ce6d43b11..48a79c476f72f15dcc0fd72f89a12e6e26092bbf 100644 --- a/l10n/fr.json +++ b/l10n/fr.json @@ -37,7 +37,8 @@ "Here is the list of currently available beta features:": "Voici la liste des fonctionnalités de la version bêta actuellement disponibles :", "A subscription is active in this account. Please cancel it or let it expire before deleting your account.": "Un abonnement est actif dans ce compte. Veuillez l'annuler ou le laisser expirer avant de supprimer votre compte.", "Loading...": "Chargement...", - "Temporary error contacting murena.com; please try again later!": "Erreur temporaire en contactant murena.com ; veuillez réessayer plus tard !" + "Temporary error contacting murena.com; please try again later!": "Erreur temporaire en contactant murena.com ; veuillez réessayer plus tard !", + "Murena Cloud 2FA": "Authentification à 2 facteurs Murena Cloud" }, "pluralForm": "nplurals=2; plural=(n != 1);" } diff --git a/l10n/it.js b/l10n/it.js index 12976c0976267010ba78dfe21f21c0f1e97db09a..7dbe44342f44b4b438a69967d6809f1fbc043f44 100644 --- a/l10n/it.js +++ b/l10n/it.js @@ -38,6 +38,7 @@ OC.L10N.register( "Here is the list of currently available beta features:": "Ecco l'elenco delle funzioni beta attualmente disponibili:", "A subscription is active in this account. Please cancel it or let it expire before deleting your account.": "In questo account è attivo un abbonamento. Si prega di annullarlo o di lasciarlo scadere prima di cancellare l'account.", "Loading...": "Caricamento...", - "Temporary error contacting murena.com; please try again later!": "Errore temporaneo nel contattare murena.com; riprova più tardi!" + "Temporary error contacting murena.com; please try again later!": "Errore temporaneo nel contattare murena.com; riprova più tardi!", + "Murena Cloud 2FA": "Codice di Autenticazione a 2 Fattori Murena Cloud" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/it.json b/l10n/it.json index 2dc17b44b992016183dfbe332bd63199b0c76a2b..1c9cb7a01cefe6e4e596ea3a9bfa638ac99af307 100644 --- a/l10n/it.json +++ b/l10n/it.json @@ -37,7 +37,8 @@ "Here is the list of currently available beta features:": "Ecco l'elenco delle funzioni beta attualmente disponibili:", "A subscription is active in this account. Please cancel it or let it expire before deleting your account.": "In questo account è attivo un abbonamento. Si prega di annullarlo o di lasciarlo scadere prima di cancellare l'account.", "Loading...": "Caricamento...", - "Temporary error contacting murena.com; please try again later!": "Errore temporaneo nel contattare murena.com; riprova più tardi!" + "Temporary error contacting murena.com; please try again later!": "Errore temporaneo nel contattare murena.com; riprova più tardi!", + "Murena Cloud 2FA": "Codice di Autenticazione a 2 Fattori Murena Cloud" }, "pluralForm": "nplurals=2; plural=(n != 1);" } diff --git a/lib/Db/SSOMapper.php b/lib/Db/SSOMapper.php index d172ddda84849adfe4ccd4b771cbc2440720dc65..3cb62a85839ca8db0139802f6e147c334b652a36 100644 --- a/lib/Db/SSOMapper.php +++ b/lib/Db/SSOMapper.php @@ -6,10 +6,12 @@ use OCP\IConfig; use OCP\ILogger; use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\Connection; +use OCA\EcloudAccounts\AppInfo\Application; use OCP\IUserManager; use OCP\Security\ICrypto; use OCP\IUser; use OCA\EcloudAccounts\Exception\DbConnectionParamsException; +use OCP\L10N\IFactory; class SSOMapper { private IConfig $config; @@ -17,20 +19,14 @@ class SSOMapper { private Connection $conn; private IUserManager $userManager; private ICrypto $crypto; + private IFactory $l10nFactory; private const USER_ATTRIBUTE_TABLE = 'USER_ATTRIBUTE'; private const CREDENTIAL_TABLE = 'CREDENTIAL'; - private const SSO_CONFIG_KEY = 'keycloak'; - private const USER_LABELS = [ - 'en' => 'Murena Cloud 2FA', - 'es' => 'Murena Cloud 2FA', - 'de' => 'Murena Cloud 2FA', - 'it' => 'Murena Cloud 2FA', - 'fr' => 'Murena Cloud 2FA', - ]; - - public function __construct(IConfig $config, IUserManager $userManager, ILogger $logger, ICrypto $crypto) { + + public function __construct(IConfig $config, IUserManager $userManager, ILogger $logger, ICrypto $crypto, IFactory $l10nFactory) { + $this->l10nFactory = $l10nFactory; $this->config = $config; $this->logger = $logger; $this->userManager = $userManager; @@ -38,6 +34,10 @@ class SSOMapper { $this->initConnection(); } + public function isSSOEnabled() : bool { + return isset($this->conn); + } + public function getUserId(string $username) : string { $qb = $this->conn->createQueryBuilder(); $qb->select('USER_ID') @@ -50,13 +50,13 @@ class SSOMapper { return (string) $result->fetchOne(); } - public function deleteCredential(string $username) { + public function deleteCredentials(string $username) { $userId = $this->getUserId($username); $qb = $this->conn->createQueryBuilder(); $qb->delete(self::CREDENTIAL_TABLE) ->where('USER_ID = :username') ->andWhere('TYPE = "otp"') - ->andWhere('CREDENTIAL_DATA LIKE "%\"subType\":\"nextcloud_totp\"%"') + ->andWhere('CREDENTIAL_DATA LIKE "%\"subType\":\"nextcloud_totp\"%" OR CREDENTIAL_DATA LIKE "%\"subType\":\"totp\"%"') ->setParameter('username', $userId) ->execute(); } @@ -73,12 +73,9 @@ class SSOMapper { } $language = $this->config->getUserValue($username, 'core', 'lang', 'en'); - if (!array_key_exists($language, self::USER_LABELS)) { - $language = 'en'; - } - // Only one "nextcloud_totp" at a time - $this->deleteCredential($username); + // Only one 2FA device at a time + $this->deleteCredentials($username); $entry = $this->getCredentialEntry($decryptedSecret, $ssoUserId, $language); $this->insertCredential($entry); @@ -101,7 +98,9 @@ class SSOMapper { // Create the random UUID from the sso user ID so multiple entries of same credential do not happen $id = $this->randomUUID(substr($ssoUserId, 0, 16)); - $userLabel = self::USER_LABELS[$language]; + $l10n = $this->l10nFactory->get(Application::APP_ID, $language); + $userLabel = $l10n->t('Murena Cloud 2FA'); + $credentialEntry = [ 'ID' => $id, 'USER_ID' => $ssoUserId, diff --git a/lib/Listeners/TwoFactorStateChangedListener.php b/lib/Listeners/TwoFactorStateChangedListener.php index 860ad4b64eb8f411076dd09e724b3dae009cc573..9624abdb67cc7803c163576ec26b0118138df9bb 100644 --- a/lib/Listeners/TwoFactorStateChangedListener.php +++ b/lib/Listeners/TwoFactorStateChangedListener.php @@ -31,16 +31,17 @@ class TwoFactorStateChangedListener implements IEventListener { public function handle(Event $event): void { - if (!($event instanceof StateChanged) || !$this->appManager->isEnabledForUser(self::TWOFACTOR_APP_ID)) { + if (!($event instanceof StateChanged) || !$this->appManager->isEnabledForUser(self::TWOFACTOR_APP_ID) || !$this->ssoMapper->isSSOEnabled()) { return; } $user = $event->getUser(); $username = $user->getUID(); try { - // When state change event is fired by user disabling 2FA, delete existing credential and return + // When state change event is fired by user disabling 2FA, delete existing 2FA credentials and return + // i.e. disable 2FA for user at SSO if (!$event->isEnabled()) { - $this->ssoMapper->deleteCredential($username); + $this->ssoMapper->deleteCredentials($username); return; }