2323use OCA \UserOIDC \Service \DiscoveryService ;
2424use OCA \UserOIDC \Service \LdapService ;
2525use OCA \UserOIDC \Service \ProviderService ;
26+ use OCA \UserOIDC \Service \ProvisioningDeniedException ;
2627use OCA \UserOIDC \Service \ProvisioningService ;
2728use OCA \UserOIDC \Service \TokenService ;
2829use OCA \UserOIDC \User \Backend ;
@@ -491,14 +492,31 @@ public function code(string $state = '', string $code = '', string $scope = '',
491492 }
492493
493494 if ($ autoProvisionAllowed ) {
494- if (!$ softAutoProvisionAllowed && $ userFromOtherBackend !== null ) {
495+ // TODO: (proposal) refactor all provisioning strategies into event handlers
496+ $ user = null ;
497+
498+ try {
499+ // use potential user from other backend, create it in our backend if it does not exist
500+ $ user = $ this ->provisioningService ->provisionUser ($ userId , $ providerId , $ idTokenPayload , $ userFromOtherBackend );
501+ } catch (ProvisioningDeniedException $ denied ) {
502+ // TODO: MagentaCLOUD should upstream the exception handling
503+ $ redirectUrl = $ denied ->getRedirectUrl ();
504+ if ($ redirectUrl === null ) {
505+ $ message = $ this ->l10n ->t ('Failed to provision user ' );
506+ return $ this ->build403TemplateResponse ($ message , Http::STATUS_BAD_REQUEST , ['reason ' => $ denied ->getMessage ()]);
507+ } else {
508+ // error response is a redirect, e.g. to a booking site
509+ // so that you can immediately get the registration page
510+ return new RedirectResponse ($ redirectUrl );
511+ }
512+ }
513+
514+ if (!$ softAutoProvisionAllowed && $ userFromOtherBackend !== null && $ user === null ) {
495515 // if soft auto-provisioning is disabled,
496516 // we refuse login for a user that already exists in another backend
497517 $ message = $ this ->l10n ->t ('User conflict ' );
498518 return $ this ->build403TemplateResponse ($ message , Http::STATUS_BAD_REQUEST , ['reason ' => 'non-soft auto provision, user conflict ' ], false );
499519 }
500- // use potential user from other backend, create it in our backend if it does not exist
501- $ user = $ this ->provisioningService ->provisionUser ($ userId , $ providerId , $ idTokenPayload , $ userFromOtherBackend );
502520 } else {
503521 // when auto provision is disabled, we assume the user has been created by another user backend (or manually)
504522 $ user = $ userFromOtherBackend ;
@@ -769,7 +787,7 @@ public function backChannelLogout(string $providerIdentifier, string $logout_tok
769787 * @return JSONResponse
770788 */
771789 private function getBackchannelLogoutErrorResponse (
772- string $ error , string $ description , array $ throttleMetadata = [],
790+ string $ error , string $ description , array $ throttleMetadata = [], ? bool $ throttle = null ,
773791 ): JSONResponse {
774792 $ this ->logger ->debug ('Backchannel logout error. ' . $ error . ' ; ' . $ description );
775793 return new JSONResponse (
@@ -806,4 +824,4 @@ private function toCodeChallenge(string $data): string {
806824 $ s = str_replace ('/ ' , '_ ' , $ s ); // 63rd char of encoding
807825 return $ s ;
808826 }
809- }
827+ }
0 commit comments