diff --git a/lib/Alchemy/Phrasea/Authentication/RegistrationService.php b/lib/Alchemy/Phrasea/Authentication/RegistrationService.php index 0e4d4fcb81..7ffdf8c489 100644 --- a/lib/Alchemy/Phrasea/Authentication/RegistrationService.php +++ b/lib/Alchemy/Phrasea/Authentication/RegistrationService.php @@ -10,9 +10,9 @@ use Alchemy\Phrasea\Core\Configuration\RegistrationManager; use Alchemy\Phrasea\Core\Event\RegistrationEvent; use Alchemy\Phrasea\Core\PhraseaEvents; use Alchemy\Phrasea\Exception\RuntimeException; -use Alchemy\Phrasea\Model\Entities\Registration; use Alchemy\Phrasea\Model\Entities\User; use Alchemy\Phrasea\Model\Entities\UsrAuthProvider; +use Alchemy\Phrasea\Model\Entities\WebhookEvent; use Alchemy\Phrasea\Model\Manipulator\RegistrationManipulator; use Alchemy\Phrasea\Model\Manipulator\TokenManipulator; use Alchemy\Phrasea\Model\Manipulator\UserManipulator; @@ -176,7 +176,7 @@ class RegistrationService ); if ($userAuthenticationProvider) { - return $userAuthenticationProvider->getUser($this->app); + return $userAuthenticationProvider->getUser(); } return null; @@ -190,8 +190,7 @@ class RegistrationService $provider = $this->oauthProviderCollection->get($providerId); } - $inscriptions = $this->registrationManager->getRegistrationSummary(); - $authorizedCollections = $this->getAuthorizedCollections($selectedCollections, $inscriptions); + $authorizedCollections = $this->getAuthorizedCollections($selectedCollections); if (!isset($data['login'])) { $data['login'] = $data['email']; @@ -205,7 +204,7 @@ class RegistrationService foreach (self::$userPropertySetterMap as $property => $method) { if (isset($data[$property])) { - call_user_func(array($user, $method), $data[$property]); + $user->$method($data[$property]); } } @@ -217,7 +216,17 @@ class RegistrationService $this->entityManager->flush(); } - $this->applyAclsToUser($authorizedCollections, $user); + if ($this->configuration->get(['registry', 'registration', 'auto-register-enabled'])) { + $acl = $this->aclProvider->get($user); + foreach ($authorizedCollections as $baseId => $collection) { + if( ($model = $collection->getAutoregisterModel($data['email'])) !== null) { + if( ($template_user = $this->userRepository->findByLogin($model)) !== null) { + $acl->apply_model($template_user, [$baseId]); + } + } + } + } + $this->createCollectionAccessDemands($user, $authorizedCollections); $user->setMailLocked(true); @@ -226,8 +235,7 @@ class RegistrationService public function createCollectionRequests(User $user, array $collections) { - $inscriptions = $this->registrationManager->getRegistrationSummary($user); - $authorizedCollections = $this->getAuthorizedCollections($collections, $inscriptions); + $authorizedCollections = $this->getAuthorizedCollections($collections); $this->createCollectionAccessDemands($user, $authorizedCollections); } @@ -279,7 +287,7 @@ class RegistrationService /** * @param array $selectedCollections - * @return array + * @return \collection[] */ private function getAuthorizedCollections(array $selectedCollections = null) { @@ -292,8 +300,8 @@ class RegistrationService continue; } - if ($canRegister = \igorw\get_in($inscriptions, [$databox->get_sbas_id(), 'config', 'collections', $collection->get_base_id(), 'can-register'])) { - $authorizedCollections[$collection->get_base_id()] = $canRegister; + if (\igorw\get_in($inscriptions, [$databox->get_sbas_id(), 'config', 'collections', $collection->get_base_id(), 'can-register'])) { + $authorizedCollections[$collection->get_base_id()] = $collection; } } } @@ -301,42 +309,41 @@ class RegistrationService return $authorizedCollections; } - /** - * @param $authorizedCollections - * @param $user - * @return mixed - * @throws \Exception - */ - private function applyAclsToUser(array $authorizedCollections, User $user) - { - $acl = $this->aclProvider->get($user); - - if ($this->configuration->get(['registry', 'registration', 'auto-register-enabled'])) { - $template_user = $this->userRepository->findByLogin(User::USER_AUTOREGISTER); - $acl->apply_model($template_user, array_keys($authorizedCollections)); - } - } - /** * @param User $user * @param array $authorizedCollections */ private function createCollectionAccessDemands(User $user, $authorizedCollections) { - $successfulRegistrations = []; $acl = $this->aclProvider->get($user); - $autoReg = $acl->get_granted_base(); + $registrationManipulator = $this->registrationManipulator; - - array_walk($authorizedCollections, function ($authorization, $baseId) use ($registrationManipulator, $user, &$successfulRegistrations, $acl) { - if (false === $authorization || $acl->has_access_to_base($baseId)) { - return; + $successfulRegistrations = []; + foreach($authorizedCollections as $baseId => $collection) { + if(!$acl->has_access_to_base($baseId)) { + $registrationManipulator->createRegistration($user, $collection); + $successfulRegistrations[$baseId] = $collection; } + } + + + $autoReg = $acl->get_granted_base(); + $granted = []; + foreach ($autoReg as $baseId => $collection) { + $granted[$baseId] = $collection->get_label($this->app['locale']); + } + if(count($granted) > 0) { + $this->app['manipulator.webhook-event']->create( + WebhookEvent::USER_REGISTRATION_GRANTED, + WebhookEvent::USER_REGISTRATION_TYPE, + [ + 'user_id' => $user->getId(), + 'granted' => $granted, + 'rejected' => [] + ] + ); + } - $collection = \collection::getByBaseId($this->app, $baseId); - $registrationManipulator->createRegistration($user, $collection); - $successfulRegistrations[$baseId] = $collection; - }); $this->eventDispatcher->dispatch(PhraseaEvents::REGISTRATION_AUTOREGISTER, new RegistrationEvent($user, $autoReg)); $this->eventDispatcher->dispatch(PhraseaEvents::REGISTRATION_CREATE, new RegistrationEvent($user, $successfulRegistrations)); diff --git a/lib/Alchemy/Phrasea/Core/Event/Subscriber/RegistrationSubscriber.php b/lib/Alchemy/Phrasea/Core/Event/Subscriber/RegistrationSubscriber.php index 6266983a18..03349aa75d 100644 --- a/lib/Alchemy/Phrasea/Core/Event/Subscriber/RegistrationSubscriber.php +++ b/lib/Alchemy/Phrasea/Core/Event/Subscriber/RegistrationSubscriber.php @@ -109,7 +109,7 @@ class RegistrationSubscriber extends AbstractNotificationSubscriber $body .= sprintf("%s : %s\n", $this->app->trans('admin::compte-utilisateur nom'), $registeredUser->getFirstName()); $body .= sprintf("%s : %s\n", $this->app->trans('admin::compte-utilisateur prenom'), $registeredUser->getLastName()); $body .= sprintf("%s : %s\n", $this->app->trans('admin::compte-utilisateur email'), $registeredUser->getEmail()); - $body .= sprintf("%s/%s\n", $registeredUser->get_job(), $registeredUser->getCompany()); + $body .= sprintf("%s/%s\n", $registeredUser->getJob(), $registeredUser->getCompany()); $readyToSend = false; try { diff --git a/lib/classes/collection.php b/lib/classes/collection.php index 4e900c1839..000144a2e3 100644 --- a/lib/classes/collection.php +++ b/lib/classes/collection.php @@ -792,6 +792,29 @@ class collection implements ThumbnailedElement, cache_cacheableInterface return false; } + /** + * matches a email against the auto-register whitelist + * + * @param string $email + * @return null|string the user-model to apply if the email matches + */ + public function getAutoregisterModel($email) + { + // try to match against the collection whitelist + if($this->isRegistrationEnabled()) { + if (($xml = @simplexml_load_string($this->get_prefs())) !== false) { + foreach ($xml->xpath('/baseprefs/registration/auto_register/email_whitelist/email') as $element) { + if (preg_match($element['pattern'], $email) === 1) { + return (string)$element['user_model']; + } + } + } + } + + // no match ? try against the databox whitelist + return $this->get_databox()->getAutoregisterModel($email); + } + /** * Gets terms of use. * diff --git a/lib/classes/databox.php b/lib/classes/databox.php index 4f189368b5..56a319f78f 100644 --- a/lib/classes/databox.php +++ b/lib/classes/databox.php @@ -1424,6 +1424,38 @@ class databox extends base implements ThumbnailedElement return false; } + /** + * matches a email against the auto-register whitelist + * + * @param string $email + * @return null|string the user-model to apply if the email matches + */ + public function getAutoregisterModel($email) + { + if(!$this->isRegistrationEnabled()) { + return null; + } + + $ret = User::USER_AUTOREGISTER; // default if there is no whitelist defined at all + + // try to match against the whitelist + if( ($xml = $this->get_sxml_structure()) !== false) { + $wl = $xml->xpath('/record/registration/auto_register/email_whitelist'); + if($wl !== false && count($wl) === 1) { + $ret = null; // there IS a whitelist, the email must match + + foreach ($wl[0]->xpath('email') as $element) { + if (preg_match($element['pattern'], $email) === 1) { + return (string)$element['user_model']; + } + } + } + } + + return $ret; + } + + /** * Return an array that can be used to restore databox. *