Passed
Push — v2 ( 5505d3...8372d3 )
by Daniel
04:27 queued 22s
created

User::setPasswordResetConfirmationToken()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 5
ccs 0
cts 3
cp 0
crap 2
rs 10
1
<?php
2
3
/*
4
 * This file is part of the Silverback API Component Bundle Project
5
 *
6
 * (c) Daniel West <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Silverback\ApiComponentBundle\Entity\User;
15
16
use DateTime;
17
use Doctrine\ORM\Mapping as ORM;
18
use Silverback\ApiComponentBundle\Validator\Constraints as APIAssert;
19
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
20
use Symfony\Component\Security\Core\User\UserInterface;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Silverback\ApiComponentB...tity\User\UserInterface. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
21
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
22
use Symfony\Component\Serializer\Annotation\Groups;
23
use Symfony\Component\Validator\Constraints as Assert;
24
25
/**
26
 * @ORM\MappedSuperclass(repositoryClass="Silverback\ApiComponentBundle\Repository\User\UserRepository")
27
 * @UniqueEntity(fields={"username"}, errorPath="username", message="Sorry, that user already exists in the database.")
28
 * @APIAssert\NewUsername(groups={"new_username", "Default"})
29
 */
30
abstract class User implements UserInterface
31
{
32
    /**
33
     * @ORM\Id
34
     * @ORM\GeneratedValue
35
     * @ORM\Column(type="integer", length=36)
36
     *
37
     * @var int
38
     */
39
    protected $id;
40
41
    /**
42
     * @ORM\Column(type="string", length=255, unique=true)
43
     * @Assert\NotBlank(groups={"Default"})
44
     * @Assert\Email(groups={"Default"})
45
     * @Groups({"admin"})
46
     *
47
     * @var string|null
48
     */
49
    protected $username;
50
51
    /**
52
     * @ORM\Column(type="string", length=255)
53
     */
54
    protected $password;
55
56
    /**
57
     * @ORM\Column(type="boolean")
58
     * @Groups({"admin"})
59
     */
60
    protected $enabled;
61
62
    /**
63
     * @ORM\Column(type="array")
64
     * @Groups({"default"})
65
     */
66
    protected $roles;
67
68
    /**
69
     * @Assert\NotBlank(message="Please enter your desired password", groups={"password_reset", "change_password"})
70
     * @Assert\Length(max="4096", min="6", maxMessage="Your password cannot be over 4096 characters", minMessage="Your password must be more than 6 characters long", groups={"Default", "password_reset", "change_password"})
71
     * @Groups({"default_write"})
72
     *
73
     * @var string|null
74
     */
75
    protected $plainPassword;
76
77
    /**
78
     * Random string sent to the user email address in order to verify it.
79
     *
80
     * @ORM\Column(nullable=true)
81
     *
82
     * @var string|null
83
     */
84
    protected $passwordResetConfirmationToken;
85
86
    /**
87
     * @ORM\Column(type="datetime", nullable=true)
88
     *
89
     * @var DateTime|null
90
     */
91
    protected $passwordRequestedAt;
92
93
    /**
94
     * @ORM\Column(type="string", length=255, nullable=true)
95
     * @Assert\NotBlank(groups={"new_username"})
96
     * @Assert\Email(groups={"new_username"})
97
     * @Groups({"default", "new_username"})
98
     *
99
     * @var string|null
100
     */
101
    protected $newUsername;
102
103
    /**
104
     * Random string sent to the user's new email address in order to verify it.
105
     *
106
     * @ORM\Column(nullable=true)
107
     *
108
     * @var string|null
109
     */
110
    protected $usernameConfirmationToken;
111
112
    /**
113
     * @UserPassword(message="You have not entered your current password correctly. Please try again.", groups={"change_password"})
114
     * @Groups({"default_write"})
115
     *
116
     * @var string|null
117
     */
118
    protected $oldPassword;
119
120
    /**
121
     * @ORM\Column(type="datetime", nullable=true)
122
     *
123
     * @var DateTime|null
124
     */
125
    protected $passwordLastUpdated;
126
127
    public function __construct(
128
        string $username = '',
129
        array $roles = ['ROLE_USER'],
130
        string $password = '',
131
        bool $enabled = true
132
    ) {
133
        $this->username = $username;
134
        $this->roles = $roles;
135
        $this->password = $password;
136
        $this->enabled = $enabled;
137
    }
138
139
    public function getId(): ?int
140
    {
141
        return $this->id;
142
    }
143
144
    public function getUsername(): ?string
145
    {
146
        return $this->username;
147
    }
148
149
    /**
150
     * @return static
151
     */
152
    public function setUsername(?string $username)
153
    {
154
        $this->username = $username;
155
156
        return $this;
157
    }
158
159
    public function getPassword(): ?string
160
    {
161
        return $this->password;
162
    }
163
164
    /**
165
     * @return static
166
     */
167
    public function setPassword(string $password)
168
    {
169
        $this->password = $password;
170
171
        return $this;
172
    }
173
174
    public function getRoles(): array
175
    {
176
        return $this->roles;
177
    }
178
179
    /**
180
     * @return static
181
     */
182
    public function setRoles(?array $roles)
183
    {
184
        $this->roles = $roles;
185
186
        return $this;
187
    }
188
189
    public function isEnabled(): bool
190
    {
191
        return $this->enabled;
192
    }
193
194
    /**
195
     * @return static
196
     */
197
    public function setEnabled(bool $enabled)
198
    {
199
        $this->enabled = $enabled;
200
201
        return $this;
202
    }
203
204
    public function getPlainPassword(): ?string
205
    {
206
        return $this->plainPassword;
207
    }
208
209
    /**
210
     * @return static
211
     */
212
    public function setPlainPassword(?string $plainPassword)
213
    {
214
        $this->plainPassword = $plainPassword;
215
        if ($plainPassword) {
216
            // Needs to update mapped field to trigger update event which will encode the plain password
217
            $this->passwordLastUpdated = new \DateTime();
218
        }
219
220
        return $this;
221
    }
222
223
    public function getPasswordResetConfirmationToken(): ?string
224
    {
225
        return $this->passwordResetConfirmationToken;
226
    }
227
228
    /**
229
     * @return static
230
     */
231
    public function setPasswordResetConfirmationToken(?string $passwordResetConfirmationToken)
232
    {
233
        $this->passwordResetConfirmationToken = $passwordResetConfirmationToken;
234
235
        return $this;
236
    }
237
238
    public function getPasswordRequestedAt(): ?DateTime
239
    {
240
        return $this->passwordRequestedAt;
241
    }
242
243
    /**
244
     * @return static
245
     */
246
    public function setPasswordRequestedAt(?DateTime $passwordRequestedAt)
247
    {
248
        $this->passwordRequestedAt = $passwordRequestedAt;
249
250
        return $this;
251
    }
252
253
    public function isPasswordRequestLimitReached($ttl)
254
    {
255
        $lastRequest = $this->getPasswordRequestedAt();
256
257
        return $lastRequest instanceof DateTime &&
258
            $lastRequest->getTimestamp() + $ttl > time();
259
    }
260
261
    public function getNewUsername(): ?string
262
    {
263
        return $this->newUsername;
264
    }
265
266
    /**
267
     * @return static
268
     */
269
    public function setNewUsername(?string $newUsername)
270
    {
271
        $this->newUsername = $newUsername;
272
273
        return $this;
274
    }
275
276
    public function getUsernameConfirmationToken(): ?string
277
    {
278
        return $this->usernameConfirmationToken;
279
    }
280
281
    /**
282
     * @return static
283
     */
284
    public function setUsernameConfirmationToken(?string $usernameConfirmationToken)
285
    {
286
        $this->usernameConfirmationToken = $usernameConfirmationToken;
287
288
        return $this;
289
    }
290
291
    public function getOldPassword(): ?string
292
    {
293
        return $this->oldPassword;
294
    }
295
296
    public function setOldPassword(?string $oldPassword): void
297
    {
298
        $this->oldPassword = $oldPassword;
299
    }
300
301
    /** @see \Serializable::serialize() */
302
    public function serialize(): string
303
    {
304
        return serialize([
305
            $this->id,
306
            $this->username,
307
            $this->password,
308
            $this->enabled,
309
        ]);
310
    }
311
312
    /**
313
     * @see \Serializable::unserialize()
314
     *
315
     * @param string $serialized
316
     */
317
    public function unserialize($serialized): void
318
    {
319
        [
320
            $this->id,
321
            $this->username,
322
            $this->password,
323
            $this->enabled
324
        ] = unserialize($serialized, ['allowed_classes' => false]);
325
    }
326
327
    // Not needed - we use bcrypt
328
    public function getSalt()
329
    {
330
    }
331
332
    // remove sensitive data - e.g. plain passwords etc.
333
    public function eraseCredentials(): void
334
    {
335
        $this->plainPassword = null;
336
    }
337
338
    public function __toString()
339
    {
340
        return (string) $this->id;
341
    }
342
}
343