Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
635be284de | ||
|
90ba326f85 | ||
|
09cf21aa7e | ||
|
3acd0e8db4 | ||
|
e1655f0e22 | ||
|
3afbf11087 | ||
|
8258c39e54 | ||
|
da38761814 | ||
|
9ac32984eb | ||
|
1ab3c45d71 | ||
|
14640ed8a5 | ||
|
16c08eb3b6 |
@ -105,11 +105,15 @@
|
|||||||
channel="pear.php.net"
|
channel="pear.php.net"
|
||||||
minimum_version="0.4.0"
|
minimum_version="0.4.0"
|
||||||
/>
|
/>
|
||||||
<!-- unit tests: -->
|
|
||||||
<package name="HTML_Request2"
|
<package name="HTML_Request2"
|
||||||
channel="pear.php.net"
|
channel="pear.php.net"
|
||||||
minimum_version="2.0.0"
|
minimum_version="2.0.0"
|
||||||
/>
|
/>
|
||||||
|
<package name="Net_WebFinger"
|
||||||
|
channel="pear.php.net"
|
||||||
|
minimum_version="0.2.0"
|
||||||
|
/>
|
||||||
|
<!-- unit tests: -->
|
||||||
<package name="Stream_Var"
|
<package name="Stream_Var"
|
||||||
channel="pear.php.net"
|
channel="pear.php.net"
|
||||||
minimum_version="1.1.0"
|
minimum_version="1.1.0"
|
||||||
|
@ -79,6 +79,15 @@ CREATE TABLE `sc_users` (
|
|||||||
|
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE TABLE `sc_users_openids` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`uId` int(11) NOT NULL,
|
||||||
|
`url` varchar(255) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
CREATE TABLE `sc_users_sslclientcerts` (
|
CREATE TABLE `sc_users_sslclientcerts` (
|
||||||
`id` INT NOT NULL AUTO_INCREMENT ,
|
`id` INT NOT NULL AUTO_INCREMENT ,
|
||||||
`uId` INT NOT NULL ,
|
`uId` INT NOT NULL ,
|
||||||
|
48
data/templates/default/editprofile-openid.tpl.php
Normal file
48
data/templates/default/editprofile-openid.tpl.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* User's own profile page: OpenID management
|
||||||
|
*
|
||||||
|
* @param array $openIds Array of OpenID association objects
|
||||||
|
* @param string $formaction URL where to send the forms to
|
||||||
|
* @param SemanticScuttle_Model_User_OpenId
|
||||||
|
* $currentOpenId Current OpenID object (may be null)
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
<h3><?php echo T_('OpenIDs'); ?></h3>
|
||||||
|
<?php if (count($openIds)) { ?>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Options</th>
|
||||||
|
<th><?php echo T_('OpenID URL'); ?></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach($openIds as $openId) { ?>
|
||||||
|
<tr <?php if ($openId->isCurrent()) { echo 'class="openid-current"'; } ?>>
|
||||||
|
<td>
|
||||||
|
<form method="post" action="<?php echo $formaction; ?>">
|
||||||
|
<input type="hidden" name="openIdUrl" value="<?php echo htmlspecialchars($openId->url); ?>"/>
|
||||||
|
<button type="submit" name="action" value="deleteOpenId">
|
||||||
|
<?php echo T_('delete'); ?>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
<td><?php echo htmlspecialchars($openId->url); ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php } ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<?php } else { ?>
|
||||||
|
<p><?php echo T_('No OpenIDs registered'); ?></p>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<form method="post" action="<?php echo $formaction; ?>">
|
||||||
|
<label for="openid"><?php echo T_('New E-Mail or OpenID'); ?></label>
|
||||||
|
<input type="text" id="openid" name="openid_identifier" size="20" />
|
||||||
|
<button type="submit" name="action" value="registerOpenId">
|
||||||
|
<?php echo T_('Register'); ?>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</p>
|
@ -59,6 +59,7 @@ $this->includeTemplate($GLOBALS['top_include']);
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<?php include 'editprofile-openid.tpl.php'; ?>
|
||||||
<?php include 'editprofile-sslclientcerts.tpl.php'; ?>
|
<?php include 'editprofile-sslclientcerts.tpl.php'; ?>
|
||||||
<h3><?php echo T_('Actions'); ?></h3>
|
<h3><?php echo T_('Actions'); ?></h3>
|
||||||
<table class="profile">
|
<table class="profile">
|
||||||
|
@ -17,6 +17,15 @@ if (!$userservice->isSessionStable()) {
|
|||||||
<form action="<?php echo $formaction; ?>" method="post">
|
<form action="<?php echo $formaction; ?>" method="post">
|
||||||
<div><input type="hidden" name="query" value="<?php echo $querystring; ?>" /></div>
|
<div><input type="hidden" name="query" value="<?php echo $querystring; ?>" /></div>
|
||||||
<table>
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th align="left"><label for="openid"><?php echo T_('E-Mail or OpenID'); ?></label></th>
|
||||||
|
<td><input type="text" id="openid" name="openid_identifier" size="20" /></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td colspan="2" class="login-or">or</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th align="left"><label for="username"><?php echo T_('Username'); ?></label></th>
|
<th align="left"><label for="username"><?php echo T_('Username'); ?></label></th>
|
||||||
<td><input type="text" id="username" name="username" size="20" /></td>
|
<td><input type="text" id="username" name="username" size="20" /></td>
|
||||||
|
@ -8,7 +8,7 @@ Prerequisites
|
|||||||
=============
|
=============
|
||||||
To run SemanticScuttle, you need:
|
To run SemanticScuttle, you need:
|
||||||
|
|
||||||
- PHP5 with filter functions enabled
|
- PHP5
|
||||||
- A web server, for example Apache
|
- A web server, for example Apache
|
||||||
|
|
||||||
|
|
||||||
|
BIN
doc/developers/OpenID-loginprocess.dia
Normal file
BIN
doc/developers/OpenID-loginprocess.dia
Normal file
Binary file not shown.
82
doc/developers/OpenID.rst
Normal file
82
doc/developers/OpenID.rst
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
**************
|
||||||
|
OpenID support
|
||||||
|
**************
|
||||||
|
|
||||||
|
Since SemanticScuttle 0.99.0, users may log in via OpenID.
|
||||||
|
|
||||||
|
=============
|
||||||
|
Login Process
|
||||||
|
=============
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
.
|
||||||
|
+------------------+
|
||||||
|
/ OpenID URL entry /
|
||||||
|
+------------------+
|
||||||
|
|
|
||||||
|
v
|
||||||
|
+----------------------------+ Cancel +------------+
|
||||||
|
| Request to OpenID provider | ------------------------> | Login fail |
|
||||||
|
+----------------------------+ +------------+
|
||||||
|
| Success ^
|
||||||
|
_____ v ________________________ | No
|
||||||
|
/ \ No +----------------------------+
|
||||||
|
| OpenID associated with a user? | ----------> | User registration enabled? |
|
||||||
|
\________________________________/ +----------------------------+
|
||||||
|
| | Yes
|
||||||
|
| Yes v
|
||||||
|
| +-------------------------+
|
||||||
|
| / Registration form /
|
||||||
|
| / prefilled with data /
|
||||||
|
| / from OpenID provider /
|
||||||
|
| / /
|
||||||
|
| / Password not required /
|
||||||
|
| / Email not required /
|
||||||
|
| +-------------------------+
|
||||||
|
| |
|
||||||
|
v v
|
||||||
|
+-------+ +----------------+
|
||||||
|
| Login | <----------------------------------------- | Create account |
|
||||||
|
+-------+ +----------------+
|
||||||
|
|
|
||||||
|
_____v_______________
|
||||||
|
/ \ Yes +------------------+
|
||||||
|
| Data update active? |------------> | Update user data |
|
||||||
|
\_____________________/ | from OpenID |
|
||||||
|
| +------------------+
|
||||||
|
v |
|
||||||
|
+----------------+ |
|
||||||
|
| Login finished | <--------------------------+
|
||||||
|
+----------------+
|
||||||
|
|
||||||
|
|
||||||
|
Automatic registration?
|
||||||
|
=======================
|
||||||
|
No. We show the user the login form prefilled with data.
|
||||||
|
|
||||||
|
1. It prevents users from creating several accounts when they use multiple
|
||||||
|
OpenIDs and forgot which they used in this instance.
|
||||||
|
2. In case the user name is already taken, we need to ask for a new user name
|
||||||
|
anyway.
|
||||||
|
3. People may not want to use the data from their OpenID provider when
|
||||||
|
registering
|
||||||
|
|
||||||
|
Discussion on this topic happened in http://drupal.org/node/637850
|
||||||
|
|
||||||
|
|
||||||
|
=====
|
||||||
|
Links
|
||||||
|
=====
|
||||||
|
|
||||||
|
- http://stackoverflow.com/questions/4564337/guidance-on-flow-for-openid-registration-form
|
||||||
|
- http://stackoverflow.com/questions/1316983/to-openid-or-not-to-openid-is-it-worth-it
|
||||||
|
- http://wiki.openid.net/w/page/12995223/Relying%20Party%20Best%20Practices
|
||||||
|
|
||||||
|
====
|
||||||
|
TODO
|
||||||
|
====
|
||||||
|
Blog post:
|
||||||
|
|
||||||
|
- automatic registration
|
||||||
|
- openid login/registration process flow chart
|
33
src/SemanticScuttle/Exception.php
Normal file
33
src/SemanticScuttle/Exception.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'SemanticScuttle/Exception/User.php';
|
||||||
|
|
||||||
|
class SemanticScuttle_Exception extends Exception
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns an error message that can be shown to the user.
|
||||||
|
*
|
||||||
|
* FIXME: maybe move that method to somewhere else
|
||||||
|
*
|
||||||
|
* @return string Error message to display to the user
|
||||||
|
*/
|
||||||
|
public static function getErrorMessage(Exception $e)
|
||||||
|
{
|
||||||
|
if ($e instanceof SemanticScuttle_Exception_User) {
|
||||||
|
if (isset($GLOBALS['debugMode']) && $GLOBALS['debugMode']) {
|
||||||
|
$prev = $e->getPrevious();
|
||||||
|
if ($prev) {
|
||||||
|
$msg = $prev->getMessage();
|
||||||
|
} else {
|
||||||
|
$msg = $e->getMessage();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$msg = $e->getMessage();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$msg = $e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $msg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
10
src/SemanticScuttle/Exception/User.php
Normal file
10
src/SemanticScuttle/Exception/User.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Exception class whose message may be displayed to users in the frontend.
|
||||||
|
*
|
||||||
|
* The detailled message is in the previous exception (getPrevious()).
|
||||||
|
*/
|
||||||
|
class SemanticScuttle_Exception_User extends Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
?>
|
60
src/SemanticScuttle/Model/OpenId.php
Normal file
60
src/SemanticScuttle/Model/OpenId.php
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* SemanticScuttle - your social bookmark manager.
|
||||||
|
*
|
||||||
|
* PHP version 5.
|
||||||
|
*
|
||||||
|
* @category Bookmarking
|
||||||
|
* @package SemanticScuttle
|
||||||
|
* @author Christian Weiske <cweiske@cweiske.de>
|
||||||
|
* @license AGPL http://www.gnu.org/licenses/agpl.html
|
||||||
|
* @link http://sourceforge.net/projects/semanticscuttle
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OpenID model. Represents one single OpenID association to a user.
|
||||||
|
*
|
||||||
|
* @category Bookmarking
|
||||||
|
* @package SemanticScuttle
|
||||||
|
* @author Christian Weiske <cweiske@cweiske.de>
|
||||||
|
* @license AGPL http://www.gnu.org/licenses/agpl.html
|
||||||
|
* @link http://sourceforge.net/projects/semanticscuttle
|
||||||
|
*/
|
||||||
|
class SemanticScuttle_Model_OpenId
|
||||||
|
{
|
||||||
|
public $id;
|
||||||
|
public $uId;
|
||||||
|
public $url;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a new object and fills it with
|
||||||
|
* the passed values from the database.
|
||||||
|
*
|
||||||
|
* @param array $arOpenIdRow Database row array
|
||||||
|
*
|
||||||
|
* @return SemanticScuttle_Model_OpenId
|
||||||
|
*/
|
||||||
|
public static function fromDb($arOpenIdRow)
|
||||||
|
{
|
||||||
|
$openId = new self();
|
||||||
|
foreach (get_object_vars($openId) as $variable => $dummy) {
|
||||||
|
if (isset($arOpenIdRow[$variable])) {
|
||||||
|
$openId->$variable = $arOpenIdRow[$variable];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $openId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns if this OpenID is the one the user is logged in with currently.
|
||||||
|
*
|
||||||
|
* @return boolean True if the User logged in with this OpenID
|
||||||
|
*/
|
||||||
|
public function isCurrent()
|
||||||
|
{
|
||||||
|
//FIXME
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
378
src/SemanticScuttle/Service/OpenId.php
Normal file
378
src/SemanticScuttle/Service/OpenId.php
Normal file
@ -0,0 +1,378 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* SemanticScuttle - your social bookmark manager.
|
||||||
|
*
|
||||||
|
* PHP version 5.
|
||||||
|
*
|
||||||
|
* @category Bookmarking
|
||||||
|
* @package SemanticScuttle
|
||||||
|
* @author Christian Weiske <cweiske@cweiske.de>
|
||||||
|
* @license AGPL http://www.gnu.org/licenses/agpl.html
|
||||||
|
* @link http://sourceforge.net/projects/semanticscuttle
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once 'SemanticScuttle/Exception/User.php';
|
||||||
|
require_once 'SemanticScuttle/Model/OpenId.php';
|
||||||
|
require_once 'OpenID.php';
|
||||||
|
require_once 'OpenID/RelyingParty.php';
|
||||||
|
require_once 'OpenID/Extension/SREG11.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SemanticScuttle OpenID verification and management
|
||||||
|
*
|
||||||
|
* @category Bookmarking
|
||||||
|
* @package SemanticScuttle
|
||||||
|
* @author Christian Weiske <cweiske@cweiske.de>
|
||||||
|
* @license AGPL http://www.gnu.org/licenses/agpl.html
|
||||||
|
* @link http://sourceforge.net/projects/semanticscuttle
|
||||||
|
*/
|
||||||
|
class SemanticScuttle_Service_OpenId extends SemanticScuttle_DbService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Creates a new instance, sets database variable and table name.
|
||||||
|
*
|
||||||
|
* @param sql_db $db Database object
|
||||||
|
*/
|
||||||
|
protected function __construct($db)
|
||||||
|
{
|
||||||
|
$this->db = $db;
|
||||||
|
$this->tablename = $GLOBALS['tableprefix'] . 'users_openids';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the single service instance
|
||||||
|
*
|
||||||
|
* @param sql_db $db Database object
|
||||||
|
*
|
||||||
|
* @return SemanticScuttle_Service_OpenId
|
||||||
|
*/
|
||||||
|
public static function getInstance($db)
|
||||||
|
{
|
||||||
|
static $instance;
|
||||||
|
if (!isset($instance)) {
|
||||||
|
$instance = new self($db);
|
||||||
|
}
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the user gives an e-mail address instead of an OpenID, we use
|
||||||
|
* WebFinger to find his OpenID.
|
||||||
|
*
|
||||||
|
* @param string $identifier OpenID URL OR e-mail address
|
||||||
|
*
|
||||||
|
* @return string Raw/unnormalized OpenID URL.
|
||||||
|
*
|
||||||
|
* @throws SemanticScuttle_Exception_User When the user's mail host does not
|
||||||
|
* support WebFinger
|
||||||
|
*/
|
||||||
|
protected function resolveEmailIdentifier($identifier)
|
||||||
|
{
|
||||||
|
if (filter_var($identifier, FILTER_VALIDATE_EMAIL) === false) {
|
||||||
|
//no valid email
|
||||||
|
return $identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once 'Net/WebFinger.php';
|
||||||
|
require_once 'HTTP/Request2.php';
|
||||||
|
|
||||||
|
$req = new HTTP_Request2();
|
||||||
|
$req->setConfig('follow_redirects', true);
|
||||||
|
$req->setHeader('User-Agent', 'SemanticScuttle');
|
||||||
|
|
||||||
|
$wf = new Net_WebFinger();
|
||||||
|
$wf->setHttpClient($req);
|
||||||
|
$react = $wf->finger($identifier);
|
||||||
|
if ($react->openid === null) {
|
||||||
|
throw new SemanticScuttle_Exception_User(
|
||||||
|
'No OpenID found for the given email address ' . $identifier,
|
||||||
|
20
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $react->openid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Part 1 of the OpenID login process: Send user to his identity provider.
|
||||||
|
*
|
||||||
|
* If an e-mail address is given, a WebFinger lookup is made to find out the
|
||||||
|
* user's OpenID.
|
||||||
|
*
|
||||||
|
* This method exits the PHP process.
|
||||||
|
*
|
||||||
|
* @param string $identifier OpenID URL OR e-mail address
|
||||||
|
* @param string $returnUrl URL the identity provider shall send the user
|
||||||
|
* back to
|
||||||
|
*
|
||||||
|
* @return void No return value needed since it exits.
|
||||||
|
*
|
||||||
|
* @throws SemanticScuttle_Exception_User When something goes wrong
|
||||||
|
*/
|
||||||
|
public function sendIdRequest($identifier, $returnUrl)
|
||||||
|
{
|
||||||
|
$identifier = $this->resolveEmailIdentifier($identifier);
|
||||||
|
|
||||||
|
//send request to ID provider
|
||||||
|
try {
|
||||||
|
$identifier = OpenID::normalizeIdentifier($identifier);
|
||||||
|
} catch (OpenID_Exception $e) {
|
||||||
|
throw new SemanticScuttle_Exception_User(
|
||||||
|
'Invalid OpenID identifier', 11, $e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$rp = new OpenID_RelyingParty(
|
||||||
|
$returnUrl,
|
||||||
|
addProtocolToUrl(ROOT)/* realm */,
|
||||||
|
$identifier
|
||||||
|
);
|
||||||
|
$authRequest = $rp->prepare();
|
||||||
|
|
||||||
|
//FIXME: when user exists already, use immediate mode first and
|
||||||
|
// fall back to normal when it fails
|
||||||
|
//FIXME: (?) when user exists already, don't request details
|
||||||
|
|
||||||
|
$sreg = new OpenID_Extension_SREG11(OpenID_Extension::REQUEST);
|
||||||
|
//$sreg->set('required', 'email');
|
||||||
|
$sreg->set('optional', 'email,nickname,fullname');
|
||||||
|
$authRequest->addExtension($sreg);
|
||||||
|
//$auth->setMode(OpenID::MODE_CHECKID_IMMEDIATE);
|
||||||
|
header('Location: ' . $authRequest->getAuthorizeURL());
|
||||||
|
exit();
|
||||||
|
} catch (OpenID_Exception $e) {
|
||||||
|
throw new SemanticScuttle_Exception_User(
|
||||||
|
'Error communicating with OpenID identity server', 12, $e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Part 2 of the OpenID login process: Handle the IDP response
|
||||||
|
*
|
||||||
|
* @param string $returnUrl URL the identity provider shall send the user
|
||||||
|
* back to
|
||||||
|
*
|
||||||
|
* @return array Array with user data. Keys:
|
||||||
|
* - identifier - OpenID URL/identifier
|
||||||
|
* - userId - Local user ID from database
|
||||||
|
* - email - OpenID-submitted email
|
||||||
|
* - nickname - OpenID-submitted nickname
|
||||||
|
* - fullname - OpenID-submitted full name
|
||||||
|
*
|
||||||
|
* @throws SemanticScuttle_Exception_User When something goes wrong
|
||||||
|
*/
|
||||||
|
public function handleIdResponse($returnUrl)
|
||||||
|
{
|
||||||
|
$rp = new OpenID_RelyingParty(
|
||||||
|
$returnUrl,
|
||||||
|
addProtocolToUrl(ROOT)/* realm */
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!count($_POST)) {
|
||||||
|
list(, $queryString) = explode('?', $_SERVER['REQUEST_URI']);
|
||||||
|
} else {
|
||||||
|
$queryString = file_get_contents('php://input');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$request = new Net_URL2($returnUrl . '?' . $queryString);
|
||||||
|
$message = new OpenID_Message($queryString, OpenID_Message::FORMAT_HTTP);
|
||||||
|
$mode = $message->get('openid.mode');
|
||||||
|
|
||||||
|
if ($mode == 'cancel') {
|
||||||
|
throw new SemanticScuttle_Exception_User(
|
||||||
|
'OpenID login cancelled', 10
|
||||||
|
);
|
||||||
|
} else if ($mode == 'setup_needed') {
|
||||||
|
throw new SemanticScuttle_Exception_User(
|
||||||
|
'Immediate OpenID login not possible', 12
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $rp->verify($request, $message);
|
||||||
|
if (!$result->success()) {
|
||||||
|
throw new SemanticScuttle_Exception_User(
|
||||||
|
'OpenID verification failed', 13
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$identifier = $message->get('openid.claimed_id');
|
||||||
|
} catch (OpenID_Exception $e) {
|
||||||
|
throw new SemanticScuttle_Exception_User(
|
||||||
|
'Unknown OpenID error', 14, $e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$identifier = OpenID::normalizeIdentifier($identifier);
|
||||||
|
} catch (OpenID_Exception $e) {
|
||||||
|
throw new SemanticScuttle_Exception_User(
|
||||||
|
'Invalid OpenID identifier', 11, $e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'identifier' => $identifier,
|
||||||
|
'userId' => $this->getUserId($identifier),
|
||||||
|
'email' => $message->get('openid.sreg.email'),
|
||||||
|
'nickname' => $message->get('openid.sreg.nickname'),
|
||||||
|
'fullname' => $message->get('openid.sreg.fullname'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the user ID for the given OpenID identifier.
|
||||||
|
*
|
||||||
|
* @param string $identifier OpenID identifier (URL)
|
||||||
|
*
|
||||||
|
* @return integer User ID or NULL if not found
|
||||||
|
*
|
||||||
|
* @throws SemanticScuttle_Exception_User When the identifier is invalid
|
||||||
|
*/
|
||||||
|
public function getUserId($identifier)
|
||||||
|
{
|
||||||
|
$query = 'SELECT sc_users_openids.uId'
|
||||||
|
. ' FROM sc_users_openids JOIN sc_users USING (uId)'
|
||||||
|
. ' WHERE url = "' . $this->db->sql_escape($identifier) . '"';
|
||||||
|
|
||||||
|
if (!($dbresult = $this->db->sql_query($query))) {
|
||||||
|
message_die(
|
||||||
|
GENERAL_ERROR,
|
||||||
|
'Could not get user',
|
||||||
|
'', __LINE__, __FILE__, $query, $this->db
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$row = $this->db->sql_fetchrow($dbresult);
|
||||||
|
$this->db->sql_freeresult($dbresult);
|
||||||
|
if (!$row) {
|
||||||
|
//OpenID not found in database.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return $row['uId'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an OpenID to a given user
|
||||||
|
*
|
||||||
|
* @param integer $uId User ID to attach the OpenID to
|
||||||
|
* @param string $identifier OpenID identifier (URL)
|
||||||
|
* @param string $email OpenID-delivered e-mail address of the user
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws SemanticScuttle_Exception When something goes wrong,
|
||||||
|
* e.g. the OpenID is already registered
|
||||||
|
*/
|
||||||
|
public function register($uId, $identifier, $email = null)
|
||||||
|
{
|
||||||
|
if ($this->getId($identifier) !== null) {
|
||||||
|
//already registered
|
||||||
|
throw new SemanticScuttle_Exception_User(
|
||||||
|
'OpenID already registered: ' . $identifier,
|
||||||
|
21
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//FIXME: use email when google-openid
|
||||||
|
$query = 'INSERT INTO ' . $this->getTableName()
|
||||||
|
. ' ' . $this->db->sql_build_array(
|
||||||
|
'INSERT', array(
|
||||||
|
'uId' => $uId,
|
||||||
|
'url' => $identifier,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (!($dbresult = $this->db->sql_query($query))) {
|
||||||
|
message_die(
|
||||||
|
GENERAL_ERROR, 'Could not register OpenID',
|
||||||
|
'', __LINE__, __FILE__, $query, $this->db
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the OpenID with the given numeric database ID
|
||||||
|
*
|
||||||
|
* @param integer $id Numeric ID from database
|
||||||
|
*
|
||||||
|
* @return boolean True if it worked, false if not
|
||||||
|
*/
|
||||||
|
public function delete($id)
|
||||||
|
{
|
||||||
|
if ($id instanceof SemanticScuttle_Model_OpenId) {
|
||||||
|
$id = $id->id;
|
||||||
|
}
|
||||||
|
$id = (int)$id;
|
||||||
|
|
||||||
|
$query = 'DELETE FROM ' . $this->getTableName()
|
||||||
|
.' WHERE id = ' . $id;
|
||||||
|
|
||||||
|
if (!($dbresult = $this->db->sql_query($query))) {
|
||||||
|
message_die(
|
||||||
|
GENERAL_ERROR, 'Could not delete OpenID',
|
||||||
|
'', __LINE__, __FILE__, $query, $this->db
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads an OpenID object from the given identifiert
|
||||||
|
*
|
||||||
|
* @param string $identifier OpenID identifier (URL)
|
||||||
|
*
|
||||||
|
* @return SemanticScuttle_Model_OpenId OpenID object or NULL if not found
|
||||||
|
*/
|
||||||
|
public function getId($identifier)
|
||||||
|
{
|
||||||
|
$query = 'SELECT * FROM ' . $this->getTableName()
|
||||||
|
. ' WHERE url = "' . $this->db->sql_escape($identifier) . '"';
|
||||||
|
if (!($dbresult = $this->db->sql_query($query))) {
|
||||||
|
message_die(
|
||||||
|
GENERAL_ERROR, 'Could not load OpenID',
|
||||||
|
'', __LINE__, __FILE__, $query, $this->db
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($row = $this->db->sql_fetchrow($dbresult)) {
|
||||||
|
$cert = SemanticScuttle_Model_OpenId::fromDb($row);
|
||||||
|
} else {
|
||||||
|
$cert = null;
|
||||||
|
}
|
||||||
|
$this->db->sql_freeresult($dbresult);
|
||||||
|
return $cert;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch all OpenIDs the given user has attached
|
||||||
|
*
|
||||||
|
* @param integer $uId User ID to fetch registered OpenIDs for
|
||||||
|
*
|
||||||
|
* @return array Array of SemanticScuttle_Model_OpenId objects
|
||||||
|
*/
|
||||||
|
public function getIds($uId)
|
||||||
|
{
|
||||||
|
$query = 'SELECT * FROM ' . $this->getTableName()
|
||||||
|
. ' WHERE uId = ' . (int)$uId
|
||||||
|
. ' ORDER BY url ASC';
|
||||||
|
if (!($dbresult = $this->db->sql_query($query))) {
|
||||||
|
message_die(
|
||||||
|
GENERAL_ERROR, 'Could not load OpenIDs',
|
||||||
|
'', __LINE__, __FILE__, $query, $this->db
|
||||||
|
);
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$certs = array();
|
||||||
|
while ($row = $this->db->sql_fetchrow($dbresult)) {
|
||||||
|
$certs[] = SemanticScuttle_Model_OpenId::fromDb($row);
|
||||||
|
}
|
||||||
|
$this->db->sql_freeresult($dbresult);
|
||||||
|
return $certs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
@ -96,15 +96,12 @@ if (DEBUG_MODE) {
|
|||||||
error_reporting(0);
|
error_reporting(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2 // Second requirements part which could display bugs
|
require_once 'silex.phar';
|
||||||
// (must come after debug management)
|
//modify silex/symfony autoloader
|
||||||
require_once 'SemanticScuttle/Service.php';
|
$loader->useIncludePath(true);
|
||||||
require_once 'SemanticScuttle/DbService.php';
|
|
||||||
require_once 'SemanticScuttle/Service/Factory.php';
|
|
||||||
require_once 'SemanticScuttle/functions.php';
|
require_once 'SemanticScuttle/functions.php';
|
||||||
require_once 'SemanticScuttle/Model/Bookmark.php';
|
|
||||||
require_once 'SemanticScuttle/Model/UserArray.php';
|
|
||||||
require_once 'SemanticScuttle/Model/User/SslClientCert.php';
|
|
||||||
|
|
||||||
if (count($GLOBALS['serviceoverrides']) > 0
|
if (count($GLOBALS['serviceoverrides']) > 0
|
||||||
&& !defined('UNIT_TEST_MODE')
|
&& !defined('UNIT_TEST_MODE')
|
||||||
|
BIN
src/silex.phar
Normal file
BIN
src/silex.phar
Normal file
Binary file not shown.
@ -35,20 +35,50 @@ isset($_POST['query']) ? define('POST_QUERY', $_POST['query']): define('POST_QUE
|
|||||||
|
|
||||||
$keeppass = (POST_KEEPPASS=='yes')?true:false;
|
$keeppass = (POST_KEEPPASS=='yes')?true:false;
|
||||||
|
|
||||||
|
@list($url, $method) = isset($_SERVER['PATH_INFO']) ? explode('/', $_SERVER['PATH_INFO']) : NULL;
|
||||||
|
|
||||||
|
|
||||||
$login = false;
|
$login = false;
|
||||||
if (POST_SUBMITTED!='' && POST_USERNAME!='' && POST_PASSWORD!='') {
|
if ($method == 'openidreturn'
|
||||||
|
|| (POST_SUBMITTED != ''
|
||||||
|
&& isset($_POST['openid_identifier']) && $_POST['openid_identifier'] != ''
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
$oids = SemanticScuttle_Service_Factory::get('OpenId');
|
||||||
|
$returnUrl = addProtocolToUrl(createURL('login', 'openidreturn'));
|
||||||
|
try {
|
||||||
|
if ($method == 'openidreturn') {
|
||||||
|
//part 2: handle response
|
||||||
|
$ret = $oids->handleIdResponse($returnUrl);
|
||||||
|
if ($ret['userId'] === null) {
|
||||||
|
//FIXME: ask to register
|
||||||
|
$tplVars['error'] = T_('OpenID login error');
|
||||||
|
} else {
|
||||||
|
$userservice->setCurrentUserId($ret['userId'], true);
|
||||||
|
$login = true;
|
||||||
|
}
|
||||||
|
//FIXME POST_KEEPPASS
|
||||||
|
} else {
|
||||||
|
//part 1: send request
|
||||||
|
$oids->sendIdRequest($_POST['openid_identifier'], $returnUrl);
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$tplVars['error'] = SemanticScuttle_Exception::getErrorMessage($e);
|
||||||
|
}
|
||||||
|
} else if (POST_SUBMITTED!='' && POST_USERNAME!='' && POST_PASSWORD!='') {
|
||||||
$posteduser = trim(utf8_strtolower(POST_USERNAME));
|
$posteduser = trim(utf8_strtolower(POST_USERNAME));
|
||||||
$login = $userservice->login($posteduser, POST_PASSWORD, $keeppass);
|
$login = $userservice->login($posteduser, POST_PASSWORD, $keeppass);
|
||||||
|
if (!$login) {
|
||||||
|
$tplVars['error'] = T_('The details you have entered are incorrect. Please try again.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($login) {
|
if ($login) {
|
||||||
if (POST_QUERY)
|
if (POST_QUERY)
|
||||||
header('Location: '. createURL('bookmarks', $posteduser .'?'. POST_QUERY));
|
header('Location: '. createURL('bookmarks', $posteduser .'?'. POST_QUERY));
|
||||||
else
|
else
|
||||||
header('Location: '. createURL('bookmarks', $posteduser));
|
header('Location: '. createURL('bookmarks', $posteduser));
|
||||||
} else {
|
} else {
|
||||||
$tplVars['error'] = T_('The details you have entered are incorrect. Please try again.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!$login) {
|
|
||||||
if ($userservice->isLoggedOn()) {
|
if ($userservice->isLoggedOn()) {
|
||||||
$cUser = $userservice->getCurrentObjectUser();
|
$cUser = $userservice->getCurrentObjectUser();
|
||||||
header('Location: '. createURL('bookmarks', strtolower($cUser->getUsername())));
|
header('Location: '. createURL('bookmarks', strtolower($cUser->getUsername())));
|
||||||
|
@ -42,9 +42,14 @@ isset($_SESSION['token']) ? define('SESSION_TOKEN', $_SESSION['token']): define(
|
|||||||
isset($_SESSION['token_stamp']) ? define('SESSION_TOKENSTAMP', $_SESSION['token_stamp']): define('SESSION_TOKENSTAMP', '');
|
isset($_SESSION['token_stamp']) ? define('SESSION_TOKENSTAMP', $_SESSION['token_stamp']): define('SESSION_TOKENSTAMP', '');
|
||||||
|
|
||||||
|
|
||||||
@list($url, $user) = isset($_SERVER['PATH_INFO']) ? explode('/', $_SERVER['PATH_INFO']) : NULL;
|
@list($url, $user, $method) = isset($_SERVER['PATH_INFO'])
|
||||||
|
? explode('/', $_SERVER['PATH_INFO']) : NULL;
|
||||||
|
|
||||||
if ($user) {
|
if (!$user) {
|
||||||
|
$tplVars['error'] = T_('Username was not specified');
|
||||||
|
$templateservice->loadTemplate('error.404.tpl', $tplVars);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
if (is_int($user)) {
|
if (is_int($user)) {
|
||||||
$userid = intval($user);
|
$userid = intval($user);
|
||||||
@ -59,11 +64,6 @@ if ($user) {
|
|||||||
$userid = $userinfo->getId();
|
$userid = $userinfo->getId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
$tplVars['error'] = T_('Username was not specified');
|
|
||||||
$templateservice->loadTemplate('error.404.tpl', $tplVars);
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
$tplVars['privateKeyIsEnabled'] = '';
|
$tplVars['privateKeyIsEnabled'] = '';
|
||||||
if ($userservice->isLoggedOn() && $user == $currentUser->getUsername()) {
|
if ($userservice->isLoggedOn() && $user == $currentUser->getUsername()) {
|
||||||
@ -170,6 +170,53 @@ if (!$userservice->isLoggedOn() || $currentUser->getId() != $userid) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$oids = SemanticScuttle_Service_Factory::get('OpenId');
|
||||||
|
if (isset($_POST['action']) && $_POST['action'] == 'deleteOpenId'
|
||||||
|
&& isset($_POST['openIdUrl'])
|
||||||
|
) {
|
||||||
|
$identifier = $_POST['openIdUrl'];
|
||||||
|
$openId = $oids->getId($identifier);
|
||||||
|
if ($openId === null || $openId->uId != $currentUser->getId()
|
||||||
|
) {
|
||||||
|
$tplVars['error'] = T_('OpenID not found.');
|
||||||
|
} else if (false === $oids->delete($openId->id)) {
|
||||||
|
$tplVars['error'] = T_('Failed to delete OpenID.');
|
||||||
|
} else {
|
||||||
|
$tplVars['msg'] = T_('OpenID deleted.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$openIdAction = false;
|
||||||
|
$openIdReturn = false;
|
||||||
|
if (isset($_POST['action']) && $_POST['action'] == 'registerOpenId'
|
||||||
|
&& isset($_POST['openid_identifier'])
|
||||||
|
) {
|
||||||
|
$openIdAction = true;
|
||||||
|
} else if (isset($method) && $method == 'openidreturn') {
|
||||||
|
$openIdAction = true;
|
||||||
|
$openIdReturn = true;
|
||||||
|
}
|
||||||
|
if ($openIdAction) {
|
||||||
|
$returnUrl = addProtocolToUrl(createURL('profile', $user . '/openidreturn'));
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!$openIdReturn) {
|
||||||
|
//part 1 of OpenID registration
|
||||||
|
$oids->sendIdRequest($_POST['openid_identifier'], $returnUrl);
|
||||||
|
} else {
|
||||||
|
//part 2
|
||||||
|
$ret = $oids->handleIdResponse($returnUrl);
|
||||||
|
$oids->register(
|
||||||
|
$currentUser->getId(), $ret['identifier'], $ret['email']
|
||||||
|
);
|
||||||
|
$tplVars['msg'] = T_('OpenID registered.');
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$tplVars['error'] = SemanticScuttle_Exception::getErrorMessage($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Token Init
|
//Token Init
|
||||||
$_SESSION['token'] = md5(uniqid(rand(), true));
|
$_SESSION['token'] = md5(uniqid(rand(), true));
|
||||||
$_SESSION['token_stamp'] = time();
|
$_SESSION['token_stamp'] = time();
|
||||||
@ -180,6 +227,7 @@ if (!$userservice->isLoggedOn() || $currentUser->getId() != $userid) {
|
|||||||
$tplVars['token'] = $_SESSION['token'];
|
$tplVars['token'] = $_SESSION['token'];
|
||||||
|
|
||||||
$tplVars['sslClientCerts'] = $scert->getUserCerts($currentUser->getId());
|
$tplVars['sslClientCerts'] = $scert->getUserCerts($currentUser->getId());
|
||||||
|
$tplVars['openIds'] = $oids->getIds($currentUser->getId());
|
||||||
$tplVars['currentCert'] = null;
|
$tplVars['currentCert'] = null;
|
||||||
if ($scert->hasValidCert()) {
|
if ($scert->hasValidCert()) {
|
||||||
$tplVars['currentCert'] = SemanticScuttle_Model_User_SslClientCert::fromCurrentCert();
|
$tplVars['currentCert'] = SemanticScuttle_Model_User_SslClientCert::fromCurrentCert();
|
||||||
|
Loading…
Reference in New Issue
Block a user