mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
mlanthaler: Implemented OpenIDAuthenticatedRole so that the OpenID credentials are now stored in a specific column (gsoc ticket #4). In that way member system is will remain extensible (no restriction due to not support multiple-inheritance).
The role is applied automatically when the OpenIDAuthenticator is registered. (merged from branches/gsoc) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@41911 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
6b378430f4
commit
d6ddbf2cff
@ -76,8 +76,13 @@ abstract class Authenticator extends Object
|
||||
if(is_subclass_of($authenticator, 'Authenticator') == false)
|
||||
return false;
|
||||
|
||||
if(in_array($authenticator, self::$authenticators) == false)
|
||||
array_push(self::$authenticators, $authenticator);
|
||||
if(in_array($authenticator, self::$authenticators) == false) {
|
||||
if(call_user_func(array($authenticator, 'onRegister')) === true) {
|
||||
array_push(self::$authenticators, $authenticator);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -92,6 +97,23 @@ abstract class Authenticator extends Object
|
||||
public static function getAuthenticators() {
|
||||
return self::$authenticators;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback function that is called when the authenticator is registered
|
||||
*
|
||||
* Use this method for initialization of a newly registered authenticator.
|
||||
* Just overload this method and it will be called when the authenticator
|
||||
* is registered.
|
||||
* <b>If the method returns FALSE, the authenticator won't be
|
||||
* registered!</b>
|
||||
*
|
||||
* @return bool Returns TRUE on success, FALSE otherwise.
|
||||
*/
|
||||
protected static function onRegister() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
@ -36,7 +36,7 @@ class MemberAuthenticator extends Authenticator {
|
||||
Session::clear("BackURL");
|
||||
} else if(!is_null($form)) {
|
||||
$form->sessionMessage(
|
||||
"That doesn't seem to be the right email address or password. Please try again.",
|
||||
"That doesn't seem to be the right e-mail address or password. Please try again.",
|
||||
"bad");
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ class MemberAuthenticator extends Authenticator {
|
||||
* @return string Returns the name of the authentication method.
|
||||
*/
|
||||
public static function getName() {
|
||||
return "Email & Password";
|
||||
return "E-mail & Password";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ class MemberLoginForm extends LoginForm {
|
||||
$fields = new FieldSet(
|
||||
new HiddenField("AuthenticationMethod", null,
|
||||
$this->authenticator_class, $this),
|
||||
new TextField("Email", "Email address",
|
||||
new TextField("Email", "E-mail address",
|
||||
Session::get('SessionForms.MemberLoginForm.Email'), null, $this),
|
||||
new EncryptField("Password", "Password", null, $this),
|
||||
new CheckboxField("Remember", "Remember me next time?",
|
||||
@ -114,7 +114,9 @@ class MemberLoginForm extends LoginForm {
|
||||
if($badLoginURL = Session::get("BadLoginURL")) {
|
||||
Director::redirect($badLoginURL);
|
||||
} else {
|
||||
Director::redirectBack();
|
||||
// Show the right tab on failed login
|
||||
Director::redirect(Director::absoluteURL(Security::Link("login")) .
|
||||
'#' . $this->FormName() .'_tab');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -178,7 +180,7 @@ class MemberLoginForm extends LoginForm {
|
||||
|
||||
} else if($data['Email']) {
|
||||
$this->sessionMessage(
|
||||
"Sorry, but I don't recognise the email address. Maybe you need to sign up, or perhaps you used another email address?",
|
||||
"Sorry, but I don't recognise the e-mail address. Maybe you need to sign up, or perhaps you used another e-mail address?",
|
||||
"bad");
|
||||
Director::redirectBack();
|
||||
|
||||
|
143
security/OpenIDAuthenticatedRole.php
Normal file
143
security/OpenIDAuthenticatedRole.php
Normal file
@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* OpenID authentication decorator
|
||||
*
|
||||
* @author Markus Lanthaler <markus@silverstripe.com>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Decorator for the member class to support OpenID authentication
|
||||
*
|
||||
* This class adds the needed fields to the default member class to support
|
||||
* authentication via OpenID.
|
||||
*
|
||||
* @author Markus Lanthaler <markus@silverstripe.com
|
||||
*/
|
||||
class OpenIDAuthenticatedRole extends DataObjectDecorator{
|
||||
|
||||
/**
|
||||
* Edit the given query object to support queries for this extension
|
||||
*/
|
||||
function augmentSQL(SQLQuery &$query) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the database schema as required by this extension
|
||||
*/
|
||||
function augmentDatabase() {
|
||||
/* if(Permission::check('ADMIN')) {
|
||||
$exist = DB::query( "SHOW TABLES LIKE 'ForumMember'" )->numRecords();
|
||||
|
||||
if($exist > 0) {
|
||||
DB::query( "UPDATE `Member`, `ForumMember` " .
|
||||
"SET `Member`.`ClassName` = 'Member'," . "`Member`.`ForumRank` =
|
||||
`ForumMember`.`ForumRank`," . "`Member`.`Occupation` =
|
||||
`ForumMember`.`Occupation`," . "`Member`.`Country` =
|
||||
`ForumMember`.`Country`," . "`Member`.`Nickname` =
|
||||
`ForumMember`.`Nickname`," . "`Member`.`FirstNamePublic` =
|
||||
`ForumMember`.`FirstNamePublic`," . "`Member`.`SurnamePublic` =
|
||||
`ForumMember`.`SurnamePublic`," . "`Member`.`OccupationPublic` =
|
||||
`ForumMember`.`OccupationPublic`," . "`Member`.`CountryPublic` =
|
||||
`ForumMember`.`CountryPublic`," . "`Member`.`EmailPublic` =
|
||||
`ForumMember`.`EmailPublic`," . "`Member`.`AvatarID` =
|
||||
`ForumMember`.`AvatarID`," . "`Member`.`LastViewed` =
|
||||
`ForumMember`.`LastViewed`" . "WHERE `Member`.`ID` =
|
||||
`ForumMember`.`ID`"
|
||||
);
|
||||
echo( "<div style=\"padding:5px; color:white;
|
||||
background-color:blue;\">The data transfer has succeeded. However,
|
||||
to complete it, you must delete the ForumMember table. To do this,
|
||||
execute the query \"DROP TABLE 'ForumMember'\".</div>" );
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Define extra database fields
|
||||
*
|
||||
* Returns a map where the keys are db, has_one, etc, and the values are
|
||||
* additional fields/relations to be defined
|
||||
*
|
||||
* @return array Returns a map where the keys are db, has_one, etc, and
|
||||
* the values are additional fields/relations to be defined
|
||||
*/
|
||||
function extraDBFields() {
|
||||
return array(
|
||||
'db' => array('IdentityURL' => 'Varchar(255)'),
|
||||
'has_one' => array(),
|
||||
'defaults' => array('IdentityURL' => null),
|
||||
'indexes' => array('IdentityURL', 'unique (IdentityURL)')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Change the member dialog in the CMS
|
||||
*
|
||||
* This method updates the form in the member dialog to make it possible
|
||||
* to edit the new database fields.
|
||||
*/
|
||||
function updateCMSFields(FieldSet &$fields) {
|
||||
//if(Permission::checkMember($this->owner->ID, "ACCESS_FORUM")) {
|
||||
$fields->push(new HeaderField("OpenID/i-name credentials"), "OpenIDHeader");
|
||||
$fields->push(new LiteralField("OpenIDDescription",
|
||||
"<p>Make sure you enter your normalized OpenID/i-name credentials here, i.e. with protocol and trailing slash for OpenID (e.g. http://openid.silverstripe.com/).</p>"));
|
||||
$fields->push(new TextField("IdentityURL", "OpenID URL/i-name"), "IdentityURL");
|
||||
|
||||
/*
|
||||
$fields->push(new PasswordField("ConfirmPassword", "Confirm Password"));
|
||||
$fields->push(new ImageField("Avatar", "Upload avatar"));
|
||||
$fields->push(new DropdownField("ForumRank", "User rating",
|
||||
array("Community Member" => "Community Member",
|
||||
"Administrator" => "Administrator",
|
||||
"Moderator" => "Moderator",
|
||||
"SilverStripe User" => "SilverStripe User",
|
||||
"SilverStripe Developer" => "SilverStripe Developer",
|
||||
"Core Development Team" => "Core Development Team",
|
||||
"Google Summer of Code Hacker" => "Google Summer of Code Hacker",
|
||||
"Lead Developer" => "Lead Developer")
|
||||
)
|
||||
);
|
||||
}*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the current user edit the given member?
|
||||
*
|
||||
* Only the user itself or an administrator can edit an user account.
|
||||
*
|
||||
* @return bool Returns TRUE if this member can be edited, FALSE otherwise
|
||||
*/
|
||||
function canEdit() {
|
||||
if($this->owner->ID == Member::currentUserID())
|
||||
return true;
|
||||
|
||||
$member = Member::currentUser();
|
||||
if($member)
|
||||
return $member->isAdmin();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Factory method for the member validator
|
||||
*
|
||||
* @return Member_Validator Returns an instance of a
|
||||
* {@link Member_Validator} object.
|
||||
*/
|
||||
function getValidator() {
|
||||
die('<p style="color: red;">Called getValidator()</p>');
|
||||
return new Member_Validator();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
@ -39,13 +39,30 @@ require_once "Auth/OpenID/SReg.php";
|
||||
*/
|
||||
class OpenIDAuthenticator extends Authenticator {
|
||||
|
||||
/**
|
||||
* Callback function that is called when the authenticator is registered
|
||||
*
|
||||
* Use this method for initialization of a newly registered authenticator.
|
||||
* Just overload this method and it will be called when the authenticator
|
||||
* is registered.
|
||||
* <b>If the method returns FALSE, the authenticator won't be
|
||||
* registered!</b>
|
||||
*
|
||||
* @return bool Returns TRUE on success, FALSE otherwise.
|
||||
*/
|
||||
protected static function onRegister() {
|
||||
Member::addRole('OpenIDAuthenticatedRole');
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to authenticate an user
|
||||
*
|
||||
* @param array $RAW_data Raw data to authenticate the user
|
||||
* @param Form $form Optional: If passed, better error messages can be
|
||||
* produced by using
|
||||
* {@link Form::sessionMessage()}
|
||||
* @param Form $form Optional: If passed, better error messages can be
|
||||
* produced by using
|
||||
* {@link Form::sessionMessage()}
|
||||
* @return bool Returns FALSE if authentication fails, otherwise the
|
||||
* method will not return at all because the browser will be
|
||||
* redirected to some other server.
|
||||
@ -54,7 +71,16 @@ class OpenIDAuthenticator extends Authenticator {
|
||||
* (without rendering a form and using javascript)
|
||||
*/
|
||||
public function authenticate(array $RAW_data, Form $form = null) {
|
||||
$openid = $RAW_data['OpenIDURL'];
|
||||
$openid = trim($RAW_data['OpenIDURL']);
|
||||
|
||||
if(strlen($openid) == 0) {
|
||||
if(!is_null($form)) {
|
||||
$form->sessionMessage("Please enter your OpenID URL or your i-name.",
|
||||
"bad");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$trust_root = Director::absoluteBaseURL();
|
||||
$return_to_url = $trust_root . 'OpenIDAuthenticator_Controller';
|
||||
@ -74,8 +100,9 @@ class OpenIDAuthenticator extends Authenticator {
|
||||
return false;
|
||||
}
|
||||
|
||||
$SQL_user = Convert::raw2sql($auth_request->endpoint->claimed_id);
|
||||
if(!($member = DataObject::get_one("Member", "Email = '$SQL_user'"))) {
|
||||
$SQL_identity = Convert::raw2sql($auth_request->endpoint->claimed_id);
|
||||
if(!($member = DataObject::get_one("Member",
|
||||
"Member.IdentityURL = '$SQL_identity'"))) {
|
||||
if(!is_null($form)) {
|
||||
$form->sessionMessage("Either your account is not enabled for " .
|
||||
"OpenID/i-name authentication " .
|
||||
@ -89,10 +116,12 @@ class OpenIDAuthenticator extends Authenticator {
|
||||
|
||||
if($auth_request->shouldSendRedirect()) {
|
||||
// For OpenID 1, send a redirect.
|
||||
$redirect_url = $auth_request->redirectURL($trust_root, $return_to_url);
|
||||
$redirect_url = $auth_request->redirectURL($trust_root,
|
||||
$return_to_url);
|
||||
|
||||
if(Auth_OpenID::isFailure($redirect_url)) {
|
||||
displayError("Could not redirect to server: " . $redirect_url->message);
|
||||
displayError("Could not redirect to server: " .
|
||||
$redirect_url->message);
|
||||
} else {
|
||||
Director::redirect($redirect_url);
|
||||
}
|
||||
@ -102,16 +131,19 @@ class OpenIDAuthenticator extends Authenticator {
|
||||
// server.
|
||||
$form_id = 'openid_message';
|
||||
$form_html = $auth_request->formMarkup($trust_root, $return_to_url,
|
||||
false, array('id' => $form_id));
|
||||
false,
|
||||
array('id' => $form_id));
|
||||
|
||||
if(Auth_OpenID::isFailure($form_html)) {
|
||||
displayError("Could not redirect to server: " . $form_html->message);
|
||||
displayError("Could not redirect to server: " .
|
||||
$form_html->message);
|
||||
} else {
|
||||
$page_contents = array(
|
||||
"<html><head><title>",
|
||||
"OpenID transaction in progress",
|
||||
"</title></head>",
|
||||
"<body onload='document.getElementById(\"".$form_id."\").submit()'>",
|
||||
"<body onload='document.getElementById(\"". $form_id .
|
||||
"\").submit()'>",
|
||||
$form_html,
|
||||
"<p>Click "Continue" to login. You are only seeing " .
|
||||
"this because you appear to have JavaScript disabled.</p>",
|
||||
@ -129,8 +161,8 @@ class OpenIDAuthenticator extends Authenticator {
|
||||
/**
|
||||
* Method that creates the login form for this authentication method
|
||||
*
|
||||
* @param Controller The parent controller, necessary to create the
|
||||
* appropriate form action tag
|
||||
* @param Controller The parent controller, necessary to create the
|
||||
* appropriate form action tag
|
||||
* @return Form Returns the login form to use with this authentication
|
||||
* method
|
||||
*/
|
||||
@ -139,12 +171,12 @@ class OpenIDAuthenticator extends Authenticator {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the name of the authentication method
|
||||
*
|
||||
* @return string Returns the name of the authentication method.
|
||||
*/
|
||||
public static function getName() {
|
||||
/**
|
||||
* Get the name of the authentication method
|
||||
*
|
||||
* @return string Returns the name of the authentication method.
|
||||
*/
|
||||
public static function getName() {
|
||||
return "OpenID/i-name";
|
||||
}
|
||||
}
|
||||
@ -202,10 +234,9 @@ class OpenIDAuthenticator_Controller extends Controller {
|
||||
|
||||
} else if($response->status == Auth_OpenID_SUCCESS) {
|
||||
$openid = $response->identity_url;
|
||||
$user = $openid;
|
||||
|
||||
if($response->endpoint->canonicalID) {
|
||||
$user = $response->endpoint->canonicalID;
|
||||
$openid = $response->endpoint->canonicalID;
|
||||
}
|
||||
|
||||
|
||||
@ -213,10 +244,12 @@ class OpenIDAuthenticator_Controller extends Controller {
|
||||
Profiler::unmark("OpenIDAuthenticator_Controller");
|
||||
|
||||
|
||||
$SQL_user = Convert::raw2sql($user);
|
||||
if($member = DataObject::get_one("Member", "Email = '$SQL_user'")) {
|
||||
$SQL_identity = Convert::raw2sql($openid);
|
||||
if($member = DataObject::get_one("Member",
|
||||
"Member.IdentityURL = '$SQL_identity'")) {
|
||||
$firstname = Convert::raw2xml($member->FirstName);
|
||||
Session::set("Security.Message.message", "Welcome Back, {$firstname}");
|
||||
Session::set("Security.Message.message",
|
||||
"Welcome Back, {$firstname}");
|
||||
Session::set("Security.Message.type", "good");
|
||||
|
||||
$member->LogIn(
|
||||
|
@ -111,7 +111,9 @@ class OpenIDLoginForm extends LoginForm {
|
||||
if($badLoginURL = Session::get("BadLoginURL")){
|
||||
Director::redirect($badLoginURL);
|
||||
} else {
|
||||
Director::redirectBack();
|
||||
// Show the right tab on failed login
|
||||
Director::redirect(Director::absoluteURL(Security::Link("login")) .
|
||||
'#' . $this->FormName() .'_tab');
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user