Passed
Push — v2 ( 5fd3b3...d6a970 )
by Daniel
06:00 queued 44s
created

AbstractUser::getPlainPassword()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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