Passed
Push — feature/auth-sms-rt-during-rec... ( e529e8 )
by Michiel
14:51
created

RecoveryTokenState::store()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
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
class RecoveryTokenState
39
{
40
    /**
41
     * @var SessionInterface
42
     */
43
    private $session;
44
45
    public const RECOVERY_TOKEN_STEP_UP_REQUEST_ID_IDENTIFIER = 'recovery_token_step_up_request_id';
46
47
    private const RECOVERY_TOKEN_STEP_UP_GIVEN_IDENTIFIER = 'recovery_token_step_up_given';
48
49
    private const RECOVERY_TOKEN_REGISTRATION_IDENTIFIER = 'recovery_token_created_during_registration';
50
51
    private const RECOVERY_TOKEN_RETURN_TO_IDENTIFIER = 'recovery_token_return_to';
52
53
    public const RECOVERY_TOKEN_RETURN_TO_CREATE_SAFE_STORE = 'ss_recovery_token_safe_store';
54
55
    public const RECOVERY_TOKEN_RETURN_TO_CREATE_SMS = 'ss_recovery_token_sms';
56
57
    private const SAFE_STORE_SESSION_NAME = 'safe_store_secret';
58
59
    public function __construct(SessionInterface $session)
60
    {
61
        $this->session = $session;
62
    }
63
64
    public function tokenCreatedDuringSecondFactorRegistration(): void
65
    {
66
        $this->session->set(self::RECOVERY_TOKEN_REGISTRATION_IDENTIFIER, true);
67
    }
68
69
    public function wasRecoveryTokenCreatedDuringSecondFactorRegistration(): bool
70
    {
71
        if ($this->session->has(self::RECOVERY_TOKEN_REGISTRATION_IDENTIFIER)) {
72
            return $this->session->get(self::RECOVERY_TOKEN_REGISTRATION_IDENTIFIER);
73
        }
74
        return false;
75
    }
76
77
    public function retrieveSecret(): SafeStoreSecret
78
    {
79
        if ($this->session->has(self::SAFE_STORE_SESSION_NAME)) {
80
            return $this->session->get(self::SAFE_STORE_SESSION_NAME);
81
        }
82
        throw new SafeStoreSecretNotFoundException('Unable to retrieve SafeStore secret, it was not found in state');
83
    }
84
85
    public function store(SafeStoreSecret $secret): void
86
    {
87
        $this->session->set(self::SAFE_STORE_SESSION_NAME, $secret);
88
    }
89
90
    public function forget(): void
91
    {
92
        $this->session->remove(self::SAFE_STORE_SESSION_NAME);
93
    }
94
95
    public function forgetTokenCreatedDuringSecondFactorRegistration(): void
96
    {
97
        $this->session->remove(self::RECOVERY_TOKEN_REGISTRATION_IDENTIFIER);
98
    }
99
100
    public function startStepUpRequest(string $requestId): void
101
    {
102
        $this->session->set(self::RECOVERY_TOKEN_STEP_UP_REQUEST_ID_IDENTIFIER, $requestId);
103
    }
104
105
    public function hasStepUpRequest(): bool
106
    {
107
        return $this->session->has(self::RECOVERY_TOKEN_STEP_UP_REQUEST_ID_IDENTIFIER);
108
    }
109
110
    public function getStepUpRequest(): string
111
    {
112
        return $this->session->get(self::RECOVERY_TOKEN_STEP_UP_REQUEST_ID_IDENTIFIER);
113
    }
114
115
    public function deleteStepUpRequest(): void
116
    {
117
        $this->session->remove(self::RECOVERY_TOKEN_STEP_UP_REQUEST_ID_IDENTIFIER);
118
    }
119
120
    public function setReturnTo(string $route, array $parameters)
121
    {
122
        $this->session->set(self::RECOVERY_TOKEN_RETURN_TO_IDENTIFIER, new ReturnTo($route, $parameters));
123
    }
124
125
    public function returnTo(): ReturnTo
126
    {
127
        return $this->session->get(self::RECOVERY_TOKEN_RETURN_TO_IDENTIFIER);
128
    }
129
130
    public function resetReturnTo()
131
    {
132
        $this->session->remove(self::RECOVERY_TOKEN_RETURN_TO_IDENTIFIER);
133
    }
134
135
    public function getStepUpGiven(): bool
136
    {
137
        if (!$this->session->has(self::RECOVERY_TOKEN_STEP_UP_GIVEN_IDENTIFIER)) {
138
            return false;
139
        }
140
        return $this->session->get(self::RECOVERY_TOKEN_STEP_UP_GIVEN_IDENTIFIER);
141
    }
142
143
    public function setStepUpGiven(bool $given)
144
    {
145
        $this->session->set(self::RECOVERY_TOKEN_STEP_UP_GIVEN_IDENTIFIER, $given);
146
    }
147
148
    public function resetStepUpGiven()
149
    {
150
        $this->session->remove(self::RECOVERY_TOKEN_STEP_UP_GIVEN_IDENTIFIER);
151
    }
152
}
153