Skip to content

Commit

Permalink
Merge pull request #274 from OpenConext/feature/allow-disabling-of-re…
Browse files Browse the repository at this point in the history
…covery-tokens

Add toggles to disable recovery token types
  • Loading branch information
MKodde authored Nov 2, 2022
2 parents 5360e24 + 90bddf6 commit 871b323
Show file tree
Hide file tree
Showing 9 changed files with 181 additions and 10 deletions.
12 changes: 6 additions & 6 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions config/legacy/parameters.yaml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,9 @@ parameters:
preferred_activation_flow_name: activate
preferred_activation_flow_options: [ra, self]

# Self-asserted tokens: enable/disable recovery methods
#
# One of the two options should be enabled to have a fully functioning
# Self-asserted token registration process.
recovery_method_sms_enabled: true
recovery_method_safe_store_code_enabled: true
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public function listAction()
$authorizationService = $this->get(AuthorizationService::class);
$recoveryTokensAllowed = $authorizationService->mayRegisterRecoveryTokens($identity);
$selfAssertedTokenRegistration = $options->allowSelfAssertedTokens === true && $recoveryTokensAllowed;

$hasRemainingTokenTypes = count($recoveryTokenService->getRemainingTokenTypes($identity)) > 0;
$recoveryTokens = [];
if ($selfAssertedTokenRegistration && $recoveryTokensAllowed) {
$recoveryTokens = $recoveryTokenService->getRecoveryTokensForIdentity($identity);
Expand All @@ -80,6 +80,7 @@ public function listAction()
'expirationHelper' => $expirationHelper,
'selfAssertedTokenRegistration' => $selfAssertedTokenRegistration,
'recoveryTokens' => $recoveryTokens,
'hasRemainingRecoveryTokens' => $hasRemainingTokenTypes,
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,17 @@ services:
- '@Surfnet\StepupMiddlewareClientBundle\Identity\Service\VettingTypeHintService'
- '@logger'

Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\RecoveryTokenConfig:
arguments:
- '%recovery_method_sms_enabled%'
- '%recovery_method_safe_store_code_enabled%'

Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\RecoveryTokenService:
arguments:
- '@Surfnet\StepupMiddlewareClientBundle\Identity\Service\RecoveryTokenService'
- '@Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\SafeStoreService'
- '@Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\RecoveryTokenState'
- '@Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\RecoveryTokenConfig'
- '@logger'

Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\SafeStoreState:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,14 @@
<p>{{ 'ss.second_factor.list.text.no_recovery_tokens'|trans }}</p>
{% endif %}

{% if hasRemainingRecoveryTokens %}
<p>
<a href="{{ path('ss_recovery_token_display_types') }}"
class="btn btn-primary pull-right">
{{ 'ss.second_factor.list.button.register_recovery_token'|trans }}
</a>
</p>

{% endif %}
<p>&nbsp;</p>
<p>&nbsp;</p>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

/**
* Copyright 2022 SURFnet bv
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\Exception;

use Surfnet\StepupSelfService\SelfServiceBundle\Exception\RuntimeException;

class RecoveryTokenConfigurationException extends RuntimeException
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

/**
* Copyright 2022 SURFnet bv
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens;

use Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\Exception\RecoveryTokenConfigurationException;

class RecoveryTokenConfig
{
/**
* @var bool
*/
private $smsEnabled;

/**
* @var bool
*/
private $safeStoreCodeEnabled;

public function __construct(bool $smsEnabled, bool $safeStoreCodeEnabled)
{
if ($smsEnabled === false && $safeStoreCodeEnabled === false) {
throw new RecoveryTokenConfigurationException('The SMS or safe-store code recovery token must be enabled');
}
$this->smsEnabled = $smsEnabled;
$this->safeStoreCodeEnabled = $safeStoreCodeEnabled;
}

public function isSmsDisabled(): bool
{
return !$this->smsEnabled;
}

public function isSafeStoreCodeDisabled(): bool
{
return !$this->safeStoreCodeEnabled;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,22 @@ class RecoveryTokenService
*/
private $stateStore;

/**
* @var RecoveryTokenConfig
*/
private $config;

public function __construct(
MiddlewareRecoveryTokenService $recoveryTokenService,
SafeStoreService $safeStoreService,
RecoveryTokenState $recoveryTokenState,
RecoveryTokenConfig $config,
LoggerInterface $logger
) {
$this->recoveryTokenService = $recoveryTokenService;
$this->safeStoreService = $safeStoreService;
$this->stateStore = $recoveryTokenState;
$this->config = $config;
$this->logger = $logger;
}

Expand All @@ -78,10 +85,13 @@ public function getRecoveryTokensForIdentity(Identity $identity): array
return $this->recoveryTokenService->findAllFor($identity);
}

public function getRemainingTokenTypes(Identity $identity)
public function getRemainingTokenTypes(Identity $identity): array
{
$tokens = $this->getRecoveryTokensForIdentity($identity);
$tokenTypes = $this->recoveryTokenService->getAvailableRecoveryTokenTypes();
$tokenTypes = $this->excludeDisabledRecoveryTokens(
$this->recoveryTokenService->getAvailableRecoveryTokenTypes()
);

/** @var RecoveryToken $token */
foreach ($tokens as $token) {
if (in_array($token->type, $tokenTypes)) {
Expand Down Expand Up @@ -173,4 +183,17 @@ public function resetStepUpGiven()
{
$this->stateStore->resetStepUpGiven();
}

private function excludeDisabledRecoveryTokens(array $availableRecoveryTokenTypes): array
{
foreach ($availableRecoveryTokenTypes as $identifier => $token) {
if ($token === 'sms' && $this->config->isSmsDisabled()) {
unset($availableRecoveryTokenTypes[$identifier]);
}
if ($token === 'safe-store' && $this->config->isSafeStoreCodeDisabled()) {
unset($availableRecoveryTokenTypes[$identifier]);
}
}
return $availableRecoveryTokenTypes;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

/**
* Copyright 2022 SURFnet bv
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace Surfnet\StepupSelfService\SelfServiceBundle\Tests\Service\SelfAssertedTokens;

use PHPUnit\Framework\TestCase;
use Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\Exception\RecoveryTokenConfigurationException;
use Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\RecoveryTokenConfig;

class RecoveryTokenConfigTest extends TestCase
{
public function test_both_recovery_token_methods_can_be_enabled()
{
$config = new RecoveryTokenConfig(true, true);
self::assertFalse($config->isSafeStoreCodeDisabled());
self::assertFalse($config->isSmsDisabled());
}

public function test_only_sms_can_be_enabled()
{
$config = new RecoveryTokenConfig(true, false);
self::assertTrue($config->isSafeStoreCodeDisabled());
self::assertFalse($config->isSmsDisabled());
}

public function test_only_safe_store_can_be_enabled()
{
$config = new RecoveryTokenConfig(false, true);
self::assertFalse($config->isSafeStoreCodeDisabled());
self::assertTrue($config->isSmsDisabled());
}

public function test_not_allowed_to_disable_both()
{
self::expectException(RecoveryTokenConfigurationException::class);
self::expectExceptionMessage('The SMS or safe-store code recovery token must be enabled');
new RecoveryTokenConfig(false, false);
}
}

0 comments on commit 871b323

Please sign in to comment.