summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/config/config.php1
-rw-r--r--modules/auth/config/auth.php37
-rw-r--r--modules/auth/config/basic_auth.php35
-rw-r--r--modules/auth/helpers/auth_installer.php63
-rw-r--r--modules/auth/libraries/Auth.php93
-rw-r--r--modules/auth/libraries/drivers/Auth.php37
-rw-r--r--modules/auth/libraries/drivers/Auth/Basic.php146
-rw-r--r--modules/auth/models/password.php22
-rw-r--r--modules/auth/tests/Auth_Installer_Test.php36
-rw-r--r--modules/gallery_unit_test/controllers/test.php2
10 files changed, 472 insertions, 0 deletions
diff --git a/core/config/config.php b/core/config/config.php
index b57a4b71..dafd107f 100644
--- a/core/config/config.php
+++ b/core/config/config.php
@@ -129,4 +129,5 @@ $config['modules'] = array
MODPATH . 'user',
MODPATH . 'info',
MODPATH . 'gmaps',
+ MODPATH . 'auth',
);
diff --git a/modules/auth/config/auth.php b/modules/auth/config/auth.php
new file mode 100644
index 00000000..b63cc114
--- /dev/null
+++ b/modules/auth/config/auth.php
@@ -0,0 +1,37 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2008 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * Name of the driver to be used for handling user authentication and password management
+ */
+$config['driver'] = 'Basic';
+
+/**
+ * Set the auto-login (remember me) cookie lifetime, in seconds. The default
+ * lifetime is two weeks.
+ */
+$config['lifetime'] = 1209600;
+
+/**
+ * Array of modules that this module depends on.
+ *
+ * Not currently used, but provided for documentation purposes
+ */
+$config['depends'] = array('user');
diff --git a/modules/auth/config/basic_auth.php b/modules/auth/config/basic_auth.php
new file mode 100644
index 00000000..9b45153e
--- /dev/null
+++ b/modules/auth/config/basic_auth.php
@@ -0,0 +1,35 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2008 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * Type of hash to use for passwords. Any algorithm supported by the hash function
+ * can be used here. Note that the length of your password is determined by the
+ * hash type + the number of salt characters.
+ * @see http://php.net/hash
+ * @see http://php.net/hash_algos
+ */
+$config['hash_method'] = 'sha1';
+
+/**
+ * Defines the hash offsets to insert the salt at. The password hash length
+ * will be increased by the total number of offsets.
+ */
+$config['salt_pattern'] = '1, 3, 5, 9, 14, 15, 20, 21, 28, 30';
+
diff --git a/modules/auth/helpers/auth_installer.php b/modules/auth/helpers/auth_installer.php
new file mode 100644
index 00000000..b1477ff8
--- /dev/null
+++ b/modules/auth/helpers/auth_installer.php
@@ -0,0 +1,63 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2008 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class auth_installer {
+ public static function install() {
+ Kohana::log("debug", "auth_installer::install");
+ $db = Database::instance();
+ try {
+ $base_version = ORM::factory("module")->where("name", "auth")->find()->version;
+ } catch (Exception $e) {
+ if ($e->getCode() == 44) {
+ $base_version = 0;
+ } else {
+ Kohana::log("error", $e);
+ throw $e;
+ }
+ }
+ Kohana::log("debug", "base_version: $base_version");
+
+ if ($base_version == 0) {
+ $db->query("CREATE TABLE IF NOT EXISTS `passwords` (
+ `id` int(9) NOT NULL auto_increment,
+ `user_id` int(9) NOT NULL,
+ `password` varchar(1128) NOT NULL,
+ `logins` int(10) unsigned NOT NULL default '0',
+ `last_login` int(10) unsigned NOT NULL default '0',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY (`user_id`))
+ ENGINE=InnoDB DEFAULT CHARSET=utf8;");
+
+ $user_module = ORM::factory("module")->where("name", "auth")->find();
+ $user_module->name = "auth";
+ $user_module->version = 1;
+ $user_module->save();
+
+ $user = ORM::factory("user")->where("name", "admin")->find();
+ Auth::instance()->set_user_password($user->id, "admin");
+ }
+ }
+
+ public static function uninstall() {
+ $db = Database::instance();
+ $db->query("DROP TABLE IF EXISTS `passwords`;");
+ $auth_module = ORM::factory("module")->where("name", "auth")->find();
+ $auth_module->delete();
+ }
+} \ No newline at end of file
diff --git a/modules/auth/libraries/Auth.php b/modules/auth/libraries/Auth.php
new file mode 100644
index 00000000..9bc59ec7
--- /dev/null
+++ b/modules/auth/libraries/Auth.php
@@ -0,0 +1,93 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2008 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * Implement the Authentication.
+ *
+ * This code was heavily influenced by code from:
+ * - http://code.google.com/p/kohana-mptt/
+ * - http://code.google.com/p/kohana-mptt/wiki/Documentation
+ * - http://code.google.com/p/s7ncms/source/browse/trunk/modules/s7ncms/libraries/ORM_MPTT.php
+ *
+ * It was extended to allow configurable drivers
+ */
+class Auth_Core implements Auth_Driver {
+
+ // Session singleton
+ private static $instance;
+
+ // Configuration and driver
+ protected $_config;
+ protected $_driver;
+
+ /**
+ * Singleton instance of Session.
+ */
+ public static function instance($config = array()) {
+ if (self::$instance == NULL) {
+ // Create a new instance
+ self::$instance = new Auth($config);
+ }
+
+ return self::$instance;
+ }
+
+ /**
+ * On first instance creation, sets up the driver.
+ */
+ protected function __construct($config = array()) {
+ // Load config
+ $config += Kohana::config('auth');
+
+ // Set the driver class name
+ $driver = "Auth_{$config['driver']}_Driver";
+ if (!Kohana::auto_load($driver)) {
+ // @todo change to gallery specific exceptions
+ throw new Kohana_Exception("Specified Driver: '{$config['driver']}' has not been defined.");
+ }
+
+ // Load the driver
+ $driver = new $driver();
+
+ if (!($driver instanceof Auth_Driver)) {
+ // @todo change to gallery specific exceptions
+ throw new Kohana_Exception(
+ "Specified Driver: '{$config['driver']}' has not implemented 'Auth_Driver'.");
+ }
+
+ $this->_driver = $driver;
+ $this->_config = $config;
+
+ Kohana::log('debug', 'Auth Library initialized');
+ }
+
+ /**
+ * @see Auth_Driver::set_user_password
+ */
+ public function set_user_password($user_id, $password) {
+ return $this->_driver->set_user_password($user_id, $password);
+ }
+
+ /**
+ * @see Auth_Driver::is_valid_password
+ */
+ public function is_valid_password($user_id, $password) {
+ return $this->_driver->is_valid_password($user_id, $password);
+ }
+}
diff --git a/modules/auth/libraries/drivers/Auth.php b/modules/auth/libraries/drivers/Auth.php
new file mode 100644
index 00000000..6a6d31b6
--- /dev/null
+++ b/modules/auth/libraries/drivers/Auth.php
@@ -0,0 +1,37 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2008 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+interface Auth_Driver {
+ /**
+ * Set the password for the specified user
+ *
+ * @param int Gallery User id
+ * @param string
+ */
+ public function set_user_password($user_id, $password);
+
+ /**
+ * Validates a user id password combination.
+ *
+ * @param int user_id
+ * @param string password
+ * @return boolean
+ */
+ public function is_valid_password($user_id, $password);
+} \ No newline at end of file
diff --git a/modules/auth/libraries/drivers/Auth/Basic.php b/modules/auth/libraries/drivers/Auth/Basic.php
new file mode 100644
index 00000000..2621812a
--- /dev/null
+++ b/modules/auth/libraries/drivers/Auth/Basic.php
@@ -0,0 +1,146 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2008 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Auth_Basic_Driver implements Auth_Driver {
+ // Configuration
+ protected $_config;
+
+ /**
+ * Instantiate the Driver and initialize it's configuration.
+ */
+ public function __construct($config = array()) {
+ // Load config
+ $config += Kohana::config('basic_auth');
+
+ // Clean up the salt pattern and split it into an array
+ $config['salt_pattern'] = preg_split('/,\s*/', $config['salt_pattern']);
+ $this->_config = $config;
+
+ Kohana::log('debug', 'Auth_Basic_Driver Library initialized');
+ }
+
+ /**
+ * @see Auth_Driver::set_user_password
+ *
+ * @param int $user_id
+ * @param string $password
+ * @return void
+ */
+ public function set_user_password($user_id, $password_text) {
+ $password = ORM::factory("password")->where('user_id', $user_id)->find();
+ $password->password = $this->_hash_password($password_text);
+ if (empty($password->user_id)) {
+ $password->user_id = $user_id;
+ }
+ $password->save();
+ }
+
+ /**
+ * Validates a user id password combination.
+ *
+ * @param int user_id
+ * @param string password
+ * @return boolean
+ */
+ public function is_valid_password($user_id, $password_text) {
+ $password = ORM::factory("password")
+ ->where('user_id', $user_id)
+ ->find();
+ if ($password->loaded != true) {
+ return false;
+ }
+
+ // Get the salt from the stored password
+ $salt = $this->_find_salt($password->password);
+ $hashed = $this->_hash_password($password_text, $salt);
+
+ return $hashed === $password->password;
+ }
+
+ /**
+ * Creates a hashed password from a plaintext password, inserting salt
+ * based on the configured salt pattern.
+ *
+ * @param string plaintext password
+ * @return string hashed password string
+ */
+ private function _hash_password($password, $salt = FALSE) {
+ if ($salt === FALSE) {
+ // Create a salt seed, same length as the number of offsets in the pattern
+ $salt = substr($this->_hash(uniqid(NULL, TRUE)), 0, count($this->_config['salt_pattern']));
+ }
+
+ // Password hash that the salt will be inserted into
+ $hash = $this->_hash($salt . $password);
+
+ // Change salt to an array
+ $salt = str_split($salt, 1);
+
+ // Returned password
+ $password = '';
+
+ // Used to calculate the length of splits
+ $last_offset = 0;
+
+ foreach ($this->_config['salt_pattern'] as $offset) {
+ // Split a new part of the hash off
+ $part = substr($hash, 0, $offset - $last_offset);
+
+ // Cut the current part out of the hash
+ $hash = substr($hash, $offset - $last_offset);
+
+ // Add the part to the password, appending the salt character
+ $password .= $part . array_shift($salt);
+
+ // Set the last offset to the current offset
+ $last_offset = $offset;
+ }
+
+ // Return the password, with the remaining hash appended
+ return $password . $hash;
+ }
+
+ /**
+ * Perform a hash, using the configured method.
+ *
+ * @param string string to hash
+ * @return string
+ */
+ private function _hash($str) {
+ return hash($this->_config['hash_method'], $str);
+ }
+
+ /**
+ * Finds the salt from a password, based on the configured salt pattern.
+ *
+ * @param string hashed password
+ * @return string
+ */
+ private function _find_salt($password) {
+ $salt = '';
+
+ foreach ($this->_config['salt_pattern'] as $i => $offset) {
+ // Find salt characters... take a good long look..
+ $salt .= substr($password, $offset + $i, 1);
+ }
+
+ return $salt;
+ }
+}
+
diff --git a/modules/auth/models/password.php b/modules/auth/models/password.php
new file mode 100644
index 00000000..fd1fee58
--- /dev/null
+++ b/modules/auth/models/password.php
@@ -0,0 +1,22 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2008 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Password_Model extends ORM {
+ protected $belongs_to = array("users");
+} \ No newline at end of file
diff --git a/modules/auth/tests/Auth_Installer_Test.php b/modules/auth/tests/Auth_Installer_Test.php
new file mode 100644
index 00000000..110131ab
--- /dev/null
+++ b/modules/auth/tests/Auth_Installer_Test.php
@@ -0,0 +1,36 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2008 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * This test case operates under the assumption that core_installer::install() is called by the
+ * test controller before it starts.
+ */
+class Auth_Installer_Test extends Unit_Test_Case {
+ public function install_basic_add_password_test() {
+ $user = ORM::factory('user')->find(1);
+
+ $auth = Auth::instance(array('driver' => 'Basic'));
+
+ $auth->set_user_password($user->id, "test_password");
+
+ $this->assert_false($auth->is_valid_password($user->id, "invalid_password"));
+ $this->assert_true($auth->is_valid_password($user->id, "test_password"));
+ }
+}
diff --git a/modules/gallery_unit_test/controllers/test.php b/modules/gallery_unit_test/controllers/test.php
index 543d3183..0761dc12 100644
--- a/modules/gallery_unit_test/controllers/test.php
+++ b/modules/gallery_unit_test/controllers/test.php
@@ -61,6 +61,7 @@ class Test_Controller extends Controller {
// We probably don't want to uninstall and reinstall the core every time, but let's start off
// this way. Uninstall modules first and core last. Ignore errors during uninstall.
try {
+ auth_installer::uninstall();
user_installer::uninstall();
core_installer::uninstall();
} catch (Exception $e) {
@@ -68,6 +69,7 @@ class Test_Controller extends Controller {
core_installer::install();
user_installer::install();
+ auth_installer::install();
print new Unit_Test();
}