diff --git a/_config.php b/_config.php index 9c4fe5e76..6167fceb0 100644 --- a/_config.php +++ b/_config.php @@ -1,12 +1,57 @@ + * Authenticator::registerAuthenticator('OpenIDAuthenticator'); + * + */ + + + +/** + * Add the security folder to the include path so that the + * {http://www.openidenabled.com/ PHP OpenID library} finds it files + */ +$path_extra = realpath(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'security'; +$path = ini_get('include_path'); +$path = $path_extra . PATH_SEPARATOR . $path; +ini_set('include_path', $path); + + +/** + * Define the random number generator for the OpenID library + * + * To set a source of randomness, define {@link Auth_OpenID_RAND_SOURCE} + * to the path to the randomness source. If your platform does not provide a + * secure randomness source, the library can operate in pseudorandom mode, + * but it is then vulnerable to theoretical attacks. + * If you wish to operate in pseudorandom mode, define + * {@link Auth_OpenID_RAND_SOURCE} to null. + * On a Unix-like platform (including MacOS X), try "/dev/random" and + * "/dev/urandom". + */ +define('Auth_OpenID_RAND_SOURCE', null); + + + +/** + * Register the {@link OpenIDAuthenticator OpenID authenticator} + */ +Authenticator::registerAuthenticator('MemberAuthenticator'); + + +/** + * Register the {@link OpenIDAuthenticator OpenID authenticator} + */ +Authenticator::registerAuthenticator('OpenIDAuthenticator'); + -// include Auth -$path = Director::baseFolder().'/sapphire/security/'; -set_include_path(get_include_path() . PATH_SEPARATOR . $path); ?> \ No newline at end of file diff --git a/security/Authenticator.php b/security/Authenticator.php index 3b8657714..1627d47ba 100644 --- a/security/Authenticator.php +++ b/security/Authenticator.php @@ -18,6 +18,14 @@ */ abstract class Authenticator extends Object { + /** + * This variable holds all authenticators that should be used + * + * @var array + */ + private static $authenticators = array(); + + /** * Method to authenticate an user * @@ -48,6 +56,42 @@ abstract class Authenticator extends Object * @return string Returns the name of the authentication method. */ public abstract static function getName(); + + + /** + * Register a new authenticator + * + * The new authenticator has to exist and to be derived from the + * {@link Authenticator}. + * Every authenticator can be registered only once. + * + * @return bool Returns TRUE on success, FALSE otherwise. + */ + public static function registerAuthenticator($authenticator) { + $authenticator = trim($authenticator); + + if(class_exists($authenticator) == false) + return false; + + if(is_subclass_of($authenticator, 'Authenticator') == false) + return false; + + if(in_array($authenticator, self::$authenticators) == false) + array_push(self::$authenticators, $authenticator); + + return true; + } + + + /** + * Get all registered authenticators + * + * @return array Returns an array with the class names of all registered + * authenticators. + */ + public static function getAuthenticators() { + return self::$authenticators; + } } ?> \ No newline at end of file diff --git a/security/LoginForm.php b/security/LoginForm.php index 903e97b5f..ad5e41c09 100644 --- a/security/LoginForm.php +++ b/security/LoginForm.php @@ -16,13 +16,33 @@ */ abstract class LoginForm extends Form { + /** + * Authenticator class to use with this login form + * + * Set this variable to the authenticator class to use with this login + * form. + * + * @var string + */ + protected $authenticator_class; + + /** * Get the authenticator class * * @return Authenticator Returns the authenticator class for this login * form. */ - public abstract static function getAuthenticator(); + public function getAuthenticator() { + if(!class_exists($this->authenticator_class) || + !is_subclass_of($this->authenticator_class, 'Authenticator')) { + user_error('The form uses an invalid authenticator class!', + E_USER_ERROR); + return; + } + + return new $this->authenticator_class; + } } ?> \ No newline at end of file diff --git a/security/MemberAuthenticator.php b/security/MemberAuthenticator.php index 7f195d648..45ad30d83 100644 --- a/security/MemberAuthenticator.php +++ b/security/MemberAuthenticator.php @@ -63,7 +63,7 @@ class MemberAuthenticator extends Authenticator { * @return string Returns the name of the authentication method. */ public static function getName() { - return "Default login method"; + return "Email & Password"; } } diff --git a/security/MemberLoginForm.php b/security/MemberLoginForm.php index 5a2c520f9..5c2212e53 100644 --- a/security/MemberLoginForm.php +++ b/security/MemberLoginForm.php @@ -31,6 +31,8 @@ class MemberLoginForm extends LoginForm { function __construct($controller, $name, $fields = null, $actions = null, $checkCurrentUser = true) { + $this->authenticator_class = 'MemberAuthenticator'; + $customCSS = project() . '/css/member_login.css'; if(Director::fileExists($customCSS)) { Requirements::css($customCSS); @@ -49,7 +51,8 @@ class MemberLoginForm extends LoginForm { } else { if(!$fields) { $fields = new FieldSet( - new HiddenField("AuthenticationMethod", null, "Member", $this), + new HiddenField("AuthenticationMethod", null, + $this->authenticator_class, $this), new TextField("Email", "Email address", Session::get('SessionForms.MemberLoginForm.Email'), null, $this), new EncryptField("Password", "Password", null, $this), @@ -185,16 +188,6 @@ class MemberLoginForm extends LoginForm { } } - - /** - * Get the authenticator class - * - * @return Authenticator Returns the authenticator class for this login - * form. - */ - public static function getAuthenticator() { - return new MemberAuthenticator; - } } diff --git a/security/OpenIDAuthenticator.php b/security/OpenIDAuthenticator.php index 000405d52..1b1d78095 100644 --- a/security/OpenIDAuthenticator.php +++ b/security/OpenIDAuthenticator.php @@ -25,6 +25,12 @@ require_once "Auth/OpenID/FileStore.php"; require_once "Auth/OpenID/SReg.php"; +//DataObject::addExtension('Member', 'OpenIDAuthenticatedRole'); +//Member::addRole('OpenIDAuthenticatedRole'); + + + + /** * OpenID authenticator diff --git a/security/OpenIDLoginForm.php b/security/OpenIDLoginForm.php index 30e5880f9..836e4460c 100644 --- a/security/OpenIDLoginForm.php +++ b/security/OpenIDLoginForm.php @@ -34,6 +34,9 @@ class OpenIDLoginForm extends LoginForm { */ function __construct($controller, $name, $fields = null, $actions = null, $checkCurrentUser = true) { + + $this->authenticator_class = 'OpenIDAuthenticator'; + $customCSS = project() . '/css/openid_login.css'; if(Director::fileExists($customCSS)) { Requirements::css($customCSS); @@ -52,7 +55,8 @@ class OpenIDLoginForm extends LoginForm { } else { if(!$fields) { $fields = new FieldSet( - new HiddenField("AuthenticationMethod", null, "OpenID"), + new HiddenField("AuthenticationMethod", null, + $this->authenticator_class, $this), new TextField("OpenIDURL", "OpenID URL", Session::get('SessionForms.OpenIDLoginForm.OpenIDURL'), null, $this), new CheckboxField("Remember", "Remember me next time?", @@ -125,19 +129,6 @@ class OpenIDLoginForm extends LoginForm { $s->logout(); } - - /** - * Get the authenticator class - * - * Attention: This method will return the class and not an - * instance of the authenticator class! - * - * @return Authenticator Returns the authenticator class for this login - * form. - */ - public static function getAuthenticator() { - return new OpenIDAuthenticator; - } } diff --git a/security/Security.php b/security/Security.php index 414fc6351..f4e739f71 100644 --- a/security/Security.php +++ b/security/Security.php @@ -93,17 +93,15 @@ class Security extends Controller { function LoginForm() { if(is_array($_REQUEST) && isset($_REQUEST['AuthenticationMethod'])) { - switch($_REQUEST['AuthenticationMethod']) - { - case 'Member': - return MemberAuthenticator::GetLoginForm($this); - break; - case 'OpenID': - return OpenIDAuthenticator::GetLoginForm($this); - break; + $authenticator = trim($_REQUEST['AuthenticationMethod']); + + $authenticators = Authenticator::getAuthenticators(); + if(in_array($authenticator, $authenticators)) { + return call_user_func(array($authenticator, 'GetLoginForm'), $this); } } - user_error('Invalid authentication method', E_USER_ERROR); + + user_error('Passed invalid authentication method', E_USER_ERROR); } @@ -118,8 +116,13 @@ class Security extends Controller { function GetLoginForms() { $forms = array(); - array_push($forms, MemberAuthenticator::GetLoginForm($this)); - array_push($forms, OpenIDAuthenticator::GetLoginForm($this)); + + $authenticators = Authenticator::getAuthenticators(); + foreach($authenticators as $authenticator) { + array_push($forms, + call_user_func(array($authenticator, 'GetLoginForm'), + $this)); + } return $forms; }