Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
92.42% |
61 / 66 |
|
0.00% |
0 / 1 |
CRAP | |
0.00% |
0 / 1 |
UpdateUserEndpoint | |
92.42% |
61 / 66 |
|
0.00% |
0 / 1 |
20.17 | |
0.00% |
0 / 1 |
handle | |
92.42% |
61 / 66 |
|
0.00% |
0 / 1 |
20.17 |
1 | <?php |
2 | |
3 | namespace Olz\Users\Endpoints; |
4 | |
5 | use Olz\Api\OlzUpdateEntityTypedEndpoint; |
6 | use Olz\Entity\Roles\Role; |
7 | use Olz\Entity\Users\User; |
8 | use PhpTypeScriptApi\Fields\ValidationError; |
9 | use PhpTypeScriptApi\HttpError; |
10 | |
11 | /** |
12 | * @phpstan-import-type OlzUserId from UserEndpointTrait |
13 | * @phpstan-import-type OlzUserData from UserEndpointTrait |
14 | * |
15 | * @extends OlzUpdateEntityTypedEndpoint<OlzUserId, OlzUserData, never, array{ |
16 | * status: 'OK'|'OK_NO_EMAIL_VERIFICATION'|'DENIED'|'ERROR', |
17 | * }> |
18 | */ |
19 | class UpdateUserEndpoint extends OlzUpdateEntityTypedEndpoint { |
20 | use UserEndpointTrait; |
21 | |
22 | protected function handle(mixed $input): mixed { |
23 | $user_repo = $this->entityManager()->getRepository(User::class); |
24 | $role_repo = $this->entityManager()->getRepository(Role::class); |
25 | $entity = $this->getEntityById($input['id']); |
26 | |
27 | $current_user = $this->authUtils()->getCurrentUser(); |
28 | $is_me = ( |
29 | $current_user |
30 | && $entity->getUsername() === $current_user->getUsername() |
31 | && $entity->getId() === $current_user->getId() |
32 | ); |
33 | $can_update = $this->entityUtils()->canUpdateOlzEntity($entity, null, 'users'); |
34 | if (!$is_me && !$can_update) { |
35 | throw new HttpError(403, "Kein Zugriff!"); |
36 | } |
37 | |
38 | // Username validation |
39 | $old_username = $entity->getUsername(); |
40 | $new_username = $input['data']['username']; |
41 | $is_username_updated = $new_username !== $old_username; |
42 | if (!$this->authUtils()->isUsernameAllowed($new_username)) { |
43 | throw new ValidationError(['username' => ["Der Benutzername darf nur Buchstaben, Zahlen, und die Zeichen -_. enthalten."]]); |
44 | } |
45 | if ($is_username_updated) { |
46 | $same_username_user = $user_repo->findOneBy(['username' => $new_username]); |
47 | $same_old_username_user = $user_repo->findOneBy(['old_username' => $new_username]); |
48 | $same_username_role = $role_repo->findOneBy(['username' => $new_username]); |
49 | $same_old_username_role = $role_repo->findOneBy(['old_username' => $new_username]); |
50 | $is_existing_username = (bool) ( |
51 | $same_username_user || $same_old_username_user |
52 | || $same_username_role || $same_old_username_role |
53 | ); |
54 | if ($is_existing_username) { |
55 | throw new ValidationError(['username' => ["Dieser Benutzername ist bereits vergeben."]]); |
56 | } |
57 | } |
58 | |
59 | // Email validation |
60 | $new_email = $input['data']['email'] ?? null; |
61 | $is_email_updated = $new_email !== $entity->getEmail(); |
62 | if (preg_match('/@olzimmerberg\.ch$/i', $new_email ?? '')) { |
63 | throw new ValidationError(['email' => ["Bitte keine @olzimmerberg.ch E-Mail verwenden."]]); |
64 | } |
65 | if ($is_email_updated) { |
66 | $same_email_user = $user_repo->findOneBy(['email' => $new_email]); |
67 | if ($same_email_user) { |
68 | throw new ValidationError(['email' => ["Es existiert bereits eine Person mit dieser E-Mail Adresse."]]); |
69 | } |
70 | } |
71 | |
72 | // TODO Do this more elegantly? |
73 | $old_data = $this->getEntityData($entity); |
74 | $this->log()->notice('OLD:', [$old_data]); |
75 | |
76 | $this->entityUtils()->updateOlzEntity($entity, $input['meta']); |
77 | if ($is_username_updated) { |
78 | $entity->setOldUsername($entity->getUsername()); |
79 | } |
80 | $this->updateEntityWithData($entity, $input['data']); |
81 | if ($is_email_updated) { |
82 | $entity->setEmailIsVerified(false); |
83 | $entity->setEmailVerificationToken(null); |
84 | $entity->removePermission('verified_email'); |
85 | } |
86 | |
87 | // TODO Do this more elegantly? |
88 | $new_data = $this->getEntityData($entity); |
89 | $this->log()->notice('NEW:', [$new_data]); |
90 | |
91 | $this->entityManager()->persist($entity); |
92 | $this->entityManager()->flush(); |
93 | $this->persistUploads($entity, $input['data']); |
94 | |
95 | if ($is_username_updated && $this->session()->get('user') === $old_username) { |
96 | $this->session()->set('user', $new_username); |
97 | } |
98 | |
99 | if ($is_email_updated) { |
100 | $this->emailUtils()->setLogger($this->log()); |
101 | try { |
102 | $this->emailUtils()->sendEmailVerificationEmail($entity); |
103 | } catch (\Throwable $th) { |
104 | return [ |
105 | 'custom' => ['status' => 'OK_NO_EMAIL_VERIFICATION'], |
106 | 'id' => $entity->getId() ?? 0, |
107 | ]; |
108 | } |
109 | $this->entityManager()->flush(); |
110 | } |
111 | |
112 | return [ |
113 | 'custom' => ['status' => 'OK'], |
114 | 'id' => $entity->getId() ?? 0, |
115 | ]; |
116 | } |
117 | } |