<?php
declare(strict_types=1);
namespace App\Security\Voter;
use App\Entity\Tool;
use App\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class ToolVoter extends Voter
{
public const VIEW = 'view';
public const EDIT = 'edit';
public const DELETE = 'delete';
public const VIEW_PARAMETERS = 'view-parameters';
public const EDIT_PARAMETERS = 'edit-parameters';
public const ACCEPT_PARAMETERS = 'accept-parameters';
public const INDIVIDUAL_PARAMETERS = 'individual-parameters';
public const UPLOAD_FILES = 'upload-files';
public const SHOW_FILES = 'show-files';
/**
* @param string $attribute
* @param mixed $subject
*
* @return bool
*/
protected function supports($attribute, $subject): bool
{
$supports = true;
if (!\in_array($attribute, [
self::VIEW,
self::EDIT,
self::VIEW_PARAMETERS,
self::EDIT_PARAMETERS,
self::ACCEPT_PARAMETERS,
self::DELETE,
self::INDIVIDUAL_PARAMETERS,
self::UPLOAD_FILES,
self::SHOW_FILES
], true)) {
$supports = false;
}
if (!$subject instanceof Tool) {
$supports = false;
}
return $supports;
}
/**
* @param string $attribute
* @param mixed $subject
* @param TokenInterface $token
*
* @return bool
*/
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
{
$user = $token->getUser();
$hasVotePassed = false;
if (!$user instanceof User) {
return $hasVotePassed;
}
/** @var Tool $tool */
$tool = $subject;
switch ($attribute) {
case self::VIEW:
case self::VIEW_PARAMETERS:
$hasVotePassed = true;
break;
case self::EDIT:
$hasVotePassed = $this->canEdit($tool, $user);
break;
case self::EDIT_PARAMETERS:
$hasVotePassed = $this->canEditParameters($tool, $user);
break;
case self::ACCEPT_PARAMETERS:
$hasVotePassed = $this->canAcceptParameters($tool, $user);
break;
case self::DELETE:
$hasVotePassed = $this->canDelete($tool);
break;
case self::INDIVIDUAL_PARAMETERS:
$hasVotePassed = $this->canIndividualParameters($tool, $user);
break;
case self::UPLOAD_FILES:
$hasVotePassed = $this->canUploadFiles($tool, $user);
break;
case self::SHOW_FILES:
$hasVotePassed = $this->canShowFiles($tool, $user);
break;
}
return $hasVotePassed;
}
/**
* @param Tool $tool
* @param User $user
*
* @return bool
*/
private function canEdit(Tool $tool, User $user): bool
{
if ($user->isSystemUser()) {
$canUserEdit = (null === $tool->getCreatedBy()) || $tool->getCreatedBy()->isSystemUser();
} else {
$canUserEdit = $tool->isInUserOrganization($user);
}
return $canUserEdit;
}
/**
* @param Tool $tool
* @param User $user
*
* @return bool
*/
private function canEditParameters(Tool $tool, User $user): bool
{
return $this->canEdit($tool, $user)
&& ($tool->isStatusNewWithoutParameters() || $tool->isStatusNewWithParameters() || $tool->isStatusActive());
}
/**
* @param Tool $tool
* @param User $user
*
* @return bool
*/
private function canAcceptParameters(Tool $tool, User $user): bool
{
return $this->canEdit($tool, $user) && ($tool->isStatusNewWithParameters());
}
/**
* @param Tool $tool
*
* @return bool
*/
private function canDelete(Tool $tool): bool
{
// TODO Wykonać dostępy na podstawie roli użytkownika
// Admin i Projekt widzi i może robić wszystko
// Default/użytkownik może widzieć element i detale
return true;
}
/**
* @param Tool $tool
* @param User $user
*
* @return bool
*/
private function canIndividualParameters(Tool $tool, User $user): bool
{
return (!$user->isSystemUser()) && $tool->isInUserOrganization($user);
}
/**
* @param Tool $tool
* @param User $user
*
* @return bool
*/
private function canUploadFiles(Tool $tool, User $user): bool
{
return ($tool->isInUserOrganization($user) || $tool->isSystemTool()) && $tool->isStatusActive();
}
/**
* @param Tool $tool
* @param User $user
*
* @return bool
*/
private function canShowFiles(Tool $tool, User $user): bool
{
return $tool->isInUserOrganization($user) || $tool->isSystemTool();
}
}