diff --git a/src/Controller/HomepageController.php b/src/Controller/HomepageController.php index dc728465..914ae8bc 100644 --- a/src/Controller/HomepageController.php +++ b/src/Controller/HomepageController.php @@ -66,6 +66,8 @@ class HomepageController extends AbstractController public function homepage(Request $request, GitVersionInfo $versionInfo, EntityManagerInterface $entityManager, UpdateAvailableManager $updateAvailableManager): Response { + $this->denyAccessUnlessGranted('HAS_ACCESS_PERMISSIONS'); + if ($this->isGranted('@tools.lastActivity')) { $table = $this->dataTable->createFromType( LogDataTable::class, diff --git a/src/Security/Voter/HasAccessPermissionsVoter.php b/src/Security/Voter/HasAccessPermissionsVoter.php new file mode 100644 index 00000000..3ea6dd36 --- /dev/null +++ b/src/Security/Voter/HasAccessPermissionsVoter.php @@ -0,0 +1,45 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Security\Voter; + +use App\Entity\UserSystem\User; + +/** + * This voter implements a virtual role, which can be used if the user has any permission set to allowed. + * We use this to restrict access to the homepage. + */ +class HasAccessPermissionsVoter extends ExtendedVoter +{ + public const ROLE = "HAS_ACCESS_PERMISSIONS"; + + protected function voteOnUser(string $attribute, $subject, User $user): bool + { + return $this->resolver->hasAnyPermissionSetToAllowInherited($user); + } + + protected function supports(string $attribute, mixed $subject): bool + { + return $attribute === self::ROLE; + } +} \ No newline at end of file diff --git a/src/Services/UserSystem/PermissionManager.php b/src/Services/UserSystem/PermissionManager.php index fa591a91..a995dad7 100644 --- a/src/Services/UserSystem/PermissionManager.php +++ b/src/Services/UserSystem/PermissionManager.php @@ -271,6 +271,27 @@ class PermissionManager } } + /** + * This function checks if the given user has any permission set to allow, either directly or inherited. + * @param User $user + * @return bool + */ + public function hasAnyPermissionSetToAllowInherited(User $user): bool + { + //Iterate over all permissions + foreach ($this->permission_structure['perms'] as $perm_key => $permission) { + //Iterate over all operations of the permission + foreach ($permission['operations'] as $op_key => $op) { + //Check if the user has the permission set to allow + if ($this->inherit($user, $perm_key, $op_key) === true) { + return true; + } + } + } + + return false; + } + protected function generatePermissionStructure() { $cache = new ConfigCache($this->cache_file, $this->kernel_debug_enabled); diff --git a/tests/Services/UserSystem/PermissionManagerTest.php b/tests/Services/UserSystem/PermissionManagerTest.php index d9c694fe..b24801df 100644 --- a/tests/Services/UserSystem/PermissionManagerTest.php +++ b/tests/Services/UserSystem/PermissionManagerTest.php @@ -31,15 +31,12 @@ use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; class PermissionManagerTest extends WebTestCase { - protected $user_withoutGroup; + protected ?User $user_withoutGroup = null; - protected $user; - protected $group; + protected ?User $user = null; + protected ?Group $group = null; - /** - * @var PermissionManager - */ - protected $service; + protected ?PermissionManager $service = null; protected function setUp(): void { @@ -294,4 +291,34 @@ class PermissionManagerTest extends WebTestCase $this->assertTrue($this->service->dontInherit($user, 'parts', 'edit')); $this->assertTrue($this->service->dontInherit($user, 'categories', 'read')); } + + public function testHasAnyPermissionSetToAllowInherited(): void + { + //For empty user this should return false + $user = new User(); + $this->assertFalse($this->service->hasAnyPermissionSetToAllowInherited($user)); + + //If all permissions are set to false this should return false + $this->service->setAllPermissions($user, false); + $this->assertFalse($this->service->hasAnyPermissionSetToAllowInherited($user)); + + //If all permissions are set to null this should return false + $this->service->setAllPermissions($user, null); + $this->assertFalse($this->service->hasAnyPermissionSetToAllowInherited($user)); + + //If all permissions are set to true this should return true + $this->service->setAllPermissions($user, true); + $this->assertTrue($this->service->hasAnyPermissionSetToAllowInherited($user)); + + //The test data should return true + $this->assertTrue($this->service->hasAnyPermissionSetToAllowInherited($this->user)); + $this->assertTrue($this->service->hasAnyPermissionSetToAllowInherited($this->user_withoutGroup)); + + //Create a user with a group + $user = new User(); + $user->setGroup($this->group); + //This should return true + $this->assertTrue($this->service->hasAnyPermissionSetToAllowInherited($user)); + + } }