-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathUserService.php
112 lines (90 loc) · 3.83 KB
/
UserService.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<?php
namespace inklabs\kommerce\Service;
use inklabs\kommerce\Entity\User;
use inklabs\kommerce\Entity\UserLogin;
use inklabs\kommerce\Entity\UserLoginResultType;
use inklabs\kommerce\Entity\UserToken;
use inklabs\kommerce\Exception\EntityNotFoundException;
use inklabs\kommerce\EntityRepository\UserLoginRepositoryInterface;
use inklabs\kommerce\EntityRepository\UserRepositoryInterface;
use inklabs\kommerce\EntityRepository\UserTokenRepositoryInterface;
use inklabs\kommerce\Exception\UserLoginException;
use inklabs\kommerce\Lib\Event\EventDispatcherInterface;
class UserService implements UserServiceInterface
{
use EntityValidationTrait;
protected $userSessionKey = 'user';
/** @var UserRepositoryInterface */
private $userRepository;
/** @var UserLoginRepositoryInterface */
private $userLoginRepository;
/** @var UserTokenRepositoryInterface */
private $userTokenRepository;
/** @var EventDispatcherInterface */
private $eventDispatcher;
public function __construct(
UserRepositoryInterface $userRepository,
UserLoginRepositoryInterface $userLoginRepository,
UserTokenRepositoryInterface $userTokenRepository,
EventDispatcherInterface $eventDispatcher
) {
$this->userRepository = $userRepository;
$this->userLoginRepository = $userLoginRepository;
$this->userTokenRepository = $userTokenRepository;
$this->eventDispatcher = $eventDispatcher;
}
public function login(string $email, string $password, string $remoteIp): User
{
$user = $this->getUserOrAssertAndRecordLoginFailure($email, $remoteIp);
if (! $user->verifyPassword($password)) {
$this->recordLogin($email, $remoteIp, UserLoginResultType::fail(), $user);
throw UserLoginException::invalidPassword();
}
$this->recordLogin($email, $remoteIp, UserLoginResultType::success(), $user);
return $user;
}
public function loginWithToken(string $email, string $token, string $remoteIp): User
{
$user = $this->getUserOrAssertAndRecordLoginFailure($email, $remoteIp);
try {
$userToken = $this->userTokenRepository->findLatestOneByUserId($user->getId());
} catch (EntityNotFoundException $e) {
$this->recordLogin($email, $remoteIp, UserLoginResultType::fail(), $user);
throw UserLoginException::tokenNotFound();
}
if (! $userToken->verifyToken($token)) {
$this->recordLogin($email, $remoteIp, UserLoginResultType::fail(), $user);
throw UserLoginException::tokenNotValid();
}
if (! $userToken->verifyTokenDateValid()) {
$this->recordLogin($email, $remoteIp, UserLoginResultType::fail(), $user);
throw UserLoginException::tokenExpired();
}
$this->recordLogin($email, $remoteIp, UserLoginResultType::success(), $user, $userToken);
return $user;
}
protected function recordLogin(
string $email,
string $ip4,
UserLoginResultType $result,
User $user = null,
UserToken $userToken = null
): void {
$userLogin = new UserLogin($result, $email, $ip4, $user, $userToken);
$this->userLoginRepository->create($userLogin);
}
private function getUserOrAssertAndRecordLoginFailure(string $email, string $remoteIp): User
{
try {
$user = $this->userRepository->findOneByEmail($email);
} catch (EntityNotFoundException $e) {
$this->recordLogin($email, $remoteIp, UserLoginResultType::fail());
throw UserLoginException::userNotFound();
}
if (! $user->getStatus()->isActive()) {
$this->recordLogin($email, $remoteIp, UserLoginResultType::fail(), $user);
throw UserLoginException::userNotActive();
}
return $user;
}
}