VettingProcedure   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 255
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 33
lcom 1
cbo 3
dl 0
loc 255
rs 9.76
c 0
b 0
f 0

17 Methods

Rating   Name   Duplication   Size   Complexity  
A start() 0 27 5
A __construct() 0 3 1
A verifySecondFactorIdentifier() 0 15 3
A verifyIdentity() 0 24 5
A vet() 0 12 2
A getId() 0 4 1
A getSecondFactor() 0 4 1
A getAuthorityId() 0 4 1
A getRegistrationCode() 0 4 1
A getInputSecondFactorIdentifier() 0 4 1
A getDocumentNumber() 0 4 1
A isIdentityVerified() 0 4 1
A isReadyForSecondFactorToBeVerified() 0 4 1
A isProvePossessionSkippable() 0 4 1
A isReadyForIdentityVerification() 0 4 2
A isReadyForVetting() 0 7 4
A isPossessionProvenOrCanItBeSkipped() 0 4 2
1
<?php
2
3
/**
4
 * Copyright 2014 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\StepupRa\RaBundle;
20
21
use Surfnet\StepupMiddlewareClientBundle\Identity\Dto\VerifiedSecondFactor;
22
use Surfnet\StepupRa\RaBundle\Exception\DomainException;
23
use Surfnet\StepupRa\RaBundle\Exception\InvalidArgumentException;
24
25
/**
26
 * @SuppressWarnings(PHPMD.UnusedPrivateFields)
27
 */
28
class VettingProcedure
29
{
30
    /**
31
     * @var string
32
     */
33
    private $id;
34
35
    /**
36
     * @var string
37
     */
38
    private $authorityId;
39
40
    /**
41
     * @var string|null
42
     */
43
    private $registrationCode;
44
45
    /**
46
     * @var VerifiedSecondFactor
47
     */
48
    private $secondFactor;
49
50
    /**
51
     * @var string|null
52
     */
53
    private $inputSecondFactorIdentifier;
54
55
    /**
56
     * @var string|null
57
     */
58
    private $documentNumber;
59
60
    /**
61
     * @var boolean|null
62
     */
63
    private $identityVerified;
64
65
    /**
66
     * @var boolean|null
67
     */
68
    private $skipProvePossession;
69
70
    /**
71
     * @var boolean|null
72
     */
73
    private $vetted;
74
75
    /**
76
     * @param string $id
77
     * @param string $authorityId
78
     * @param string $registrationCode
79
     * @param VerifiedSecondFactor $secondFactor
80
     * @param bool $skipProvePossession
81
     * @return self
82
     */
83
    public static function start($id, $authorityId, $registrationCode, VerifiedSecondFactor $secondFactor, $skipProvePossession)
84
    {
85
        if (!is_string($id)) {
86
            throw InvalidArgumentException::invalidType('string', 'id', $id);
87
        }
88
89
        if (!is_string($authorityId)) {
90
            throw InvalidArgumentException::invalidType('string', 'authorityId', $authorityId);
91
        }
92
93
        if (!is_string($registrationCode)) {
94
            throw InvalidArgumentException::invalidType('string', 'registrationCode', $registrationCode);
95
        }
96
97
        if (!is_bool($skipProvePossession)) {
98
            throw InvalidArgumentException::invalidType('string', 'skipProvePossession', $skipProvePossession);
99
        }
100
101
        $procedure = new self();
102
        $procedure->id = $id;
103
        $procedure->authorityId = $authorityId;
104
        $procedure->registrationCode = $registrationCode;
105
        $procedure->secondFactor = $secondFactor;
106
        $procedure->skipProvePossession = $skipProvePossession;
107
108
        return $procedure;
109
    }
110
111
    final private function __construct()
0 ignored issues
show
introduced by
Instead of declaring the constructor as final, maybe you should declare the entire class as final.
Loading history...
112
    {
113
    }
114
115
    /**
116
     * @param string $secondFactorIdentifier
117
     * @return void
118
     * @throws DomainException
119
     */
120
    public function verifySecondFactorIdentifier($secondFactorIdentifier)
121
    {
122
        if (!$this->isReadyForSecondFactorToBeVerified()) {
123
            throw new DomainException(
124
                'Second factor is not yet ready for verification of second factor, ' .
125
                'it has already been verified or the registration code is unknown.'
126
            );
127
        }
128
129
        if ($secondFactorIdentifier !== $this->secondFactor->secondFactorIdentifier) {
130
            throw new DomainException("Input second factor identifier doesn't match expected second factor identifier");
131
        }
132
133
        $this->inputSecondFactorIdentifier = $secondFactorIdentifier;
134
    }
135
136
    /**
137
     * @param string $documentNumber
138
     * @param bool $identityVerified
139
     * @return void
140
     * @throws DomainException
141
     */
142
    public function verifyIdentity($documentNumber, $identityVerified)
143
    {
144
        if (!$this->isReadyForIdentityVerification()) {
145
            throw new DomainException(
146
                'Second factor is not yet ready for verification of its Identity; ' .
147
                'verify the registrant has the same second factor as used during the registration process.'
148
            );
149
        }
150
151
        if (!is_string($documentNumber)) {
152
            throw InvalidArgumentException::invalidType('string', 'documentNumber', $documentNumber);
153
        }
154
155
        if (empty($documentNumber)) {
156
            throw new InvalidArgumentException('Document number may not be empty.');
157
        }
158
159
        if ($identityVerified !== true) {
160
            throw new DomainException("The registrant's identity must have been confirmed by the RA.");
161
        }
162
163
        $this->documentNumber = $documentNumber;
164
        $this->identityVerified = true;
165
    }
166
167
    /**
168
     * @return void
169
     * @throws DomainException
170
     */
171
    public function vet()
172
    {
173
        if (!$this->isReadyForVetting()) {
174
            throw new DomainException(
175
                'Second factor is not yet ready for verification of its Identity; ' .
176
                'verify the registrant has the same second factor as used during the registration process, '.
177
                "and verify the registrant's identity."
178
            );
179
        }
180
181
        $this->vetted = true;
182
    }
183
184
    /**
185
     * @return string
186
     */
187
    public function getId()
188
    {
189
        return $this->id;
190
    }
191
192
    /**
193
     * @return VerifiedSecondFactor
194
     */
195
    public function getSecondFactor()
196
    {
197
        return $this->secondFactor;
198
    }
199
200
    /**
201
     * @return string
202
     */
203
    public function getAuthorityId()
204
    {
205
        return $this->authorityId;
206
    }
207
208
    /**
209
     * @return null|string
210
     */
211
    public function getRegistrationCode()
212
    {
213
        return $this->registrationCode;
214
    }
215
216
    /**
217
     * @return null|string
218
     */
219
    public function getInputSecondFactorIdentifier()
220
    {
221
        return $this->inputSecondFactorIdentifier;
222
    }
223
224
    /**
225
     * @return null|string
226
     */
227
    public function getDocumentNumber()
228
    {
229
        return $this->documentNumber;
230
    }
231
232
    /**
233
     * @return bool|null
234
     */
235
    public function isIdentityVerified()
236
    {
237
        return $this->identityVerified;
238
    }
239
240
    /**
241
     * @return bool|null
242
     */
243
    public function isProvePossessionSkippable()
244
    {
245
        return $this->skipProvePossession;
246
    }
247
248
    /**
249
     * @return bool
250
     */
251
    private function isReadyForSecondFactorToBeVerified()
252
    {
253
        return !empty($this->registrationCode);
254
    }
255
256
    /**
257
     * @return bool
258
     */
259
    private function isReadyForIdentityVerification()
260
    {
261
        return $this->isPossessionProvenOrCanItBeSkipped() && !empty($this->registrationCode);
262
    }
263
264
    /**
265
     * @return bool
266
     */
267
    private function isReadyForVetting()
268
    {
269
        return $this->isPossessionProvenOrCanItBeSkipped()
270
            && !empty($this->registrationCode)
271
            && !empty($this->documentNumber)
272
            && $this->identityVerified === true;
273
    }
274
275
    /**
276
     * @return bool
277
     */
278
    private function isPossessionProvenOrCanItBeSkipped()
279
    {
280
        return ($this->inputSecondFactorIdentifier === $this->secondFactor->secondFactorIdentifier || $this->skipProvePossession);
281
    }
282
}
283