Dropped other classes we don't need any longer
This commit is contained in:
parent
e299d268c8
commit
1381fd82a0
5 changed files with 0 additions and 723 deletions
|
@ -89,11 +89,6 @@ class Display extends Object
|
|||
|
||||
if ($return_template && $this->module->templates)
|
||||
{
|
||||
// Determines if we're using a custom class or not
|
||||
$dynamic_class = (class_exists('CustomDynamic') ? 'CustomDynamic' : 'Dynamic');
|
||||
$form_class = (class_exists('CustomForm') ? 'CustomForm' : 'Form');
|
||||
$html_class = (class_exists('CustomHTML') ? 'CustomHTML' : 'HTML');
|
||||
|
||||
// Exposes some objects and variables to the local scope of the template
|
||||
$this->request = $this->js_file = $_REQUEST['request'];
|
||||
$this->css_class = strtr($this->request, '/', '-');
|
||||
|
|
|
@ -1,342 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Security System for PICKLES
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistribution of these files must retain the above copyright notice.
|
||||
*
|
||||
* @author Josh Sherman <josh@gravityblvd.com>
|
||||
* @copyright Copyright 2007-2014, Josh Sherman
|
||||
* @license http://www.opensource.org/licenses/mit-license.html
|
||||
* @package PICKLES
|
||||
* @link https://github.com/joshtronic/pickles
|
||||
*/
|
||||
|
||||
/**
|
||||
* Security Class
|
||||
*
|
||||
* Collection of static methods for handling security within a website running
|
||||
* on PICKLES. Requires sessions to be enabled.
|
||||
*
|
||||
* @usage <code>Security::login(10);</code>
|
||||
* @usage <code>Security::isLevel(SECURITY_LEVEL_ADMIN);</code>
|
||||
*/
|
||||
class Security
|
||||
{
|
||||
/**
|
||||
* Lookup Cache
|
||||
*
|
||||
* Used to minimize database lookups
|
||||
*
|
||||
* @static
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private static $cache = [];
|
||||
|
||||
/**
|
||||
* Generate Hash
|
||||
*
|
||||
* Generates an SHA1 hash from the provided string. Salt optional.
|
||||
*
|
||||
* @param string $source value to hash
|
||||
* @param mixed $salts optional salt or salts
|
||||
* @return string SHA1 hash
|
||||
* @todo Transition away from this
|
||||
*/
|
||||
public static function generateHash($source, $salts = null)
|
||||
{
|
||||
// Determines which salt(s) to use
|
||||
if ($salts == null)
|
||||
{
|
||||
$config = Config::getInstance();
|
||||
|
||||
if (isset($config->security['salt']) && $config->security['salt'] != null)
|
||||
{
|
||||
$salts = $config->security['salt'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$salts = ['P1ck73', 'Ju1C3'];
|
||||
}
|
||||
}
|
||||
|
||||
// Forces the variable to be an array
|
||||
if (!is_array($salts))
|
||||
{
|
||||
$salts = [$salts];
|
||||
}
|
||||
|
||||
// Loops through the salts, applies them and calculates the hash
|
||||
$hash = $source;
|
||||
|
||||
foreach ($salts as $salt)
|
||||
{
|
||||
$hash = sha1($salt . $hash);
|
||||
}
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate SHA-256 Hash
|
||||
*
|
||||
* Generates an SHA-256 hash from the provided string and salt. Borrowed the
|
||||
* large iteration logic from fCryptography::hashWithSalt() as, and I quote,
|
||||
* "makes rainbow table attacks infesible".
|
||||
*
|
||||
* @param string $source value to hash
|
||||
* @param mixed $salt value to use as salt
|
||||
* @return string SHA-256 hash
|
||||
* @link https://github.com/flourishlib/flourish-classes/blob/master/fCryptography.php
|
||||
*/
|
||||
public static function generateSHA256Hash($source, $salt)
|
||||
{
|
||||
$sha256 = sha1($salt . $source);
|
||||
|
||||
for ($i = 0; $i < 1000; $i++)
|
||||
{
|
||||
$sha256 = hash('sha256', $sha256 . (($i % 2 == 0) ? $source : $salt));
|
||||
}
|
||||
|
||||
return $sha256;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Session
|
||||
*
|
||||
* Checks if sessions are enabled.
|
||||
*
|
||||
* @static
|
||||
* @access private
|
||||
* @return boolean whether or not sessions are enabled
|
||||
*/
|
||||
private static function checkSession()
|
||||
{
|
||||
if (session_id() == '')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Level
|
||||
*
|
||||
* Checks if a passed level is an integer and/or properly defined in the
|
||||
* site's configuration file.
|
||||
*
|
||||
* @static
|
||||
* @access private
|
||||
* @param mixed access level to validate
|
||||
* @return whether ot not the access level is valid
|
||||
*/
|
||||
private static function checkLevel(&$access_level)
|
||||
{
|
||||
return is_int($access_level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Login
|
||||
*
|
||||
* Creates a session variable containing the user ID and generated token.
|
||||
* The token is also assigned to a cookie to be used when validating the
|
||||
* security level. When the level value is present, the class will by pass
|
||||
* the database look up and simply use that value when validating (the less
|
||||
* paranoid scenario).
|
||||
*
|
||||
* @static
|
||||
* @param integer $user_id ID of the user that's been logged in
|
||||
* @param integer $level optional level for the user being logged in
|
||||
* @param string $role textual representation of the user's level
|
||||
* @return boolean whether or not the login could be completed
|
||||
*/
|
||||
public static function login($user_id, $level = null, $role = null)
|
||||
{
|
||||
if (self::checkSession())
|
||||
{
|
||||
$token = sha1(microtime());
|
||||
|
||||
$_SESSION['__pickles']['security'] = [
|
||||
'token' => $token,
|
||||
'user_id' => (int)$user_id,
|
||||
'level' => $level,
|
||||
'role' => $role,
|
||||
];
|
||||
|
||||
setcookie('pickles_security_token', $token);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout
|
||||
*
|
||||
* Clears out the security information in the session and the cookie.
|
||||
*
|
||||
* @static
|
||||
* @return boolean true
|
||||
*/
|
||||
public static function logout()
|
||||
{
|
||||
if (isset($_SESSION['__pickles']['security']))
|
||||
{
|
||||
$_SESSION['__pickles']['security'] = null;
|
||||
unset($_SESSION['__pickles']['security']);
|
||||
|
||||
setcookie('pickles_security_token', '', time() - 3600);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get User Level
|
||||
*
|
||||
* Looks up the user level in the database and caches it. Cache is used
|
||||
* for any subsequent look ups for the user. Also validates the session
|
||||
* variable against the cookie to ensure everything is legit. If the user
|
||||
* level is set in the session, that value will take precedence.
|
||||
*
|
||||
* return integer user level or false
|
||||
*/
|
||||
private static function getUserLevel()
|
||||
{
|
||||
if (self::checkSession() == true && isset($_SESSION['__pickles']['security']['user_id']))
|
||||
{
|
||||
// Checks the session against the cookie
|
||||
if (isset($_SESSION['__pickles']['security']['token'], $_COOKIE['pickles_security_token'])
|
||||
&& $_SESSION['__pickles']['security']['token'] != $_COOKIE['pickles_security_token'])
|
||||
{
|
||||
Security::logout();
|
||||
}
|
||||
elseif (isset($_SESSION['__pickles']['security']['level']) && $_SESSION['__pickles']['security']['level'] != null)
|
||||
{
|
||||
return $_SESSION['__pickles']['security']['level'];
|
||||
}
|
||||
// Used to hit the database to determine the user's level, found it
|
||||
// to be overkill and just opted for a simple logout.
|
||||
else
|
||||
{
|
||||
Security::logout();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Level
|
||||
*
|
||||
* Checks the user's access level is exactly the passed level
|
||||
*
|
||||
* @static
|
||||
* @param integer $access_level access level to be checked against
|
||||
* @return boolean whether or not the user is that level
|
||||
*/
|
||||
public static function isLevel()
|
||||
{
|
||||
$is_level = false;
|
||||
|
||||
if (self::checkSession())
|
||||
{
|
||||
$arguments = func_get_args();
|
||||
if (is_array($arguments[0]))
|
||||
{
|
||||
$arguments = $arguments[0];
|
||||
}
|
||||
|
||||
foreach ($arguments as $access_level)
|
||||
{
|
||||
if (self::checkLevel($access_level))
|
||||
{
|
||||
if (self::getUserLevel() == $access_level)
|
||||
{
|
||||
$is_level = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $is_level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has Level
|
||||
*
|
||||
* Checks the user's access level against the passed level.
|
||||
*
|
||||
* @static
|
||||
* @param integer $access_level access level to be checked against
|
||||
* @return boolean whether or not the user has access
|
||||
*/
|
||||
public static function hasLevel()
|
||||
{
|
||||
$has_level = false;
|
||||
|
||||
if (self::checkSession())
|
||||
{
|
||||
$arguments = func_get_args();
|
||||
|
||||
if (is_array($arguments[0]))
|
||||
{
|
||||
$arguments = $arguments[0];
|
||||
}
|
||||
|
||||
foreach ($arguments as $access_level)
|
||||
{
|
||||
if (self::checkLevel($access_level))
|
||||
{
|
||||
if (self::getUserLevel() >= $access_level)
|
||||
{
|
||||
$has_level = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $has_level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Between Level
|
||||
*
|
||||
* Checks the user's access level against the passed range.
|
||||
*
|
||||
* @static
|
||||
* @param integer $low access level to be checked against
|
||||
* @param integer $high access level to be checked against
|
||||
* @return boolean whether or not the user has access
|
||||
*/
|
||||
public static function betweenLevel($low, $high)
|
||||
{
|
||||
$between_level = false;
|
||||
|
||||
if (self::checkSession())
|
||||
{
|
||||
if (self::checkLevel($low) && self::checkLevel($high))
|
||||
{
|
||||
$user_level = self::getUserLevel();
|
||||
|
||||
if ($user_level >= $low && $user_level <= $high)
|
||||
{
|
||||
$between_level = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $between_level;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,125 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Session Handling for PICKLES
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistribution of these files must retain the above copyright notice.
|
||||
*
|
||||
* @author Josh Sherman <josh@gravityblvd.com>
|
||||
* @copyright Copyright 2007-2014, Josh Sherman
|
||||
* @license http://www.opensource.org/licenses/mit-license.html
|
||||
* @package PICKLES
|
||||
* @link https://github.com/joshtronic/pickles
|
||||
*/
|
||||
|
||||
/**
|
||||
* Session Class
|
||||
*
|
||||
* Provides session handling via database instead of the file based session
|
||||
* handling built into PHP. Using this class requires an array to be defined
|
||||
* in place of the boolean true/false (on/off). If simply an empty array, the
|
||||
* datasource will default to the value in $config['pickles']['datasource'] and
|
||||
* if the table will default to "sessions". The format is as follows:
|
||||
*/
|
||||
class Session extends Object
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* All of our set up logic for the session in contained here. This class is
|
||||
* initially instantiated from pickles.php. Non-file handlers need to be
|
||||
* configured in the site's config. MySQL support was dropped in favor of
|
||||
* in memory stores or simply relying on file based sessions. Why? Because
|
||||
* using MySQL for sessions is very write intensive and having done it in
|
||||
* the past I don't recommend it. If you run a single server, files are
|
||||
* good enough if your volume is lower. Memcache[d] is fine if you don't
|
||||
* mind logging all of your users off your site when you restart the
|
||||
* service and/or you run out of memory for the process. Redis is the best
|
||||
* choice as it can be configured to be persistent and lives in memory.
|
||||
* This is assuming you don't just want to roll your own sessions, which is
|
||||
* pretty damn easy as well.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (isset($_SERVER['REQUEST_METHOD']))
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// Sets up our configuration variables
|
||||
if (isset($this->config->pickles['sessions']))
|
||||
{
|
||||
$session = $this->config->pickles['sessions'];
|
||||
}
|
||||
|
||||
$datasources = $this->config->datasources;
|
||||
$handler = 'files';
|
||||
$datasource = false;
|
||||
|
||||
if (isset($session, $datasources[$session]))
|
||||
{
|
||||
$datasource = $datasources[$session];
|
||||
$handler = $datasource['type'];
|
||||
|
||||
if ($handler != 'files')
|
||||
{
|
||||
if (isset($datasource['hostname'], $datasource['port']))
|
||||
{
|
||||
$host = ($handler != 'memcached' ? 'tcp://' : '')
|
||||
. $datasource['hostname'] . ':' . $datasource['port'];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception('You must provide both the hostname and port for the datasource.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch ($handler)
|
||||
{
|
||||
case 'memcache':
|
||||
ini_set('session.save_handler', 'memcache');
|
||||
ini_set('session.save_path', $host . '?persistent=1&weight=1&timeout=1&retry_interval=15');
|
||||
break;
|
||||
|
||||
case 'memcached':
|
||||
ini_set('session.save_handler', 'memcached');
|
||||
ini_set('session.save_path', $host);
|
||||
break;
|
||||
|
||||
case 'redis':
|
||||
$save_path = $host . '?weight=1';
|
||||
|
||||
// Database ignored by phpredis when this was coded
|
||||
if (isset($datasource['database']))
|
||||
{
|
||||
$save_path .= '&database=' . $datasource['database'];
|
||||
}
|
||||
|
||||
if (isset($datasource['prefix']))
|
||||
{
|
||||
$save_path .= '&prefix=' . $datasource['prefix'];
|
||||
}
|
||||
|
||||
ini_set('session.save_handler', 'redis');
|
||||
ini_set('session.save_path', $save_path);
|
||||
break;
|
||||
|
||||
case 'files':
|
||||
ini_set('session.save_handler', 'files');
|
||||
break;
|
||||
}
|
||||
|
||||
// Don't start sessions for people without a user agent and bots.
|
||||
if (isset($_SERVER['HTTP_USER_AGENT'])
|
||||
&& !String::isEmpty($_SERVER['HTTP_USER_AGENT'])
|
||||
&& !preg_match('/(Baidu|Gigabot|Googlebot|libwww-perl|lwp-trivial|msnbot|SiteUptime|Slurp|WordPress|ZIBB|ZyBorg)/i', $_SERVER['HTTP_USER_AGENT']))
|
||||
{
|
||||
session_start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
<?php
|
||||
|
||||
class MockUserModel extends Model
|
||||
{
|
||||
public $table = 'users';
|
||||
}
|
||||
|
||||
class SecurityTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testGenerateHashWithDefaultSalts()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'4940e793006aa897db22751bba80dff4cb6a3e08',
|
||||
Security::generateHash('source')
|
||||
);
|
||||
}
|
||||
|
||||
public function testGenerateHashWithCustomSalts()
|
||||
{
|
||||
$config = Config::getInstance();
|
||||
$config->data['security']['salt'] = 'salt';
|
||||
|
||||
$this->assertEquals(
|
||||
'4eac88c934c33cfa9a80c0b2eb322f23ac3b13c5',
|
||||
Security::generateHash('source')
|
||||
);
|
||||
}
|
||||
|
||||
public function testGenerateSHA256Hash()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'3d04f805aff4838ecaf98c7260a813fffd2b7a8a7f957add8018908a1bbdad04',
|
||||
Security::generateSHA256Hash('source', 'salt')
|
||||
);
|
||||
}
|
||||
|
||||
public function testLogin()
|
||||
{
|
||||
$this->assertTrue(Security::login(1, 10, 'USER'));
|
||||
$this->assertTrue(isset($_SESSION['__pickles']['security']));
|
||||
}
|
||||
|
||||
public function testLoginNoSession()
|
||||
{
|
||||
session_destroy();
|
||||
$this->assertFalse(Security::login(1, 10, 'USER'));
|
||||
}
|
||||
|
||||
public function testLogout()
|
||||
{
|
||||
session_start();
|
||||
Security::login(1, 10, 'USER');
|
||||
|
||||
$this->assertTrue(Security::logout());
|
||||
$this->assertFalse(isset($_SESSION['__pickles']['security']));
|
||||
}
|
||||
|
||||
public function testIsLevel()
|
||||
{
|
||||
Security::login(1, 10, 'USER');
|
||||
|
||||
$this->assertTrue(Security::isLevel(SECURITY_LEVEL_USER));
|
||||
}
|
||||
|
||||
public function testIsLevelArray()
|
||||
{
|
||||
Security::login(1, 10, 'USER');
|
||||
|
||||
$this->assertTrue(Security::isLevel([SECURITY_LEVEL_USER, SECURITY_LEVEL_ADMIN]));
|
||||
}
|
||||
|
||||
public function testHasLevel()
|
||||
{
|
||||
Security::login(1, 10, 'USER');
|
||||
|
||||
$this->assertTrue(Security::hasLevel(SECURITY_LEVEL_USER));
|
||||
}
|
||||
|
||||
public function testHasLevelArray()
|
||||
{
|
||||
Security::login(1, 10, 'USER');
|
||||
|
||||
$this->assertTrue(Security::hasLevel([SECURITY_LEVEL_USER, SECURITY_LEVEL_ADMIN]));
|
||||
}
|
||||
|
||||
public function testBetweenLevel()
|
||||
{
|
||||
Security::login(1, 10, 'USER');
|
||||
|
||||
$this->assertTrue(Security::betweenLevel(SECURITY_LEVEL_USER, SECURITY_LEVEL_ADMIN));
|
||||
}
|
||||
|
||||
public function testTokenMismatch()
|
||||
{
|
||||
Security::login(1, 10, 'USER');
|
||||
|
||||
$_SESSION['__pickles']['security']['token'] = 'foo';
|
||||
$_COOKIE['pickles_security_token'] = 'bar';
|
||||
|
||||
$this->assertFalse(Security::isLevel(SECURITY_LEVEL_USER));
|
||||
}
|
||||
|
||||
public function testIsLevelDB()
|
||||
{
|
||||
$config = Config::getInstance();
|
||||
|
||||
$config->data = [
|
||||
'pickles' => [
|
||||
'datasource' => 'mysql',
|
||||
'cache' => 'memcache',
|
||||
],
|
||||
'datasources' => [
|
||||
'mysql' => [
|
||||
'type' => 'mysql',
|
||||
'driver' => 'pdo_mysql',
|
||||
'hostname' => 'localhost',
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
'database' => 'test',
|
||||
'cache' => true,
|
||||
],
|
||||
'memcache' => [
|
||||
'type' => 'memcache',
|
||||
'hostname' => 'localhost',
|
||||
'port' => 11211,
|
||||
'namespace' => '',
|
||||
],
|
||||
],
|
||||
'security' => ['model' => 'MockUserModel'],
|
||||
];
|
||||
|
||||
$model = new MockUserModel();
|
||||
$model->record['username'] = 'pickles';
|
||||
$model->commit();
|
||||
|
||||
setUpConfig([
|
||||
|
||||
]);
|
||||
|
||||
new Config();
|
||||
|
||||
Security::login(1, 10, 'USER');
|
||||
|
||||
unset(
|
||||
$_SESSION['__pickles']['security']['token'],
|
||||
$_COOKIE['pickles_security_token'],
|
||||
$_SESSION['__pickles']['security']['level']
|
||||
);
|
||||
|
||||
$this->assertFalse(Security::isLevel([SECURITY_LEVEL_USER, SECURITY_LEVEL_ADMIN]));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
<?php
|
||||
|
||||
class SessionTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
if (session_id())
|
||||
{
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
$_SERVER['HTTP_USER_AGENT'] = 'yes';
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
}
|
||||
|
||||
public function testFiles()
|
||||
{
|
||||
$config = Config::getInstance();
|
||||
$config->data['pickles']['sessions'] = 'files';
|
||||
|
||||
new Session();
|
||||
|
||||
$_SESSION['test'] = 'files';
|
||||
$this->assertEquals('files', $_SESSION['test']);
|
||||
}
|
||||
|
||||
public function testMemcache()
|
||||
{
|
||||
$config = Config::getInstance();
|
||||
$config->data['pickles']['sessions'] = 'memcache';
|
||||
$config->data['datasources']['memcache'] = [
|
||||
'type' => 'memcache',
|
||||
'hostname' => 'localhost',
|
||||
'port' => '11211',
|
||||
];
|
||||
|
||||
new Session();
|
||||
|
||||
$_SESSION['test'] = 'memcache';
|
||||
$this->assertEquals('memcache', $_SESSION['test']);
|
||||
}
|
||||
|
||||
public function testMemcached()
|
||||
{
|
||||
$config = Config::getInstance();
|
||||
$config->data['pickles']['sessions'] = 'memcached';
|
||||
$config->data['datasources']['memcached'] = [
|
||||
'type' => 'memcached',
|
||||
'hostname' => 'localhost',
|
||||
'port' => '11211',
|
||||
];
|
||||
|
||||
new Session();
|
||||
|
||||
$_SESSION['test'] = 'memcached';
|
||||
$this->assertEquals('memcached', $_SESSION['test']);
|
||||
}
|
||||
|
||||
public function testRedis()
|
||||
{
|
||||
$config = Config::getInstance();
|
||||
$config->data['pickles']['sessions'] = 'redis';
|
||||
$config->data['datasources']['redis'] = [
|
||||
'type' => 'redis',
|
||||
'hostname' => 'localhost',
|
||||
'port' => '6379',
|
||||
'database' => '1',
|
||||
'prefix' => 'p:',
|
||||
];
|
||||
|
||||
new Session();
|
||||
|
||||
$_SESSION['test'] = 'redis';
|
||||
$this->assertEquals('redis', $_SESSION['test']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionMessage You must provide both the hostname and port for the datasource.
|
||||
*/
|
||||
public function testMissingHostname()
|
||||
{
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
|
||||
$config = Config::getInstance();
|
||||
$config->data['pickles']['sessions'] = 'redis';
|
||||
$config->data['datasources']['redis'] = [
|
||||
'type' => 'redis',
|
||||
'port' => '6379',
|
||||
];
|
||||
|
||||
new Session();
|
||||
|
||||
$_SESSION['test'] = 'redis';
|
||||
$this->assertEquals('redis', $_SESSION['test']);
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue