Merge pull request #11409 from nextcloud/feature/consolidated-2fa-settings
Consolidate personal two-factor provider settings
This commit is contained in:
commit
f9e201adfe
13 changed files with 225 additions and 66 deletions
Binary file not shown.
Binary file not shown.
|
@ -25,12 +25,15 @@ namespace OCA\TwoFactorBackupCodes\Provider;
|
|||
|
||||
use OC\App\AppManager;
|
||||
use OCA\TwoFactorBackupCodes\Service\BackupCodeStorage;
|
||||
use OCA\TwoFactorBackupCodes\Settings\Personal;
|
||||
use OCP\Authentication\TwoFactorAuth\IPersonalProviderSettings;
|
||||
use OCP\Authentication\TwoFactorAuth\IProvider;
|
||||
use OCP\Authentication\TwoFactorAuth\IProvidesPersonalSettings;
|
||||
use OCP\IL10N;
|
||||
use OCP\IUser;
|
||||
use OCP\Template;
|
||||
|
||||
class BackupCodesProvider implements IProvider {
|
||||
class BackupCodesProvider implements IProvider, IProvidesPersonalSettings {
|
||||
|
||||
/** @var string */
|
||||
private $appName;
|
||||
|
@ -139,4 +142,14 @@ class BackupCodesProvider implements IProvider {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IUser $user
|
||||
*
|
||||
* @return IPersonalProviderSettings
|
||||
*/
|
||||
public function getPersonalSettings(IUser $user): IPersonalProviderSettings {
|
||||
return new Personal();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de>
|
||||
*
|
||||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
|
||||
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
|
@ -24,59 +25,13 @@
|
|||
namespace OCA\TwoFactorBackupCodes\Settings;
|
||||
|
||||
|
||||
use OCA\TwoFactorBackupCodes\AppInfo\Application;
|
||||
use OCA\TwoFactorBackupCodes\Provider\BackupCodesProvider;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\IUserSession;
|
||||
use OCP\Settings\ISettings;
|
||||
use OCP\Authentication\TwoFactorAuth\IPersonalProviderSettings;
|
||||
use OCP\Template;
|
||||
|
||||
class Personal implements ISettings {
|
||||
class Personal implements IPersonalProviderSettings {
|
||||
|
||||
/** @var Application */
|
||||
private $app;
|
||||
/** @var BackupCodesProvider */
|
||||
private $provider;
|
||||
/** @var IUserSession */
|
||||
private $userSession;
|
||||
|
||||
public function __construct(Application $app, BackupCodesProvider $provider, IUserSession $userSession) {
|
||||
$this->app = $app;
|
||||
$this->provider = $provider;
|
||||
$this->userSession = $userSession;
|
||||
public function getBody(): Template {
|
||||
return new Template('twofactor_backupcodes', 'personal');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TemplateResponse returns the instance with all parameters set, ready to be rendered
|
||||
* @since 9.1
|
||||
*/
|
||||
public function getForm() {
|
||||
$templateOwner = 'settings';
|
||||
$templateName = 'settings/empty';
|
||||
if ($this->provider->isActive($this->userSession->getUser())) {
|
||||
$templateOwner = $this->app->getContainer()->getAppName();
|
||||
$templateName = 'personal';
|
||||
}
|
||||
|
||||
return new TemplateResponse($templateOwner, $templateName, [], '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the section ID, e.g. 'sharing'
|
||||
* @since 9.1
|
||||
*/
|
||||
public function getSection() {
|
||||
return 'security';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int whether the form should be rather on the top or bottom of
|
||||
* the admin section. The forms are arranged in ascending order of the
|
||||
* priority values. It is required to return a value between 0 and 100.
|
||||
*
|
||||
* E.g.: 70
|
||||
* @since 9.1
|
||||
*/
|
||||
public function getPriority() {
|
||||
return 40;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<li v-for="code in codes" class="backup-code">{{code}}</li>
|
||||
</ul>
|
||||
<a :href="downloadUrl"
|
||||
class="button"
|
||||
class="button primary"
|
||||
download="Nextcloud-backup-codes.txt">{{ t('twofactor_backupcodes', 'Save backup codes') }}</a>
|
||||
<button class="button"
|
||||
v-on:click="printCodes">{{ t('twofactor_backupcodes', 'Print backup codes') }}</button>
|
||||
|
@ -25,9 +25,9 @@
|
|||
:class="{'icon-loading-small': generatingCodes}"
|
||||
v-on:click="generateBackupCodes">{{ t('twofactor_backupcodes', 'Regenerate backup codes') }}</button>
|
||||
</p>
|
||||
<p>
|
||||
<p><em>
|
||||
{{ t('twofactor_backupcodes', 'If you regenerate backup codes, you automatically invalidate old codes.') }}
|
||||
</p>
|
||||
</em></p>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -5,7 +5,4 @@ style('twofactor_backupcodes', 'style');
|
|||
|
||||
?>
|
||||
|
||||
<div class="section">
|
||||
<h2 data-anchor-name="second-factor-backup-codes"><?php p($l->t('Second-factor backup codes')); ?></h2>
|
||||
<div id="twofactor-backupcodes-settings"></div>
|
||||
</div>
|
||||
<div id="twofactor-backupcodes-settings"></div>
|
||||
|
|
|
@ -72,9 +72,11 @@ return array(
|
|||
'OCP\\Authentication\\LoginCredentials\\IStore' => $baseDir . '/lib/public/Authentication/LoginCredentials/IStore.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IActivatableByAdmin' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IActivatableByAdmin.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IDeactivatableByAdmin' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IDeactivatableByAdmin.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IPersonalProviderSettings' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IPersonalProviderSettings.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IProvider' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IProvider.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IProvidesCustomCSP' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IProvidesCustomCSP.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IProvidesIcons' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IProvidesIcons.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IProvidesPersonalSettings' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IProvidesPersonalSettings.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IRegistry' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IRegistry.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\RegistryEvent' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/RegistryEvent.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\TwoFactorException' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/TwoFactorException.php',
|
||||
|
|
|
@ -102,9 +102,11 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
|
|||
'OCP\\Authentication\\LoginCredentials\\IStore' => __DIR__ . '/../../..' . '/lib/public/Authentication/LoginCredentials/IStore.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IActivatableByAdmin' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IActivatableByAdmin.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IDeactivatableByAdmin' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IDeactivatableByAdmin.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IPersonalProviderSettings' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IPersonalProviderSettings.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IProvider' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IProvider.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IProvidesCustomCSP' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IProvidesCustomCSP.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IProvidesIcons' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IProvidesIcons.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IProvidesPersonalSettings' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IProvidesPersonalSettings.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\IRegistry' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IRegistry.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\RegistryEvent' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/RegistryEvent.php',
|
||||
'OCP\\Authentication\\TwoFactorAuth\\TwoFactorException' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/TwoFactorException.php',
|
||||
|
|
|
@ -24,18 +24,41 @@
|
|||
namespace OC\Settings\Personal;
|
||||
|
||||
|
||||
use function array_filter;
|
||||
use function array_map;
|
||||
use function is_null;
|
||||
use OC\Authentication\TwoFactorAuth\Manager as TwoFactorManager;
|
||||
use OC\Authentication\TwoFactorAuth\ProviderLoader;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\Authentication\TwoFactorAuth\IProvider;
|
||||
use OCP\Authentication\TwoFactorAuth\IProvidesPersonalSettings;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IUserSession;
|
||||
use OCP\Settings\ISettings;
|
||||
|
||||
class Security implements ISettings {
|
||||
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
|
||||
public function __construct(
|
||||
IUserManager $userManager
|
||||
) {
|
||||
/** @var TwoFactorManager */
|
||||
private $twoFactorManager;
|
||||
|
||||
/** @var ProviderLoader */
|
||||
private $providerLoader;
|
||||
|
||||
/** @var IUserSession */
|
||||
private $userSession;
|
||||
|
||||
|
||||
public function __construct(IUserManager $userManager,
|
||||
TwoFactorManager $providerManager,
|
||||
ProviderLoader $providerLoader,
|
||||
IUserSession $userSession) {
|
||||
$this->userManager = $userManager;
|
||||
$this->twoFactorManager = $providerManager;
|
||||
$this->providerLoader = $providerLoader;
|
||||
$this->userSession = $userSession;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -50,7 +73,8 @@ class Security implements ISettings {
|
|||
}
|
||||
|
||||
return new TemplateResponse('settings', 'settings/personal/security', [
|
||||
'passwordChangeSupported' => $passwordChangeSupported
|
||||
'passwordChangeSupported' => $passwordChangeSupported,
|
||||
'twoFactorProviderData' => $this->getTwoFactorProviderData(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -73,4 +97,24 @@ class Security implements ISettings {
|
|||
public function getPriority() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
private function getTwoFactorProviderData(): array {
|
||||
$user = $this->userSession->getUser();
|
||||
if (is_null($user)) {
|
||||
// Actually impossible, but still …
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'isEnabled' => $this->twoFactorManager->isTwoFactorAuthenticated($user),
|
||||
'providers' => array_map(function (IProvidesPersonalSettings $provider) use ($user) {
|
||||
return [
|
||||
'provider' => $provider,
|
||||
'settings' => $provider->getPersonalSettings($user)
|
||||
];
|
||||
}, array_filter($this->providerLoader->getProviders($user), function (IProvider $provider) {
|
||||
return $provider instanceof IProvidesPersonalSettings;
|
||||
}))
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @author Christoph Wurst <christoph@owncloud.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCP\Authentication\TwoFactorAuth;
|
||||
|
||||
use OCP\Template;
|
||||
|
||||
/**
|
||||
* Interface IPersonalProviderSettings
|
||||
*
|
||||
* @since 15.0.0
|
||||
*/
|
||||
interface IPersonalProviderSettings {
|
||||
|
||||
/**
|
||||
* @return Template
|
||||
*
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getBody(): Template;
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @author Christoph Wurst <christoph@owncloud.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCP\Authentication\TwoFactorAuth;
|
||||
|
||||
use OCP\IUser;
|
||||
|
||||
/**
|
||||
* Interface for admins that have personal settings. These settings will be shown in the
|
||||
* security sections. Some information like the display name of the provider is read
|
||||
* from the provider directly.
|
||||
*
|
||||
* @since 15.0.0
|
||||
*/
|
||||
interface IProvidesPersonalSettings extends IProvider {
|
||||
|
||||
/**
|
||||
* @param IUser $user
|
||||
*
|
||||
* @return IPersonalProviderSettings
|
||||
*
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getPersonalSettings(IUser $user): IPersonalProviderSettings;
|
||||
|
||||
}
|
|
@ -471,6 +471,27 @@ table.nostyle {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Two-Factor Authentication (2FA) */
|
||||
|
||||
#two-factor-auth {
|
||||
h3 {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
li > div {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.two-factor-provider-settings-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: sub;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#new-app-login-name,
|
||||
#new-app-password {
|
||||
width: 245px;
|
||||
|
|
|
@ -101,3 +101,38 @@ if($_['passwordChangeSupported']) {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="two-factor-auth" class="section">
|
||||
<h2><?php p($l->t('Two-Factor Authentication'));?></h2>
|
||||
<p class="settings-hint">
|
||||
<?php
|
||||
if ($_['twoFactorProviderData']['enabled']) {
|
||||
p($l->t('Two-factor authentication is enabled on your account.'));
|
||||
} else {
|
||||
p($l->t('Two-factor authentication is disabled on your account.'));
|
||||
}
|
||||
?>
|
||||
</p>
|
||||
<ul>
|
||||
<?php foreach ($_['twoFactorProviderData']['providers'] as $data) { ?>
|
||||
<li>
|
||||
<?php
|
||||
/** @var \OCP\Authentication\TwoFactorAuth\IProvidesPersonalSettings $provider */
|
||||
$provider = $data['provider'];
|
||||
if ($provider instanceof \OCP\Authentication\TwoFactorAuth\IProvidesIcons) {
|
||||
$icon = $provider->getDarkIcon();
|
||||
} else {
|
||||
$icon = image_path('core', 'actions/password.svg');
|
||||
}
|
||||
/** @var \OCP\Authentication\TwoFactorAuth\IPersonalProviderSettings $settings */
|
||||
$settings = $data['settings'];
|
||||
?>
|
||||
<h3>
|
||||
<img class="two-factor-provider-settings-icon" src="<?php p($icon) ?>" alt="">
|
||||
<?php p($provider->getDisplayName()) ?>
|
||||
</h3>
|
||||
<?php print_unescaped($settings->getBody()->fetchPage()) ?>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue