7
7
use App \Exceptions \InvalidArgumentException ;
8
8
use App \Exceptions \NotFoundException ;
9
9
use App \Exceptions \WrongCredentialsException ;
10
+ use App \Model \Entity \ExternalLogin ;
10
11
use App \Model \Entity \Group ;
11
12
use App \Model \Entity \Login ;
12
13
use App \Model \Entity \SecurityEvent ;
13
14
use App \Model \Entity \User ;
14
15
use App \Model \Entity \UserUiData ;
16
+ use App \Model \Repository \ExternalLogins ;
15
17
use App \Model \Repository \Logins ;
16
18
use App \Model \Repository \SecurityEvents ;
17
19
use App \Exceptions \BadRequestException ;
@@ -36,6 +38,12 @@ class UsersPresenter extends BasePresenter
36
38
*/
37
39
public $ logins ;
38
40
41
+ /**
42
+ * @var ExternalLogins
43
+ * @inject
44
+ */
45
+ public $ externalLogins ;
46
+
39
47
/**
40
48
* @var SecurityEvents
41
49
* @inject
@@ -294,7 +302,7 @@ private function changeUserEmail(User $user, ?string $email)
294
302
}
295
303
296
304
if (filter_var ($ email , FILTER_VALIDATE_EMAIL ) === false ) {
297
- throw new InvalidArgumentException ("Provided email is not in correct format " );
305
+ throw new InvalidArgumentException (' email ' , "Provided email is not in correct format " );
298
306
}
299
307
300
308
$ oldEmail = $ user ->getEmail ();
@@ -375,7 +383,7 @@ private function changeUserPassword(
375
383
376
384
if (!$ password || !$ passwordConfirm ) {
377
385
// old password was provided but the new ones not, illegal state
378
- throw new InvalidArgumentException ("New password was not provided " );
386
+ throw new InvalidArgumentException (' password|passwordConfirm ' , "New password was not provided " );
379
387
}
380
388
381
389
// passwords need to be handled differently
@@ -764,4 +772,76 @@ public function actionSetAllowed(string $id)
764
772
$ this ->users ->flush ();
765
773
$ this ->sendSuccessResponse ($ this ->userViewFactory ->getUser ($ user ));
766
774
}
775
+
776
+ public function checkUpdateExternalLogin (string $ id , string $ service )
777
+ {
778
+ $ user = $ this ->users ->findOrThrow ($ id );
779
+ if (!$ this ->userAcl ->canSetExternalIds ($ user )) {
780
+ throw new ForbiddenRequestException ();
781
+ }
782
+
783
+ // in the future, we might consider cross-checking the service ID
784
+ }
785
+
786
+ /**
787
+ * Add or update existing external ID of given authentication service.
788
+ * @POST
789
+ * @param string $id identifier of the user
790
+ * @param string $service identifier of the authentication service (login type)
791
+ * @Param(type="post", name="externalId", validation="string:1..128")
792
+ * @throws InvalidArgumentException
793
+ */
794
+ public function actionUpdateExternalLogin (string $ id , string $ service )
795
+ {
796
+ $ user = $ this ->users ->findOrThrow ($ id );
797
+
798
+ // make sure the external ID is not used for another user
799
+ $ externalId = $ this ->getRequest ()->getPost ("externalId " );
800
+ $ anotherUser = $ this ->externalLogins ->getUser ($ service , $ externalId );
801
+ if ($ anotherUser ) {
802
+ if ($ anotherUser ->getId () !== $ id ) {
803
+ // oopsie, this external ID is alreay used for a different user
804
+ throw new InvalidArgumentException ('externalId ' , "This ID is already used by another user. " );
805
+ }
806
+ // otherwise the external ID is already set to this user, so there is nothing to change...
807
+ } else {
808
+ // create/update external login entry
809
+ $ login = $ this ->externalLogins ->findByUser ($ user , $ service );
810
+ if ($ login ) {
811
+ $ login ->setExternalId ($ externalId );
812
+ } else {
813
+ $ login = new ExternalLogin ($ user , $ service , $ externalId );
814
+ }
815
+
816
+ $ this ->externalLogins ->persist ($ login );
817
+ }
818
+
819
+ $ this ->sendSuccessResponse ($ this ->userViewFactory ->getUser ($ user ));
820
+ }
821
+
822
+ public function checkRemoveExternalLogin (string $ id , string $ service )
823
+ {
824
+ $ user = $ this ->users ->findOrThrow ($ id );
825
+ if (!$ this ->userAcl ->canSetExternalIds ($ user )) {
826
+ throw new ForbiddenRequestException ();
827
+ }
828
+
829
+ // in the future, we might consider cross-checking the service ID
830
+ }
831
+
832
+ /**
833
+ * Remove external ID of given authentication service.
834
+ * @DELETE
835
+ * @param string $id identifier of the user
836
+ * @param string $service identifier of the authentication service (login type)
837
+ */
838
+ public function actionRemoveExternalLogin (string $ id , string $ service )
839
+ {
840
+ $ user = $ this ->users ->findOrThrow ($ id );
841
+ $ login = $ this ->externalLogins ->findByUser ($ user , $ service );
842
+ if ($ login ) {
843
+ $ this ->externalLogins ->remove ($ login );
844
+ }
845
+ $ this ->sendSuccessResponse ($ this ->userViewFactory ->getUser ($ user ));
846
+ }
767
847
}
0 commit comments