Re-usable ACL checks on teams (#5925)
This commit is contained in:
@@ -17,6 +17,7 @@ use App\Voter\ProjectVoter;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
use Symfony\Component\Security\Core\User\InMemoryUser;
|
||||
|
||||
#[CoversClass(ProjectVoter::class)]
|
||||
class ProjectVoterTest extends AbstractVoterTestCase
|
||||
@@ -137,4 +138,140 @@ class ProjectVoterTest extends AbstractVoterTestCase
|
||||
|
||||
$this->assertVote($user, $project, 'edit', VoterInterface::ACCESS_GRANTED);
|
||||
}
|
||||
|
||||
public function testAccessGrantedWhenProjectAndCustomerHaveNoTeams(): void
|
||||
{
|
||||
$project = new Project();
|
||||
$project->setCustomer(new Customer('foo'));
|
||||
|
||||
$this->assertVote(new User(), $project, 'access', VoterInterface::ACCESS_GRANTED);
|
||||
}
|
||||
|
||||
public function testAccessGrantedWhenProjectHasNoCustomer(): void
|
||||
{
|
||||
// checkTeamAccessProject() skips the customer chain when project->getCustomer() is null.
|
||||
$project = new Project();
|
||||
|
||||
$this->assertVote(new User(), $project, 'access', VoterInterface::ACCESS_GRANTED);
|
||||
}
|
||||
|
||||
public function testAccessGrantedForCanSeeAllDataDespiteRestrictiveTeams(): void
|
||||
{
|
||||
$project = new Project();
|
||||
$customer = new Customer('foo');
|
||||
$customer->addTeam(new Team('customerTeam'));
|
||||
$project->setCustomer($customer);
|
||||
$project->addTeam(new Team('projectTeam'));
|
||||
|
||||
$user = new User();
|
||||
$user->initCanSeeAllData(true);
|
||||
|
||||
$this->assertVote($user, $project, 'access', VoterInterface::ACCESS_GRANTED);
|
||||
}
|
||||
|
||||
public function testAccessGrantedWhenUserMemberOfCustomerTeamAndNoProjectTeams(): void
|
||||
{
|
||||
$customerTeam = new Team('customerTeam');
|
||||
$customer = new Customer('foo');
|
||||
$customer->addTeam($customerTeam);
|
||||
|
||||
$project = new Project();
|
||||
$project->setCustomer($customer);
|
||||
|
||||
$user = new User();
|
||||
$customerTeam->addUser($user);
|
||||
|
||||
$this->assertVote($user, $project, 'access', VoterInterface::ACCESS_GRANTED);
|
||||
}
|
||||
|
||||
public function testAccessGrantedWhenUserMemberOfProjectTeamAndNoCustomerTeams(): void
|
||||
{
|
||||
$project = new Project();
|
||||
$project->setCustomer(new Customer('foo'));
|
||||
$projectTeam = new Team('projectTeam');
|
||||
$project->addTeam($projectTeam);
|
||||
|
||||
$user = new User();
|
||||
$projectTeam->addUser($user);
|
||||
|
||||
$this->assertVote($user, $project, 'access', VoterInterface::ACCESS_GRANTED);
|
||||
}
|
||||
|
||||
public function testAccessGrantedWhenUserMemberOfBothCustomerAndProjectTeams(): void
|
||||
{
|
||||
$customerTeam = new Team('customerTeam');
|
||||
$customer = new Customer('foo');
|
||||
$customer->addTeam($customerTeam);
|
||||
|
||||
$project = new Project();
|
||||
$project->setCustomer($customer);
|
||||
$projectTeam = new Team('projectTeam');
|
||||
$project->addTeam($projectTeam);
|
||||
|
||||
$user = new User();
|
||||
$customerTeam->addUser($user);
|
||||
$projectTeam->addUser($user);
|
||||
|
||||
$this->assertVote($user, $project, 'access', VoterInterface::ACCESS_GRANTED);
|
||||
}
|
||||
|
||||
public function testAccessDeniedWhenCustomerTeamBlocks(): void
|
||||
{
|
||||
$customer = new Customer('foo');
|
||||
$customer->addTeam(new Team('customerTeam'));
|
||||
|
||||
$project = new Project();
|
||||
$project->setCustomer($customer);
|
||||
// project has no teams of its own — would otherwise be permissive
|
||||
$this->assertVote(new User(), $project, 'access', VoterInterface::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
public function testAccessDeniedWhenCustomerOkButProjectTeamBlocks(): void
|
||||
{
|
||||
$customerTeam = new Team('customerTeam');
|
||||
$customer = new Customer('foo');
|
||||
$customer->addTeam($customerTeam);
|
||||
|
||||
$project = new Project();
|
||||
$project->setCustomer($customer);
|
||||
$project->addTeam(new Team('projectTeam'));
|
||||
|
||||
$user = new User();
|
||||
$customerTeam->addUser($user);
|
||||
|
||||
$this->assertVote($user, $project, 'access', VoterInterface::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
public function testAccessDeniedWhenProjectTeamBlocksAndCustomerHasNoTeams(): void
|
||||
{
|
||||
$project = new Project();
|
||||
$project->setCustomer(new Customer('foo'));
|
||||
$project->addTeam(new Team('projectTeam'));
|
||||
|
||||
$this->assertVote(new User(), $project, 'access', VoterInterface::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
public function testAccessDeniedForUserInUnrelatedTeam(): void
|
||||
{
|
||||
$unrelated = new Team('unrelated');
|
||||
$user = new User();
|
||||
$unrelated->addTeamlead($user);
|
||||
|
||||
$customer = new Customer('foo');
|
||||
$customer->addTeam(new Team('customerTeam'));
|
||||
|
||||
$project = new Project();
|
||||
$project->setCustomer($customer);
|
||||
|
||||
$this->assertVote($user, $project, 'access', VoterInterface::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
public function testAccessDeniedForNonUserToken(): void
|
||||
{
|
||||
$project = new Project();
|
||||
$token = new UsernamePasswordToken(new InMemoryUser('anon', null), 'bar', []);
|
||||
$sut = $this->getVoter(ProjectVoter::class);
|
||||
|
||||
self::assertEquals(VoterInterface::ACCESS_DENIED, $sut->vote($token, $project, ['access']));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user