diff --git a/src/classes/Display.php b/src/classes/Display.php index 59bd53c..2efc838 100644 --- a/src/classes/Display.php +++ b/src/classes/Display.php @@ -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, '/', '-'); diff --git a/src/classes/Security.php b/src/classes/Security.php deleted file mode 100644 index 3e2e4c5..0000000 --- a/src/classes/Security.php +++ /dev/null @@ -1,342 +0,0 @@ - - * @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 Security::login(10); - * @usage Security::isLevel(SECURITY_LEVEL_ADMIN); - */ -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; - } -} - diff --git a/src/classes/Session.php b/src/classes/Session.php deleted file mode 100644 index 62b6869..0000000 --- a/src/classes/Session.php +++ /dev/null @@ -1,125 +0,0 @@ - - * @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(); - } - } - } -} - diff --git a/tests/classes/SecurityTest.php b/tests/classes/SecurityTest.php deleted file mode 100644 index 7f3d041..0000000 --- a/tests/classes/SecurityTest.php +++ /dev/null @@ -1,153 +0,0 @@ -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])); - } -} - diff --git a/tests/classes/SessionTest.php b/tests/classes/SessionTest.php deleted file mode 100644 index 85759a4..0000000 --- a/tests/classes/SessionTest.php +++ /dev/null @@ -1,98 +0,0 @@ -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']); - } -} -