zend-blog-3-backend
175 строк · 4.7 Кб
1<?php
2
3namespace App\Service;
4
5use App\DTO\ExternalUserDTO;
6use App\Entity\User;
7use App\Entity\UserExtraInfo;
8use App\Exception\ShortPasswordException;
9use Doctrine\ORM\EntityManager;
10use Doctrine\ORM\EntityManagerInterface;
11use Exception;
12use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
13
14class UserManager
15{
16/**
17* @var EntityManager
18*/
19private $em;
20
21private UserPasswordHasherInterface $passwordHasher;
22
23/**
24* @var Tracking
25*/
26private $tracking;
27
28public function __construct(
29EntityManagerInterface $em,
30UserPasswordHasherInterface $passwordHasher,
31Tracking $tracking
32) {
33$this->em = $em;
34$this->passwordHasher = $passwordHasher;
35$this->tracking = $tracking;
36}
37
38public function findByExternalDTO(ExternalUserDTO $data): array
39{
40$infoRepository = $this->em->getRepository(UserExtraInfo::class);
41$userInfo = $infoRepository->findOneBy([
42'externalId' => $data->id,
43'dataProvider' => $data->dataProvider,
44]);
45
46if ($userInfo) {
47return [$userInfo->getUser(), true];
48}
49
50if (!empty($data->email)) {
51$userRepository = $this->em->getRepository(User::class);
52$user = $userRepository->findOneBy(['email' => $data->email]);
53if ($user) {
54return [$user, false];
55}
56}
57
58return [null, false];
59}
60
61public function createFromExternalDTO(ExternalUserDTO $data): User
62{
63$generatedUsername = 'ext-' . str_pad(mt_rand(0, 9999999), 7, '0', STR_PAD_LEFT);
64$userRepository = $this->em->getRepository(User::class);
65
66$username = $data->username;
67$email = $data->email;
68
69if (empty($username)) {
70$username = $generatedUsername;
71} else {
72$temporaryUser = $userRepository->findOneByUsername($username);
73if ($temporaryUser) {
74$username = $generatedUsername;
75}
76}
77
78if (empty($email)) {
79$email = $generatedUsername . '@xelbot.fake';
80}
81
82$user = $this->createUser($username, $email);
83
84if (!empty($data->displayName)) {
85$user->setDisplayName($data->displayName);
86}
87
88if (!empty($data->gender) && $data->gender === 'female') {
89$user->setGender(User::FEMALE);
90}
91
92return $user;
93}
94
95/**
96* @param string $username
97* @param string $email
98* @param string|null $password
99*
100* @return User
101*/
102public function createUser(string $username, string $email, string $password = null): User
103{
104if (is_null($password)) {
105try {
106$password = base64_encode(random_bytes(32));
107} catch (Exception $exception) {
108$password = hash('sha256', uniqid(mt_rand(), true));
109}
110}
111
112$user = new User();
113$user
114->setUsername($username)
115->setEmail($email)
116->setPassword($this->passwordHasher->hashPassword($user, $password))
117;
118
119return $user;
120}
121
122/**
123* @param User $user
124* @param string $password
125*
126* @throws ShortPasswordException
127* @throws \Doctrine\ORM\Exception\ORMException
128*/
129public function updatePassword(User $user, string $password): void
130{
131if (strlen($password) <= 4) {
132throw new ShortPasswordException('Password too short');
133}
134
135$user->setRandomSalt();
136$user->setRandomWsseKey();
137
138$user->setPassword($this->passwordHasher->hashPassword($user, $password));
139
140$this->em->persist($user);
141$this->em->flush();
142}
143
144public function saveUserExtraInfo(ExternalUserDTO $data, User $user, ?string $ip, ?string $userAgent): UserExtraInfo
145{
146$agent = $userAgent ? $this->tracking->getTrackingAgent($userAgent) : null;
147
148$userInfo = new UserExtraInfo();
149$userInfo
150->setUser($user)
151->setExternalId($data->id)
152->setDataProvider($data->dataProvider)
153->setRawData($data->rawData)
154->setIpAddress($ip)
155->setTrackingAgent($agent)
156->setUsername($data->username)
157->setFirstName($data->firstName)
158->setLastName($data->lastName)
159->setDisplayName($data->displayName)
160->setEmail($data->email)
161->setAvatar($data->avatar)
162;
163
164if ($data->gender === 'female') {
165$userInfo->setGender(UserExtraInfo::FEMALE);
166} elseif ($data->gender === 'male') {
167$userInfo->setGender(UserExtraInfo::MALE);
168}
169
170$this->em->persist($userInfo);
171$this->em->flush();
172
173return $userInfo;
174}
175}
176