Allow access to log detail page (only) if a user has permission to show_history of an entity

This commit is contained in:
Jan Böhmer 2023-05-16 00:05:54 +02:00
parent 272684e7eb
commit 6a1aefa5a5
2 changed files with 28 additions and 2 deletions

View file

@ -106,7 +106,7 @@ class LogController extends AbstractController
public function logDetails(Request $request, AbstractLogEntry $logEntry, LogEntryExtraFormatter $logEntryExtraFormatter, public function logDetails(Request $request, AbstractLogEntry $logEntry, LogEntryExtraFormatter $logEntryExtraFormatter,
LogLevelHelper $logLevelHelper, LogTargetHelper $logTargetHelper, EntityManagerInterface $entityManager): Response LogLevelHelper $logLevelHelper, LogTargetHelper $logTargetHelper, EntityManagerInterface $entityManager): Response
{ {
$this->denyAccessUnlessGranted('read', $logEntry); $this->denyAccessUnlessGranted('show_details', $logEntry);
$extra_html = $logEntryExtraFormatter->format($logEntry); $extra_html = $logEntryExtraFormatter->format($logEntry);
$target_html = $logTargetHelper->formatTarget($logEntry); $target_html = $logTargetHelper->formatTarget($logEntry);

View file

@ -24,13 +24,28 @@ namespace App\Security\Voter;
use App\Entity\LogSystem\AbstractLogEntry; use App\Entity\LogSystem\AbstractLogEntry;
use App\Entity\UserSystem\User; use App\Entity\UserSystem\User;
use App\Services\UserSystem\PermissionManager;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Security;
class LogEntryVoter extends ExtendedVoter class LogEntryVoter extends ExtendedVoter
{ {
public const ALLOWED_OPS = ['read', 'delete']; public const ALLOWED_OPS = ['read', 'show_details', 'delete'];
private Security $security;
public function __construct(PermissionManager $resolver, EntityManagerInterface $entityManager, Security $security)
{
parent::__construct($resolver, $entityManager);
$this->security = $security;
}
protected function voteOnUser(string $attribute, $subject, User $user): bool protected function voteOnUser(string $attribute, $subject, User $user): bool
{ {
if (!$subject instanceof AbstractLogEntry) {
throw new \InvalidArgumentException('The subject must be an instance of '.AbstractLogEntry::class);
}
if ('delete' === $attribute) { if ('delete' === $attribute) {
return $this->resolver->inherit($user, 'system', 'delete_logs') ?? false; return $this->resolver->inherit($user, 'system', 'delete_logs') ?? false;
} }
@ -47,6 +62,17 @@ class LogEntryVoter extends ExtendedVoter
return $this->resolver->inherit($user, 'system', 'show_logs') ?? false; return $this->resolver->inherit($user, 'system', 'show_logs') ?? false;
} }
if ('show_details' === $attribute) {
//To view details of a element related log entry, the user needs to be able to view the history of this entity type
$targetClass = $subject->getTargetClass();
if (null !== $targetClass) {
return $this->security->isGranted('show_history', $targetClass) ?? false;
}
//In other cases, this behaves like the read permission
return $this->voteOnUser('read', $subject, $user);
}
return false; return false;
} }