Passed
Push — develop ( c85f88...7c450d )
by Peter
14:03
created

RecoveryTokenState::retrieveSecret()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Copyright 2022 SURFnet bv
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens;
20
21
use Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\Dto\ReturnTo;
22
use Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\Dto\SafeStoreSecret;
23
use Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\Exception\SafeStoreSecretNotFoundException;
24
use Symfony\Component\HttpFoundation\Session\SessionInterface;
25
26
/**
27
 * State manager for Recovery Tokens
28
 *
29
 * There are several scenarios where we keep recovery token state. They are:
30
 *
31
 * 1. Store the SAML AuthNRequest request id to match the step up authentication
32
 *    with the corresponding SAML Response
33
 * 2. Keep track of whether a Recovery Token is being registered during SF token
34
 *    registration or not.
35
 * 3. Remember the route where to return to after giving step up
36
 * 4. Store the fact if step up was given for a given Recovery Token action.
37
 *
38
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
39
 */
40
class RecoveryTokenState
41
{
42
    /**
43
     * @var SessionInterface
44
     */
45
    private $session;
46
47
    public const RECOVERY_TOKEN_STEP_UP_REQUEST_ID_IDENTIFIER = 'recovery_token_step_up_request_id';
48
49
    private const RECOVERY_TOKEN_STEP_UP_GIVEN_IDENTIFIER = 'recovery_token_step_up_given';
50
51
    private const RECOVERY_TOKEN_REGISTRATION_IDENTIFIER = 'recovery_token_created_during_registration';
52
53
    private const RECOVERY_TOKEN_RETURN_TO_IDENTIFIER = 'recovery_token_return_to';
54
55
    public const RECOVERY_TOKEN_RETURN_TO_CREATE_SAFE_STORE = 'ss_recovery_token_safe_store';
56
57
    public const RECOVERY_TOKEN_RETURN_TO_CREATE_SMS = 'ss_recovery_token_sms';
58
59
    private const SAFE_STORE_SESSION_NAME = 'safe_store_secret';
60
61
    public function __construct(SessionInterface $session)
62
    {
63
        $this->session = $session;
64
    }
65
66
    public function tokenCreatedDuringSecondFactorRegistration(): void
67
    {
68
        $this->session->set(self::RECOVERY_TOKEN_REGISTRATION_IDENTIFIER, true);
69
    }
70
71
    public function wasRecoveryTokenCreatedDuringSecondFactorRegistration(): bool
72
    {
73
        if ($this->session->has(self::RECOVERY_TOKEN_REGISTRATION_IDENTIFIER)) {
74
            return $this->session->get(self::RECOVERY_TOKEN_REGISTRATION_IDENTIFIER);
75
        }
76
        return false;
77
    }
78
79
    public function retrieveSecret(): SafeStoreSecret
80
    {
81
        if ($this->session->has(self::SAFE_STORE_SESSION_NAME)) {
82
            return $this->session->get(self::SAFE_STORE_SESSION_NAME);
83
        }
84
        throw new SafeStoreSecretNotFoundException('Unable to retrieve SafeStore secret, it was not found in state');
85
    }
86
87
    public function store(SafeStoreSecret $secret): void
88
    {
89
        $this->session->set(self::SAFE_STORE_SESSION_NAME, $secret);
90
    }
91
92
    public function forget(): void
93
    {
94
        $this->session->remove(self::SAFE_STORE_SESSION_NAME);
95
    }
96
97
    public function forgetTokenCreatedDuringSecondFactorRegistration(): void
98
    {
99
        $this->session->remove(self::RECOVERY_TOKEN_REGISTRATION_IDENTIFIER);
100
    }
101
102
    public function startStepUpRequest(string $requestId): void
103
    {
104
        $this->session->set(self::RECOVERY_TOKEN_STEP_UP_REQUEST_ID_IDENTIFIER, $requestId);
105
    }
106
107
    public function hasStepUpRequest(): bool
108
    {
109
        return $this->session->has(self::RECOVERY_TOKEN_STEP_UP_REQUEST_ID_IDENTIFIER);
110
    }
111
112
    public function getStepUpRequest(): string
113
    {
114
        return $this->session->get(self::RECOVERY_TOKEN_STEP_UP_REQUEST_ID_IDENTIFIER);
115
    }
116
117
    public function deleteStepUpRequest(): void
118
    {
119
        $this->session->remove(self::RECOVERY_TOKEN_STEP_UP_REQUEST_ID_IDENTIFIER);
120
    }
121
122
    public function setReturnTo(string $route, array $parameters)
123
    {
124
        $this->session->set(self::RECOVERY_TOKEN_RETURN_TO_IDENTIFIER, new ReturnTo($route, $parameters));
125
    }
126
127
    public function returnTo(): ReturnTo
128
    {
129
        return $this->session->get(self::RECOVERY_TOKEN_RETURN_TO_IDENTIFIER);
130
    }
131
132
    public function resetReturnTo()
133
    {
134
        $this->session->remove(self::RECOVERY_TOKEN_RETURN_TO_IDENTIFIER);
135
    }
136
137
    public function getStepUpGiven(): bool
138
    {
139
        if (!$this->session->has(self::RECOVERY_TOKEN_STEP_UP_GIVEN_IDENTIFIER)) {
140
            return false;
141
        }
142
        return $this->session->get(self::RECOVERY_TOKEN_STEP_UP_GIVEN_IDENTIFIER);
143
    }
144
145
    public function setStepUpGiven(bool $given)
146
    {
147
        $this->session->set(self::RECOVERY_TOKEN_STEP_UP_GIVEN_IDENTIFIER, $given);
148
    }
149
150
    public function resetStepUpGiven()
151
    {
152
        $this->session->remove(self::RECOVERY_TOKEN_STEP_UP_GIVEN_IDENTIFIER);
153
    }
154
}
155