PHRAS-2096_Autoregister-Whitelist_MASTER (#2642)

Add a whitelist to filter autoregistration
This commit is contained in:
jygaulier
2018-06-21 18:35:44 +02:00
committed by GitHub
parent b06169678b
commit b9aa04be6b
4 changed files with 100 additions and 38 deletions

View File

@@ -10,9 +10,9 @@ use Alchemy\Phrasea\Core\Configuration\RegistrationManager;
use Alchemy\Phrasea\Core\Event\RegistrationEvent; use Alchemy\Phrasea\Core\Event\RegistrationEvent;
use Alchemy\Phrasea\Core\PhraseaEvents; use Alchemy\Phrasea\Core\PhraseaEvents;
use Alchemy\Phrasea\Exception\RuntimeException; use Alchemy\Phrasea\Exception\RuntimeException;
use Alchemy\Phrasea\Model\Entities\Registration;
use Alchemy\Phrasea\Model\Entities\User; use Alchemy\Phrasea\Model\Entities\User;
use Alchemy\Phrasea\Model\Entities\UsrAuthProvider; use Alchemy\Phrasea\Model\Entities\UsrAuthProvider;
use Alchemy\Phrasea\Model\Entities\WebhookEvent;
use Alchemy\Phrasea\Model\Manipulator\RegistrationManipulator; use Alchemy\Phrasea\Model\Manipulator\RegistrationManipulator;
use Alchemy\Phrasea\Model\Manipulator\TokenManipulator; use Alchemy\Phrasea\Model\Manipulator\TokenManipulator;
use Alchemy\Phrasea\Model\Manipulator\UserManipulator; use Alchemy\Phrasea\Model\Manipulator\UserManipulator;
@@ -176,7 +176,7 @@ class RegistrationService
); );
if ($userAuthenticationProvider) { if ($userAuthenticationProvider) {
return $userAuthenticationProvider->getUser($this->app); return $userAuthenticationProvider->getUser();
} }
return null; return null;
@@ -190,8 +190,7 @@ class RegistrationService
$provider = $this->oauthProviderCollection->get($providerId); $provider = $this->oauthProviderCollection->get($providerId);
} }
$inscriptions = $this->registrationManager->getRegistrationSummary(); $authorizedCollections = $this->getAuthorizedCollections($selectedCollections);
$authorizedCollections = $this->getAuthorizedCollections($selectedCollections, $inscriptions);
if (!isset($data['login'])) { if (!isset($data['login'])) {
$data['login'] = $data['email']; $data['login'] = $data['email'];
@@ -205,7 +204,7 @@ class RegistrationService
foreach (self::$userPropertySetterMap as $property => $method) { foreach (self::$userPropertySetterMap as $property => $method) {
if (isset($data[$property])) { 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->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); $this->createCollectionAccessDemands($user, $authorizedCollections);
$user->setMailLocked(true); $user->setMailLocked(true);
@@ -226,8 +235,7 @@ class RegistrationService
public function createCollectionRequests(User $user, array $collections) public function createCollectionRequests(User $user, array $collections)
{ {
$inscriptions = $this->registrationManager->getRegistrationSummary($user); $authorizedCollections = $this->getAuthorizedCollections($collections);
$authorizedCollections = $this->getAuthorizedCollections($collections, $inscriptions);
$this->createCollectionAccessDemands($user, $authorizedCollections); $this->createCollectionAccessDemands($user, $authorizedCollections);
} }
@@ -279,7 +287,7 @@ class RegistrationService
/** /**
* @param array $selectedCollections * @param array $selectedCollections
* @return array * @return \collection[]
*/ */
private function getAuthorizedCollections(array $selectedCollections = null) private function getAuthorizedCollections(array $selectedCollections = null)
{ {
@@ -292,8 +300,8 @@ class RegistrationService
continue; continue;
} }
if ($canRegister = \igorw\get_in($inscriptions, [$databox->get_sbas_id(), 'config', 'collections', $collection->get_base_id(), 'can-register'])) { if (\igorw\get_in($inscriptions, [$databox->get_sbas_id(), 'config', 'collections', $collection->get_base_id(), 'can-register'])) {
$authorizedCollections[$collection->get_base_id()] = $canRegister; $authorizedCollections[$collection->get_base_id()] = $collection;
} }
} }
} }
@@ -301,42 +309,41 @@ class RegistrationService
return $authorizedCollections; 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 User $user
* @param array $authorizedCollections * @param array $authorizedCollections
*/ */
private function createCollectionAccessDemands(User $user, $authorizedCollections) private function createCollectionAccessDemands(User $user, $authorizedCollections)
{ {
$successfulRegistrations = [];
$acl = $this->aclProvider->get($user); $acl = $this->aclProvider->get($user);
$autoReg = $acl->get_granted_base();
$registrationManipulator = $this->registrationManipulator; $registrationManipulator = $this->registrationManipulator;
$successfulRegistrations = [];
array_walk($authorizedCollections, function ($authorization, $baseId) use ($registrationManipulator, $user, &$successfulRegistrations, $acl) { foreach($authorizedCollections as $baseId => $collection) {
if (false === $authorization || $acl->has_access_to_base($baseId)) { if(!$acl->has_access_to_base($baseId)) {
return; $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_AUTOREGISTER, new RegistrationEvent($user, $autoReg));
$this->eventDispatcher->dispatch(PhraseaEvents::REGISTRATION_CREATE, new RegistrationEvent($user, $successfulRegistrations)); $this->eventDispatcher->dispatch(PhraseaEvents::REGISTRATION_CREATE, new RegistrationEvent($user, $successfulRegistrations));

View File

@@ -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 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 prenom'), $registeredUser->getLastName());
$body .= sprintf("%s : %s\n", $this->app->trans('admin::compte-utilisateur email'), $registeredUser->getEmail()); $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; $readyToSend = false;
try { try {

View File

@@ -792,6 +792,29 @@ class collection implements ThumbnailedElement, cache_cacheableInterface
return false; 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. * Gets terms of use.
* *

View File

@@ -1424,6 +1424,38 @@ class databox extends base implements ThumbnailedElement
return false; 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. * Return an array that can be used to restore databox.
* *