utilize UserService for SAML (#4748)

This commit is contained in:
Kevin Papst
2024-04-05 19:22:13 +02:00
committed by GitHub
parent b6c98f871d
commit dd51c8dfba
16 changed files with 320 additions and 352 deletions

View File

@@ -50,7 +50,7 @@ final class ActivateUserCommand extends Command
if (!$user->isEnabled()) {
$user->setEnabled(true);
$this->userService->updateUser($user);
$this->userService->saveUser($user);
$io->success(sprintf('User "%s" has been activated.', $username));
} else {
$io->warning(sprintf('User "%s" is already active.', $username));

View File

@@ -76,7 +76,7 @@ final class CreateUserCommand extends AbstractUserCommand
}
try {
$this->userService->saveNewUser($user);
$this->userService->saveUser($user);
$io->success(sprintf('Success! Created user: %s', $username));
} catch (ValidationFailedException $ex) {
$this->validationError($ex, $io);

View File

@@ -50,7 +50,7 @@ final class DeactivateUserCommand extends Command
if ($user->isEnabled()) {
$user->setEnabled(false);
$this->userService->updateUser($user);
$this->userService->saveUser($user);
$io->success(sprintf('User "%s" has been deactivated.', $username));
} else {
$io->warning(sprintf('User "%s" is already deactivated.', $username));

View File

@@ -39,7 +39,7 @@ final class DemoteUserCommand extends AbstractRoleCommand
if ($super) {
if ($user->isSuperAdmin()) {
$user->setSuperAdmin(false);
$manipulator->updateUser($user);
$manipulator->saveUser($user);
$output->success(sprintf('Super administrator role has been removed from the user "%s".', $username));
} else {
$output->warning(sprintf('User "%s" doesn\'t have the super administrator role.', $username));
@@ -47,7 +47,7 @@ final class DemoteUserCommand extends AbstractRoleCommand
} else {
if ($user->hasRole($role)) {
$user->removeRole($role);
$manipulator->updateUser($user);
$manipulator->saveUser($user);
$output->success(sprintf('Role "%s" has been removed from user "%s".', $role, $username));
} else {
$output->warning(sprintf('User "%s" didn\'t have "%s" role.', $username, $role));

View File

@@ -39,7 +39,7 @@ final class PromoteUserCommand extends AbstractRoleCommand
if ($super) {
if (!$user->isSuperAdmin()) {
$user->setSuperAdmin(true);
$manipulator->updateUser($user);
$manipulator->saveUser($user);
$output->success(sprintf('User "%s" has been promoted as a super administrator.', $username));
} else {
$output->warning(sprintf('User "%s" does already have the super administrator role.', $username));
@@ -47,7 +47,7 @@ final class PromoteUserCommand extends AbstractRoleCommand
} else {
if (!$user->hasRole($role)) {
$user->addRole($role);
$manipulator->updateUser($user);
$manipulator->saveUser($user);
$output->success(sprintf('Role "%s" has been added to user "%s".', $role, $username));
} else {
$output->warning(sprintf('User "%s" did already have "%s" role.', $username, $role));

View File

@@ -136,7 +136,7 @@ final class ProfileController extends AbstractController
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$userService->updateUser($profile);
$userService->saveUser($profile);
$this->flashSuccess('action.update.success');
@@ -409,7 +409,7 @@ final class ProfileController extends AbstractController
{
if (!$profile->hasTotpSecret()) {
$profile->setTotpSecret($totpAuthenticator->generateSecret());
$userService->updateUser($profile);
$userService->saveUser($profile);
}
$data = new TotpActivation($profile);
@@ -423,7 +423,7 @@ final class ProfileController extends AbstractController
if ($form->isSubmitted() && $form->isValid()) {
$profile->enableTotpAuthentication();
$userService->updateUser($profile);
$userService->saveUser($profile);
$this->flashSuccess('action.update.success');
@@ -473,7 +473,7 @@ final class ProfileController extends AbstractController
if ($form->isSubmitted() && $form->isValid()) {
$profile->disableTotpAuthentication();
$userService->updateUser($profile);
$userService->saveUser($profile);
$this->flashSuccess('action.update.success');
}

View File

@@ -87,7 +87,7 @@ final class PasswordResetController extends AbstractController
$this->eventDispatcher->dispatch(new EmailEvent($event->getEmail()));
$user->markPasswordRequested();
$this->userService->updateUser($user);
$this->userService->saveUser($user);
}
return $this->redirectToRoute('resetting_check_email', ['username' => $username]);
@@ -146,7 +146,7 @@ final class PasswordResetController extends AbstractController
$user->markPasswordResetted();
$user->setEnabled(true);
$this->userService->updateUser($user);
$this->userService->saveUser($user);
$response = $this->redirectToRoute('my_profile');
$loginManager->logInUser($user, $response);

View File

@@ -69,7 +69,7 @@ final class SelfRegistrationController extends AbstractController
$request->getSession()->set('confirmation_email_address', $user->getEmail());
$this->userService->saveNewUser($user);
$this->userService->saveUser($user);
return $this->redirectToRoute('user_registration_check_email');
}
@@ -126,7 +126,7 @@ final class SelfRegistrationController extends AbstractController
$user->setConfirmationToken(null);
$user->setEnabled(true);
$this->userService->updateUser($user);
$this->userService->saveUser($user);
$response = $this->redirectToRoute('registration_confirmed');
$loginManager->logInUser($user, $response);

View File

@@ -35,7 +35,7 @@ final class WizardController extends AbstractController
if ($wizard === 'intro') {
$user->setWizardAsSeen('intro');
$userService->updateUser($user);
$userService->saveUser($user);
return $this->render('wizard/intro.html.twig', [
'percent' => 0,
@@ -77,7 +77,7 @@ final class WizardController extends AbstractController
$user->setTimezone($data[UserPreference::TIMEZONE]);
$user->setPreferenceValue(UserPreference::SKIN, $data[UserPreference::SKIN]);
$user->setWizardAsSeen('profile');
$userService->updateUser($user);
$userService->saveUser($user);
if ($data['reload'] === '1') {
return $this->redirectToRoute('wizard', ['wizard' => 'profile', '_locale' => $user->getLanguage()]);
@@ -104,7 +104,7 @@ final class WizardController extends AbstractController
if ($form->isSubmitted() && $form->isValid()) {
$user->setRequiresPasswordReset(false);
$userService->updateUser($user);
$userService->saveUser($user);
return $this->redirectToRoute('wizard', ['wizard' => 'done']);
}

View File

@@ -11,7 +11,7 @@ namespace App\Saml;
use App\Configuration\SamlConfigurationInterface;
use App\Entity\User;
use App\Repository\UserRepository;
use App\User\UserService;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
@@ -23,7 +23,7 @@ final class SamlProvider
* @param UserProviderInterface<User> $userProvider
*/
public function __construct(
private readonly UserRepository $repository,
private readonly UserService $userService,
private readonly UserProviderInterface $userProvider,
private readonly SamlConfigurationInterface $configuration,
private readonly LoggerInterface $logger
@@ -40,17 +40,17 @@ final class SamlProvider
$user = $this->userProvider->loadUserByIdentifier($token->getUserIdentifier());
}
} catch (UserNotFoundException $ex) {
$this->logger->error($ex->getMessage());
// this is expected for new users
$this->logger->debug('User is not existing: ' . $token->getUserIdentifier());
}
try {
if (null === $user) {
$user = $this->createUser($token);
} else {
$this->hydrateUser($user, $token);
$user = $this->userService->createNewUser();
$user->setUserIdentifier($token->getUserIdentifier());
}
$this->repository->saveUser($user);
$this->hydrateUser($user, $token);
$this->userService->saveUser($user);
} catch (\Exception $ex) {
$this->logger->error($ex->getMessage());
throw new AuthenticationException(
@@ -61,19 +61,6 @@ final class SamlProvider
return $user;
}
private function createUser(SamlLoginAttributes $token): User
{
// Not using UserService: user settings should be set via SAML attributes
$user = new User();
$user->setEnabled(true);
$user->setUserIdentifier($token->getUserIdentifier());
$user->setPassword('');
$this->hydrateUser($user, $token);
return $user;
}
private function hydrateUser(User $user, SamlLoginAttributes $token): void
{
$groupAttribute = $this->configuration->getRolesAttribute();
@@ -119,11 +106,13 @@ final class SamlProvider
}
}
// fill them after hydrating account, so they can't be overwritten
// by the mapping attributes
// change after hydrating account, so it can't be overwritten by mapping attributes
if ($user->getId() === null) {
// set a plain password to satisfy the validator
$user->setPlainPassword(substr(bin2hex(random_bytes(100)), 0, 50));
$user->setPassword('');
}
$user->setUserIdentifier($token->getUserIdentifier());
$user->setAuth(User::AUTH_SAML);
}

View File

@@ -37,11 +37,11 @@ class UserService
private array $cache = [];
public function __construct(
private UserRepository $repository,
private EventDispatcherInterface $dispatcher,
private ValidatorInterface $validator,
private SystemConfiguration $configuration,
private UserPasswordHasherInterface $passwordHasher
private readonly UserRepository $repository,
private readonly EventDispatcherInterface $dispatcher,
private readonly ValidatorInterface $validator,
private readonly SystemConfiguration $configuration,
private readonly UserPasswordHasherInterface $passwordHasher
) {
}
@@ -70,6 +70,18 @@ class UserService
return $user;
}
public function saveUser(User $user): User
{
if ($user->getId() === null) {
return $this->saveNewUser($user);
} else {
return $this->updateUser($user);
}
}
/**
* @internal will be made private soon
*/
public function saveNewUser(User $user): User
{
if (null !== $user->getId()) {