Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10328 from cakephp/3.next-cookies
New cookie implementation for the HTTP stack
- Loading branch information
Showing
10 changed files
with
1,326 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<?php | ||
/** | ||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org) | ||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) | ||
* | ||
* Licensed under The MIT License | ||
* Redistributions of files must retain the above copyright notice. | ||
* | ||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) | ||
* @link http://cakephp.org CakePHP(tm) Project | ||
* @since 3.5.0 | ||
* @license http://www.opensource.org/licenses/mit-license.php MIT License | ||
*/ | ||
namespace Cake\Http\Cookie; | ||
|
||
use ArrayIterator; | ||
use InvalidArgumentException; | ||
use IteratorAggregate; | ||
|
||
/** | ||
* Cookie Collection | ||
*/ | ||
class CookieCollection implements IteratorAggregate | ||
{ | ||
|
||
/** | ||
* Cookie objects | ||
* | ||
* @var Cookie[] | ||
*/ | ||
protected $cookies = []; | ||
|
||
/** | ||
* Constructor | ||
* | ||
* @param array $cookies Array of cookie objects | ||
*/ | ||
public function __construct(array $cookies = []) | ||
{ | ||
$this->checkCookies($cookies); | ||
foreach ($cookies as $cookie) { | ||
$name = $cookie->getName(); | ||
$key = mb_strtolower($name); | ||
$this->cookies[$key] = $cookie; | ||
} | ||
} | ||
|
||
/** | ||
* Checks if only valid cookie objects are in the array | ||
* | ||
* @param array $cookies Array of cookie objects | ||
* @return void | ||
* @throws \InvalidArgumentException | ||
*/ | ||
protected function checkCookies(array $cookies) | ||
{ | ||
foreach ($cookies as $index => $cookie) { | ||
if (!$cookie instanceof CookieInterface) { | ||
throw new InvalidArgumentException( | ||
sprintf( | ||
'Expected `%s[]` as $cookies but instead got `%s` at index %d', | ||
static::class, | ||
is_object($cookie) ? get_class($cookie) : gettype($cookie), | ||
$index | ||
) | ||
); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Gets the iterator | ||
* | ||
* @return \ArrayIterator | ||
*/ | ||
public function getIterator() | ||
{ | ||
return new ArrayIterator($this->cookies); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
<?php | ||
/** | ||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org) | ||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) | ||
* | ||
* Licensed under The MIT License | ||
* For full copyright and license information, please see the LICENSE.txt | ||
* Redistributions of files must retain the above copyright notice. | ||
* | ||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) | ||
* @link http://cakephp.org CakePHP(tm) Project | ||
* @since 3.5.0 | ||
* @license http://www.opensource.org/licenses/mit-license.php MIT License | ||
*/ | ||
namespace Cake\Http\Cookie; | ||
|
||
use Cake\Utility\Security; | ||
use RuntimeException; | ||
|
||
/** | ||
* Cookie Crypt Trait. | ||
* | ||
* Provides the encrypt/decrypt logic. | ||
*/ | ||
trait CookieCryptTrait | ||
{ | ||
|
||
/** | ||
* Valid cipher names for encrypted cookies. | ||
* | ||
* @var array | ||
*/ | ||
protected $_validCiphers = [ | ||
'aes' | ||
]; | ||
|
||
/** | ||
* Encryption cipher | ||
* | ||
* @param string|bool | ||
*/ | ||
protected $encryptionCipher = 'aes'; | ||
|
||
/** | ||
* The key for encrypting and decrypting the cookie | ||
* | ||
* @var string | ||
*/ | ||
protected $encryptionKey = ''; | ||
|
||
/** | ||
* Prefix of the encrypted string | ||
* | ||
* @var string | ||
*/ | ||
protected $encryptedStringPrefix = 'Q2FrZQ==.'; | ||
|
||
/** | ||
* Sets the encryption cipher | ||
* | ||
* @param string $cipher Cipher | ||
* @return $this | ||
*/ | ||
public function setEncryptionCipher($cipher) | ||
{ | ||
$this->checkCipher($cipher); | ||
$this->encryptionCipher = $cipher; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Check if encryption is enabled | ||
* | ||
* @return bool | ||
*/ | ||
public function isEncryptionEnabled() | ||
{ | ||
return is_string($this->encryptionCipher); | ||
} | ||
|
||
/** | ||
* Disables the encryption | ||
* | ||
* @return $this | ||
*/ | ||
public function disableEncryption() | ||
{ | ||
$this->encryptionCipher = false; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Sets the encryption key | ||
* | ||
* @param string $key Encryption key | ||
* @return $this | ||
*/ | ||
public function setEncryptionKey($key) | ||
{ | ||
$this->encryptionKey = $key; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Returns the encryption key to be used. | ||
* | ||
* @return string | ||
*/ | ||
public function getEncryptionKey() | ||
{ | ||
if ($this->encryptionKey === null) { | ||
return Security::salt(); | ||
} | ||
|
||
return $this->encryptionKey; | ||
} | ||
|
||
/** | ||
* Encrypts $value using public $type method in Security class | ||
* | ||
* @param string|array $value Value to encrypt | ||
* @return string Encoded values | ||
*/ | ||
protected function _encrypt($value) | ||
{ | ||
if (is_array($value)) { | ||
$value = $this->_flatten($value); | ||
} | ||
|
||
$encrypt = $this->encryptionCipher; | ||
if ($encrypt === false) { | ||
throw new RuntimeException('Encryption is disabled, no cipher provided.'); | ||
} | ||
|
||
$cipher = null; | ||
$key = $this->getEncryptionKey(); | ||
|
||
if ($encrypt === 'aes') { | ||
$cipher = Security::encrypt($value, $key); | ||
} | ||
|
||
return $this->encryptedStringPrefix . base64_encode($cipher); | ||
} | ||
|
||
/** | ||
* Helper method for validating encryption cipher names. | ||
* | ||
* @param string $encrypt The cipher name. | ||
* @return void | ||
* @throws \RuntimeException When an invalid cipher is provided. | ||
*/ | ||
protected function checkCipher($encrypt) | ||
{ | ||
if (!in_array($encrypt, $this->_validCiphers)) { | ||
$msg = sprintf( | ||
'Invalid encryption cipher. Must be one of %s.', | ||
implode(', ', $this->_validCiphers) | ||
); | ||
throw new RuntimeException($msg); | ||
} | ||
} | ||
|
||
/** | ||
* Decrypts $value using public $type method in Security class | ||
* | ||
* @param string|array $values Values to decrypt | ||
* @return string|array Decrypted values | ||
*/ | ||
protected function _decrypt($values) | ||
{ | ||
if (is_string($values)) { | ||
return $this->_decode($values); | ||
} | ||
|
||
$decrypted = []; | ||
foreach ($values as $name => $value) { | ||
$decrypted[$name] = $this->_decode($value); | ||
} | ||
|
||
return $decrypted; | ||
} | ||
|
||
/** | ||
* Decodes and decrypts a single value. | ||
* | ||
* @param string $value The value to decode & decrypt. | ||
* @return string|array Decoded values. | ||
*/ | ||
protected function _decode($value) | ||
{ | ||
if (!$this->isEncryptionEnabled()) { | ||
return $this->_expand($value); | ||
} | ||
|
||
$key = $this->getEncryptionKey(); | ||
$encrypt = $this->encryptionCipher; | ||
|
||
$value = base64_decode(substr($value, strlen($this->encryptedStringPrefix))); | ||
|
||
if ($encrypt === 'aes') { | ||
$value = Security::decrypt($value, $key); | ||
} | ||
|
||
return $this->_expand($value); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<?php | ||
/** | ||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org) | ||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) | ||
* | ||
* Licensed under The MIT License | ||
* Redistributions of files must retain the above copyright notice. | ||
* | ||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) | ||
* @link http://cakephp.org CakePHP(tm) Project | ||
* @since 3.5.0 | ||
* @license http://www.opensource.org/licenses/mit-license.php MIT License | ||
*/ | ||
namespace Cake\Http\Cookie; | ||
|
||
/** | ||
* Cookie Interface | ||
*/ | ||
interface CookieInterface | ||
{ | ||
/** | ||
* Sets the cookie name | ||
* | ||
* @param string $name Name of the cookie | ||
* @return $this | ||
*/ | ||
public function setName($name); | ||
|
||
/** | ||
* Gets the cookie name | ||
* | ||
* @return string | ||
*/ | ||
public function getName(); | ||
|
||
/** | ||
* Gets the cookie value | ||
* | ||
* @return string|array | ||
*/ | ||
public function getValue(); | ||
|
||
/** | ||
* Sets the raw cookie data | ||
* | ||
* @param string|array $value Value of the cookie to set | ||
* @return $this | ||
*/ | ||
public function setValue($value); | ||
|
||
/** | ||
* Returns the cookie as header value | ||
* | ||
* @return string | ||
*/ | ||
public function toHeaderValue(); | ||
} |
Oops, something went wrong.