Przeglądaj źródła

[Security] Allow authentication tokens to hold attributes

Jeremy Mikola 14 lat temu
rodzic
commit
b8d574087f

+ 65 - 2
src/Symfony/Component/Security/Core/Authentication/Token/Token.php

@@ -29,6 +29,7 @@ abstract class Token implements TokenInterface
     protected $credentials;
     protected $immutable;
     protected $providerKey;
+    protected $attributes;
 
     /**
      * Constructor.
@@ -40,6 +41,7 @@ abstract class Token implements TokenInterface
         $this->setRoles($roles);
         $this->authenticated = false;
         $this->immutable = false;
+        $this->attributes = array();
     }
 
     /**
@@ -193,7 +195,7 @@ abstract class Token implements TokenInterface
      */
     public function serialize()
     {
-        return serialize(array($this->user, $this->credentials, $this->authenticated, $this->roles, $this->immutable, $this->providerKey));
+        return serialize(array($this->user, $this->credentials, $this->authenticated, $this->roles, $this->immutable, $this->providerKey, $this->attributes));
     }
 
     /**
@@ -201,6 +203,67 @@ abstract class Token implements TokenInterface
      */
     public function unserialize($serialized)
     {
-        list($this->user, $this->credentials, $this->authenticated, $this->roles, $this->immutable, $this->providerKey) = unserialize($serialized);
+        list($this->user, $this->credentials, $this->authenticated, $this->roles, $this->immutable, $this->providerKey, $this->attributes) = unserialize($serialized);
+    }
+
+    /**
+     * Returns the token attributes.
+     *
+     * @return array The token attributes
+     */
+    public function getAttributes()
+    {
+        return $this->attributes;
+    }
+
+    /**
+     * Sets the token attributes.
+     *
+     * @param array $attributes The token attributes
+     */
+    public function setAttributes(array $attributes)
+    {
+        $this->attributes = $attributes;
+    }
+
+    /**
+     * Returns true if the attribute exists.
+     *
+     * @param  string  $name  The attribute name
+     *
+     * @return Boolean true if the attribute exists, false otherwise
+     */
+    public function hasAttribute($name)
+    {
+        return array_key_exists($name, $this->attributes);
+    }
+
+    /**
+     * Returns a attribute value.
+     *
+     * @param string $name The attribute name
+     *
+     * @return mixed The attribute value
+     *
+     * @throws \InvalidArgumentException When attribute doesn't exist for this token
+     */
+    public function getAttribute($name)
+    {
+        if (!array_key_exists($name, $this->attributes)) {
+            throw new \InvalidArgumentException(sprintf('This token has no "%s" attribute.', $name));
+        }
+
+        return $this->attributes[$name];
+    }
+
+    /**
+     * Sets a attribute.
+     *
+     * @param string $name  The attribute name
+     * @param mixed  $value The attribute value
+     */
+    public function setAttribute($name, $value)
+    {
+        $this->attributes[$name] = $value;
     }
 }

+ 42 - 0
src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php

@@ -99,4 +99,46 @@ interface TokenInterface extends \Serializable
      * Removes sensitive information from the token.
      */
     function eraseCredentials();
+
+    /**
+     * Returns the token attributes.
+     *
+     * @return array The token attributes
+     */
+    function getAttributes();
+
+    /**
+     * Sets the token attributes.
+     *
+     * @param array $attributes The token attributes
+     */
+    function setAttributes(array $attributes);
+
+    /**
+     * Returns true if the attribute exists.
+     *
+     * @param  string  $name  The attribute name
+     *
+     * @return Boolean true if the attribute exists, false otherwise
+     */
+    function hasAttribute($name);
+
+    /**
+     * Returns a attribute value.
+     *
+     * @param string $name The attribute name
+     *
+     * @return mixed The attribute value
+     *
+     * @throws \InvalidArgumentException When attribute doesn't exist for this token
+     */
+    function getAttribute($name);
+
+    /**
+     * Sets a attribute.
+     *
+     * @param string $name  The attribute name
+     * @param mixed  $value The attribute value
+     */
+    function setAttribute($name, $value);
 }

+ 34 - 0
tests/Symfony/Tests/Component/Security/Core/Authentication/Token/TokenTest.php

@@ -70,9 +70,14 @@ class TokenTest extends \PHPUnit_Framework_TestCase
         $token->eraseCredentials();
     }
 
+    /**
+     * @covers Symfony\Component\Security\Core\Authentication\Token\Token::serialize
+     * @covers Symfony\Component\Security\Core\Authentication\Token\Token::unserialize
+     */
     public function testSerialize()
     {
         $token = new Token(array('ROLE_FOO'));
+        $token->setAttributes(array('foo' => 'bar'));
 
         $this->assertEquals($token, unserialize(serialize($token)));
     }
@@ -157,4 +162,33 @@ class TokenTest extends \PHPUnit_Framework_TestCase
             array('setRoles', array('foo', 'asdf')),
         );
     }
+
+    /**
+     * @covers Symfony\Component\Security\Core\Authentication\Token\Token::getAttributes
+     * @covers Symfony\Component\Security\Core\Authentication\Token\Token::setAttributes
+     * @covers Symfony\Component\Security\Core\Authentication\Token\Token::hasAttribute
+     * @covers Symfony\Component\Security\Core\Authentication\Token\Token::getAttribute
+     * @covers Symfony\Component\Security\Core\Authentication\Token\Token::setAttribute
+     */
+    public function testAttributes()
+    {
+        $attributes = array('foo' => 'bar');
+        $token = new Token();
+        $token->setAttributes($attributes);
+
+        $this->assertEquals($attributes, $token->getAttributes(), '->getAttributes() returns the token attributes');
+        $this->assertEquals('bar', $token->getAttribute('foo'), '->getAttribute() returns the value of a attribute');
+        $token->setAttribute('foo', 'foo');
+        $this->assertEquals('foo', $token->getAttribute('foo'), '->setAttribute() changes the value of a attribute');
+        $this->assertTrue($token->hasAttribute('foo'), '->hasAttribute() returns true if the attribute is defined');
+        $this->assertFalse($token->hasAttribute('oof'), '->hasAttribute() returns false if the attribute is not defined');
+
+        try {
+            $token->getAttribute('foobar');
+            $this->fail('->getAttribute() throws an \InvalidArgumentException exception when the attribute does not exist');
+        } catch (\Exception $e) {
+            $this->assertInstanceOf('\InvalidArgumentException', $e, '->getAttribute() throws an \InvalidArgumentException exception when the attribute does not exist');
+            $this->assertEquals('This token has no "foobar" attribute.', $e->getMessage(), '->getAttribute() throws an \InvalidArgumentException exception when the attribute does not exist');
+        }
+    }
 }