feat: superadmin attribute for extended permissions like impersonating

This commit is contained in:
Björn Fromme
2024-04-17 18:06:56 +02:00
parent 30218d6f80
commit 8b4e9f546b
4 changed files with 61 additions and 1 deletions
+36
View File
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240417160406 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE user ADD super_admin TINYINT(1) NOT NULL');
}
public function postUp(Schema $schema): void
{
$this->connection->executeQuery('UPDATE user SET super_admin = 0');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE user DROP super_admin');
}
}
+15
View File
@@ -39,6 +39,9 @@ class User implements UserInterface, TimestampableEntityInterface
#[ORM\Column(type: 'json')]
private array $roles = [];
#[ORM\Column]
private bool $superAdmin = false;
#[ORM\Column(nullable: true)]
private ?\DateTimeImmutable $lastLoginAt = null;
@@ -159,6 +162,18 @@ class User implements UserInterface, TimestampableEntityInterface
return in_array($role, $this->getRoles());
}
public function isSuperAdmin(): bool
{
return $this->superAdmin;
}
public function setSuperAdmin(bool $superAdmin): static
{
$this->superAdmin = $superAdmin;
return $this;
}
public function getLastLoginAt(): ?\DateTimeImmutable
{
return $this->lastLoginAt;
+5 -1
View File
@@ -40,6 +40,10 @@ class ImpersonationVoter extends Voter
}
// Admin is the only role allowed to impersonate
return $this->security->isGranted('ROLE_ADMIN');
if (false === $this->security->isGranted('ROLE_ADMIN')) {
return false;
}
return $currentUser->isSuperAdmin();
}
}
@@ -94,6 +94,11 @@
</td>
<td>
<div class="flex items-center space-x-1 justify-end">
{% if is_granted('CAN_IMPERSONATE', teamer.user) %}
<a href="{{ path('app_teamer_index', { '_switch_user': teamer.user.email }) }}" title="Als Teamer:in maskieren">
{{ icon('mask') }}
</a>
{% endif %}
<a href="{{ path('app_administrative_teamer_profile', { 'uuid': teamer.uuid }) }}" title="Teamer:innenprofil {{ teamer }}">
{{ icon('user') }}
</a>