feat: bpn as single source of truth for role and hotel code assignments
This commit is contained in:
1 parent
1fd0fbc21e
commit
f0e850978b
17 files changed
+818
-198
No files matched your search
+24
-29
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Config\HouseCatalog;
|
||||
use App\Entity\User;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
@@ -12,27 +11,20 @@ use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* The account settings of an administrative user - and nothing else.
|
||||
*
|
||||
* Roles and hotel codes are synced from BusPro on every login and are not editable here or
|
||||
* anywhere else, so they are not fields: the edit page renders them as information. The one
|
||||
* role decision left to a human, approving a nomination, is its own action with its own
|
||||
* confirmation (see App\Controller\Admin\System\User\ApproveRoleController). Keeping all
|
||||
* three apart is deliberate - a form field that cannot be submitted only looks broken.
|
||||
*/
|
||||
class UserType extends AbstractType
|
||||
{
|
||||
public function __construct(private readonly HouseCatalog $houseCatalog)
|
||||
{
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('roles', MultiselectType::class, [
|
||||
'label' => 'Rollen',
|
||||
'required' => false,
|
||||
'property_path' => 'assignedRoles',
|
||||
'choices' => array_flip(User::ROLES),
|
||||
'empty_label' => 'keine Rolle',
|
||||
])
|
||||
->add('superAdmin', CheckboxType::class, [
|
||||
'label' => 'Superadmin',
|
||||
'required' => false,
|
||||
'help' => 'Setzt die Rolle Admin voraus.',
|
||||
])
|
||||
->add('disabled', CheckboxType::class, [
|
||||
'label' => 'Account gesperrt',
|
||||
'required' => false,
|
||||
@@ -74,23 +66,26 @@ class UserType extends AbstractType
|
||||
;
|
||||
});
|
||||
|
||||
// hotel codes already assigned to the user may predate the catalog, so they are
|
||||
// added as choices to keep them selectable instead of failing
|
||||
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event): void {
|
||||
// Super admin is an elevation of an existing role, never a grant of its own, so the
|
||||
// field exists only for somebody who already holds ROLE_ADMIN - offering it to
|
||||
// anyone else would only produce the violation from User::validateSuperAdmin().
|
||||
// A flag already set without the role is the exception: it has to stay editable, or
|
||||
// that user could not be saved at all until BusPro claims them an admin again.
|
||||
$builder->addEventListener(FormEvents::PRE_SET_DATA, static function (FormEvent $event): void {
|
||||
$user = $event->getData();
|
||||
|
||||
$choices = $this->houseCatalog->getCodeChoices();
|
||||
foreach ($user instanceof User ? $user->getHotelCodes() : [] as $code) {
|
||||
if (false === in_array($code, $choices, true)) {
|
||||
$choices[$code] = $code;
|
||||
}
|
||||
if (false === $user instanceof User) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event->getForm()->add('hotelCodes', MultiselectType::class, [
|
||||
'label' => 'Häuser',
|
||||
if (false === in_array('ROLE_ADMIN', $user->getAssignedRoles(), true) && false === $user->isSuperAdmin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event->getForm()->add('superAdmin', CheckboxType::class, [
|
||||
'label' => 'Superadmin',
|
||||
'required' => false,
|
||||
'choices' => $choices,
|
||||
'empty_label' => 'keine Häuser',
|
||||
'help' => 'Darf Rollen freischalten und Accounts verwalten.',
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user