summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavier Eguiluz <javier.eguiluz@gmail.com>2016-02-22 16:03:02 +0100
committerFabien Potencier <fabien.potencier@gmail.com>2016-03-04 08:25:17 +0100
commit3257616eceadff2599e5a06eaa0413d440fbaabc (patch)
tree2cca418d144c6c79d54ff5c034b649154d920986
parentf416b655ca311f84e32a4ac05be0da1e83763734 (diff)
downloadsymfony-security-3257616eceadff2599e5a06eaa0413d440fbaabc.zip
symfony-security-3257616eceadff2599e5a06eaa0413d440fbaabc.tar.gz
symfony-security-3257616eceadff2599e5a06eaa0413d440fbaabc.tar.bz2
Show more information in the security profiler
-rw-r--r--Core/Authorization/DebugAccessDecisionManager.php120
1 files changed, 120 insertions, 0 deletions
diff --git a/Core/Authorization/DebugAccessDecisionManager.php b/Core/Authorization/DebugAccessDecisionManager.php
new file mode 100644
index 0000000..de7ec4d
--- /dev/null
+++ b/Core/Authorization/DebugAccessDecisionManager.php
@@ -0,0 +1,120 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Security\Core\Authorization;
+
+use Doctrine\Common\Util\ClassUtils;
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+
+/**
+ * Decorates the original AccessDecisionManager class to log information
+ * about the security voters and the decisions made by them.
+ *
+ * @author Javier Eguiluz <javier.eguiluz@gmail.com>
+ *
+ * @internal
+ */
+class DebugAccessDecisionManager implements AccessDecisionManagerInterface
+{
+ private $manager;
+ private $strategy;
+ private $voters;
+ private $decisionLog = array();
+
+ public function __construct(AccessDecisionManager $manager)
+ {
+ $this->manager = $manager;
+
+ // The strategy is stored in a private property of the decorated service
+ $reflection = new \ReflectionProperty($manager, 'strategy');
+ $reflection->setAccessible(true);
+ $this->strategy = $reflection->getValue($manager);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function decide(TokenInterface $token, array $attributes, $object = null)
+ {
+ $result = $this->manager->decide($token, $attributes, $object);
+
+ $this->decisionLog[] = array(
+ 'attributes' => $attributes,
+ 'object' => $this->getStringRepresentation($object),
+ 'result' => $result,
+ );
+
+ return $result;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setVoters(array $voters)
+ {
+ $this->voters = $voters;
+ }
+
+ /**
+ * @return string
+ */
+ public function getStrategy()
+ {
+ // The $strategy property is misleading because it stores the name of its
+ // method (e.g. 'decideAffirmative') instead of the original strategy name
+ // (e.g. 'affirmative')
+ return strtolower(substr($this->strategy, 6));
+ }
+
+ /**
+ * @return array
+ */
+ public function getVoters()
+ {
+ return $this->voters;
+ }
+
+ /**
+ * @return array
+ */
+ public function getDecisionLog()
+ {
+ return $this->decisionLog;
+ }
+
+ /**
+ * @param mixed $object
+ *
+ * @return string
+ */
+ private function getStringRepresentation($object)
+ {
+ if (null === $object) {
+ return 'NULL';
+ }
+
+ if (!is_object($object)) {
+ return sprintf('%s (%s)', gettype($object), $object);
+ }
+
+ $objectClass = class_exists('Doctrine\Common\Util\ClassUtils') ? ClassUtils::getClass($object) : get_class($object);
+
+ if (method_exists($object, 'getId')) {
+ $objectAsString = sprintf('ID: %s', $object->getId());
+ } elseif (method_exists($object, '__toString')) {
+ $objectAsString = (string) $object;
+ } else {
+ $objectAsString = sprintf('object hash: %s', spl_object_hash($object));
+ }
+
+ return sprintf('%s (%s)', $objectClass, $objectAsString);
+ }
+}