Completed
Push — feature/self-vet ( 66ee82...7edffb )
by Michiel
03:58
created

SensitiveData   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 177
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 22
lcom 1
cbo 7
dl 0
loc 177
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A withCommonName() 0 7 1
A withEmail() 0 7 1
A withSecondFactorIdentifier() 0 10 1
A withDocumentNumber() 0 7 1
A withVettingType() 0 7 1
A forget() 0 7 1
A getCommonName() 0 4 2
A getEmail() 0 4 2
A getSecondFactorIdentifier() 0 4 2
A getVettingType() 0 4 2
B deserialize() 0 27 6
A serialize() 0 11 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\StepupMiddleware\CommandHandlingBundle\SensitiveData;
20
21
use Broadway\Serializer\Serializable as SerializableInterface;
22
use Surfnet\Stepup\Identity\Value\CommonName;
23
use Surfnet\Stepup\Identity\Value\DocumentNumber;
24
use Surfnet\Stepup\Identity\Value\Email;
25
use Surfnet\Stepup\Identity\Value\SecondFactorIdentifier;
26
use Surfnet\Stepup\Identity\Value\SecondFactorIdentifierFactory;
27
use Surfnet\Stepup\Identity\Value\UnknownVettingType;
28
use Surfnet\Stepup\Identity\Value\VettingType;
29
use Surfnet\StepupBundle\Value\SecondFactorType;
30
31
class SensitiveData implements SerializableInterface
32
{
33
    /**
34
     * @var CommonName|null
35
     */
36
    private $commonName;
37
38
    /**
39
     * @var Email|null
40
     */
41
    private $email;
42
43
    /**
44
     * @var SecondFactorIdentifier|null
45
     */
46
    private $secondFactorIdentifier;
47
48
    /**
49
     * @var SecondFactorType|null
50
     */
51
    private $secondFactorType;
52
53
    /**
54
     * @var DocumentNumber|null
55
     */
56
    private $documentNumber;
57
58
    /**
59
     * @var VettingType
60
     */
61
    private $vettingType;
62
63
    /**
64
     * @param CommonName $commonName
65
     * @return SensitiveData
66
     */
67
    public function withCommonName(CommonName $commonName)
68
    {
69
        $clone = clone $this;
70
        $clone->commonName = $commonName;
71
72
        return $clone;
73
    }
74
75
    /**
76
     * @param Email $email
77
     * @return SensitiveData
78
     */
79
    public function withEmail(Email $email)
80
    {
81
        $clone = clone $this;
82
        $clone->email = $email;
83
84
        return $clone;
85
    }
86
87
    /**
88
     * @param SecondFactorIdentifier $secondFactorIdentifier
89
     * @param SecondFactorType       $secondFactorType
90
     * @return SensitiveData
91
     */
92
    public function withSecondFactorIdentifier(
93
        SecondFactorIdentifier $secondFactorIdentifier,
94
        SecondFactorType $secondFactorType
95
    ) {
96
        $clone = clone $this;
97
        $clone->secondFactorType = $secondFactorType;
98
        $clone->secondFactorIdentifier = $secondFactorIdentifier;
99
100
        return $clone;
101
    }
102
103
    /**
104
     * @param DocumentNumber $documentNumber
105
     * @return SensitiveData
106
     */
107
    public function withDocumentNumber(DocumentNumber $documentNumber)
108
    {
109
        $clone = clone $this;
110
        $clone->documentNumber = $documentNumber;
111
112
        return $clone;
113
    }
114
115
    public function withVettingType(VettingType $vettingType): self
116
    {
117
        $clone = clone $this;
118
        $clone->vettingType = $vettingType;
119
120
        return $clone;
121
    }
122
123
    /**
124
     * Returns an instance in which all sensitive data is forgotten.
125
     *
126
     * @return SensitiveData
127
     */
128
    public function forget()
129
    {
130
        $forgotten = new self();
131
        $forgotten->secondFactorType = $this->secondFactorType;
132
133
        return $forgotten;
134
    }
135
136
    /**
137
     * @return CommonName
138
     */
139
    public function getCommonName()
140
    {
141
        return $this->commonName ?: CommonName::unknown();
142
    }
143
144
    /**
145
     * @return Email
146
     */
147
    public function getEmail()
148
    {
149
        return $this->email ?: Email::unknown();
150
    }
151
152
    /**
153
     * @return SecondFactorIdentifier
154
     */
155
    public function getSecondFactorIdentifier()
156
    {
157
        return $this->secondFactorIdentifier ?: SecondFactorIdentifierFactory::unknownForType($this->secondFactorType);
0 ignored issues
show
Bug introduced by
It seems like $this->secondFactorType can be null; however, unknownForType() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
158
    }
159
160
    /**
161
     * @return VettingType
162
     */
163
    public function getVettingType()
164
    {
165
        return $this->vettingType ?: new UnknownVettingType();
166
    }
167
168
    public static function deserialize(array $data)
169
    {
170
        $self = new self;
171
172
        if (isset($data['common_name'])) {
173
            $self->commonName = new CommonName($data['common_name']);
174
        }
175
176
        if (isset($data['email'])) {
177
            $self->email = new Email($data['email']);
178
        }
179
180
        if (isset($data['second_factor_type'])) {
181
            $self->secondFactorType = new SecondFactorType($data['second_factor_type']);
182
        }
183
184
        if (isset($data['second_factor_identifier'])) {
185
            $self->secondFactorIdentifier =
186
                SecondFactorIdentifierFactory::forType($self->secondFactorType, $data['second_factor_identifier']);
0 ignored issues
show
Bug introduced by
It seems like $self->secondFactorType can be null; however, forType() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
187
        }
188
189
        if (isset($data['document_number'])) {
190
            $self->documentNumber = new DocumentNumber($data['document_number']);
191
        }
192
193
        return $self;
194
    }
195
196
    public function serialize(): array
197
    {
198
        $vettingType = (!is_null($this->vettingType)) ? $this->vettingType->jsonSerialize() : null;
199
        return array_filter([
200
            'common_name'              => $this->commonName,
201
            'email'                    => $this->email,
202
            'second_factor_type'       => $this->secondFactorType,
203
            'second_factor_identifier' => $this->secondFactorIdentifier,
204
            'vetting_type' => $vettingType
205
        ]);
206
    }
207
}
208