<?php
/**
* Created by PhpStorm.
* User: ouit0097
* Date: 24/06/15
* Time: 14:21
*/
namespace App\Ox\HoardBundle\Security\Authorization\Voter;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use NUCLEOS\UserBundle\Model\UserInterface;
class HoardVoter implements VoterInterface
{
const VIEW = 'view';
const VIEW_COINS = 'view_coins';
const VIEW_COINS_SUMMARY = 'view_coins_summary';
const EDIT = 'edit';
const DELETE = 'delete';
private $supportedClass = 'App\Ox\HoardBundle\Entity\Hoard';
public function supportsAttribute($attribute)
{
return in_array($attribute, array(
self::VIEW,
self::VIEW_COINS,
self::VIEW_COINS_SUMMARY,
self::EDIT,
self::DELETE,
));
}
public function supportsClass($class)
{
return $this->supportedClass === $class || $this->isChildofSupportedClass($class);
}
public function isChildofSupportedClass($class)
{
return is_subclass_of($class, $this->supportedClass);
}
// validate whether a particular user can access a particular hoard based on country and access grants
private function checkUserCanAccessHoardByCountry($user, $hoard) {
// check for user exception access
foreach($user->getAccessibleHoards() as $userHoard) {
if($userHoard->getHoard() == $hoard)
return true;
}
$forbiddenCountryFlag = false;
// check for country access
foreach($hoard->getCountries() as $country) {
if (!in_array($country, $user->getAccessibleCountries()->toArray())){
$forbiddenCountryFlag = true;
}
}
if (!$forbiddenCountryFlag){
return true;
}
return false;
}
// the haord (or some part of it) is hidden from the user
private function getHoardIsHiddenFromUser($user, $hoard) {
//public
if(!$user instanceof UserInterface || !($user->getId() > 0) ) {
return $hoard->getHideFrom()->getId() != 3; // != 'none'
}
//admin
elseif($user && ( $user->hasRole('ROLE_ADMIN') || $user->hasRole('ROLE_SUPER_ADMIN'))) {
return false;
}
//user
elseif($this->checkUserCanAccessHoardByCountry($user, $hoard)) {
return false;
}
else {
return $hoard->getHideFrom()->getHideFrom() == 2; //"public + collaborator";
}
}
/**
* @param TokenInterface $token A TokenInterface instance
* @param object|null $object The hoard to secure
* @param array $attributes An array of attributes associated with the method being invoked
*
* @return int either ACCESS_GRANTED, ACCESS_ABSTAIN, or ACCESS_DENIED
*/
public function vote(TokenInterface $token, $object, array $attributes)
{
// check if class of this object is supported by this voter
if (!is_object($object) || !$this->supportsClass(get_class($object))) {
return VoterInterface::ACCESS_ABSTAIN;
}
// check if the voter is used correct, only allow one attribute
// this isn't a requirement, it's just one easy way for you to
// design your voter
if (1 !== count($attributes)) {
throw new \InvalidArgumentException(
'Only one attribute is allowed for VIEW or EDIT'
);
}
// set the attribute to check against
$attribute = $attributes[0];
// check if the given attribute is covered by this voter
if (!$this->supportsAttribute($attribute)) {
return VoterInterface::ACCESS_ABSTAIN;
}
// get current logged in user
$user = $token->getUser();
$hoard = $object;
//not doing what we expect. Returns true when we are querying about a hoard.
// if($this->isChildofSupportedClass(get_class($object)))
// $hoard = $object->getHoard();
switch($attribute) {
case self::VIEW:
// check if hidden value is set
$hideFromNone = $hoard->getHideFrom()->getId() == 3;// || $hoard->getHideFrom()->getHideFrom()=='none';
$hideAll = $hoard->getHideWhat() && $hoard->getHideWhat()->getId() == 3; //'all'
if($hideFromNone || !$hideAll) {
// check if marked as hidden
if(!$hoard->getValidatedByUser())
{
if(!$user instanceof UserInterface || !($user->getId() > 0) )
{
return VoterInterface::ACCESS_DENIED;
}
}
return VoterInterface::ACCESS_GRANTED;
}
// check if user is authenticated
elseif(!$user instanceof UserInterface || !($user->getId() > 0) ) {
return VoterInterface::ACCESS_DENIED;
}
elseif($user && ( $user->hasRole('ROLE_ADMIN') || $user->hasRole('ROLE_SUPER_ADMIN'))) {
return VoterInterface::ACCESS_GRANTED;
}
// check if user is the creator of the hoard
elseif( $hoard->getCreated() && $user->getId() == $hoard->getCreated()->getId()) {
return VoterInterface::ACCESS_GRANTED;
}
// check if user has access by country or specific access grant
elseif($this->checkUserCanAccessHoardByCountry($user, $hoard)) {
return VoterInterface::ACCESS_GRANTED;
}
// check if hoard is hidden from users from other countries
elseif($hoard->getHideFrom()->getId() == 2) { //"public + collaborator with view rights") {
return VoterInterface::ACCESS_DENIED;
}
return VoterInterface::ACCESS_GRANTED;
case self::VIEW_COINS:
if($this->getHoardIsHiddenFromUser($user, $hoard))
{
$hideCoins = $hoard->getHideWhat() && $hoard->getHideWhat()->getId() == 1; //'the coins'
$hideCoinsAndSummary = $hoard->getHideWhat() && $hoard->getHideWhat()->getId() == 2; //'the coins + the coin summary';
if(!$hideCoins && !$hideCoinsAndSummary)
{
return VoterInterface::ACCESS_GRANTED;
}
return VoterInterface::ACCESS_DENIED;
}
return VoterInterface::ACCESS_GRANTED;
case self::VIEW_COINS_SUMMARY:
if($this->getHoardIsHiddenFromUser($user, $hoard))
{
$hideCoinsAndSummary = $hoard->getHideWhat() && $hoard->getHideWhat()->getId() == 2;//'the coins + the coin summary';
if(!$hideCoinsAndSummary)
{
return VoterInterface::ACCESS_GRANTED;
}
return VoterInterface::ACCESS_DENIED;
}
return VoterInterface::ACCESS_GRANTED;
case self::EDIT: case self::DELETE:
// check if user is authenticated
if(!$user instanceof UserInterface || !($user->getId() > 0) ) {
return VoterInterface::ACCESS_DENIED;
}
// check if user is the creator of the hoard
elseif( $hoard->getCreated() && $user->getId() == $hoard->getCreated()->getId()) {
return VoterInterface::ACCESS_GRANTED;
}
// check if user has access by country or specific access grant
elseif($this->checkUserCanAccessHoardByCountry($user, $hoard)) {
return VoterInterface::ACCESS_GRANTED;
}
elseif($user && ( $user->hasRole('ROLE_ADMIN') || $user->hasRole('ROLE_SUPER_ADMIN'))) {
return VoterInterface::ACCESS_GRANTED;
}
return VoterInterface::ACCESS_DENIED;
}
return VoterInterface::ACCESS_DENIED;
}
}