Completed
Push — feature/self-vet ( 7edffb...85e549 )
by Michiel
03:37
created

SensitiveData::withDocumentNumber()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
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 VettingType
55
     */
56
    private $vettingType;
57
58
    /**
59
     * @param CommonName $commonName
60
     * @return SensitiveData
61
     */
62
    public function withCommonName(CommonName $commonName)
63
    {
64
        $clone = clone $this;
65
        $clone->commonName = $commonName;
66
67
        return $clone;
68
    }
69
70
    /**
71
     * @param Email $email
72
     * @return SensitiveData
73
     */
74
    public function withEmail(Email $email)
75
    {
76
        $clone = clone $this;
77
        $clone->email = $email;
78
79
        return $clone;
80
    }
81
82
    /**
83
     * @param SecondFactorIdentifier $secondFactorIdentifier
84
     * @param SecondFactorType       $secondFactorType
85
     * @return SensitiveData
86
     */
87
    public function withSecondFactorIdentifier(
88
        SecondFactorIdentifier $secondFactorIdentifier,
89
        SecondFactorType $secondFactorType
90
    ) {
91
        $clone = clone $this;
92
        $clone->secondFactorType = $secondFactorType;
93
        $clone->secondFactorIdentifier = $secondFactorIdentifier;
94
95
        return $clone;
96
    }
97
98
    public function withVettingType(VettingType $vettingType): self
99
    {
100
        $clone = clone $this;
101
        $clone->vettingType = $vettingType;
102
103
        return $clone;
104
    }
105
106
    /**
107
     * Returns an instance in which all sensitive data is forgotten.
108
     *
109
     * @return SensitiveData
110
     */
111
    public function forget()
112
    {
113
        $forgotten = new self();
114
        $forgotten->secondFactorType = $this->secondFactorType;
115
116
        return $forgotten;
117
    }
118
119
    /**
120
     * @return CommonName
121
     */
122
    public function getCommonName()
123
    {
124
        return $this->commonName ?: CommonName::unknown();
125
    }
126
127
    /**
128
     * @return Email
129
     */
130
    public function getEmail()
131
    {
132
        return $this->email ?: Email::unknown();
133
    }
134
135
    /**
136
     * @return SecondFactorIdentifier
137
     */
138
    public function getSecondFactorIdentifier()
139
    {
140
        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...
141
    }
142
143
    /**
144
     * @return VettingType
145
     */
146
    public function getVettingType()
147
    {
148
        return $this->vettingType ?: new UnknownVettingType();
149
    }
150
151
    public static function deserialize(array $data)
152
    {
153
        $self = new self;
154
155
        if (isset($data['common_name'])) {
156
            $self->commonName = new CommonName($data['common_name']);
157
        }
158
159
        if (isset($data['email'])) {
160
            $self->email = new Email($data['email']);
161
        }
162
163
        if (isset($data['second_factor_type'])) {
164
            $self->secondFactorType = new SecondFactorType($data['second_factor_type']);
165
        }
166
167
        if (isset($data['second_factor_identifier'])) {
168
            $self->secondFactorIdentifier =
169
                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...
170
        }
171
172
        if (isset($data['document_number'])) {
173
            $self->documentNumber = new DocumentNumber($data['document_number']);
0 ignored issues
show
Bug introduced by
The property documentNumber does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
174
        }
175
176
        return $self;
177
    }
178
179
    public function serialize(): array
180
    {
181
        $vettingType = (!is_null($this->vettingType)) ? $this->vettingType->jsonSerialize() : null;
182
        return array_filter([
183
            'common_name'              => $this->commonName,
184
            'email'                    => $this->email,
185
            'second_factor_type'       => $this->secondFactorType,
186
            'second_factor_identifier' => $this->secondFactorIdentifier,
187
            'vetting_type' => $vettingType
188
        ]);
189
    }
190
}
191