Initial commit with Symfony 2.1+Vendors
Signed-off-by: Gergely POLONKAI (W00d5t0ck) <polesz@w00d5t0ck.info>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Acl\Expression;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ConstantExpression;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func\FunctionCompilerInterface;
|
||||
|
||||
class HasPermissionFunctionCompiler implements FunctionCompilerInterface
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'hasPermission';
|
||||
}
|
||||
|
||||
public function compilePreconditions(ExpressionCompiler $compiler, FunctionExpression $function)
|
||||
{
|
||||
$compiler->verifyItem('token', 'Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
|
||||
}
|
||||
|
||||
public function compile(ExpressionCompiler $compiler, FunctionExpression $function)
|
||||
{
|
||||
$compiler
|
||||
->compileInternal(new VariableExpression('permission_evaluator'))
|
||||
->write('->hasPermission(')
|
||||
->compileInternal(new VariableExpression('token'))
|
||||
->write(', ')
|
||||
->compileInternal($function->args[0])
|
||||
->write(', ')
|
||||
;
|
||||
|
||||
if ($function->args[1] instanceof ConstantExpression) {
|
||||
$compiler->write(var_export(strtoupper($function->args[1]->value), true).')');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->write('strtoupper(')
|
||||
->compileInternal($function->args[1])
|
||||
->write('))')
|
||||
;
|
||||
}
|
||||
}
|
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Acl\Expression;
|
||||
|
||||
use Symfony\Component\Security\Acl\Exception\NoAceFoundException;
|
||||
use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
|
||||
use Symfony\Component\Security\Acl\Model\ObjectIdentityInterface;
|
||||
use Symfony\Component\Security\Acl\Permission\PermissionMapInterface;
|
||||
use Symfony\Component\Security\Acl\Model\AclProviderInterface;
|
||||
use Symfony\Component\Security\Acl\Model\SecurityIdentityRetrievalStrategyInterface;
|
||||
use Symfony\Component\Security\Acl\Model\ObjectIdentityRetrievalStrategyInterface;
|
||||
use Symfony\Component\HttpKernel\Log\LoggerInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
class PermissionEvaluator
|
||||
{
|
||||
private $aclProvider;
|
||||
private $oidRetrievalStrategy;
|
||||
private $sidRetrievalStrategy;
|
||||
private $permissionMap;
|
||||
private $allowIfObjectIdentityUnavailable;
|
||||
private $logger;
|
||||
|
||||
public function __construct(AclProviderInterface $aclProvider,
|
||||
ObjectIdentityRetrievalStrategyInterface $oidRetrievalStrategy,
|
||||
SecurityIdentityRetrievalStrategyInterface $sidRetrievalStrategy,
|
||||
PermissionMapInterface $permissionMap,
|
||||
$allowIfObjectIdentityUnavailable = true,
|
||||
LoggerInterface $logger = null)
|
||||
{
|
||||
$this->aclProvider = $aclProvider;
|
||||
$this->oidRetrievalStrategy = $oidRetrievalStrategy;
|
||||
$this->sidRetrievalStrategy = $sidRetrievalStrategy;
|
||||
$this->permissionMap = $permissionMap;
|
||||
$this->allowIfObjectIdentityUnavailable = $allowIfObjectIdentityUnavailable;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function hasPermission(TokenInterface $token, $object, $permission)
|
||||
{
|
||||
if (null === $masks = $this->permissionMap->getMasks($permission, $object)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null === $object) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug(sprintf('Object identity unavailable. Voting to %s', $this->allowIfObjectIdentityUnavailable? 'grant access' : 'abstain'));
|
||||
}
|
||||
|
||||
return $this->allowIfObjectIdentityUnavailable ? true : false;
|
||||
} else if ($object instanceof FieldVote) {
|
||||
$field = $object->getField();
|
||||
$object = $object->getDomainObject();
|
||||
} else {
|
||||
$field = null;
|
||||
}
|
||||
|
||||
if ($object instanceof ObjectIdentityInterface) {
|
||||
$oid = $object;
|
||||
} else if (null === $oid = $this->oidRetrievalStrategy->getObjectIdentity($object)) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug(sprintf('Object identity unavailable. Voting to %s', $this->allowIfObjectIdentityUnavailable? 'grant access' : 'abstain'));
|
||||
}
|
||||
|
||||
return $this->allowIfObjectIdentityUnavailable ? true : false;
|
||||
}
|
||||
|
||||
$sids = $this->sidRetrievalStrategy->getSecurityIdentities($token);
|
||||
|
||||
try {
|
||||
$acl = $this->aclProvider->findAcl($oid, $sids);
|
||||
|
||||
if (null === $field && $acl->isGranted($masks, $sids, false)) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('ACL found, permission granted. Voting to grant access');
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (null !== $field && $acl->isFieldGranted($field, $masks, $sids, false)) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('ACL found, permission granted. Voting to grant access');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('ACL found, insufficient permissions. Voting to deny access.');
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (AclNotFoundException $noAcl) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('No ACL found for the object identity. Voting to deny access.');
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (NoAceFoundException $noAce) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('ACL found, no ACE applicable. Voting to deny access.');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
136
vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Acl/Voter/AclVoter.php
vendored
Normal file
136
vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Acl/Voter/AclVoter.php
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Acl\Voter;
|
||||
|
||||
use Symfony\Component\Security\Acl\Voter\FieldVote;
|
||||
use Symfony\Component\HttpKernel\Log\LoggerInterface;
|
||||
use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
|
||||
use Symfony\Component\Security\Acl\Exception\NoAceFoundException;
|
||||
use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
|
||||
use Symfony\Component\Security\Acl\Model\AclProviderInterface;
|
||||
use Symfony\Component\Security\Acl\Model\ObjectIdentityInterface;
|
||||
use Symfony\Component\Security\Acl\Permission\PermissionMapInterface;
|
||||
use Symfony\Component\Security\Acl\Model\SecurityIdentityRetrievalStrategyInterface;
|
||||
use Symfony\Component\Security\Acl\Model\ObjectIdentityRetrievalStrategyInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
|
||||
/**
|
||||
* This voter can be used as a base class for implementing your own permissions.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class AclVoter implements VoterInterface
|
||||
{
|
||||
private $aclProvider;
|
||||
private $permissionMap;
|
||||
private $objectIdentityRetrievalStrategy;
|
||||
private $securityIdentityRetrievalStrategy;
|
||||
private $allowIfObjectIdentityUnavailable;
|
||||
private $logger;
|
||||
|
||||
public function __construct(AclProviderInterface $aclProvider, ObjectIdentityRetrievalStrategyInterface $oidRetrievalStrategy, SecurityIdentityRetrievalStrategyInterface $sidRetrievalStrategy, PermissionMapInterface $permissionMap, LoggerInterface $logger = null, $allowIfObjectIdentityUnavailable = true)
|
||||
{
|
||||
$this->aclProvider = $aclProvider;
|
||||
$this->permissionMap = $permissionMap;
|
||||
$this->objectIdentityRetrievalStrategy = $oidRetrievalStrategy;
|
||||
$this->securityIdentityRetrievalStrategy = $sidRetrievalStrategy;
|
||||
$this->logger = $logger;
|
||||
$this->allowIfObjectIdentityUnavailable = $allowIfObjectIdentityUnavailable;
|
||||
}
|
||||
|
||||
public function supportsAttribute($attribute)
|
||||
{
|
||||
return $this->permissionMap->contains($attribute);
|
||||
}
|
||||
|
||||
public function vote(TokenInterface $token, $object, array $attributes)
|
||||
{
|
||||
foreach ($attributes as $attribute) {
|
||||
if (null === $masks = $this->permissionMap->getMasks((string) $attribute, $object)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (null === $object) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug(sprintf('Object identity unavailable. Voting to %s', $this->allowIfObjectIdentityUnavailable? 'grant access' : 'abstain'));
|
||||
}
|
||||
|
||||
return $this->allowIfObjectIdentityUnavailable ? self::ACCESS_GRANTED : self::ACCESS_ABSTAIN;
|
||||
} else if ($object instanceof FieldVote) {
|
||||
$field = $object->getField();
|
||||
$object = $object->getDomainObject();
|
||||
} else {
|
||||
$field = null;
|
||||
}
|
||||
|
||||
if ($object instanceof ObjectIdentityInterface) {
|
||||
$oid = $object;
|
||||
} else if (null === $oid = $this->objectIdentityRetrievalStrategy->getObjectIdentity($object)) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug(sprintf('Object identity unavailable. Voting to %s', $this->allowIfObjectIdentityUnavailable? 'grant access' : 'abstain'));
|
||||
}
|
||||
|
||||
return $this->allowIfObjectIdentityUnavailable ? self::ACCESS_GRANTED : self::ACCESS_ABSTAIN;
|
||||
}
|
||||
|
||||
if (!$this->supportsClass($oid->getType())) {
|
||||
return self::ACCESS_ABSTAIN;
|
||||
}
|
||||
|
||||
$sids = $this->securityIdentityRetrievalStrategy->getSecurityIdentities($token);
|
||||
|
||||
try {
|
||||
$acl = $this->aclProvider->findAcl($oid, $sids);
|
||||
|
||||
if (null === $field && $acl->isGranted($masks, $sids, false)) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('ACL found, permission granted. Voting to grant access');
|
||||
}
|
||||
|
||||
return self::ACCESS_GRANTED;
|
||||
} else if (null !== $field && $acl->isFieldGranted($field, $masks, $sids, false)) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('ACL found, permission granted. Voting to grant access');
|
||||
}
|
||||
|
||||
return self::ACCESS_GRANTED;
|
||||
}
|
||||
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('ACL found, insufficient permissions. Voting to deny access.');
|
||||
}
|
||||
|
||||
return self::ACCESS_DENIED;
|
||||
} catch (AclNotFoundException $noAcl) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('No ACL found for the object identity. Voting to deny access.');
|
||||
}
|
||||
|
||||
return self::ACCESS_DENIED;
|
||||
} catch (NoAceFoundException $noAce) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('ACL found, no ACE applicable. Voting to deny access.');
|
||||
}
|
||||
|
||||
return self::ACCESS_DENIED;
|
||||
}
|
||||
}
|
||||
|
||||
// no attribute was supported
|
||||
return self::ACCESS_ABSTAIN;
|
||||
}
|
||||
|
||||
/**
|
||||
* You can override this method when writing a voter for a specific domain
|
||||
* class.
|
||||
*
|
||||
* @param string $class The class name
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function supportsClass($class)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authentication\Provider;
|
||||
|
||||
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
||||
use JMS\SecurityExtraBundle\Security\Authentication\Token\RunAsUserToken;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
|
||||
|
||||
/**
|
||||
* Class which authenticates RunAsTokens.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class RunAsAuthenticationProvider implements AuthenticationProviderInterface
|
||||
{
|
||||
private $key;
|
||||
|
||||
public function __construct($key)
|
||||
{
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
public function authenticate(TokenInterface $token)
|
||||
{
|
||||
if (!$this->supports($token)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($token->getKey() === $this->key) {
|
||||
return $token;
|
||||
} else {
|
||||
throw new BadCredentialsException('The keys do not match.');
|
||||
}
|
||||
}
|
||||
|
||||
public function supports(TokenInterface $token)
|
||||
{
|
||||
return $token instanceof RunAsUserToken;
|
||||
}
|
||||
}
|
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authentication\Token;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
|
||||
|
||||
/**
|
||||
* This token is automatically generated by the RunAsManager when an invocation
|
||||
* is supposed to be run with a different Token.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class RunAsUserToken extends AbstractToken
|
||||
{
|
||||
private $originalToken;
|
||||
private $key;
|
||||
private $credentials;
|
||||
|
||||
public function __construct($key, $user, $credentials, array $roles, TokenInterface $originalToken)
|
||||
{
|
||||
parent::__construct($roles);
|
||||
|
||||
$this->originalToken = $originalToken;
|
||||
$this->credentials = $credentials;
|
||||
$this->key = $key;
|
||||
|
||||
$this->setUser($user);
|
||||
$this->setAuthenticated(true);
|
||||
}
|
||||
|
||||
public function getKey()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function getOriginalToken()
|
||||
{
|
||||
return $this->originalToken;
|
||||
}
|
||||
|
||||
public function getCredentials()
|
||||
{
|
||||
return $this->credentials;
|
||||
}
|
||||
|
||||
public function eraseCredentials()
|
||||
{
|
||||
parent::eraseCredentials();
|
||||
|
||||
$this->credentials = null;
|
||||
}
|
||||
|
||||
public function serialize()
|
||||
{
|
||||
return serialize(array(
|
||||
$this->originalToken,
|
||||
$this->key,
|
||||
$this->credentials,
|
||||
parent::serialize(),
|
||||
));
|
||||
}
|
||||
|
||||
public function unserialize($str)
|
||||
{
|
||||
list($this->originalToken, $this->key, $this->credentials, $parentStr) = unserialize($str);
|
||||
parent::unserialize($parentStr);
|
||||
}
|
||||
}
|
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\AfterInvocation;
|
||||
|
||||
use Symfony\Component\HttpKernel\Log\LoggerInterface;
|
||||
use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
|
||||
use Symfony\Component\Security\Acl\Exception\NoAceFoundException;
|
||||
use Symfony\Component\Security\Acl\Model\SecurityIdentityRetrievalStrategyInterface;
|
||||
use Symfony\Component\Security\Acl\Model\ObjectIdentityRetrievalStrategyInterface;
|
||||
use Symfony\Component\Security\Acl\Model\AclProviderInterface;
|
||||
use Symfony\Component\Security\Acl\Permission\PermissionMapInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
||||
|
||||
/**
|
||||
* This after invocation provider filters returned objects based on ACLs.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class AclAfterInvocationProvider implements AfterInvocationProviderInterface
|
||||
{
|
||||
private $aclProvider;
|
||||
private $oidRetrievalStrategy;
|
||||
private $sidRetrievalStrategy;
|
||||
private $permissionMap;
|
||||
private $logger;
|
||||
|
||||
public function __construct(AclProviderInterface $aclProvider, ObjectIdentityRetrievalStrategyInterface $oidRetrievalStrategy, SecurityIdentityRetrievalStrategyInterface $sidRetrievalStrategy, PermissionMapInterface $permissionMap, LoggerInterface $logger = null)
|
||||
{
|
||||
$this->aclProvider = $aclProvider;
|
||||
$this->oidRetrievalStrategy = $oidRetrievalStrategy;
|
||||
$this->sidRetrievalStrategy = $sidRetrievalStrategy;
|
||||
$this->permissionMap = $permissionMap;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function decide(TokenInterface $token, $secureObject, array $attributes, $returnedObject)
|
||||
{
|
||||
if (null === $returnedObject) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('Returned object was null, skipping security check.');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
if (!$this->supportsAttribute($attribute)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (null === $oid = $this->oidRetrievalStrategy->getObjectIdentity($returnedObject)) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('Returned object was no domain object, skipping security check.');
|
||||
}
|
||||
|
||||
return $returnedObject;
|
||||
}
|
||||
|
||||
$sids = $this->sidRetrievalStrategy->getSecurityIdentities($token);
|
||||
|
||||
try {
|
||||
$acl = $this->aclProvider->findAcl($oid, $sids);
|
||||
if ($acl->isGranted($this->permissionMap->getMasks($attribute, $returnedObject), $sids, false)) {
|
||||
return $returnedObject;
|
||||
}
|
||||
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('Token has been denied access for returned object.');
|
||||
}
|
||||
} catch (AclNotFoundException $noAcl) {
|
||||
throw new AccessDeniedException('No applicable ACL found for domain object.');
|
||||
} catch (NoAceFoundException $noAce) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('No applicable ACE found for the given Token, denying access.');
|
||||
}
|
||||
}
|
||||
|
||||
throw new AccessDeniedException('ACL has denied access for attribute: '.$attribute);
|
||||
}
|
||||
|
||||
// no attribute was supported
|
||||
return $returnedObject;
|
||||
}
|
||||
|
||||
public function supportsAttribute($attribute)
|
||||
{
|
||||
return $this->permissionMap->contains($attribute);
|
||||
}
|
||||
|
||||
public function supportsClass($className)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\AfterInvocation;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
/**
|
||||
* This is the pendant to the AccessDecisionManager which is used to make
|
||||
* access decisions after a method has been executed.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class AfterInvocationManager implements AfterInvocationManagerInterface
|
||||
{
|
||||
private $providers;
|
||||
|
||||
public function __construct(array $providers)
|
||||
{
|
||||
$this->providers = $providers;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function decide(TokenInterface $token, $secureInvocation, array $attributes, $returnedObject)
|
||||
{
|
||||
foreach ($this->providers as $provider) {
|
||||
$returnedObject = $provider->decide($token, $secureInvocation, $attributes, $returnedObject);
|
||||
}
|
||||
|
||||
return $returnedObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsAttribute($attribute)
|
||||
{
|
||||
foreach ($this->providers as $provider) {
|
||||
if (true === $provider->supportsAttribute($attribute)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsClass($className)
|
||||
{
|
||||
foreach ($this->providers as $provider) {
|
||||
if (true === $provider->supportsClass($className)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\AfterInvocation;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
/**
|
||||
* AfterInvocationManagerInterface
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
interface AfterInvocationManagerInterface
|
||||
{
|
||||
/**
|
||||
* Makes an access decision after the invocation of a method
|
||||
*
|
||||
* @param TokenInterface $token
|
||||
* @param object $secureObject
|
||||
* @param array $attributes
|
||||
* @param mixed $returnedValue the value that was returned by the method invocation
|
||||
* @return mixed the filter return value
|
||||
*/
|
||||
function decide(TokenInterface $token, $secureObject, array $attributes, $returnedValue);
|
||||
|
||||
/**
|
||||
* Determines whether the given attribute is supported
|
||||
*
|
||||
* @param string $attribute
|
||||
* @return Boolean
|
||||
*/
|
||||
function supportsAttribute($attribute);
|
||||
|
||||
/**
|
||||
* Determines whether the given class is supported
|
||||
*
|
||||
* @param string $className the class of the secure object
|
||||
* @return Boolean
|
||||
*/
|
||||
function supportsClass($className);
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\AfterInvocation;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
/**
|
||||
* AfterInvocationProviderInterface
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
interface AfterInvocationProviderInterface
|
||||
{
|
||||
function decide(TokenInterface $token, $secureObject, array $attributes, $returnedObject);
|
||||
function supportsAttribute($attribute);
|
||||
function supportsClass($className);
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast;
|
||||
|
||||
class AndExpression implements ExpressionInterface
|
||||
{
|
||||
public $left;
|
||||
public $right;
|
||||
|
||||
public function __construct(ExpressionInterface $left, ExpressionInterface $right)
|
||||
{
|
||||
$this->left = $left;
|
||||
$this->right = $right;
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast;
|
||||
|
||||
class ArrayExpression implements ExpressionInterface
|
||||
{
|
||||
public $elements;
|
||||
|
||||
public function __construct(array $elements)
|
||||
{
|
||||
$this->elements = $elements;
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast;
|
||||
|
||||
class ConstantExpression implements ExpressionInterface
|
||||
{
|
||||
public $value;
|
||||
|
||||
public function __construct($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast;
|
||||
|
||||
interface ExpressionInterface
|
||||
{
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast;
|
||||
|
||||
class FunctionExpression implements ExpressionInterface
|
||||
{
|
||||
/** READ-ONLY */
|
||||
public $name;
|
||||
public $args;
|
||||
|
||||
public function __construct($name, array $args)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->args = $args;
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast;
|
||||
|
||||
class GetItemExpression
|
||||
{
|
||||
public $array;
|
||||
public $key;
|
||||
|
||||
public function __construct(ExpressionInterface $array, ExpressionInterface $key)
|
||||
{
|
||||
$this->array = $array;
|
||||
$this->key = $key;
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast;
|
||||
|
||||
class GetPropertyExpression implements ExpressionInterface
|
||||
{
|
||||
public $object;
|
||||
public $name;
|
||||
|
||||
public function __construct(ExpressionInterface $obj, $name)
|
||||
{
|
||||
$this->object = $obj;
|
||||
$this->name = $name;
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast;
|
||||
|
||||
class IsEqualExpression implements ExpressionInterface
|
||||
{
|
||||
public $left;
|
||||
public $right;
|
||||
|
||||
public function __construct(ExpressionInterface $left, ExpressionInterface $right)
|
||||
{
|
||||
$this->left = $left;
|
||||
$this->right = $right;
|
||||
}
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast;
|
||||
|
||||
class MethodCallExpression implements ExpressionInterface
|
||||
{
|
||||
public $object;
|
||||
public $method;
|
||||
public $args;
|
||||
|
||||
public function __construct(ExpressionInterface $obj, $method, array $args)
|
||||
{
|
||||
$this->object = $obj;
|
||||
$this->method = $method;
|
||||
$this->args = $args;
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast;
|
||||
|
||||
class NotExpression implements ExpressionInterface
|
||||
{
|
||||
public $expr;
|
||||
|
||||
public function __construct(ExpressionInterface $expr)
|
||||
{
|
||||
$this->expr = $expr;
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast;
|
||||
|
||||
class OrExpression implements ExpressionInterface
|
||||
{
|
||||
public $left;
|
||||
public $right;
|
||||
|
||||
public function __construct(ExpressionInterface $left, ExpressionInterface $right)
|
||||
{
|
||||
$this->left = $left;
|
||||
$this->right = $right;
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast;
|
||||
|
||||
class ParameterExpression implements ExpressionInterface
|
||||
{
|
||||
public $name;
|
||||
|
||||
public function __construct($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast;
|
||||
|
||||
class VariableExpression implements ExpressionInterface
|
||||
{
|
||||
public $name;
|
||||
public $allowNull;
|
||||
|
||||
public function __construct($name, $allowNull = false)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->allowNull = $allowNull;
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler;
|
||||
|
||||
class AndExpressionCompiler extends BinaryExprCompiler
|
||||
{
|
||||
public function getType()
|
||||
{
|
||||
return 'JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\AndExpression';
|
||||
}
|
||||
|
||||
protected function getOperator()
|
||||
{
|
||||
return '&&';
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ExpressionInterface;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler;
|
||||
|
||||
/**
|
||||
* Base Compiler for Binary Operators.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
abstract class BinaryExprCompiler implements TypeCompilerInterface
|
||||
{
|
||||
public function compilePreconditions(ExpressionCompiler $compiler, ExpressionInterface $expr)
|
||||
{
|
||||
$compiler
|
||||
->compilePreconditions($expr->left)
|
||||
->compilePreconditions($expr->right)
|
||||
;
|
||||
}
|
||||
|
||||
public function compile(ExpressionCompiler $compiler, ExpressionInterface $expr)
|
||||
{
|
||||
$compiler
|
||||
->write("(")
|
||||
->compileInternal($expr->left)
|
||||
->write(") ".$this->getOperator()." (")
|
||||
->compileInternal($expr->right)
|
||||
->write(")")
|
||||
;
|
||||
}
|
||||
|
||||
abstract protected function getOperator();
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ExpressionInterface;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\VariableExpressionCompiler;
|
||||
|
||||
class ContainerAwareVariableCompiler extends VariableExpressionCompiler
|
||||
{
|
||||
private $serviceMap = array();
|
||||
private $parameterMap = array();
|
||||
|
||||
public function setMaps(array $serviceMap, array $parameterMap)
|
||||
{
|
||||
$this->serviceMap = $serviceMap;
|
||||
$this->parameterMap = $parameterMap;
|
||||
}
|
||||
|
||||
public function compile(ExpressionCompiler $compiler, ExpressionInterface $expr)
|
||||
{
|
||||
if (isset($this->serviceMap[$expr->name])) {
|
||||
$compiler->write("\$context['container']->get('{$this->serviceMap[$expr->name]}'");
|
||||
|
||||
if ($expr->allowNull) {
|
||||
$compiler->write(", ".ContainerInterface::NULL_ON_INVALID_REFERENCE);
|
||||
}
|
||||
|
||||
$compiler->write(")");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($this->parameterMap[$expr->name])) {
|
||||
$compiler->write("\$context['container']->getParameter('{$this->parameterMap[$expr->name]}')");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
parent::compile($compiler, $expr);
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func;
|
||||
|
||||
use JMS\SecurityExtraBundle\Exception\InvalidArgumentException;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler;
|
||||
|
||||
abstract class AuthenticationTrustFunctionCompiler implements FunctionCompilerInterface
|
||||
{
|
||||
public function compilePreconditions(ExpressionCompiler $compiler, FunctionExpression $function)
|
||||
{
|
||||
if (!empty($function->args)) {
|
||||
throw new InvalidArgumentException(sprintf('The '.$this->getName().'() function does not accept any arguments, but got "%s".', var_export($function->args, true)));
|
||||
}
|
||||
|
||||
$compiler->verifyItem('token', 'Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler;
|
||||
|
||||
interface FunctionCompilerInterface
|
||||
{
|
||||
function getName();
|
||||
function compilePreconditions(ExpressionCompiler $compiler, FunctionExpression $function);
|
||||
function compile(ExpressionCompiler $compiler, FunctionExpression $function);
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func;
|
||||
|
||||
use JMS\SecurityExtraBundle\Exception\RuntimeException;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler;
|
||||
|
||||
class HasAnyRoleFunctionCompiler implements FunctionCompilerInterface
|
||||
{
|
||||
private $rolesExpr;
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'hasAnyRole';
|
||||
}
|
||||
|
||||
public function compilePreconditions(ExpressionCompiler $compiler, FunctionExpression $function)
|
||||
{
|
||||
if (0 === count($function->args)) {
|
||||
throw new RuntimeException('The function hasAnyRole() expects at least one argument, but got none.');
|
||||
}
|
||||
|
||||
$this->rolesExpr = $compiler->getRolesExpr();
|
||||
}
|
||||
|
||||
public function compile(ExpressionCompiler $compiler, FunctionExpression $function)
|
||||
{
|
||||
$compiler->write("(");
|
||||
|
||||
$first = true;
|
||||
foreach ($function->args as $arg) {
|
||||
if (!$first) {
|
||||
$compiler->write(" || ");
|
||||
}
|
||||
$first = false;
|
||||
|
||||
$compiler
|
||||
->write("isset({$this->rolesExpr}[")
|
||||
->compileInternal($arg)
|
||||
->write("])")
|
||||
;
|
||||
}
|
||||
|
||||
$compiler->write(")");
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func;
|
||||
|
||||
use JMS\SecurityExtraBundle\Exception\RuntimeException;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler;
|
||||
|
||||
class HasRoleFunctionCompiler implements FunctionCompilerInterface
|
||||
{
|
||||
private $rolesExpr;
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'hasRole';
|
||||
}
|
||||
|
||||
public function compilePreconditions(ExpressionCompiler $compiler, FunctionExpression $function)
|
||||
{
|
||||
if (1 !== count($function->args)) {
|
||||
throw new RuntimeException(sprintf('The hasRole() function expects exactly one argument, but got "%s".', var_export($function->args, true)));
|
||||
}
|
||||
|
||||
$this->rolesExpr = $compiler->getRolesExpr();
|
||||
}
|
||||
|
||||
public function compile(ExpressionCompiler $compiler, FunctionExpression $function)
|
||||
{
|
||||
$compiler
|
||||
->write("isset({$this->rolesExpr}[")
|
||||
->compileInternal($function->args[0])
|
||||
->write("])")
|
||||
;
|
||||
}
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler;
|
||||
|
||||
class IsAnonymousFunctionCompiler extends AuthenticationTrustFunctionCompiler
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'isAnonymous';
|
||||
}
|
||||
|
||||
public function compile(ExpressionCompiler $compiler, FunctionExpression $function)
|
||||
{
|
||||
$compiler
|
||||
->compileInternal(new VariableExpression('trust_resolver'))
|
||||
->write("->isAnonymous(\$context['token'])");
|
||||
}
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler;
|
||||
|
||||
class IsAuthenticatedFunctionCompiler extends AuthenticationTrustFunctionCompiler
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'isAuthenticated';
|
||||
}
|
||||
|
||||
public function compile(ExpressionCompiler $compiler, FunctionExpression $function)
|
||||
{
|
||||
$compiler
|
||||
->write("!")
|
||||
->compileInternal(new VariableExpression('trust_resolver'))
|
||||
->write("->isAnonymous(\$context['token'])")
|
||||
;
|
||||
}
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler;
|
||||
|
||||
class IsFullyAuthenticatedFunctionCompiler extends AuthenticationTrustFunctionCompiler
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'isFullyAuthenticated';
|
||||
}
|
||||
|
||||
public function compile(ExpressionCompiler $compiler, FunctionExpression $function)
|
||||
{
|
||||
$compiler
|
||||
->compileInternal(new VariableExpression('trust_resolver'))
|
||||
->write("->isFullFledged(\$context['token'])");
|
||||
}
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler;
|
||||
|
||||
class IsRememberMeFunctionCompiler extends AuthenticationTrustFunctionCompiler
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'isRememberMe';
|
||||
}
|
||||
|
||||
public function compile(ExpressionCompiler $compiler, FunctionExpression $function)
|
||||
{
|
||||
$compiler
|
||||
->compileInternal(new VariableExpression('trust_resolver'))
|
||||
->write("->isRememberMe(\$context['token'])");
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler;
|
||||
|
||||
class IsEqualExpressionCompiler extends BinaryExprCompiler
|
||||
{
|
||||
public function getType()
|
||||
{
|
||||
return 'JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\IsEqualExpression';
|
||||
}
|
||||
|
||||
protected function getOperator()
|
||||
{
|
||||
return '===';
|
||||
}
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ExpressionInterface;
|
||||
|
||||
class NotExpressionCompiler implements TypeCompilerInterface
|
||||
{
|
||||
public function getType()
|
||||
{
|
||||
return 'JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\NotExpression';
|
||||
}
|
||||
|
||||
public function compilePreconditions(ExpressionCompiler $compiler, ExpressionInterface $expr)
|
||||
{
|
||||
$compiler->compilePreconditions($expr->expr);
|
||||
}
|
||||
|
||||
public function compile(ExpressionCompiler $compiler, ExpressionInterface $expr)
|
||||
{
|
||||
$compiler
|
||||
->write('!(')
|
||||
->compileInternal($expr->expr)
|
||||
->write(')')
|
||||
;
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler;
|
||||
|
||||
class OrExpressionCompiler extends BinaryExprCompiler
|
||||
{
|
||||
public function getType()
|
||||
{
|
||||
return 'JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\OrExpression';
|
||||
}
|
||||
|
||||
protected function getOperator()
|
||||
{
|
||||
return '||';
|
||||
}
|
||||
}
|
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ExpressionInterface;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\TypeCompilerInterface;
|
||||
|
||||
class ParameterExpressionCompiler implements TypeCompilerInterface
|
||||
{
|
||||
public function getType()
|
||||
{
|
||||
return 'JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ParameterExpression';
|
||||
}
|
||||
|
||||
public function compilePreconditions(ExpressionCompiler $compiler, ExpressionInterface $parameter)
|
||||
{
|
||||
$compiler->verifyItem('object', 'CG\Proxy\MethodInvocation');
|
||||
|
||||
if (!isset($compiler->attributes['parameter_mapping_name'])) {
|
||||
$this->addParameterMapping($compiler);
|
||||
}
|
||||
|
||||
$compiler
|
||||
->writeln("if (!isset(\${$compiler->attributes['parameter_mapping_name']}['{$parameter->name}'])) {")
|
||||
->indent()
|
||||
->write("throw new RuntimeException(sprintf('There is no parameter with name \"{$parameter->name}\" for method \"%s\".', ")
|
||||
->compileInternal(new VariableExpression('object'))
|
||||
->writeln("));")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
;
|
||||
}
|
||||
|
||||
public function compile(ExpressionCompiler $compiler, ExpressionInterface $parameter)
|
||||
{
|
||||
$compiler
|
||||
->compileInternal(new VariableExpression('object'))
|
||||
->write("->arguments[")
|
||||
->write("\${$compiler->attributes['parameter_mapping_name']}")
|
||||
->write("['{$parameter->name}']]")
|
||||
;
|
||||
}
|
||||
|
||||
private function addParameterMapping(ExpressionCompiler $compiler)
|
||||
{
|
||||
$name = $compiler->nextName();
|
||||
$indexName = $compiler->nextName();
|
||||
$paramName = $compiler->nextName();
|
||||
|
||||
$compiler
|
||||
->setAttribute('parameter_mapping_name', $name)
|
||||
->writeln("\$$name = array();")
|
||||
->write("foreach (")
|
||||
->compileInternal(new VariableExpression('object'))
|
||||
->writeln("->reflection->getParameters() as \$$indexName => \$$paramName) {")
|
||||
->indent()
|
||||
->writeln("\${$name}[\${$paramName}->name] = \$$indexName;")
|
||||
->outdent()
|
||||
->writeln("}\n")
|
||||
;
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ExpressionInterface;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler;
|
||||
|
||||
interface TypeCompilerInterface
|
||||
{
|
||||
function getType();
|
||||
function compilePreconditions(ExpressionCompiler $compiler, ExpressionInterface $expr);
|
||||
function compile(ExpressionCompiler $compiler, ExpressionInterface $expr);
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ExpressionInterface;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler;
|
||||
|
||||
class VariableExpressionCompiler implements TypeCompilerInterface
|
||||
{
|
||||
public function getType()
|
||||
{
|
||||
return 'JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression';
|
||||
}
|
||||
|
||||
public function compilePreconditions(ExpressionCompiler $compiler, ExpressionInterface $expr)
|
||||
{
|
||||
if ('user' === $expr->name) {
|
||||
$compiler
|
||||
->setAttribute('user_var_name', $name = $compiler->nextName())
|
||||
->write("\$$name = ")
|
||||
->compileInternal(new VariableExpression('token'))
|
||||
->write("->getUser();\n\n")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
public function compile(ExpressionCompiler $compiler, ExpressionInterface $expr)
|
||||
{
|
||||
if ('permitAll' === $expr->name) {
|
||||
$compiler->write('true');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ('denyAll' === $expr->name) {
|
||||
$compiler->write('false');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ('user' === $expr->name) {
|
||||
$compiler->write("\${$compiler->attributes['user_var_name']}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($expr->allowNull) {
|
||||
$compiler->write("(isset(\$context['{$expr->name}']) ? ");
|
||||
}
|
||||
|
||||
$compiler->write("\$context['{$expr->name}']");
|
||||
|
||||
if ($expr->allowNull) {
|
||||
$compiler->write(" : null)");
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionHandlerInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Lazy-loading container aware expression handler.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ContainerAwareExpressionHandler implements ExpressionHandlerInterface
|
||||
{
|
||||
private $container;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
public function createContext(TokenInterface $token, $object)
|
||||
{
|
||||
return array(
|
||||
'container' => $this->container,
|
||||
'token' => $token,
|
||||
'object' => $object,
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression;
|
||||
|
||||
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
class DefaultExpressionHandler implements ExpressionHandlerInterface
|
||||
{
|
||||
private $trustResolver;
|
||||
private $roleHierarchy;
|
||||
|
||||
public function __construct(AuthenticationTrustResolverInterface $trustResolver,
|
||||
RoleHierarchyInterface $roleHierarchy = null)
|
||||
{
|
||||
$this->trustResolver = $trustResolver;
|
||||
$this->roleHierarchy = $roleHierarchy;
|
||||
}
|
||||
|
||||
public function createContext(TokenInterface $token, $object)
|
||||
{
|
||||
$context = array(
|
||||
'token' => $token,
|
||||
'object' => $object,
|
||||
'trust_resolver' => $this->trustResolver,
|
||||
);
|
||||
|
||||
if (null !== $this->roleHierarchy) {
|
||||
$context['role_hierarchy'] = $this->roleHierarchy;
|
||||
}
|
||||
|
||||
return $context;
|
||||
}
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression;
|
||||
|
||||
final class Expression
|
||||
{
|
||||
/** READ-ONLY */
|
||||
public $expression;
|
||||
|
||||
public function __construct($expression)
|
||||
{
|
||||
$this->expression = $expression;
|
||||
}
|
||||
|
||||
public function getHashCode()
|
||||
{
|
||||
return sha1($this->expression);
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return 'EXPRESSION('.$this->expression.')';
|
||||
}
|
||||
}
|
@@ -0,0 +1,395 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression;
|
||||
|
||||
use JMS\SecurityExtraBundle\Exception\RuntimeException;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\TypeCompilerInterface;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\IsEqualExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Compiler\Func\FunctionCompilerInterface;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ExpressionInterface;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\OrExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\MethodCallExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\GetPropertyExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\GetItemExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ConstantExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ArrayExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\AndExpression;
|
||||
|
||||
class ExpressionCompiler
|
||||
{
|
||||
public $attributes = array();
|
||||
|
||||
private $indentationLevel = 0;
|
||||
private $indentationSpaces = 4;
|
||||
|
||||
private $nameCount = 0;
|
||||
private $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
private $charCount = 52;
|
||||
private $reservedNames = array('context' => true);
|
||||
|
||||
private $itemExists = array();
|
||||
private $itemType = array();
|
||||
private $rolesName;
|
||||
|
||||
private $code;
|
||||
private $parser;
|
||||
private $typeCompilers;
|
||||
private $functionCompilers;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->addTypeCompiler(new Compiler\AndExpressionCompiler());
|
||||
$this->addTypeCompiler(new Compiler\IsEqualExpressionCompiler());
|
||||
$this->addTypeCompiler(new Compiler\OrExpressionCompiler());
|
||||
$this->addTypeCompiler(new Compiler\VariableExpressionCompiler());
|
||||
$this->addTypeCompiler(new Compiler\NotExpressionCompiler());
|
||||
|
||||
$this->functionCompilers = array(
|
||||
'isAnonymous' => new Compiler\Func\IsAnonymousFunctionCompiler(),
|
||||
'isAuthenticated' => new Compiler\Func\IsAuthenticatedFunctionCompiler(),
|
||||
'isRememberMe' => new Compiler\Func\IsRememberMeFunctionCompiler(),
|
||||
'isFullyAuthenticated' => new Compiler\Func\IsFullyAuthenticatedFunctionCompiler(),
|
||||
'hasRole' => new Compiler\Func\HasRoleFunctionCompiler(),
|
||||
'hasAnyRole' => new Compiler\Func\HasAnyRoleFunctionCompiler(),
|
||||
);
|
||||
}
|
||||
|
||||
public function setAttribute($name, $value)
|
||||
{
|
||||
$this->attributes[$name] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addTypeCompiler(TypeCompilerInterface $compiler)
|
||||
{
|
||||
$this->typeCompilers[$compiler->getType()] = $compiler;
|
||||
}
|
||||
|
||||
public function addFunctionCompiler(FunctionCompilerInterface $compiler)
|
||||
{
|
||||
$this->functionCompilers[$compiler->getName()] = $compiler;
|
||||
}
|
||||
|
||||
public function compileExpression(Expression $expr)
|
||||
{
|
||||
return $this->compile($this->getParser()->parse($expr->expression),
|
||||
$expr->expression);
|
||||
}
|
||||
|
||||
public function compile(ExpressionInterface $expr, $raw = null)
|
||||
{
|
||||
$this->nameCount = 0;
|
||||
$this->code = '';
|
||||
$this->itemExists = $this->itemType = $this->attributes = array();
|
||||
$this->rolesName = null;
|
||||
|
||||
if ($raw) {
|
||||
$this->writeln('// Expression: '.$raw);
|
||||
}
|
||||
|
||||
$this
|
||||
->writeln('return function(array $context) {')
|
||||
->indent()
|
||||
->compilePreconditions($expr)
|
||||
->write('return ')
|
||||
->compileInternal($expr)
|
||||
->writeln(';')
|
||||
->outdent()
|
||||
->writeln('};')
|
||||
;
|
||||
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
public function indent()
|
||||
{
|
||||
$this->indentationLevel += 1;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function outdent()
|
||||
{
|
||||
$this->indentationLevel -= 1;
|
||||
|
||||
if ($this->indentationLevel < 0) {
|
||||
throw new RuntimeException('The identation level cannot be less than zero.');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function writeln($content)
|
||||
{
|
||||
$this->write($content."\n");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRolesExpr()
|
||||
{
|
||||
if (null !== $this->rolesName) {
|
||||
return '$'.$this->rolesName;
|
||||
}
|
||||
|
||||
$this->verifyItem('token', 'Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
|
||||
|
||||
$this->rolesName = $rolesName = $this->nextName();
|
||||
$hierarchyName = $this->nextName();
|
||||
$tmpName = $this->nextName();
|
||||
$this
|
||||
->writeln("\$$rolesName = \$context['token']->getRoles();")
|
||||
->write("if (null !== \$$hierarchyName = ")
|
||||
->compileInternal(new VariableExpression('role_hierarchy', true))
|
||||
->writeln(") {")
|
||||
->indent()
|
||||
->writeln("\$$rolesName = \${$hierarchyName}->getReachableRoles(\$$rolesName);")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
->writeln("\$$tmpName = array();")
|
||||
->writeln("foreach (\$$rolesName as \$role) {")
|
||||
->indent()
|
||||
->writeln("\${$tmpName}[\$role->getRole()] = true;")
|
||||
->outdent()
|
||||
->writeln("}")
|
||||
->write("\$$rolesName = \$$tmpName;\n\n")
|
||||
;
|
||||
|
||||
return '$'.$rolesName;
|
||||
}
|
||||
|
||||
public function verifyItem($key, $expectedType = null)
|
||||
{
|
||||
if (!isset($this->itemExists[$key])) {
|
||||
$this->itemExists[$key] = true;
|
||||
|
||||
$this
|
||||
->writeln("if (!isset(\$context['$key'])) {")
|
||||
->indent()
|
||||
->writeln("throw new RuntimeException('The context contains no item with key \"$key\".');")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
;
|
||||
}
|
||||
|
||||
if (null !== $expectedType) {
|
||||
if (isset($this->itemType[$key])) {
|
||||
if ($this->itemType[$key] !== $expectedType) {
|
||||
throw new RuntimeException(sprintf('Cannot verify that item "%s" is of type "%s" because it is already expected to be of type "%s".',
|
||||
$key, $expectedType, $this->itemType[$key]
|
||||
));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this
|
||||
->writeln("if (!\$context['$key'] instanceof $expectedType) {")
|
||||
->indent()
|
||||
->writeln("throw new RuntimeException(sprintf('The item \"$key\" is expected to be of type \"$expectedType\", but got \"%s\".', get_class(\$context['$key'])));")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function write($content)
|
||||
{
|
||||
$lines = explode("\n", $content);
|
||||
for ($i=0,$c=count($lines); $i<$c; $i++) {
|
||||
if ($this->indentationLevel > 0
|
||||
&& !empty($lines[$i])
|
||||
&& (empty($this->code) || "\n" === substr($this->code, -1))) {
|
||||
$this->code .= str_repeat(' ', $this->indentationLevel * $this->indentationSpaces);
|
||||
}
|
||||
|
||||
$this->code .= $lines[$i];
|
||||
|
||||
if ($i+1 < $c) {
|
||||
$this->code .= "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function nextName()
|
||||
{
|
||||
while (true) {
|
||||
$name = '';
|
||||
$i = $this->nameCount;
|
||||
|
||||
$name .= $this->chars[$i % $this->charCount];
|
||||
$i = intval($i / $this->charCount);
|
||||
|
||||
while ($i > 0) {
|
||||
$i -= 1;
|
||||
$name .= $this->chars[$i % $this->charCount];
|
||||
$i = intval($i / $this->charCount);
|
||||
}
|
||||
|
||||
$this->nameCount += 1;
|
||||
|
||||
// check that the name is not reserved
|
||||
if (isset($this->reservedNames[$name])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
|
||||
public function compilePreconditions(ExpressionInterface $expr)
|
||||
{
|
||||
if ($typeCompiler = $this->findTypeCompiler(get_class($expr))) {
|
||||
$typeCompiler->compilePreconditions($this, $expr);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($expr instanceof FunctionExpression) {
|
||||
$this->getFunctionCompiler($expr->name)->compilePreconditions($this, $expr);
|
||||
|
||||
foreach ($expr->args as $arg) {
|
||||
$this->compilePreconditions($arg);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($expr instanceof VariableExpression) {
|
||||
$this->getVariableCompiler($expr->name)->compilePreconditions($this, $expr);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($expr instanceof MethodCallExpression) {
|
||||
$this->compilePreconditions($expr->object);
|
||||
|
||||
foreach ($expr->args as $arg) {
|
||||
$this->compilePreconditions($arg);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($expr instanceof GetPropertyExpression) {
|
||||
$this->compilePreconditions($expr->object);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function compileInternal(ExpressionInterface $expr)
|
||||
{
|
||||
if ($typeCompiler = $this->findTypeCompiler(get_class($expr))) {
|
||||
$typeCompiler->compile($this, $expr);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($expr instanceof ArrayExpression) {
|
||||
$this->code .= 'array(';
|
||||
foreach ($expr->elements as $key => $value) {
|
||||
$this->code .= var_export($key, true).' => ';
|
||||
$this->compileInternal($value);
|
||||
$this->code .= ',';
|
||||
}
|
||||
$this->code .= ')';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($expr instanceof ConstantExpression) {
|
||||
$this->code .= var_export($expr->value, true);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($expr instanceof FunctionExpression) {
|
||||
$this->getFunctionCompiler($expr->name)->compile($this, $expr);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($expr instanceof GetItemExpression) {
|
||||
$this->compileInternal($expr->array);
|
||||
$this->code .= '['.$expr->key.']';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($expr instanceof GetPropertyExpression) {
|
||||
$this->compileInternal($expr->object);
|
||||
$this->code .= '->'.$expr->name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($expr instanceof MethodCallExpression) {
|
||||
$this->compileInternal($expr->object);
|
||||
$this->code .= '->'.$expr->method.'(';
|
||||
|
||||
$first = true;
|
||||
foreach ($expr->args as $arg) {
|
||||
if (!$first) {
|
||||
$this->code .= ', ';
|
||||
}
|
||||
$first = false;
|
||||
|
||||
$this->compileInternal($arg);
|
||||
}
|
||||
$this->code .= ')';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf('Unknown expression "%s".', get_class($expr)));
|
||||
}
|
||||
|
||||
public function getFunctionCompiler($name)
|
||||
{
|
||||
if (!isset($this->functionCompilers[$name])) {
|
||||
throw new RuntimeException(sprintf('There is no compiler for function "%s".', $name));
|
||||
}
|
||||
|
||||
return $this->functionCompilers[$name];
|
||||
}
|
||||
|
||||
private function findTypeCompiler($type)
|
||||
{
|
||||
return isset($this->typeCompilers[$type]) ? $this->typeCompilers[$type] : null;
|
||||
}
|
||||
|
||||
private function getParser()
|
||||
{
|
||||
if (null !== $this->parser) {
|
||||
return $this->parser;
|
||||
}
|
||||
|
||||
return $this->parser = new ExpressionParser();
|
||||
}
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
interface ExpressionHandlerInterface
|
||||
{
|
||||
function createContext(TokenInterface $token, $object);
|
||||
}
|
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression;
|
||||
|
||||
use JMS\SecurityExtraBundle\Exception\InvalidArgumentException;
|
||||
|
||||
final class ExpressionLexer
|
||||
{
|
||||
public $token;
|
||||
public $lookahead;
|
||||
|
||||
private $tokens;
|
||||
private $pointer;
|
||||
|
||||
const T_STRING = 1;
|
||||
const T_IDENTIFIER = 2;
|
||||
const T_NONE = 3;
|
||||
const T_COMMA = 4;
|
||||
const T_OPEN_PARENTHESIS = 5;
|
||||
const T_CLOSE_PARENTHESIS = 6;
|
||||
const T_AND = 7;
|
||||
const T_OR = 8;
|
||||
const T_PARAMETER = 9;
|
||||
const T_OBJECT_OPERATOR = 10;
|
||||
const T_OPEN_BRACKET = 11;
|
||||
const T_CLOSE_BRACKET = 12;
|
||||
const T_OPEN_BRACE = 13;
|
||||
const T_CLOSE_BRACE = 14;
|
||||
const T_COLON = 15;
|
||||
const T_IS_EQUAL = 16;
|
||||
const T_NOT = 17;
|
||||
|
||||
public static function getLiteral($type)
|
||||
{
|
||||
static $constants;
|
||||
|
||||
if (null === $constants) {
|
||||
$ref = new \ReflectionClass(get_called_class());
|
||||
$constants = $ref->getConstants();
|
||||
}
|
||||
|
||||
if (false === $literal = array_search($type, $constants, true)) {
|
||||
throw new InvalidArgumentException(sprintf('There is no token of value "%s".', $type));
|
||||
}
|
||||
|
||||
return $literal;
|
||||
}
|
||||
|
||||
public function initialize($input)
|
||||
{
|
||||
static $pattern = '/(#?[a-z][a-z0-9]*|\'(?:[^\']|(?<=\\\\)\')*\'|"(?:[^"]|(?<=\\\\)")*"|&&|\|\||==)|\s+|(.)/i';
|
||||
|
||||
$parts = preg_split($pattern, $input, -1, PREG_SPLIT_OFFSET_CAPTURE
|
||||
| PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
$tokens = array();
|
||||
foreach ($parts as $part) {
|
||||
list($value, $position) = $part;
|
||||
$type = self::T_NONE;
|
||||
|
||||
if ("'" === $value[0] || '"' === $value[0]) {
|
||||
$type = self::T_STRING;
|
||||
$value = substr($value, 1, -1);
|
||||
} else if (',' === $value) {
|
||||
$type = self::T_COMMA;
|
||||
} else if ('(' === $value) {
|
||||
$type = self::T_OPEN_PARENTHESIS;
|
||||
} else if (')' === $value) {
|
||||
$type = self::T_CLOSE_PARENTHESIS;
|
||||
} else if ('[' === $value) {
|
||||
$type = self::T_OPEN_BRACKET;
|
||||
} else if (']' === $value) {
|
||||
$type = self::T_CLOSE_BRACKET;
|
||||
} else if ('{' === $value) {
|
||||
$type = self::T_OPEN_BRACE;
|
||||
} else if ('}' === $value) {
|
||||
$type = self::T_CLOSE_BRACE;
|
||||
} else if ('&&' === $value || 'and' === strtolower($value)) {
|
||||
$type = self::T_AND;
|
||||
} else if ('||' === $value || 'or' === strtolower($value)) {
|
||||
$type = self::T_OR;
|
||||
} else if ('!' === $value || 'not' === strtolower($value)) {
|
||||
$type = self::T_NOT;
|
||||
} else if (':' === $value) {
|
||||
$type = self::T_COLON;
|
||||
} else if ('.' === $value) {
|
||||
$type = self::T_OBJECT_OPERATOR;
|
||||
} else if ('==' === $value) {
|
||||
$type = self::T_IS_EQUAL;
|
||||
} else if ('#' === $value[0]) {
|
||||
$type = self::T_PARAMETER;
|
||||
$value = substr($value, 1);
|
||||
} else if (ctype_alpha($value)) {
|
||||
$type = self::T_IDENTIFIER;
|
||||
}
|
||||
|
||||
$tokens[] = array(
|
||||
'type' => $type,
|
||||
'value' => $value,
|
||||
'position' => $position,
|
||||
);
|
||||
}
|
||||
|
||||
$this->tokens = $tokens;
|
||||
$this->pointer = -1;
|
||||
$this->next();
|
||||
}
|
||||
|
||||
public function next()
|
||||
{
|
||||
$this->pointer += 1;
|
||||
$this->token = $this->lookahead;
|
||||
$this->lookahead = isset($this->tokens[$this->pointer]) ?
|
||||
$this->tokens[$this->pointer] : null;
|
||||
|
||||
return $this->lookahead !== null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,290 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\NotExpression;
|
||||
|
||||
use JMS\SecurityExtraBundle\Exception\RuntimeException;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\IsEqualExpression;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ParameterExpression;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\VariableExpression;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ConstantExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\OrExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\AndExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ArrayExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\GetItemExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\GetPropertyExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\MethodCallExpression;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\ExpressionInterface;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast\FunctionExpression;
|
||||
|
||||
final class ExpressionParser
|
||||
{
|
||||
const PRECEDENCE_OR = 10;
|
||||
const PRECEDENCE_AND = 15;
|
||||
const PRECEDENCE_IS_EQUAL = 20;
|
||||
const PRECEDENCE_NOT = 30;
|
||||
|
||||
private $lexer;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->lexer = new ExpressionLexer();
|
||||
}
|
||||
|
||||
public function parse($str)
|
||||
{
|
||||
$this->lexer->initialize($str);
|
||||
|
||||
return $this->Expression();
|
||||
}
|
||||
|
||||
private function Expression($precedence = 0)
|
||||
{
|
||||
$expr = $this->Primary();
|
||||
|
||||
while (true) {
|
||||
if (ExpressionLexer::T_AND === $this->lexer->lookahead['type']
|
||||
&& $precedence <= self::PRECEDENCE_AND) {
|
||||
$this->lexer->next();
|
||||
|
||||
$expr = new AndExpression($expr, $this->Expression(
|
||||
self::PRECEDENCE_AND + 1));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ExpressionLexer::T_OR === $this->lexer->lookahead['type']
|
||||
&& $precedence <= self::PRECEDENCE_OR) {
|
||||
$this->lexer->next();
|
||||
|
||||
$expr = new OrExpression($expr, $this->Expression(
|
||||
self::PRECEDENCE_OR + 1));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ExpressionLexer::T_IS_EQUAL === $this->lexer->lookahead['type']
|
||||
&& $precedence <= self::PRECEDENCE_IS_EQUAL) {
|
||||
$this->lexer->next();
|
||||
|
||||
$expr = new IsEqualExpression($expr, $this->Expression(
|
||||
self::PRECEDENCE_IS_EQUAL + 1));
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return $expr;
|
||||
}
|
||||
|
||||
private function Primary()
|
||||
{
|
||||
if (ExpressionLexer::T_NOT === $this->lexer->lookahead['type']) {
|
||||
$this->lexer->next();
|
||||
$expr = new NotExpression($this->Expression(self::PRECEDENCE_NOT));
|
||||
|
||||
return $this->Suffix($expr);
|
||||
}
|
||||
|
||||
if (ExpressionLexer::T_OPEN_PARENTHESIS === $this->lexer->lookahead['type']) {
|
||||
$this->lexer->next();
|
||||
$expr = $this->Expression();
|
||||
$this->match(ExpressionLexer::T_CLOSE_PARENTHESIS);
|
||||
|
||||
return $this->Suffix($expr);
|
||||
}
|
||||
|
||||
if (ExpressionLexer::T_STRING === $this->lexer->lookahead['type']) {
|
||||
return new ConstantExpression($this->match(ExpressionLexer::T_STRING));
|
||||
}
|
||||
|
||||
if (ExpressionLexer::T_OPEN_BRACE === $this->lexer->lookahead['type']) {
|
||||
return $this->Suffix($this->MapExpr());
|
||||
}
|
||||
|
||||
if (ExpressionLexer::T_OPEN_BRACKET === $this->lexer->lookahead['type']) {
|
||||
return $this->Suffix($this->ListExpr());
|
||||
}
|
||||
|
||||
if (ExpressionLexer::T_IDENTIFIER === $this->lexer->lookahead['type']) {
|
||||
$name = $this->match(ExpressionLexer::T_IDENTIFIER);
|
||||
|
||||
if (ExpressionLexer::T_OPEN_PARENTHESIS === $this->lexer->lookahead['type']) {
|
||||
$args = $this->Arguments();
|
||||
|
||||
return $this->Suffix(new FunctionExpression($name, $args));
|
||||
}
|
||||
|
||||
return $this->Suffix(new VariableExpression($name));
|
||||
}
|
||||
|
||||
if (ExpressionLexer::T_PARAMETER === $this->lexer->lookahead['type']) {
|
||||
return $this->Suffix(new ParameterExpression($this->match(ExpressionLexer::T_PARAMETER)));
|
||||
}
|
||||
|
||||
$this->error('primary expression');
|
||||
}
|
||||
|
||||
private function ListExpr()
|
||||
{
|
||||
$this->match(ExpressionLexer::T_OPEN_BRACKET);
|
||||
|
||||
$elements = array();
|
||||
while (ExpressionLexer::T_CLOSE_BRACKET !== $this->lexer->lookahead['type']) {
|
||||
$elements[] = $this->Expression();
|
||||
|
||||
if (ExpressionLexer::T_COMMA !== $this->lexer->lookahead['type']) {
|
||||
break;
|
||||
}
|
||||
$this->lexer->next();
|
||||
}
|
||||
|
||||
$this->match(ExpressionLexer::T_CLOSE_BRACKET);
|
||||
|
||||
return new ArrayExpression($elements);
|
||||
}
|
||||
|
||||
private function MapExpr()
|
||||
{
|
||||
$this->match(ExpressionLexer::T_OPEN_BRACE);
|
||||
|
||||
$entries = array();
|
||||
while (ExpressionLexer::T_CLOSE_BRACE !== $this->lexer->lookahead['type']) {
|
||||
$key = $this->match(ExpressionLexer::T_STRING);
|
||||
$this->match(ExpressionLexer::T_COLON);
|
||||
$entries[$key] = $this->Expression();
|
||||
|
||||
if (ExpressionLexer::T_COMMA !== $this->lexer->lookahead['type']) {
|
||||
break;
|
||||
}
|
||||
|
||||
$this->lexer->next();
|
||||
}
|
||||
|
||||
$this->match(ExpressionLexer::T_CLOSE_BRACE);
|
||||
|
||||
return new ArrayExpression($entries);
|
||||
}
|
||||
|
||||
private function Suffix(ExpressionInterface $expr)
|
||||
{
|
||||
while (true) {
|
||||
if (ExpressionLexer::T_OBJECT_OPERATOR === $this->lexer->lookahead['type']) {
|
||||
$this->lexer->next();
|
||||
$name = $this->match(ExpressionLexer::T_IDENTIFIER);
|
||||
|
||||
if (ExpressionLexer::T_OPEN_PARENTHESIS === $this->lexer->lookahead['type']) {
|
||||
$args = $this->Arguments();
|
||||
$expr = new MethodCallExpression($expr, $name, $args);
|
||||
continue;
|
||||
}
|
||||
|
||||
$expr = new GetPropertyExpression($expr, $name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ExpressionLexer::T_OPEN_BRACKET === $this->lexer->lookahead['type']) {
|
||||
$this->lexer->next();
|
||||
$key = $this->Expression();
|
||||
$this->match(ExpressionLexer::T_CLOSE_BRACKET);
|
||||
$expr = new GetItemExpression($expr, $key);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return $expr;
|
||||
}
|
||||
|
||||
private function FunctionCall()
|
||||
{
|
||||
$name = $this->match(ExpressionLexer::T_IDENTIFIER);
|
||||
$args = $this->Arguments();
|
||||
|
||||
return new FunctionExpression($name, $args);
|
||||
}
|
||||
|
||||
private function Arguments()
|
||||
{
|
||||
$this->match(ExpressionLexer::T_OPEN_PARENTHESIS);
|
||||
$args = array();
|
||||
|
||||
while (ExpressionLexer::T_CLOSE_PARENTHESIS !== $this->lexer->lookahead['type']) {
|
||||
$args[] = $this->Expression();
|
||||
|
||||
if (ExpressionLexer::T_COMMA !== $this->lexer->lookahead['type']) {
|
||||
break;
|
||||
}
|
||||
|
||||
$this->match(ExpressionLexer::T_COMMA);
|
||||
}
|
||||
$this->match(ExpressionLexer::T_CLOSE_PARENTHESIS);
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
private function Value()
|
||||
{
|
||||
return $this->matchAny(array(ExpressionLexer::T_STRING));
|
||||
}
|
||||
|
||||
private function matchAny(array $types)
|
||||
{
|
||||
if (null !== $this->lexer->lookahead) {
|
||||
foreach ($types as $type) {
|
||||
if ($type === $this->lexer->lookahead['type']) {
|
||||
$this->lexer->next();
|
||||
|
||||
return $this->lexer->token['value'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->error(sprintf('one of these tokens "%s"',
|
||||
implode('", "', array_map(array('JMS\SecurityExtraBundle\Security\Authorization\Expression\Lexer', 'getLiteral'), $types))
|
||||
));
|
||||
}
|
||||
|
||||
private function match($type)
|
||||
{
|
||||
if (null === $this->lexer->lookahead
|
||||
|| $type !== $this->lexer->lookahead['type']) {
|
||||
$this->error(sprintf('token "%s"', ExpressionLexer::getLiteral($type)));
|
||||
}
|
||||
|
||||
$this->lexer->next();
|
||||
|
||||
return $this->lexer->token['value'];
|
||||
}
|
||||
|
||||
private function error($expected)
|
||||
{
|
||||
$actual = null === $this->lexer->lookahead ? 'end of file'
|
||||
: sprintf('token "%s" with value "%s" at position %d',
|
||||
ExpressionLexer::getLiteral($this->lexer->lookahead['type']),
|
||||
$this->lexer->lookahead['value'],
|
||||
$this->lexer->lookahead['position']);
|
||||
|
||||
throw new RuntimeException(sprintf('Expected %s, but got %s.', $expected, $actual));
|
||||
}
|
||||
}
|
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression;
|
||||
|
||||
use JMS\SecurityExtraBundle\Exception\RuntimeException;
|
||||
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
|
||||
/**
|
||||
* Expression-based voter.
|
||||
*
|
||||
* This voter allows to use complex access expression in a high-performance
|
||||
* way. This is the preferred voter for any non-simple access checks.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ExpressionVoter implements VoterInterface
|
||||
{
|
||||
private $evaluators = array();
|
||||
private $compiler;
|
||||
private $cacheDir;
|
||||
private $expressionHandler;
|
||||
|
||||
public function __construct(ExpressionHandlerInterface $expressionHandler) {
|
||||
$this->expressionHandler = $expressionHandler;
|
||||
}
|
||||
|
||||
public function setCacheDir($cacheDir)
|
||||
{
|
||||
$this->cacheDir = $cacheDir;
|
||||
}
|
||||
|
||||
public function setCompiler(ExpressionCompiler $compiler)
|
||||
{
|
||||
$this->compiler = $compiler;
|
||||
}
|
||||
|
||||
public function vote(TokenInterface $token, $object, array $attributes)
|
||||
{
|
||||
$result = VoterInterface::ACCESS_ABSTAIN;
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
if (!$attribute instanceof Expression) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result = VoterInterface::ACCESS_DENIED;
|
||||
if (!isset($this->evaluators[$attribute->expression])) {
|
||||
$this->evaluators[$attribute->expression] =
|
||||
$this->createEvaluator($attribute);
|
||||
}
|
||||
|
||||
if (call_user_func($this->evaluators[$attribute->expression],
|
||||
$this->expressionHandler->createContext($token, $object))) {
|
||||
return VoterInterface::ACCESS_GRANTED;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function supportsAttribute($attribute)
|
||||
{
|
||||
return $attribute instanceof Expression;
|
||||
}
|
||||
|
||||
public function supportsClass($class)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getCompiler()
|
||||
{
|
||||
if (null === $this->compiler) {
|
||||
throw new RuntimeException('A compiler must be set.');
|
||||
}
|
||||
|
||||
return $this->compiler;
|
||||
}
|
||||
|
||||
private function createEvaluator(Expression $expr)
|
||||
{
|
||||
if ($this->cacheDir) {
|
||||
if (is_file($file = $this->cacheDir.'/'.sha1($expr->expression).'.php')) {
|
||||
return require $file;
|
||||
}
|
||||
|
||||
$source = $this->getCompiler()->compileExpression($expr);
|
||||
file_put_contents($file, "<?php\n".$source);
|
||||
|
||||
return require $file;
|
||||
}
|
||||
|
||||
return eval($this->getCompiler()->compileExpression($expr));
|
||||
}
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Expression;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionVoter;
|
||||
|
||||
class LazyLoadingExpressionVoter extends ExpressionVoter
|
||||
{
|
||||
private $container;
|
||||
private $compilerId;
|
||||
|
||||
public function setLazyCompiler(ContainerInterface $container, $id)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->compilerId = $id;
|
||||
}
|
||||
|
||||
protected function getCompiler()
|
||||
{
|
||||
return $this->container->get($this->compilerId);
|
||||
}
|
||||
}
|
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Interception;
|
||||
|
||||
use JMS\SecurityExtraBundle\Exception\RuntimeException;
|
||||
use CG\Core\ClassUtils;
|
||||
|
||||
use CG\Proxy\MethodInterceptorInterface;
|
||||
use CG\Proxy\MethodInvocation;
|
||||
use JMS\SecurityExtraBundle\Metadata\MethodMetadata;
|
||||
use JMS\SecurityExtraBundle\Security\Authentication\Token\RunAsUserToken;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\AfterInvocation\AfterInvocationManagerInterface;
|
||||
use JMS\SecurityExtraBundle\Security\Authorization\RunAsManagerInterface;
|
||||
use Metadata\MetadataFactoryInterface;
|
||||
use Symfony\Component\HttpKernel\Log\LoggerInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
|
||||
use Symfony\Component\Security\Core\SecurityContext;
|
||||
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
|
||||
|
||||
/**
|
||||
* All invocations of secure methods will go through this class.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class MethodSecurityInterceptor implements MethodInterceptorInterface
|
||||
{
|
||||
private $alwaysAuthenticate;
|
||||
private $securityContext;
|
||||
private $metadataFactory;
|
||||
private $authenticationManager;
|
||||
private $accessDecisionManager;
|
||||
private $afterInvocationManager;
|
||||
private $runAsManager;
|
||||
private $logger;
|
||||
|
||||
public function __construct(SecurityContext $securityContext, AuthenticationManagerInterface $authenticationManager, AccessDecisionManagerInterface $accessDecisionManager,
|
||||
AfterInvocationManagerInterface $afterInvocationManager, RunAsManagerInterface $runAsManager, MetadataFactoryInterface $metadataFactory, LoggerInterface $logger = null)
|
||||
{
|
||||
$this->alwaysAuthenticate = false;
|
||||
$this->securityContext = $securityContext;
|
||||
$this->metadataFactory = $metadataFactory;
|
||||
$this->authenticationManager = $authenticationManager;
|
||||
$this->accessDecisionManager = $accessDecisionManager;
|
||||
$this->afterInvocationManager = $afterInvocationManager;
|
||||
$this->runAsManager = $runAsManager;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function setAlwaysAuthenticate($boolean)
|
||||
{
|
||||
$this->alwaysAuthenticate = !!$boolean;
|
||||
}
|
||||
|
||||
public function intercept(MethodInvocation $method)
|
||||
{
|
||||
$metadata = $this->metadataFactory->getMetadataForClass($method->reflection->class);
|
||||
|
||||
// no security metadata, proceed
|
||||
if (empty($metadata) || !isset($metadata->methodMetadata[$method->reflection->name])) {
|
||||
return $method->proceed();
|
||||
}
|
||||
$metadata = $metadata->methodMetadata[$method->reflection->name];
|
||||
|
||||
if (null === $token = $this->securityContext->getToken()) {
|
||||
throw new AuthenticationCredentialsNotFoundException(
|
||||
'The security context was not populated with a Token.'
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->alwaysAuthenticate || !$token->isAuthenticated()) {
|
||||
$token = $this->authenticationManager->authenticate($token);
|
||||
$this->securityContext->setToken($token);
|
||||
}
|
||||
|
||||
if (!empty($metadata->roles) && false === $this->accessDecisionManager->decide($token, $metadata->roles, $method)) {
|
||||
throw new AccessDeniedException('Token does not have the required roles.');
|
||||
}
|
||||
|
||||
if (!empty($metadata->paramPermissions)) {
|
||||
foreach ($method->arguments as $index => $argument) {
|
||||
if (null !== $argument && isset($metadata->paramPermissions[$index]) && false === $this->accessDecisionManager->decide($token, $metadata->paramPermissions[$index], $argument)) {
|
||||
throw new AccessDeniedException(sprintf('Token does not have the required permissions for method "%s::%s".', $method->reflection->class, $method->reflection->name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$runAsToken = null;
|
||||
if (!empty($metadata->runAsRoles)) {
|
||||
$runAsToken = $this->runAsManager->buildRunAs($token, $method, $metadata->runAsRoles);
|
||||
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('Populating security context with RunAsToken');
|
||||
}
|
||||
|
||||
if (null === $runAsToken) {
|
||||
throw new RuntimeException('RunAsManager must not return null from buildRunAs().');
|
||||
}
|
||||
|
||||
$this->securityContext->setToken($runAsToken);
|
||||
}
|
||||
|
||||
try {
|
||||
$returnValue = $method->proceed();
|
||||
|
||||
if (null !== $runAsToken) {
|
||||
$this->restoreOriginalToken($runAsToken);
|
||||
}
|
||||
|
||||
if (empty($metadata->returnPermissions)) {
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
return $this->afterInvocationManager->decide($this->securityContext->getToken(), $method, $metadata->returnPermissions, $returnValue);
|
||||
} catch (\Exception $failed) {
|
||||
if (null !== $runAsToken) {
|
||||
$this->restoreOriginalToken($runAsToken);
|
||||
}
|
||||
|
||||
throw $failed;
|
||||
}
|
||||
}
|
||||
|
||||
private function restoreOriginalToken(RunAsUserToken $runAsToken)
|
||||
{
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('Populating security context with original Token.');
|
||||
}
|
||||
|
||||
$this->securityContext->setToken($runAsToken->getOriginalToken());
|
||||
}
|
||||
}
|
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Interception;
|
||||
|
||||
use CG\Core\ClassUtils;
|
||||
use Metadata\MetadataFactoryInterface;
|
||||
use JMS\AopBundle\Aop\PointcutInterface;
|
||||
|
||||
class SecurityPointcut implements PointcutInterface
|
||||
{
|
||||
private $metadataFactory;
|
||||
private $secureAllServices;
|
||||
private $securedClasses = array();
|
||||
private $patterns;
|
||||
|
||||
public function __construct(MetadataFactoryInterface $metadataFactory, $secureAllServices = false, array $patterns = array())
|
||||
{
|
||||
$this->metadataFactory = $metadataFactory;
|
||||
$this->secureAllServices = $secureAllServices;
|
||||
$this->patterns = $patterns;
|
||||
}
|
||||
|
||||
public function setSecuredClasses(array $classes)
|
||||
{
|
||||
$this->securedClasses = $classes;
|
||||
}
|
||||
|
||||
public function matchesClass(\ReflectionClass $class)
|
||||
{
|
||||
if ($this->secureAllServices) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ('Controller' === substr(ClassUtils::getUserClass($class->name), -10)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($this->patterns as $pattern => $expr) {
|
||||
// if not for all patterns the class is specified, then we need to scan all
|
||||
// classes to catch all methods
|
||||
if (false === $pos = strpos($pattern, '::')) {
|
||||
// controller notation is already checked by JMSDiExtraBundle,
|
||||
// we can safely ignore these patterns here
|
||||
if (2 === substr_count($pattern, ':')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (0 < preg_match('#'.substr($pattern, 0, $pos).'$#', $class->name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->securedClasses as $securedClass) {
|
||||
if ($class->name === $securedClass || $class->isSubclassOf($securedClass)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function matchesMethod(\ReflectionMethod $method)
|
||||
{
|
||||
$userClass = ClassUtils::getUserClass($method->class);
|
||||
$metadata = $this->metadataFactory->getMetadataForClass($userClass);
|
||||
|
||||
if (null === $metadata) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isset($metadata->methodMetadata[$method->name]);
|
||||
}
|
||||
}
|
79
vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/RunAsManager.php
vendored
Normal file
79
vendor/jms/security-extra-bundle/JMS/SecurityExtraBundle/Security/Authorization/RunAsManager.php
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization;
|
||||
|
||||
use JMS\SecurityExtraBundle\Security\Authentication\Token\RunAsUserToken;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
/**
|
||||
* The RunAsManager creates throw-away Tokens which are temporarily injected into
|
||||
* the security context for the duration of the invocation of a specific method.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class RunAsManager implements RunAsManagerInterface
|
||||
{
|
||||
private $key;
|
||||
private $rolePrefix;
|
||||
|
||||
public function __construct($key, $rolePrefix = 'ROLE_')
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->rolePrefix = $rolePrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function buildRunAs(TokenInterface $token, $secureObject, array $attributes)
|
||||
{
|
||||
$roles = array();
|
||||
foreach ($attributes as $attribute)
|
||||
{
|
||||
if ($this->supportsAttribute($attribute)) {
|
||||
$roles[] = new Role($attribute);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 === count($roles)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$roles = array_merge($roles, $token->getRoles());
|
||||
|
||||
return new RunAsUserToken($this->key, $token->getUser(), $token->getCredentials(), $roles, $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsAttribute($attribute)
|
||||
{
|
||||
return !empty($attribute) && 0 === strpos($attribute, $this->rolePrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsClass($className)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
/**
|
||||
* RunAsManagerInterface
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
interface RunAsManagerInterface
|
||||
{
|
||||
/**
|
||||
* Creates a temporary RunAsToken.
|
||||
*
|
||||
* The returned Token must have a complementing AuthenticationProvider implementation.
|
||||
*
|
||||
* @param TokenInterface $token the original Token
|
||||
* @param object $secureObject the secure object which caused this call
|
||||
* @param array $attributes an array of attributes to apply to the built token
|
||||
* @return TokenInterface
|
||||
*/
|
||||
function buildRunAs(TokenInterface $token, $secureObject, array $attributes);
|
||||
|
||||
/**
|
||||
* Whether this RunAsManager supports the given attribute
|
||||
*
|
||||
* @param string $attribute
|
||||
* @return Boolean
|
||||
*/
|
||||
function supportsAttribute($attribute);
|
||||
|
||||
/**
|
||||
* Whether this RunAsManager supports the given class.
|
||||
*
|
||||
* @param string $className The class of the secure object which requests RunAs capabilities
|
||||
* @return Boolean
|
||||
*/
|
||||
function supportsClass($className);
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace JMS\SecurityExtraBundle\Security\Authorization\Voter;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
|
||||
/**
|
||||
* This voter adds a special role "ROLE_IDDQD" which effectively bypasses any,
|
||||
* and all security checks.
|
||||
*
|
||||
* Most of the time, you will want to use this rule in combination with a
|
||||
* @RunAs annotation to disable security checks for the invocation of a
|
||||
* specific method.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class IddqdVoter implements VoterInterface
|
||||
{
|
||||
public function vote(TokenInterface $token, $object, array $attributes)
|
||||
{
|
||||
return $this->isIddqd($token) ? VoterInterface::ACCESS_GRANTED : VoterInterface::ACCESS_ABSTAIN;
|
||||
}
|
||||
|
||||
protected function isIddqd(TokenInterface $token)
|
||||
{
|
||||
foreach ($token->getRoles() as $role) {
|
||||
if ('ROLE_IDDQD' === $role->getRole()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function supportsAttribute($attribute)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function supportsClass($class)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user