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