<?php
namespace App\Security;
use App\Entity\UserManagement\ApiUser;
use App\Exception\ApiVersionMismatchHigh;
use App\Exception\ApiVersionMismatchLow;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class ApiVersionVoter extends Voter {
public const API_VERSION = 'API_VERSION';
protected function supports($attribute, $subject): bool {
if ($attribute !== self::API_VERSION) {
return false;
}
if (!is_int($subject)) {
return false;
}
return true;
}
/**
* Check if User is available and if the user's clinic has the right API version for this call
* @param $attribute
* @param $subject
* @param TokenInterface $token
* @return bool
* @throws ApiVersionMismatchHigh
* @throws ApiVersionMismatchLow
*/
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool {
$user = $token->getUser();
if (!$user instanceof ApiUser || 0 === $clinicApiVersion = $user->getClinicApiVersion()) {
return false;
}
if ($subject === $clinicApiVersion) {
return true;
}
if ($subject < $clinicApiVersion) {
throw new ApiVersionMismatchLow("API version mismatch - Clinic API version: " . $clinicApiVersion);
}
if ($subject > $clinicApiVersion) {
throw new ApiVersionMismatchHigh("API version mismatch - Clinic API version: " . $clinicApiVersion);
}
return false;
}
private function canView(Post $post, User $user): bool {
// if they can edit, they can view
if ($this->canEdit($post, $user)) {
return true;
}
// the Post object could have, for example, a method `isPrivate()`
return !$post->isPrivate();
}
private function canEdit(Post $post, User $user): bool {
// this assumes that the Post object has a `getOwner()` method
return $user === $post->getOwner();
}
}