diff --git a/config/packages/security.yaml b/config/packages/security.yaml index ee69e4f1..5fd51805 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -16,6 +16,7 @@ security: security: false main: anonymous: true + user_checker: App\Security\UserChecker # activate different ways to authenticate diff --git a/src/Entity/UserSystem/User.php b/src/Entity/UserSystem/User.php index 265141ad..62de3412 100644 --- a/src/Entity/UserSystem/User.php +++ b/src/Entity/UserSystem/User.php @@ -78,6 +78,7 @@ use Symfony\Component\Validator\Constraints as Assert; /** * This entity represents a user, which can log in and have permissions. * Also this entity is able to save some informations about the user, like the names, email-address and other info. + * Also this entity is able to save some informations about the user, like the names, email-address and other info. * * @ORM\Entity(repositoryClass="App\Repository\UserRepository") * @ORM\Table("`users`") @@ -340,6 +341,26 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe return $this; } + /** + * Checks if this user is disabled (user cannot login any more). + * @return bool True, if the user is disabled. + */ + public function isDisabled(): bool + { + return $this->disabled; + } + + /** + * Sets the status if a user is disabled. + * @param bool $disabled True if the user should be disabled. + * @return User + */ + public function setDisabled(bool $disabled): User + { + $this->disabled = $disabled; + return $this; + } + /** @@ -566,6 +587,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe public function __toString() { - return $this->getFullName(true); + $tmp = $this->isDisabled() ? ' [DISABLED]' : ''; + return $this->getFullName(true) . $tmp; } } diff --git a/src/EventSubscriber/LogoutOnDisabledUserListener.php b/src/EventSubscriber/LogoutOnDisabledUserListener.php new file mode 100644 index 00000000..a2dd934e --- /dev/null +++ b/src/EventSubscriber/LogoutOnDisabledUserListener.php @@ -0,0 +1,94 @@ +security = $security; + + $this->urlGenerator = $urlGenerator; + } + + public function onRequest(RequestEvent $event) + { + $user = $this->security->getUser(); + if ($user instanceof User && $user->isDisabled()) { + //Redirect to login + $response = new RedirectResponse($this->urlGenerator->generate('logout')); + $event->setResponse($response); + } + } + + /** + * Returns an array of event names this subscriber wants to listen to. + * + * The array keys are event names and the value can be: + * + * * The method name to call (priority defaults to 0) + * * An array composed of the method name to call and the priority + * * An array of arrays composed of the method names to call and respective + * priorities, or 0 if unset + * + * For instance: + * + * * ['eventName' => 'methodName'] + * * ['eventName' => ['methodName', $priority]] + * * ['eventName' => [['methodName1', $priority], ['methodName2']]] + * + * @return array The event names to listen to + */ + public static function getSubscribedEvents() + { + return [KernelEvents::REQUEST => 'onRequest']; + } +} \ No newline at end of file diff --git a/src/Form/UserAdminForm.php b/src/Form/UserAdminForm.php index 86ae0f21..1f48be8d 100644 --- a/src/Form/UserAdminForm.php +++ b/src/Form/UserAdminForm.php @@ -129,6 +129,7 @@ class UserAdminForm extends AbstractType 'disabled' => !$this->security->isGranted('edit_infos', $entity), ]) + //Config section ->add('language', LanguageType::class, [ 'required' => false, @@ -170,6 +171,7 @@ class UserAdminForm extends AbstractType 'invalid_message' => 'password_must_match', 'required' => false, 'mapped' => false, + 'disabled' => !$this->security->isGranted('set_password', $entity), 'constraints' => [new Length([ 'min' => 6, 'max' => 128, @@ -179,7 +181,17 @@ class UserAdminForm extends AbstractType ->add('need_pw_change', CheckboxType::class, [ 'required' => false, 'label_attr' => ['class' => 'checkbox-custom'], - 'label' => $this->trans->trans('user.edit.needs_pw_change') + 'label' => $this->trans->trans('user.edit.needs_pw_change'), + 'disabled' => !$this->security->isGranted('set_password', $entity) + ]) + + ->add('disabled', CheckboxType::class, [ + 'required' => false, + 'label_attr' => ['class' => 'checkbox-custom'], + 'label' => $this->trans->trans('user.edit.user_disabled'), + 'disabled' => !$this->security->isGranted('set_password', $entity) + || $entity === $this->security->getUser() + ]) //Permission section diff --git a/src/Security/UserChecker.php b/src/Security/UserChecker.php new file mode 100644 index 00000000..4c54c621 --- /dev/null +++ b/src/Security/UserChecker.php @@ -0,0 +1,78 @@ +translator = $translator; + } + + /** + * Checks the user account before authentication. + * + * @throws AccountStatusException + */ + public function checkPreAuth(UserInterface $user) + { + // TODO: Implement checkPreAuth() method. + } + + /** + * Checks the user account after authentication. + * + * @throws AccountStatusException + */ + public function checkPostAuth(UserInterface $user) + { + if (!$user instanceof User) { + return; + } + + //Check if user is disabled. Then dont allow login + if ($user->isDisabled()) { + throw new DisabledException(); + } + } +} \ No newline at end of file diff --git a/src/Security/Voter/ExtendedVoter.php b/src/Security/Voter/ExtendedVoter.php index c0c027f7..40e2fe81 100644 --- a/src/Security/Voter/ExtendedVoter.php +++ b/src/Security/Voter/ExtendedVoter.php @@ -56,6 +56,12 @@ abstract class ExtendedVoter extends Voter final protected function voteOnAttribute($attribute, $subject, TokenInterface $token) { $user = $token->getUser(); + + //An allowed user is not allowed to do anything... + if($user instanceof User && $user->isDisabled()) { + return false; + } + // if the user is anonymous, we use the anonymous user. if (!$user instanceof User) { $user = $this->entityManager->find(User::class, User::ID_ANONYMOUS); diff --git a/templates/AdminPages/UserAdmin.html.twig b/templates/AdminPages/UserAdmin.html.twig index b4574bd4..41a89232 100644 --- a/templates/AdminPages/UserAdmin.html.twig +++ b/templates/AdminPages/UserAdmin.html.twig @@ -33,6 +33,7 @@
{{ form_row(form.new_password) }} {{ form_row(form.need_pw_change) }} + {{ form_row(form.disabled) }}