@@ -221,10 +221,6 @@ function (Filter\Condition $condition) {
221221
222222 $ contactId = $ this ->getContactId ($ identifier );
223223 if ($ contactId !== null ) {
224- if (isset ($ data ['username ' ])) {
225- $ this ->assertUniqueUsername ($ data ['username ' ]);
226- }
227-
228224 $ db ->update ('contact ' , [
229225 'full_name ' => $ data ['full_name ' ],
230226 'username ' => $ data ['username ' ] ?? null ,
@@ -397,10 +393,6 @@ protected function getContactId(string $identifier): ?int
397393 */
398394 private function addContact (array $ data ): void
399395 {
400- if (isset ($ data ['username ' ])) {
401- $ this ->assertUniqueUsername ($ data ['username ' ]);
402- }
403-
404396 Database::get ()->insert ('contact ' , [
405397 'full_name ' => $ data ['full_name ' ],
406398 'username ' => $ data ['username ' ] ?? null ,
@@ -419,55 +411,6 @@ private function addContact(array $data): void
419411 }
420412 }
421413
422- /**
423- * Assert that the username is unique
424- *
425- * @param string $username
426- *
427- * @return void
428- *
429- * @throws HttpBadRequestException if the username already exists
430- */
431- private function assertUniqueUsername (string $ username ): void
432- {
433- $ user = Database::get ()->fetchOne (
434- (new Select ())
435- ->from ('contact ' )
436- ->columns (1 )
437- ->where (['username = ? ' => $ username ])
438- );
439-
440- if ($ user !== false ) {
441- $ this ->httpBadRequest ('Username already exists ' );
442- }
443- }
444-
445- /**
446- * Assert that the address type exists
447- *
448- * @param string[] $addressTypes
449- *
450- * @return void
451- *
452- * @throws HttpBadRequestException if the username already exists
453- */
454- private function assertAddressTypesExist (array $ addressTypes ): void
455- {
456- $ types = Database::get ()->fetchCol (
457- (new Select ())
458- ->from ('available_channel_type ' )
459- ->columns ('type ' )
460- ->where (['type IN (?) ' => $ addressTypes ])
461- );
462-
463- if (count ($ types ) !== count ($ addressTypes )) {
464- $ this ->httpBadRequest (sprintf (
465- 'Undefined address type %s given ' ,
466- implode (', ' , array_diff ($ addressTypes , $ types ))
467- ));
468- }
469- }
470-
471414 /**
472415 * Add the groups to the given contact
473416 *
@@ -498,8 +441,6 @@ private function addGroups(int $contactId, array $groups): void
498441 */
499442 private function addAddresses (int $ contactId , array $ addresses ): void
500443 {
501- $ this ->assertAddressTypesExist (array_keys ($ addresses ));
502-
503444 foreach ($ addresses as $ type => $ address ) {
504445 Database::get ()->insert ('contact_address ' , [
505446 'contact_id ' => $ contactId ,
@@ -534,26 +475,79 @@ private function removeContact(int $id): void
534475 */
535476 private function assertValidData (array $ data ): void
536477 {
537- if (! isset ($ data ['id ' ], $ data ['full_name ' ], $ data ['default_channel ' ])) {
538- $ this ->httpBadRequest ('The request body must contain the fields id, full_name and default_channel ' );
478+ $ msgPrefix = 'Invalid request body: ' ;
479+
480+ if (! isset ($ data ['id ' ], $ data ['full_name ' ], $ data ['default_channel ' ])
481+ || ! is_string ($ data ['id ' ])
482+ || ! is_string ($ data ['full_name ' ])
483+ || ! is_string ($ data ['default_channel ' ])
484+ ) {
485+ $ this ->httpBadRequest (
486+ $ msgPrefix . 'the fields id, full_name and default_channel must be present and of type string '
487+ );
539488 }
540489
541490 if (! Uuid::isValid ($ data ['id ' ])) {
542- $ this ->httpBadRequest ('Given id in the request body is not a valid UUID ' );
491+ $ this ->httpBadRequest ($ msgPrefix . 'given id is not a valid UUID ' );
492+ }
493+
494+ if (! empty ($ data ['username ' ])) {
495+ if (! is_string ($ data ['username ' ])) {
496+ $ this ->httpBadRequest ($ msgPrefix . 'expects username to be a string ' );
497+ }
498+
499+ $ user = Database::get ()->fetchOne (
500+ (new Select ())
501+ ->from ('contact ' )
502+ ->columns (1 )
503+ ->where (['username = ? ' => $ data ['username ' ]])
504+ );
505+
506+ if ($ user !== false ) {
507+ $ this ->httpBadRequest ($ msgPrefix . 'username already exists ' );
508+ }
543509 }
544510
545511 if (! empty ($ data ['groups ' ])) {
512+ if (! is_array ($ data ['groups ' ])) {
513+ $ this ->httpBadRequest ($ msgPrefix . 'expects groups to be an array ' );
514+ }
515+
546516 foreach ($ data ['groups ' ] as $ group ) {
547- if (! Uuid::isValid ($ group )) {
548- $ this ->httpBadRequest (' Group identifiers in the request body must be valid UUIDs ' );
517+ if (! is_string ( $ group ) || ! Uuid::isValid ($ group )) {
518+ $ this ->httpBadRequest ($ msgPrefix . ' group identifiers must be valid UUIDs ' );
549519 }
550520 }
551521 }
552522
553- if (! empty ($ data ['addresses ' ]['email ' ])
554- && ! (new EmailAddressValidator ())->isValid ($ data ['addresses ' ]['email ' ])
555- ) {
556- $ this ->httpBadRequest ('Request body contains an invalid email address ' );
523+ if (! empty ($ data ['addresses ' ])) {
524+ if (! is_array ($ data ['addresses ' ])) {
525+ $ this ->httpBadRequest ($ msgPrefix . 'expects addresses to be an array ' );
526+ }
527+
528+ $ addressTypes = array_keys ($ data ['addresses ' ]);
529+
530+ $ types = Database::get ()->fetchCol (
531+ (new Select ())
532+ ->from ('available_channel_type ' )
533+ ->columns ('type ' )
534+ ->where (['type IN (?) ' => $ addressTypes ])
535+ );
536+
537+ if (count ($ types ) !== count ($ addressTypes )) {
538+ $ this ->httpBadRequest (sprintf (
539+ $ msgPrefix . 'undefined address type %s given ' ,
540+ implode (', ' , array_diff ($ addressTypes , $ types ))
541+ ));
542+ }
543+ //TODO: cant decide if this is a a good idea to check valid types and username here, if yes,
544+ //default_contact and group identifiers must be checked here as well..404 OR 400?
545+
546+ if (! empty ($ data ['addresses ' ]['email ' ])
547+ && ! (new EmailAddressValidator ())->isValid ($ data ['addresses ' ]['email ' ])
548+ ) {
549+ $ this ->httpBadRequest ($ msgPrefix . 'an invalid email address given ' );
550+ }
557551 }
558552 }
559553}
0 commit comments