Merge pull request #11765 from nextcloud/feature/mandatory-2fa-for-groups
Mandatory 2FA for groups
This commit is contained in:
commit
8177fdb0f6
|
@ -26,6 +26,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace OC\Core\Command\TwoFactorAuth;
|
||||
|
||||
use function implode;
|
||||
use OC\Authentication\TwoFactorAuth\EnforcementState;
|
||||
use OC\Authentication\TwoFactorAuth\MandatoryTwoFactor;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
|
@ -58,17 +60,32 @@ class Enforce extends Command {
|
|||
InputOption::VALUE_NONE,
|
||||
'don\'t enforce two-factor authenticaton'
|
||||
);
|
||||
$this->addOption(
|
||||
'group',
|
||||
null,
|
||||
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
|
||||
'enforce only for the given group(s)'
|
||||
);
|
||||
$this->addOption(
|
||||
'exclude',
|
||||
null,
|
||||
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
|
||||
'exclude mandatory two-factor auth for the given group(s)'
|
||||
);
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output) {
|
||||
if ($input->getOption('on')) {
|
||||
$this->mandatoryTwoFactor->setEnforced(true);
|
||||
$enforcedGroups = $input->getOption('group');
|
||||
$excludedGroups = $input->getOption('exclude');
|
||||
$this->mandatoryTwoFactor->setState(new EnforcementState(true, $enforcedGroups, $excludedGroups));
|
||||
} elseif ($input->getOption('off')) {
|
||||
$this->mandatoryTwoFactor->setEnforced(false);
|
||||
$this->mandatoryTwoFactor->setState(new EnforcementState(false));
|
||||
}
|
||||
|
||||
if ($this->mandatoryTwoFactor->isEnforced()) {
|
||||
$this->writeEnforced($output);
|
||||
$state = $this->mandatoryTwoFactor->getState();
|
||||
if ($state->isEnforced()) {
|
||||
$this->writeEnforced($output, $state);
|
||||
} else {
|
||||
$this->writeNotEnforced($output);
|
||||
}
|
||||
|
@ -77,8 +94,16 @@ class Enforce extends Command {
|
|||
/**
|
||||
* @param OutputInterface $output
|
||||
*/
|
||||
protected function writeEnforced(OutputInterface $output) {
|
||||
$output->writeln('Two-factor authentication is enforced for all users');
|
||||
protected function writeEnforced(OutputInterface $output, EnforcementState $state) {
|
||||
if (empty($state->getEnforcedGroups())) {
|
||||
$message = 'Two-factor authentication is enforced for all users';
|
||||
} else {
|
||||
$message = 'Two-factor authentication is enforced for members of the group(s) ' . implode(', ', $state->getEnforcedGroups());
|
||||
}
|
||||
if (!empty($state->getExcludedGroups())) {
|
||||
$message .= ', except members of ' . implode(', ', $state->getExcludedGroups());
|
||||
}
|
||||
$output->writeln($message);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -460,6 +460,7 @@ return array(
|
|||
'OC\\Authentication\\Token\\PublicKeyTokenMapper' => $baseDir . '/lib/private/Authentication/Token/PublicKeyTokenMapper.php',
|
||||
'OC\\Authentication\\Token\\PublicKeyTokenProvider' => $baseDir . '/lib/private/Authentication/Token/PublicKeyTokenProvider.php',
|
||||
'OC\\Authentication\\TwoFactorAuth\\Db\\ProviderUserAssignmentDao' => $baseDir . '/lib/private/Authentication/TwoFactorAuth/Db/ProviderUserAssignmentDao.php',
|
||||
'OC\\Authentication\\TwoFactorAuth\\EnforcementState' => $baseDir . '/lib/private/Authentication/TwoFactorAuth/EnforcementState.php',
|
||||
'OC\\Authentication\\TwoFactorAuth\\Manager' => $baseDir . '/lib/private/Authentication/TwoFactorAuth/Manager.php',
|
||||
'OC\\Authentication\\TwoFactorAuth\\MandatoryTwoFactor' => $baseDir . '/lib/private/Authentication/TwoFactorAuth/MandatoryTwoFactor.php',
|
||||
'OC\\Authentication\\TwoFactorAuth\\ProviderLoader' => $baseDir . '/lib/private/Authentication/TwoFactorAuth/ProviderLoader.php',
|
||||
|
|
|
@ -490,6 +490,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
|
|||
'OC\\Authentication\\Token\\PublicKeyTokenMapper' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/PublicKeyTokenMapper.php',
|
||||
'OC\\Authentication\\Token\\PublicKeyTokenProvider' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/PublicKeyTokenProvider.php',
|
||||
'OC\\Authentication\\TwoFactorAuth\\Db\\ProviderUserAssignmentDao' => __DIR__ . '/../../..' . '/lib/private/Authentication/TwoFactorAuth/Db/ProviderUserAssignmentDao.php',
|
||||
'OC\\Authentication\\TwoFactorAuth\\EnforcementState' => __DIR__ . '/../../..' . '/lib/private/Authentication/TwoFactorAuth/EnforcementState.php',
|
||||
'OC\\Authentication\\TwoFactorAuth\\Manager' => __DIR__ . '/../../..' . '/lib/private/Authentication/TwoFactorAuth/Manager.php',
|
||||
'OC\\Authentication\\TwoFactorAuth\\MandatoryTwoFactor' => __DIR__ . '/../../..' . '/lib/private/Authentication/TwoFactorAuth/MandatoryTwoFactor.php',
|
||||
'OC\\Authentication\\TwoFactorAuth\\ProviderLoader' => __DIR__ . '/../../..' . '/lib/private/Authentication/TwoFactorAuth/ProviderLoader.php',
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2018 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
*
|
||||
* @author 2018 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
*
|
||||
* @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 OC\Authentication\TwoFactorAuth;
|
||||
|
||||
use JsonSerializable;
|
||||
|
||||
class EnforcementState implements JsonSerializable {
|
||||
|
||||
/** @var bool */
|
||||
private $enforced;
|
||||
|
||||
/** @var array */
|
||||
private $enforcedGroups;
|
||||
|
||||
/** @var array */
|
||||
private $excludedGroups;
|
||||
|
||||
/**
|
||||
* EnforcementState constructor.
|
||||
*
|
||||
* @param bool $enforced
|
||||
* @param string[] $enforcedGroups
|
||||
* @param string[] $excludedGroups
|
||||
*/
|
||||
public function __construct(bool $enforced,
|
||||
array $enforcedGroups = [],
|
||||
array $excludedGroups = []) {
|
||||
$this->enforced = $enforced;
|
||||
$this->enforcedGroups = $enforcedGroups;
|
||||
$this->excludedGroups = $excludedGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function isEnforced(): bool {
|
||||
return $this->enforced;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getEnforcedGroups(): array {
|
||||
return $this->enforcedGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getExcludedGroups(): array {
|
||||
return $this->excludedGroups;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array {
|
||||
return [
|
||||
'enforced' => $this->enforced,
|
||||
'enforcedGroups' => $this->enforcedGroups,
|
||||
'excludedGroups' => $this->excludedGroups,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -106,7 +106,7 @@ class Manager {
|
|||
* @return boolean
|
||||
*/
|
||||
public function isTwoFactorAuthenticated(IUser $user): bool {
|
||||
if ($this->mandatoryTwoFactor->isEnforced()) {
|
||||
if ($this->mandatoryTwoFactor->isEnforcedFor($user)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,22 +27,89 @@ declare(strict_types=1);
|
|||
namespace OC\Authentication\TwoFactorAuth;
|
||||
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUser;
|
||||
|
||||
class MandatoryTwoFactor {
|
||||
|
||||
/** @var IConfig */
|
||||
private $config;
|
||||
|
||||
public function __construct(IConfig $config) {
|
||||
/** @var IGroupManager */
|
||||
private $groupManager;
|
||||
|
||||
public function __construct(IConfig $config, IGroupManager $groupManager) {
|
||||
$this->config = $config;
|
||||
$this->groupManager = $groupManager;
|
||||
}
|
||||
|
||||
public function isEnforced(): bool {
|
||||
return $this->config->getSystemValue('twofactor_enforced', 'false') === 'true';
|
||||
/**
|
||||
* Get the state of enforced two-factor auth
|
||||
*/
|
||||
public function getState(): EnforcementState {
|
||||
return new EnforcementState(
|
||||
$this->config->getSystemValue('twofactor_enforced', 'false') === 'true',
|
||||
$this->config->getSystemValue('twofactor_enforced_groups', []),
|
||||
$this->config->getSystemValue('twofactor_enforced_excluded_groups', [])
|
||||
);
|
||||
}
|
||||
|
||||
public function setEnforced(bool $enforced) {
|
||||
$this->config->setSystemValue('twofactor_enforced', $enforced ? 'true' : 'false');
|
||||
/**
|
||||
* Set the state of enforced two-factor auth
|
||||
*/
|
||||
public function setState(EnforcementState $state) {
|
||||
$this->config->setSystemValue('twofactor_enforced', $state->isEnforced() ? 'true' : 'false');
|
||||
$this->config->setSystemValue('twofactor_enforced_groups', $state->getEnforcedGroups());
|
||||
$this->config->setSystemValue('twofactor_enforced_excluded_groups', $state->getExcludedGroups());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if two-factor auth is enforced for a specific user
|
||||
*
|
||||
* The admin(s) can enforce two-factor auth system-wide, for certain groups only
|
||||
* and also have the option to exclude users of certain groups. This method will
|
||||
* check their membership of those groups.
|
||||
*
|
||||
* @param IUser $user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnforcedFor(IUser $user): bool {
|
||||
$state = $this->getState();
|
||||
if (!$state->isEnforced()) {
|
||||
return false;
|
||||
}
|
||||
$uid = $user->getUID();
|
||||
|
||||
/*
|
||||
* If there is a list of enforced groups, we only enforce 2FA for members of those groups.
|
||||
* For all the other users it is not enforced (overruling the excluded groups list).
|
||||
*/
|
||||
if (!empty($state->getEnforcedGroups())) {
|
||||
foreach ($state->getEnforcedGroups() as $group) {
|
||||
if ($this->groupManager->isInGroup($uid, $group)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Not a member of any of these groups -> no 2FA enforced
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user is member of an excluded group, 2FA won't be enforced.
|
||||
*/
|
||||
foreach ($state->getExcludedGroups() as $group) {
|
||||
if ($this->groupManager->isInGroup($uid, $group)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* No enforced groups configured and user not member of an excluded groups,
|
||||
* so 2FA is enforced.
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -26,12 +26,11 @@ declare(strict_types=1);
|
|||
|
||||
namespace OC\Settings\Controller;
|
||||
|
||||
use OC\Authentication\TwoFactorAuth\EnforcementState;
|
||||
use OC\Authentication\TwoFactorAuth\MandatoryTwoFactor;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\IRequest;
|
||||
use OCP\JSON;
|
||||
|
||||
class TwoFactorSettingsController extends Controller {
|
||||
|
||||
|
@ -46,18 +45,16 @@ class TwoFactorSettingsController extends Controller {
|
|||
$this->mandatoryTwoFactor = $mandatoryTwoFactor;
|
||||
}
|
||||
|
||||
public function index(): Response {
|
||||
return new JSONResponse([
|
||||
'enabled' => $this->mandatoryTwoFactor->isEnforced(),
|
||||
]);
|
||||
public function index(): JSONResponse {
|
||||
return new JSONResponse($this->mandatoryTwoFactor->getState());
|
||||
}
|
||||
|
||||
public function update(bool $enabled): Response {
|
||||
$this->mandatoryTwoFactor->setEnforced($enabled);
|
||||
public function update(bool $enforced, array $enforcedGroups = [], array $excludedGroups = []): JSONResponse {
|
||||
$this->mandatoryTwoFactor->setState(
|
||||
new EnforcementState($enforced, $enforcedGroups, $excludedGroups)
|
||||
);
|
||||
|
||||
return new JSONResponse([
|
||||
'enabled' => $enabled
|
||||
]);
|
||||
return new JSONResponse($this->mandatoryTwoFactor->getState());
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -3292,8 +3292,7 @@
|
|||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
|
@ -3314,14 +3313,12 @@
|
|||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
|
@ -3336,20 +3333,17 @@
|
|||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
|
@ -3466,8 +3460,7 @@
|
|||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
|
@ -3479,7 +3472,6 @@
|
|||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
|
@ -3494,7 +3486,6 @@
|
|||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
|
@ -3502,14 +3493,12 @@
|
|||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.2.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.1",
|
||||
"yallist": "^3.0.0"
|
||||
|
@ -3528,7 +3517,6 @@
|
|||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
|
@ -3609,8 +3597,7 @@
|
|||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
|
@ -3622,7 +3609,6 @@
|
|||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
|
@ -3708,8 +3694,7 @@
|
|||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
|
@ -3745,7 +3730,6 @@
|
|||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
|
@ -3765,7 +3749,6 @@
|
|||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
|
@ -3809,14 +3792,12 @@
|
|||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -4689,10 +4670,9 @@
|
|||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.5",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz",
|
||||
"integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==",
|
||||
"dev": true
|
||||
"version": "4.17.11",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
|
||||
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
|
||||
},
|
||||
"lodash.assign": {
|
||||
"version": "4.2.0",
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.0.0",
|
||||
"lodash": "^4.17.11",
|
||||
"nextcloud-axios": "^0.1.2",
|
||||
"nextcloud-vue": "^0.2.0",
|
||||
"v-tooltip": "^2.0.0-rc.33",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div>
|
||||
<p>
|
||||
{{ t('settings', 'Two-factor authentication can be enforced for all users. If they do not have a two-factor provider configured, they will be unable to log into the system.') }}
|
||||
{{ t('settings', 'Two-factor authentication can be enforced for all users and specific groups. If they do not have a two-factor provider configured, they will be unable to log into the system.') }}
|
||||
</p>
|
||||
<p v-if="loading">
|
||||
<span class="icon-loading-small two-factor-loading"></span>
|
||||
|
@ -11,22 +11,74 @@
|
|||
<input type="checkbox"
|
||||
id="two-factor-enforced"
|
||||
class="checkbox"
|
||||
v-model="enabled"
|
||||
v-on:change="onEnforcedChanged">
|
||||
v-model="state.enforced"
|
||||
v-on:change="saveChanges">
|
||||
<label for="two-factor-enforced">{{ t('settings', 'Enforce two-factor authentication') }}</label>
|
||||
</p>
|
||||
<h3>{{ t('settings', 'Limit to groups') }}</h3>
|
||||
{{ t('settings', 'Enforcement of two-factor authentication can be set for certain groups only.') }}
|
||||
<p>
|
||||
{{ t('settings', 'Two-factor authentication is enforced for all members of the following groups.') }}
|
||||
</p>
|
||||
<p>
|
||||
<Multiselect v-model="state.enforcedGroups"
|
||||
:options="groups"
|
||||
:placeholder="t('settings', 'Enforced groups')"
|
||||
:disabled="loading"
|
||||
:multiple="true"
|
||||
:searchable="true"
|
||||
@search-change="searchGroup"
|
||||
:loading="loadingGroups"
|
||||
:show-no-options="false"
|
||||
:close-on-select="false">
|
||||
</Multiselect>
|
||||
</p>
|
||||
<p>
|
||||
{{ t('settings', 'Two-factor authentication is not enforced for members of the following groups.') }}
|
||||
</p>
|
||||
<p>
|
||||
<Multiselect v-model="state.excludedGroups"
|
||||
:options="groups"
|
||||
:placeholder="t('settings', 'Excluded groups')"
|
||||
:disabled="loading"
|
||||
:multiple="true"
|
||||
:searchable="true"
|
||||
@search-change="searchGroup"
|
||||
:loading="loadingGroups"
|
||||
:show-no-options="false"
|
||||
:close-on-select="false">
|
||||
</Multiselect>
|
||||
</p>
|
||||
<p>
|
||||
<button class="button primary"
|
||||
v-on:click="saveChanges"
|
||||
:disabled="loading">
|
||||
{{ t('settings', 'Save changes') }}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Axios from 'nextcloud-axios'
|
||||
import {Multiselect} from 'nextcloud-vue'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: "AdminTwoFactor",
|
||||
components: {
|
||||
Multiselect
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
enabled: false,
|
||||
loading: false
|
||||
state: {
|
||||
enforced: false,
|
||||
enforcedGroups: [],
|
||||
excludedGroups: [],
|
||||
},
|
||||
loading: false,
|
||||
groups: [],
|
||||
loadingGroups: false,
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
|
@ -34,33 +86,45 @@
|
|||
Axios.get(OC.generateUrl('/settings/api/admin/twofactorauth'))
|
||||
.then(resp => resp.data)
|
||||
.then(state => {
|
||||
this.enabled = state.enabled
|
||||
this.state = state
|
||||
|
||||
// Groups are loaded dynamically, but the assigned ones *should*
|
||||
// be valid groups, so let's add them as initial state
|
||||
this.groups = _.sortedUniq(this.state.enforcedGroups.concat(this.state.excludedGroups))
|
||||
|
||||
this.loading = false
|
||||
console.info('loaded')
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(error)
|
||||
this.loading = false
|
||||
console.error('Could not load two-factor state', err)
|
||||
throw err
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
onEnforcedChanged () {
|
||||
searchGroup: _.debounce(function (query) {
|
||||
this.loadingGroups = true
|
||||
Axios.get(OC.linkToOCS(`cloud/groups?offset=0&search=${encodeURIComponent(query)}&limit=20`, 2))
|
||||
.then(res => res.data.ocs)
|
||||
.then(ocs => ocs.data.groups)
|
||||
.then(groups => this.groups = _.sortedUniq(this.groups.concat(groups)))
|
||||
.catch(err => console.error('could not search groups', err))
|
||||
.then(() => this.loadingGroups = false)
|
||||
}, 500),
|
||||
|
||||
saveChanges () {
|
||||
this.loading = true
|
||||
const data = {
|
||||
enabled: this.enabled
|
||||
}
|
||||
Axios.put(OC.generateUrl('/settings/api/admin/twofactorauth'), data)
|
||||
|
||||
const oldState = this.state
|
||||
|
||||
Axios.put(OC.generateUrl('/settings/api/admin/twofactorauth'), this.state)
|
||||
.then(resp => resp.data)
|
||||
.then(state => {
|
||||
this.enabled = state.enabled
|
||||
this.loading = false
|
||||
})
|
||||
.then(state => this.state = state)
|
||||
.catch(err => {
|
||||
console.error(error)
|
||||
this.loading = false
|
||||
throw err
|
||||
console.error('could not save changes', err)
|
||||
|
||||
// Restore
|
||||
this.state = oldState
|
||||
})
|
||||
.then(() => this.loading = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Tests\Core\Command\TwoFactorAuth;
|
||||
|
||||
use OC\Authentication\TwoFactorAuth\EnforcementState;
|
||||
use OC\Authentication\TwoFactorAuth\MandatoryTwoFactor;
|
||||
use OC\Core\Command\TwoFactorAuth\Enforce;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
|
@ -51,11 +52,11 @@ class EnforceTest extends TestCase {
|
|||
|
||||
public function testEnforce() {
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('setEnforced')
|
||||
->with(true);
|
||||
->method('setState')
|
||||
->with($this->equalTo(new EnforcementState(true)));
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('isEnforced')
|
||||
->willReturn(true);
|
||||
->method('getState')
|
||||
->willReturn(new EnforcementState(true));
|
||||
|
||||
$rc = $this->command->execute([
|
||||
'--on' => true,
|
||||
|
@ -66,13 +67,49 @@ class EnforceTest extends TestCase {
|
|||
$this->assertContains("Two-factor authentication is enforced for all users", $display);
|
||||
}
|
||||
|
||||
public function testEnforceForOneGroup() {
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('setState')
|
||||
->with($this->equalTo(new EnforcementState(true, ['twofactorers'])));
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('getState')
|
||||
->willReturn(new EnforcementState(true, ['twofactorers']));
|
||||
|
||||
$rc = $this->command->execute([
|
||||
'--on' => true,
|
||||
'--group' => ['twofactorers'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(0, $rc);
|
||||
$display = $this->command->getDisplay();
|
||||
$this->assertContains("Two-factor authentication is enforced for members of the group(s) twofactorers", $display);
|
||||
}
|
||||
|
||||
public function testEnforceForAllExceptOneGroup() {
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('setState')
|
||||
->with($this->equalTo(new EnforcementState(true, [], ['yoloers'])));
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('getState')
|
||||
->willReturn(new EnforcementState(true, [], ['yoloers']));
|
||||
|
||||
$rc = $this->command->execute([
|
||||
'--on' => true,
|
||||
'--exclude' => ['yoloers'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(0, $rc);
|
||||
$display = $this->command->getDisplay();
|
||||
$this->assertContains("Two-factor authentication is enforced for all users, except members of yoloers", $display);
|
||||
}
|
||||
|
||||
public function testDisableEnforced() {
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('setEnforced')
|
||||
->with(false);
|
||||
->method('setState')
|
||||
->with(new EnforcementState(false));
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('isEnforced')
|
||||
->willReturn(false);
|
||||
->method('getState')
|
||||
->willReturn(new EnforcementState(false));
|
||||
|
||||
$rc = $this->command->execute([
|
||||
'--off' => true,
|
||||
|
@ -85,8 +122,8 @@ class EnforceTest extends TestCase {
|
|||
|
||||
public function testCurrentStateEnabled() {
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('isEnforced')
|
||||
->willReturn(true);
|
||||
->method('getState')
|
||||
->willReturn(new EnforcementState(true));
|
||||
|
||||
$rc = $this->command->execute([]);
|
||||
|
||||
|
@ -97,8 +134,8 @@ class EnforceTest extends TestCase {
|
|||
|
||||
public function testCurrentStateDisabled() {
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('isEnforced')
|
||||
->willReturn(false);
|
||||
->method('getState')
|
||||
->willReturn(new EnforcementState(false));
|
||||
|
||||
$rc = $this->command->execute([]);
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
namespace Tests\Settings\Controller;
|
||||
|
||||
use OC\Authentication\TwoFactorAuth\EnforcementState;
|
||||
use OC\Authentication\TwoFactorAuth\MandatoryTwoFactor;
|
||||
use OC\Settings\Controller\TwoFactorSettingsController;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
|
@ -54,12 +55,11 @@ class TwoFactorSettingsControllerTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testIndex() {
|
||||
$state = new EnforcementState(true);
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('isEnforced')
|
||||
->willReturn(true);
|
||||
$expected = new JSONResponse([
|
||||
'enabled' => true,
|
||||
]);
|
||||
->method('getState')
|
||||
->willReturn($state);
|
||||
$expected = new JSONResponse($state);
|
||||
|
||||
$resp = $this->controller->index();
|
||||
|
||||
|
@ -67,12 +67,14 @@ class TwoFactorSettingsControllerTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testUpdate() {
|
||||
$state = new EnforcementState(true);
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('setEnforced')
|
||||
->with(true);
|
||||
$expected = new JSONResponse([
|
||||
'enabled' => true,
|
||||
]);
|
||||
->method('setState')
|
||||
->with($this->equalTo(new EnforcementState(true)));
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('getState')
|
||||
->willReturn($state);
|
||||
$expected = new JSONResponse($state);
|
||||
|
||||
$resp = $this->controller->update(true);
|
||||
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2018 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
*
|
||||
* @author 2018 Christoph Wurst <christoph@winzerhof-wurst.at>
|
||||
*
|
||||
* @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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: christoph
|
||||
* Date: 11.10.18
|
||||
* Time: 13:01
|
||||
*/
|
||||
|
||||
namespace Tests\Authentication\TwoFactorAuth;
|
||||
|
||||
use OC\Authentication\TwoFactorAuth\EnforcementState;
|
||||
use Test\TestCase;
|
||||
|
||||
class EnforcementStateTest extends TestCase {
|
||||
|
||||
public function testIsEnforced() {
|
||||
$state = new EnforcementState(true);
|
||||
|
||||
$this->assertTrue($state->isEnforced());
|
||||
}
|
||||
|
||||
public function testGetEnforcedGroups() {
|
||||
$state = new EnforcementState(true, ['twofactorers']);
|
||||
|
||||
$this->assertEquals(['twofactorers'], $state->getEnforcedGroups());
|
||||
}
|
||||
|
||||
public function testGetExcludedGroups() {
|
||||
$state = new EnforcementState(true, [], ['yoloers']);
|
||||
|
||||
$this->assertEquals(['yoloers'], $state->getExcludedGroups());
|
||||
}
|
||||
|
||||
public function testJsonSerialize() {
|
||||
$state = new EnforcementState(true, ['twofactorers'], ['yoloers']);
|
||||
$expected = [
|
||||
'enforced' => true,
|
||||
'enforcedGroups' => ['twofactorers'],
|
||||
'excludedGroups' => ['yoloers'],
|
||||
];
|
||||
|
||||
$json = $state->jsonSerialize();
|
||||
|
||||
$this->assertEquals($expected, $json);
|
||||
}
|
||||
}
|
|
@ -37,58 +37,59 @@ use OCP\IConfig;
|
|||
use OCP\ILogger;
|
||||
use OCP\ISession;
|
||||
use OCP\IUser;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
class ManagerTest extends TestCase {
|
||||
|
||||
/** @var IUser|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var IUser|MockObject */
|
||||
private $user;
|
||||
|
||||
/** @var ProviderLoader|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var ProviderLoader|MockObject */
|
||||
private $providerLoader;
|
||||
|
||||
/** @var IRegistry|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var IRegistry|MockObject */
|
||||
private $providerRegistry;
|
||||
|
||||
/** @var MandatoryTwoFactor|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var MandatoryTwoFactor|MockObject */
|
||||
private $mandatoryTwoFactor;
|
||||
|
||||
/** @var ISession|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var ISession|MockObject */
|
||||
private $session;
|
||||
|
||||
/** @var Manager */
|
||||
private $manager;
|
||||
|
||||
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var IConfig|MockObject */
|
||||
private $config;
|
||||
|
||||
/** @var IManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var IManager|MockObject */
|
||||
private $activityManager;
|
||||
|
||||
/** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var ILogger|MockObject */
|
||||
private $logger;
|
||||
|
||||
/** @var IProvider|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var IProvider|MockObject */
|
||||
private $fakeProvider;
|
||||
|
||||
/** @var IProvider|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var IProvider|MockObject */
|
||||
private $backupProvider;
|
||||
|
||||
/** @var TokenProvider|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var TokenProvider|MockObject */
|
||||
private $tokenProvider;
|
||||
|
||||
/** @var ITimeFactory|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var ITimeFactory|MockObject */
|
||||
private $timeFactory;
|
||||
|
||||
/** @var EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var EventDispatcherInterface|MockObject */
|
||||
private $eventDispatcher;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->user = $this->createMock(IUser::class);
|
||||
$this->providerLoader = $this->createMock(\OC\Authentication\TwoFactorAuth\ProviderLoader::class);
|
||||
$this->providerLoader = $this->createMock(ProviderLoader::class);
|
||||
$this->providerRegistry = $this->createMock(IRegistry::class);
|
||||
$this->mandatoryTwoFactor = $this->createMock(MandatoryTwoFactor::class);
|
||||
$this->session = $this->createMock(ISession::class);
|
||||
|
@ -150,7 +151,8 @@ class ManagerTest extends TestCase {
|
|||
|
||||
public function testIsTwoFactorAuthenticatedEnforced() {
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('isEnforced')
|
||||
->method('isEnforcedFor')
|
||||
->with($this->user)
|
||||
->willReturn(true);
|
||||
|
||||
$enabled = $this->manager->isTwoFactorAuthenticated($this->user);
|
||||
|
@ -160,7 +162,8 @@ class ManagerTest extends TestCase {
|
|||
|
||||
public function testIsTwoFactorAuthenticatedNoProviders() {
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('isEnforced')
|
||||
->method('isEnforcedFor')
|
||||
->with($this->user)
|
||||
->willReturn(false);
|
||||
$this->providerRegistry->expects($this->once())
|
||||
->method('getProviderStates')
|
||||
|
@ -174,7 +177,8 @@ class ManagerTest extends TestCase {
|
|||
|
||||
public function testIsTwoFactorAuthenticatedOnlyBackupCodes() {
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('isEnforced')
|
||||
->method('isEnforcedFor')
|
||||
->with($this->user)
|
||||
->willReturn(false);
|
||||
$this->providerRegistry->expects($this->once())
|
||||
->method('getProviderStates')
|
||||
|
@ -196,7 +200,8 @@ class ManagerTest extends TestCase {
|
|||
|
||||
public function testIsTwoFactorAuthenticatedFailingProviders() {
|
||||
$this->mandatoryTwoFactor->expects($this->once())
|
||||
->method('isEnforced')
|
||||
->method('isEnforcedFor')
|
||||
->with($this->user)
|
||||
->willReturn(false);
|
||||
$this->providerRegistry->expects($this->once())
|
||||
->method('getProviderStates')
|
||||
|
|
|
@ -26,8 +26,11 @@ declare(strict_types=1);
|
|||
|
||||
namespace Tests\Authentication\TwoFactorAuth;
|
||||
|
||||
use OC\Authentication\TwoFactorAuth\EnforcementState;
|
||||
use OC\Authentication\TwoFactorAuth\MandatoryTwoFactor;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUser;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Test\TestCase;
|
||||
|
||||
|
@ -36,6 +39,9 @@ class MandatoryTwoFactorTest extends TestCase {
|
|||
/** @var IConfig|MockObject */
|
||||
private $config;
|
||||
|
||||
/** @var IGroupManager|MockObject */
|
||||
private $groupManager;
|
||||
|
||||
/** @var MandatoryTwoFactor */
|
||||
private $mandatoryTwoFactor;
|
||||
|
||||
|
@ -43,46 +49,150 @@ class MandatoryTwoFactorTest extends TestCase {
|
|||
parent::setUp();
|
||||
|
||||
$this->config = $this->createMock(IConfig::class);
|
||||
$this->groupManager = $this->createMock(IGroupManager::class);
|
||||
|
||||
$this->mandatoryTwoFactor = new MandatoryTwoFactor($this->config);
|
||||
$this->mandatoryTwoFactor = new MandatoryTwoFactor($this->config, $this->groupManager);
|
||||
}
|
||||
|
||||
public function testIsNotEnforced() {
|
||||
$this->config->expects($this->once())
|
||||
$this->config
|
||||
->method('getSystemValue')
|
||||
->with('twofactor_enforced', 'false')
|
||||
->willReturn('false');
|
||||
->willReturnMap([
|
||||
['twofactor_enforced', 'false', 'false'],
|
||||
['twofactor_enforced_groups', [], []],
|
||||
['twofactor_enforced_excluded_groups', [], []],
|
||||
]);
|
||||
|
||||
$isEnforced = $this->mandatoryTwoFactor->isEnforced();
|
||||
$state = $this->mandatoryTwoFactor->getState();
|
||||
|
||||
$this->assertFalse($state->isEnforced());
|
||||
}
|
||||
|
||||
public function testIsEnforced() {
|
||||
$this->config
|
||||
->method('getSystemValue')
|
||||
->willReturnMap([
|
||||
['twofactor_enforced', 'false', 'true'],
|
||||
['twofactor_enforced_groups', [], []],
|
||||
['twofactor_enforced_excluded_groups', [], []],
|
||||
]);
|
||||
|
||||
$state = $this->mandatoryTwoFactor->getState();
|
||||
|
||||
$this->assertTrue($state->isEnforced());
|
||||
}
|
||||
|
||||
public function testIsNotEnforcedForAnybody() {
|
||||
$user = $this->createMock(IUser::class);
|
||||
$user->method('getUID')->willReturn('user123');
|
||||
$this->config
|
||||
->method('getSystemValue')
|
||||
->willReturnMap([
|
||||
['twofactor_enforced', 'false', 'false'],
|
||||
['twofactor_enforced_groups', [], []],
|
||||
['twofactor_enforced_excluded_groups', [], []],
|
||||
]);
|
||||
|
||||
$isEnforced = $this->mandatoryTwoFactor->isEnforcedFor($user);
|
||||
|
||||
$this->assertFalse($isEnforced);
|
||||
}
|
||||
|
||||
public function testIsEnforced() {
|
||||
$this->config->expects($this->once())
|
||||
public function testIsEnforcedForAGroupMember() {
|
||||
$user = $this->createMock(IUser::class);
|
||||
$user->method('getUID')->willReturn('user123');
|
||||
$this->config
|
||||
->method('getSystemValue')
|
||||
->with('twofactor_enforced', 'false')
|
||||
->willReturn('true');
|
||||
->willReturnMap([
|
||||
['twofactor_enforced', 'false', 'true'],
|
||||
['twofactor_enforced_groups', [], ['twofactorers']],
|
||||
['twofactor_enforced_excluded_groups', [], []],
|
||||
]);
|
||||
$this->groupManager->method('isInGroup')
|
||||
->willReturnCallback(function($user, $group) {
|
||||
return $user === 'user123' && $group ==='twofactorers';
|
||||
});
|
||||
|
||||
$isEnforced = $this->mandatoryTwoFactor->isEnforced();
|
||||
$isEnforced = $this->mandatoryTwoFactor->isEnforcedFor($user);
|
||||
|
||||
$this->assertTrue($isEnforced);
|
||||
}
|
||||
|
||||
public function testSetEnforced() {
|
||||
$this->config->expects($this->once())
|
||||
->method('setSystemValue')
|
||||
->with('twofactor_enforced', 'true');
|
||||
public function testIsEnforcedForOtherGroups() {
|
||||
$user = $this->createMock(IUser::class);
|
||||
$user->method('getUID')->willReturn('user123');
|
||||
$this->config
|
||||
->method('getSystemValue')
|
||||
->willReturnMap([
|
||||
['twofactor_enforced', 'false', 'true'],
|
||||
['twofactor_enforced_groups', [], ['twofactorers']],
|
||||
['twofactor_enforced_excluded_groups', [], []],
|
||||
]);
|
||||
$this->groupManager->method('isInGroup')
|
||||
->willReturn(false);
|
||||
|
||||
$this->mandatoryTwoFactor->setEnforced(true);
|
||||
$isEnforced = $this->mandatoryTwoFactor->isEnforcedFor($user);
|
||||
|
||||
$this->assertFalse($isEnforced);
|
||||
}
|
||||
|
||||
public function testIsEnforcedButMemberOfExcludedGroup() {
|
||||
$user = $this->createMock(IUser::class);
|
||||
$user->method('getUID')->willReturn('user123');
|
||||
$this->config
|
||||
->method('getSystemValue')
|
||||
->willReturnMap([
|
||||
['twofactor_enforced', 'false', 'true'],
|
||||
['twofactor_enforced_groups', [], []],
|
||||
['twofactor_enforced_excluded_groups', [], ['yoloers']],
|
||||
]);
|
||||
$this->groupManager->method('isInGroup')
|
||||
->willReturnCallback(function($user, $group) {
|
||||
return $user === 'user123' && $group ==='yoloers';
|
||||
});
|
||||
|
||||
$isEnforced = $this->mandatoryTwoFactor->isEnforcedFor($user);
|
||||
|
||||
$this->assertFalse($isEnforced);
|
||||
}
|
||||
|
||||
public function testSetEnforced() {
|
||||
$this->config
|
||||
->expects($this->exactly(3))
|
||||
->method('setSystemValue')
|
||||
->willReturnMap([
|
||||
['twofactor_enforced', 'true'],
|
||||
['twofactor_enforced_groups', []],
|
||||
['twofactor_enforced_excluded_groups', []],
|
||||
]);
|
||||
|
||||
$this->mandatoryTwoFactor->setState(new EnforcementState(true));
|
||||
}
|
||||
|
||||
public function testSetEnforcedForGroups() {
|
||||
$this->config
|
||||
->expects($this->exactly(3))
|
||||
->method('setSystemValue')
|
||||
->willReturnMap([
|
||||
['twofactor_enforced', 'true'],
|
||||
['twofactor_enforced_groups', ['twofactorers']],
|
||||
['twofactor_enforced_excluded_groups', ['yoloers']],
|
||||
]);
|
||||
|
||||
$this->mandatoryTwoFactor->setState(new EnforcementState(true, ['twofactorers'], ['yoloers']));
|
||||
}
|
||||
|
||||
public function testSetNotEnforced() {
|
||||
$this->config->expects($this->once())
|
||||
$this->config
|
||||
->expects($this->exactly(3))
|
||||
->method('setSystemValue')
|
||||
->with('twofactor_enforced', 'false');
|
||||
->willReturnMap([
|
||||
['twofactor_enforced', 'false'],
|
||||
['twofactor_enforced_groups', []],
|
||||
['twofactor_enforced_excluded_groups', []],
|
||||
]);
|
||||
|
||||
$this->mandatoryTwoFactor->setEnforced(false);
|
||||
$this->mandatoryTwoFactor->setState(new EnforcementState(false));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue