new privatekey2 branch with privatekey changes
This commit is contained in:
parent
803b83fb7d
commit
ec345f7a13
@ -13,3 +13,7 @@ CREATE TABLE `sc_users_sslclientcerts` (
|
||||
PRIMARY KEY ( `id` ) ,
|
||||
UNIQUE (`id`)
|
||||
) CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||
|
||||
ALTER TABLE `sc_users` ADD `privateKey` VARCHAR(33) NULL;
|
||||
CREATE INDEX `privateKey` ON `sc_users` (`privateKey`);
|
||||
|
||||
|
@ -84,8 +84,9 @@ CREATE TABLE `sc_users_sslclientcerts` (
|
||||
`sslClientIssuerDn` VARCHAR( 1024 ) NOT NULL ,
|
||||
`sslName` VARCHAR( 64 ) NOT NULL ,
|
||||
`sslEmail` VARCHAR( 64 ) NOT NULL ,
|
||||
`privateKey` varchar(33) default NULL,
|
||||
PRIMARY KEY ( `id` ) ,
|
||||
UNIQUE (`id`)
|
||||
UNIQUE KEY `privateKey` (`privateKey`)
|
||||
) CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||
|
||||
--
|
||||
|
@ -28,6 +28,14 @@ $this->includeTemplate($GLOBALS['top_include']);
|
||||
<td><input type="text" name="pMail" size="75" value="<?php echo filter($objectUser->getEmail(), 'xml'); ?>" /></td>
|
||||
<td>← <?php echo T_('Required'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th align="left"><?php echo T_('Private RSS Feed'); ?></th>
|
||||
<td><input type="checkbox" id="pEnablePrivateKey" name="pEnablePrivateKey" value="true" <?php echo $privateKeyIsEnabled;?> />
|
||||
<label for="pEnablePrivateKey"><?php echo T_('Enable'); ?></label>
|
||||
<input type="text" id="pPrivateKey" name="pPrivateKey" size="40" value="<?php echo $privateKey;?>" readonly="readonly" />
|
||||
<input type="submit" name="submittedPK" value="<?php echo T_('Generate New Key'); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3><?php echo T_('Personal Details'); ?></h3>
|
||||
|
@ -3,7 +3,7 @@ echo '<' . '?xml version="1.0" encoding="utf-8" ?' . ">\n";
|
||||
?>
|
||||
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<channel>
|
||||
<title><?php echo htmlspecialchars($feedtitle); ?></title>
|
||||
<title><?php echo $feedtitle; ?></title>
|
||||
<link><?php echo htmlspecialchars($feedlink); ?></link>
|
||||
<description><?php echo htmlspecialchars($feeddescription); ?></description>
|
||||
<pubDate><?php echo date('r'); ?></pubDate>
|
||||
@ -23,4 +23,4 @@ echo '<' . '?xml version="1.0" encoding="utf-8" ?' . ">\n";
|
||||
</item>
|
||||
<?php endforeach; ?>
|
||||
</channel>
|
||||
</rss>
|
||||
</rss>
|
||||
|
@ -12,7 +12,7 @@ if (isset($rsschannels)) {
|
||||
$size = count($rsschannels);
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
echo ' <link rel="alternate" type="application/rss+xml" title="'
|
||||
. htmlspecialchars($rsschannels[$i][0]) . '"'
|
||||
. $rsschannels[$i][0] . '"'
|
||||
. ' href="'. $rsschannels[$i][1] .'" />';
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,9 @@ Database updates: Apply data/schema/6.sql or do the following:
|
||||
|
||||
INSERT INTO `sc_version` (`schema_version`) VALUES ('6');
|
||||
|
||||
ALTER TABLE `sc_users` ADD `privateKey` VARCHAR(33) NULL;
|
||||
CREATE INDEX `privateKey` ON `sc_users` (`privateKey`);
|
||||
|
||||
|
||||
From version 0.96 to 0.97
|
||||
-------------------------
|
||||
|
@ -35,6 +35,7 @@ class SemanticScuttle_Model_User
|
||||
var $content;
|
||||
var $datetime;
|
||||
var $isAdmin;
|
||||
var $privateKey;
|
||||
|
||||
/**
|
||||
* Create a new user object
|
||||
@ -68,6 +69,29 @@ class SemanticScuttle_Model_User
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns private key
|
||||
*
|
||||
* @param boolean return sanitized value which basically drops
|
||||
* leading dash if exists
|
||||
*
|
||||
* @return string private key
|
||||
*/
|
||||
public function getPrivateKey($sanitized = false)
|
||||
{
|
||||
// Look for value only if not already set
|
||||
if (!isset($this->privateKey)) {
|
||||
$us = SemanticScuttle_Service_Factory::get('User');
|
||||
$user = $us->getUser($this->id);
|
||||
$this->privateKey = $user['privateKey'];
|
||||
}
|
||||
if ($sanitized == true) {
|
||||
return substr($this->privateKey, -32);
|
||||
} else {
|
||||
return $this->privateKey;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns full user name as specified in the profile.
|
||||
*
|
||||
@ -182,4 +206,4 @@ class SemanticScuttle_Model_User
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
?>
|
||||
|
@ -717,7 +717,7 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
|
||||
// All public bookmarks, user's own bookmarks
|
||||
// and any shared with user
|
||||
$privacy = ' AND ((B.bStatus = 0) OR (B.uId = '. $sId .')';
|
||||
$watchnames = $userservice->getWatchNames($sId, true);
|
||||
$watchnames = $userservice->getWatchNames($sId);
|
||||
foreach ($watchnames as $watchuser) {
|
||||
$privacy .= ' OR (U.username = "'. $watchuser .'" AND B.bStatus = 1)';
|
||||
}
|
||||
|
@ -48,9 +48,10 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||
protected $currentuser = null;
|
||||
|
||||
protected $fields = array(
|
||||
'primary' => 'uId',
|
||||
'username' => 'username',
|
||||
'password' => 'password'
|
||||
'primary' => 'uId',
|
||||
'username' => 'username',
|
||||
'password' => 'password',
|
||||
'privatekey' => 'privatekey'
|
||||
);
|
||||
|
||||
protected $profileurl;
|
||||
@ -215,6 +216,18 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||
return $this->_getuser($this->getFieldName('username'), $username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns user row from database.
|
||||
*
|
||||
* @param string $privatekey Private Key
|
||||
*
|
||||
* @return array User array from database, false if no user was found
|
||||
*/
|
||||
public function getUserByPrivateKey($privatekey)
|
||||
{
|
||||
return $this->_getuser($this->getFieldName('privatekey'), $privatekey);
|
||||
}
|
||||
|
||||
function getObjectUserByUsername($username) {
|
||||
$user = $this->_getuser($this->getFieldName('username'), $username);
|
||||
if($user != false) {
|
||||
@ -279,6 +292,22 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||
return ($this->getCurrentUserId() !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells you if the private key is enabled and valid
|
||||
*
|
||||
* @param string $privateKey Private Key
|
||||
*
|
||||
* @return boolean True if enabled and valid
|
||||
*/
|
||||
public function isPrivateKeyValid($privateKey)
|
||||
{
|
||||
// check length of private key
|
||||
if (strlen($privateKey) == 32) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current user object
|
||||
*
|
||||
@ -293,7 +322,7 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||
{
|
||||
if (!is_null($newval)) {
|
||||
//internal use only: reset currentuser
|
||||
$currentuser = $newval;
|
||||
$this->currentuser = $newval;
|
||||
} else if ($refresh || !isset($this->currentuser)) {
|
||||
if ($id = $this->getCurrentUserId()) {
|
||||
$this->currentuser = $this->getUser($id);
|
||||
@ -509,6 +538,47 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to authenticate via the privatekey
|
||||
*
|
||||
* @param string $privatekey Private Key
|
||||
*
|
||||
* @return boolean true if the user could be authenticated,
|
||||
* false if not.
|
||||
*/
|
||||
public function loginPrivateKey($privatekey)
|
||||
{
|
||||
/* Check if private key valid and enabled */
|
||||
if (!$this->isPrivateKeyValid($privatekey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = 'SELECT '. $this->getFieldName('primary') .' FROM '
|
||||
. $this->getTableName() .' WHERE '
|
||||
. $this->getFieldName('privatekey') .' = "'
|
||||
. $this->db->sql_escape($privatekey) .'"';
|
||||
|
||||
if (!($dbresult = $this->db->sql_query($query))) {
|
||||
message_die(
|
||||
GENERAL_ERROR,
|
||||
'Could not get user',
|
||||
'', __LINE__, __FILE__, $query, $this->db
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
$row = $this->db->sql_fetchrow($dbresult);
|
||||
$this->db->sql_freeresult($dbresult);
|
||||
|
||||
if ($row) {
|
||||
$id = $_SESSION[$this->getSessionKey()]
|
||||
= $row[$this->getFieldName('primary')];
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the user off
|
||||
*
|
||||
@ -519,7 +589,8 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||
@setcookie($this->getCookiekey(), '', time() - 1, '/');
|
||||
unset($_COOKIE[$this->getCookiekey()]);
|
||||
session_unset();
|
||||
$this->getCurrentUser(TRUE, false);
|
||||
$this->currentuserId = null;
|
||||
$this->currentuser = null;
|
||||
}
|
||||
|
||||
function getWatchlist($uId) {
|
||||
@ -646,24 +717,26 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||
* No checks are done in here - you ought to have checked
|
||||
* everything before calling this method!
|
||||
*
|
||||
* @param string $username Username to use
|
||||
* @param string $password Password to use
|
||||
* @param string $email Email to use
|
||||
* @param string $username Username to use
|
||||
* @param string $password Password to use
|
||||
* @param string $email Email to use
|
||||
* @param string $privateKey Key for RSS auth
|
||||
*
|
||||
* @return mixed Integer user ID if all is well,
|
||||
* boolean false if an error occured
|
||||
*/
|
||||
public function addUser($username, $password, $email)
|
||||
public function addUser($username, $password, $email, $privateKey = null)
|
||||
{
|
||||
// Set up the SQL UPDATE statement.
|
||||
$datetime = gmdate('Y-m-d H:i:s', time());
|
||||
$password = $this->sanitisePassword($password);
|
||||
$values = array(
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'email' => $email,
|
||||
'uDatetime' => $datetime,
|
||||
'uModified' => $datetime
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'email' => $email,
|
||||
'uDatetime' => $datetime,
|
||||
'uModified' => $datetime,
|
||||
'privateKey' => $privateKey
|
||||
);
|
||||
$sql = 'INSERT INTO '. $this->getTableName()
|
||||
. ' '. $this->db->sql_build_array('INSERT', $values);
|
||||
@ -687,40 +760,64 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||
/**
|
||||
* Updates the given user
|
||||
*
|
||||
* @param integer $uId ID of user to change
|
||||
* @param string $password Password to use
|
||||
* @param string $name Realname to use
|
||||
* @param string $email Email to use
|
||||
* @param string $homepage User's homepage
|
||||
* @param string $uContent User note
|
||||
* @param integer $uId ID of user to change
|
||||
* @param string $password Password to use
|
||||
* @param string $name Realname to use
|
||||
* @param string $email Email to use
|
||||
* @param string $homepage User's homepage
|
||||
* @param string $uContent User note
|
||||
* @param string $privateKey RSS Private Key
|
||||
* @param boolean $enablePrivateKey RSS Private Key Flag
|
||||
*
|
||||
* @return boolean True when all is well, false if not
|
||||
*/
|
||||
public function updateUser(
|
||||
$uId, $password, $name, $email, $homepage, $uContent
|
||||
$uId, $password, $name, $email, $homepage, $uContent,
|
||||
$privateKey = null, $enablePrivateKey = false
|
||||
) {
|
||||
if (!is_numeric($uId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// prepend '-' to privateKey if disabled
|
||||
if ($privateKey != null && strlen($privateKey) == 32
|
||||
&& $enablePrivateKey == false
|
||||
) {
|
||||
$privateKey = '-' . $privateKey;
|
||||
}
|
||||
|
||||
// remove '-' from privateKey if enabling
|
||||
if ($privateKey != null && strlen($privateKey) == 33
|
||||
&& $enablePrivateKey == true
|
||||
) {
|
||||
$privateKey = substr($privateKey, 1, 32);
|
||||
}
|
||||
|
||||
// if new user is enabling Private Key, create new key
|
||||
if ($privateKey == null && $enablePrivateKey == true) {
|
||||
$privateKey = $this->getNewPrivateKey();
|
||||
}
|
||||
|
||||
// Set up the SQL UPDATE statement.
|
||||
$moddatetime = gmdate('Y-m-d H:i:s', time());
|
||||
if ($password == '') {
|
||||
$updates = array(
|
||||
'uModified' => $moddatetime,
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'homepage' => $homepage,
|
||||
'uContent' => $uContent
|
||||
'uModified' => $moddatetime,
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'homepage' => $homepage,
|
||||
'uContent' => $uContent,
|
||||
'privateKey' => $privateKey
|
||||
);
|
||||
} else {
|
||||
$updates = array(
|
||||
'uModified' => $moddatetime,
|
||||
'password' => $this->sanitisePassword($password),
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'homepage' => $homepage,
|
||||
'uContent' => $uContent
|
||||
'uModified' => $moddatetime,
|
||||
'password' => $this->sanitisePassword($password),
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'homepage' => $homepage,
|
||||
'uContent' => $uContent,
|
||||
'privateKey' => $privateKey
|
||||
);
|
||||
}
|
||||
$sql = 'UPDATE '. $this->getTableName()
|
||||
@ -837,6 +934,56 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a new private key and confirms it isn't being used.
|
||||
* Private key is 32 characters long, consisting of lowercase and
|
||||
* numeric characters.
|
||||
*
|
||||
* @return string the new key value
|
||||
*/
|
||||
public function getNewPrivateKey()
|
||||
{
|
||||
do {
|
||||
$newKey = md5(uniqid('SemanticScuttle', true));
|
||||
} while ($this->privateKeyExists($newKey));
|
||||
|
||||
return $newKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a private key already exists
|
||||
*
|
||||
* @param string $privateKey key that has been generated
|
||||
*
|
||||
* @return boolean true when the private key exists,
|
||||
* False if not.
|
||||
*/
|
||||
public function privateKeyExists($privateKey)
|
||||
{
|
||||
if (!$privateKey) {
|
||||
return false;
|
||||
}
|
||||
$crit = array('privateKey' => $privateKey);
|
||||
|
||||
$sql = 'SELECT COUNT(*) as "0" FROM '
|
||||
. $GLOBALS['tableprefix'] . 'users'
|
||||
. ' WHERE '. $this->db->sql_build_array('SELECT', $crit);
|
||||
|
||||
if (!($dbresult = $this->db->sql_query($sql))) {
|
||||
message_die(
|
||||
GENERAL_ERROR, 'Could not get vars', '',
|
||||
__LINE__, __FILE__, $sql, $this->db
|
||||
);
|
||||
}
|
||||
if ($this->db->sql_fetchfield(0, 0) > 0) {
|
||||
$exists = true;
|
||||
} else {
|
||||
$exists = false;
|
||||
}
|
||||
$this->db->sql_freeresult($dbresult);
|
||||
return $exists;
|
||||
}
|
||||
|
||||
function isReserved($username) {
|
||||
if (in_array($username, $GLOBALS['reservedusers'])) {
|
||||
return true;
|
||||
|
@ -1330,5 +1330,51 @@ class BookmarkTest extends TestBase
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test private bookmarks
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testPrivateBookmarks()
|
||||
{
|
||||
$uid = $this->addUser();
|
||||
/* create private bookmark */
|
||||
$this->bs->addBookmark(
|
||||
'http://test', 'test', 'desc', 'note',
|
||||
2,//private
|
||||
array(), null, null, false, false, $uid
|
||||
);
|
||||
/* create public bookmark */
|
||||
$this->bs->addBookmark(
|
||||
'http://example.org', 'title', 'desc', 'priv',
|
||||
0,//public
|
||||
array(), null, null, false, false, $uid
|
||||
);
|
||||
|
||||
$this->assertEquals(1, $this->bs->countBookmarks($uid, 'public'));
|
||||
$this->assertEquals(1, $this->bs->countBookmarks($uid, 'private'));
|
||||
$this->assertEquals(0, $this->bs->countBookmarks($uid, 'shared'));
|
||||
$this->assertEquals(2, $this->bs->countBookmarks($uid, 'all'));
|
||||
|
||||
$this->us->setCurrentUserId($uid);
|
||||
$bookmarks = $this->bs->getBookmarks();
|
||||
// first record should be private bookmark
|
||||
$b0 = $bookmarks['bookmarks'][0];
|
||||
$this->assertEquals('test', $b0['bTitle']);
|
||||
// second record should be public bookmark
|
||||
$b0 = $bookmarks['bookmarks'][1];
|
||||
$this->assertEquals('title', $b0['bTitle']);
|
||||
|
||||
// test non authenticated query
|
||||
$this->us->setCurrentUserId(null);
|
||||
$bookmarks = $this->bs->getBookmarks();
|
||||
// should only result in one link - public
|
||||
$b2 = $bookmarks['bookmarks'][0];
|
||||
$this->assertEquals('title', $b2['bTitle']);
|
||||
// there should be no second record
|
||||
$this->assertEquals(1,count($bookmarks['bookmarks']));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
|
@ -78,14 +78,15 @@ class TestBase extends PHPUnit_Framework_TestCase
|
||||
*
|
||||
* @param string $username Username
|
||||
* @param string $password Password
|
||||
* @param string $pkey Private Key
|
||||
*
|
||||
* @return integer ID of user
|
||||
*
|
||||
* @uses addUserData()
|
||||
*/
|
||||
protected function addUser($username = null, $password = null)
|
||||
protected function addUser($username = null, $password = null, $pkey = null)
|
||||
{
|
||||
return reset($this->addUserData($username, $password));
|
||||
return reset($this->addUserData($username, $password, $pkey));
|
||||
}
|
||||
|
||||
|
||||
@ -95,10 +96,11 @@ class TestBase extends PHPUnit_Framework_TestCase
|
||||
*
|
||||
* @param string $username Username
|
||||
* @param string $password Password
|
||||
* @param string $pkey Private Key
|
||||
*
|
||||
* @return array ID of user, Name of user, password of user
|
||||
*/
|
||||
protected function addUserData($username = null, $password = null)
|
||||
protected function addUserData($username = null, $password = null, $pkey = null)
|
||||
{
|
||||
$us = SemanticScuttle_Service_Factory::get('User');
|
||||
$rand = rand();
|
||||
@ -113,7 +115,8 @@ class TestBase extends PHPUnit_Framework_TestCase
|
||||
$uid = $us->addUser(
|
||||
$username,
|
||||
$password,
|
||||
'unittest-' . $rand . '@example.org'
|
||||
'unittest-' . $rand . '@example.org',
|
||||
$pkey
|
||||
);
|
||||
return array($uid, $username, $password);
|
||||
}
|
||||
@ -148,4 +151,4 @@ class TestBase extends PHPUnit_Framework_TestCase
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
?>
|
||||
|
@ -34,6 +34,157 @@ class UserTest extends TestBase
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_User::addUser
|
||||
*/
|
||||
public function testAddUserPrivateKey()
|
||||
{
|
||||
$name = substr(md5(uniqid()), 0, 6);
|
||||
$pkey = 'my-privatekey';
|
||||
$id = $this->us->addUser(
|
||||
$name, uniqid(), 'foo@example.org', $pkey
|
||||
);
|
||||
$this->assertNotEquals(false, $id);
|
||||
$this->assertInternalType('integer', $id);
|
||||
|
||||
$arUser = $this->us->getUserByPrivateKey($pkey);
|
||||
$this->assertNotEquals(false, $arUser, 'user not found by private key');
|
||||
$this->assertEquals($id, $arUser['uId'], 'wrong user loaded');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_User::updateUser
|
||||
*/
|
||||
public function testUpdateUserFalseWhenIdNotNumeric()
|
||||
{
|
||||
$this->assertFalse(
|
||||
$this->us->updateUser('foo', null, null, null, null, null)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_User::updateUser
|
||||
*/
|
||||
public function testUpdateUserPrivateKeyNewKeyEnabled()
|
||||
{
|
||||
$pkey = 'testUpdateUserPrivateKeyNewKey12';
|
||||
$uid = $this->addUser();
|
||||
|
||||
$this->assertTrue(
|
||||
$this->us->updateUser(
|
||||
$uid, 'password', 'name', 'test@example.org', '', '',
|
||||
$pkey, true
|
||||
)
|
||||
);
|
||||
$arUser = $this->us->getUser($uid);
|
||||
$this->assertInternalType('array', $arUser);
|
||||
$this->assertEquals($pkey, $arUser['privateKey']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_User::updateUser
|
||||
*/
|
||||
public function testUpdateUserPrivateKeyNewKeyDisabled()
|
||||
{
|
||||
$pkey = 'testUpdateUserPrivateKeyNewKeyDi';
|
||||
$uid = $this->addUser();
|
||||
|
||||
$this->assertTrue(
|
||||
$this->us->updateUser(
|
||||
$uid, 'password', 'name', 'test@example.org', '', '',
|
||||
$pkey, false
|
||||
)
|
||||
);
|
||||
$arUser = $this->us->getUser($uid);
|
||||
$this->assertInternalType('array', $arUser);
|
||||
$this->assertEquals(
|
||||
'-' . $pkey, $arUser['privateKey'],
|
||||
'private key did not get disabled'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Passing an empty string / NULL as key but enabling it
|
||||
* should automatically create a new key.
|
||||
*
|
||||
* @covers SemanticScuttle_Service_User::updateUser
|
||||
*/
|
||||
public function testUpdateUserPrivateKeyNoKeyEnabled()
|
||||
{
|
||||
$pkey = 'testUpdateUserPrivateKeyNoKeyEna';
|
||||
$uid = $this->addUser();
|
||||
|
||||
$this->assertTrue(
|
||||
$this->us->updateUser(
|
||||
$uid, 'password', 'name', 'test@example.org', '', '',
|
||||
null, true
|
||||
)
|
||||
);
|
||||
$arUser = $this->us->getUser($uid);
|
||||
$this->assertInternalType('array', $arUser);
|
||||
$this->assertNotEquals(
|
||||
'', $arUser['privateKey'], 'private key was not created'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Passing an empty string / NULL as key and disabling it
|
||||
* should keep no key
|
||||
*
|
||||
* @covers SemanticScuttle_Service_User::updateUser
|
||||
*/
|
||||
public function testUpdateUserPrivateKeyNoKeyDisabled()
|
||||
{
|
||||
$pkey = 'testUpdateUserPrivateKeyNoKeyDis';
|
||||
$uid = $this->addUser();
|
||||
|
||||
$this->assertTrue(
|
||||
$this->us->updateUser(
|
||||
$uid, 'password', 'name', 'test@example.org', '', '',
|
||||
null, false
|
||||
)
|
||||
);
|
||||
$arUser = $this->us->getUser($uid);
|
||||
$this->assertInternalType('array', $arUser);
|
||||
$this->assertEquals(
|
||||
'', $arUser['privateKey'], 'private key was set'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Passing an empty string / NULL as key and disabling it
|
||||
* should keep no key
|
||||
*
|
||||
* @covers SemanticScuttle_Service_User::updateUser
|
||||
*/
|
||||
public function testUpdateUserPrivateKeyExistingKeyEnabled()
|
||||
{
|
||||
$pkey = '12345678901234567890123456789012';
|
||||
$uid = $this->addUser();
|
||||
|
||||
$this->assertTrue(
|
||||
$this->us->updateUser(
|
||||
$uid, 'password', 'name', 'test@example.org', '', '',
|
||||
'-' . $pkey, true
|
||||
)
|
||||
);
|
||||
$arUser = $this->us->getUser($uid);
|
||||
$this->assertInternalType('array', $arUser);
|
||||
$this->assertEquals(
|
||||
$pkey, $arUser['privateKey'], 'private key was not enabled'
|
||||
);
|
||||
}
|
||||
|
||||
//FIXME: verify I cannot re-use private key of different user
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test that setting the current user ID is permanent.
|
||||
* and that the current user array is the same ID
|
||||
@ -176,5 +327,185 @@ class UserTest extends TestBase
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function testGetUserByPrivateKeyEmptyKey()
|
||||
{
|
||||
$arUser = $this->us->getUserByPrivateKey(null);
|
||||
$this->assertFalse($arUser);
|
||||
}
|
||||
|
||||
|
||||
public function testGetUserByPrivateKeyInvalid()
|
||||
{
|
||||
$arUser = $this->us->getUserByPrivateKey('foobar');
|
||||
$this->assertFalse($arUser);
|
||||
|
||||
$arUser = $this->us->getUserByPrivateKey('%');
|
||||
$this->assertFalse($arUser);
|
||||
}
|
||||
|
||||
|
||||
public function testGetUserByPrivateKeyValidKey()
|
||||
{
|
||||
$pkey = $this->us->getNewPrivateKey();
|
||||
$uId = $this->addUser(null, null, $pkey);
|
||||
|
||||
$arUser = $this->us->getUserByPrivateKey($pkey);
|
||||
$this->assertInternalType('array', $arUser);
|
||||
$this->assertArrayHasKey('uId', $arUser);
|
||||
$this->assertArrayHasKey('username', $arUser);
|
||||
|
||||
$this->assertEquals($uId, $arUser['uId']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_User::privateKeyExists
|
||||
*/
|
||||
public function testPrivateKeyExistsEmpty()
|
||||
{
|
||||
$this->assertFalse($this->us->privateKeyExists(null));
|
||||
$this->assertFalse($this->us->privateKeyExists(''));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_User::privateKeyExists
|
||||
*/
|
||||
public function testPrivateKeyExistsInvalid()
|
||||
{
|
||||
$this->assertFalse($this->us->privateKeyExists('-1'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_User::privateKeyExists
|
||||
*/
|
||||
public function testPrivateKeyExists()
|
||||
{
|
||||
$randKey = $this->us->getNewPrivateKey();
|
||||
$this->assertFalse($this->us->privateKeyExists($randKey));
|
||||
$uid = $this->addUser(null, null, $randKey);
|
||||
|
||||
$this->us->setCurrentUserId($uid);
|
||||
$this->assertEquals($uid, $this->us->getCurrentUserId());
|
||||
|
||||
$this->assertTrue($this->us->privateKeyExists($randKey));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @covers SemanticScuttle_Service_User::isPrivateKeyValid
|
||||
*/
|
||||
public function testIsPrivateKeyValid()
|
||||
{
|
||||
$this->assertFalse(
|
||||
$this->us->isPrivateKeyValid(null),
|
||||
'NULL is an invalid private key'
|
||||
);
|
||||
|
||||
$randKey = $this->us->getNewPrivateKey();
|
||||
$this->assertTrue(
|
||||
$this->us->isPrivateKeyValid($randKey),
|
||||
'generated key should be valid'
|
||||
);
|
||||
|
||||
$randKey2 = '-'.$this->us->getNewPrivateKey();
|
||||
$this->assertFalse(
|
||||
$this->us->isPrivateKeyValid($randKey2),
|
||||
'disabled privatekey should return false'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function testLoginPrivateKeyInvalid()
|
||||
{
|
||||
/* normal user with enabled privatekey */
|
||||
$randKey = $this->us->getNewPrivateKey();
|
||||
$uid1 = $this->addUser('testusername', 'passw0rd', $randKey);
|
||||
/* user that has disabled privatekey */
|
||||
$randKey2 = '-'.$this->us->getNewPrivateKey();
|
||||
$uid2 = $this->addUser('seconduser', 'passw0RD', $randKey2);
|
||||
|
||||
/* test invalid private key */
|
||||
$this->assertFalse(
|
||||
$this->us->loginPrivateKey('02848248084082408240824802408248')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function testLoginPrivateKeyValidEnabledKey()
|
||||
{
|
||||
/* normal user with enabled privatekey */
|
||||
$randKey = $this->us->getNewPrivateKey();
|
||||
$uid1 = $this->addUser('testusername', 'passw0rd', $randKey);
|
||||
/* user that has disabled privatekey */
|
||||
$randKey2 = '-'.$this->us->getNewPrivateKey();
|
||||
$uid2 = $this->addUser('seconduser', 'passw0RD', $randKey2);
|
||||
|
||||
|
||||
/* test valid credentials with private key enabled */
|
||||
$this->assertTrue(
|
||||
$this->us->loginPrivateKey($randKey)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function testLoginPrivateKeyInvalidEnabledKey()
|
||||
{
|
||||
/* normal user with enabled privatekey */
|
||||
$randKey = $this->us->getNewPrivateKey();
|
||||
$uid1 = $this->addUser('testusername', 'passw0rd', $randKey);
|
||||
/* user that has disabled privatekey */
|
||||
$randKey2 = '-'.$this->us->getNewPrivateKey();
|
||||
$uid2 = $this->addUser('seconduser', 'passw0RD', $randKey2);
|
||||
|
||||
|
||||
/* test valid credentials with private key enabled but invalid key */
|
||||
$this->assertFalse(
|
||||
$this->us->loginPrivateKey('123')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function testLoginPrivateKeyValidDisabledKey()
|
||||
{
|
||||
/* normal user with enabled privatekey */
|
||||
$randKey = $this->us->getNewPrivateKey();
|
||||
$uid1 = $this->addUser('testusername', 'passw0rd', $randKey);
|
||||
/* user that has disabled privatekey */
|
||||
$randKey2 = '-'.$this->us->getNewPrivateKey();
|
||||
$uid2 = $this->addUser('seconduser', 'passw0RD', $randKey2);
|
||||
|
||||
/* confirm user exists so future fails should be due to randkey */
|
||||
$this->assertTrue(
|
||||
$this->us->login('seconduser', 'passw0RD', false)
|
||||
);
|
||||
|
||||
/* test valid credentials with private key disabled */
|
||||
$this->assertFalse(
|
||||
$this->us->loginPrivateKey($randKey2)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function testLoginPrivateKeyInvalidDisabled()
|
||||
{
|
||||
/* normal user with enabled privatekey */
|
||||
$randKey = $this->us->getNewPrivateKey();
|
||||
$uid1 = $this->addUser('testusername', 'passw0rd', $randKey);
|
||||
/* user that has disabled privatekey */
|
||||
$randKey2 = '-'.$this->us->getNewPrivateKey();
|
||||
$uid2 = $this->addUser('seconduser', 'passw0RD', $randKey2);
|
||||
|
||||
/* test valid credentials with private key disabled and invalid key */
|
||||
$this->assertFalse(
|
||||
$this->us->loginPrivateKey('-1')
|
||||
);
|
||||
$this->assertFalse(
|
||||
$this->us->loginPrivateKey(null)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
?>
|
||||
|
@ -45,6 +45,19 @@ $tplVars['rsschannels'] = array(
|
||||
array(sprintf(T_('%s: Recent bookmarks'), $sitename), createURL('rss').'?sort='.getSortOrder())
|
||||
);
|
||||
|
||||
if ($userservice->isLoggedOn()) {
|
||||
$currentUsername = $currentUser->getUsername();
|
||||
if ($userservice->isPrivateKeyValid($currentUser->getPrivateKey())) {
|
||||
array_push(
|
||||
$tplVars['rsschannels'],
|
||||
array(
|
||||
filter($sitename . sprintf(T_(': (private) ')) . $currentUsername),
|
||||
createURL('rss', filter($currentUsername, 'url') . '?sort='.getSortOrder().'&privatekey='.$currentUser->getPrivateKey())
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($usecache) {
|
||||
// Generate hash for caching on
|
||||
$hashtext = $_SERVER['REQUEST_URI'];
|
||||
|
@ -89,6 +89,16 @@ function useAddress(ele) {
|
||||
}
|
||||
}
|
||||
|
||||
function getNewPrivateKey(input, response){
|
||||
var pk = document.getElementById('pPrivateKey');
|
||||
if (response != null) {
|
||||
pk.value = response.trim();
|
||||
} else {
|
||||
loadXMLDocProc('<?php echo ROOT; ?>ajaxGetNewPrivateKey.php');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getTitle(input, response){
|
||||
var title = document.getElementById('titleField');
|
||||
if (title.value == '') {
|
||||
|
@ -25,10 +25,13 @@ require_once 'www-header.php';
|
||||
// No specific services
|
||||
|
||||
/* Managing all possible inputs */
|
||||
isset($_POST['submittedPK']) ? define('POST_SUBMITTEDPK', $_POST['submittedPK']): define('POST_SUBMITTEDPK', '');
|
||||
isset($_POST['submitted']) ? define('POST_SUBMITTED', $_POST['submitted']): define('POST_SUBMITTED', '');
|
||||
isset($_POST['pPass']) ? define('POST_PASS', $_POST['pPass']): define('POST_PASS', '');
|
||||
isset($_POST['pPassConf']) ? define('POST_PASSCONF', $_POST['pPassConf']): define('POST_PASSCONF', '');
|
||||
isset($_POST['pName']) ? define('POST_NAME', $_POST['pName']): define('POST_NAME', '');
|
||||
isset($_POST['pPrivateKey']) ? define('POST_PRIVATEKEY', $_POST['pPrivateKey']): define('POST_PRIVATEKEY', '');
|
||||
isset($_POST['pEnablePrivateKey']) ? define('POST_ENABLEPRIVATEKEY', $_POST['pEnablePrivateKey']): define('POST_ENABLEPRIVATEKEY', '');
|
||||
isset($_POST['pMail']) ? define('POST_MAIL', $_POST['pMail']): define('POST_MAIL', '');
|
||||
isset($_POST['pPage']) ? define('POST_PAGE', $_POST['pPage']): define('POST_PAGE', '');
|
||||
isset($_POST['pDesc']) ? define('POST_DESC', $_POST['pDesc']): define('POST_DESC', '');
|
||||
@ -61,10 +64,19 @@ if ($user) {
|
||||
exit();
|
||||
}
|
||||
|
||||
$tplVars['privateKeyIsEnabled'] = '';
|
||||
if ($userservice->isLoggedOn() && $user == $currentUser->getUsername()) {
|
||||
$title = T_('My Profile');
|
||||
$title = T_('My Profile');
|
||||
$tplVars['privateKey'] = $currentUser->getPrivateKey(true);
|
||||
|
||||
if ($userservice->isPrivateKeyValid($currentUser->getPrivateKey())) {
|
||||
$tplVars['privateKeyIsEnabled'] = 'checked="checked"';
|
||||
} else {
|
||||
$tplVars['privateKeyIsEnabled'] = '';
|
||||
}
|
||||
} else {
|
||||
$title = T_('Profile') .': '. $user;
|
||||
$title = T_('Profile') .': '. $user;
|
||||
$tplVars['privateKey'] = '';
|
||||
}
|
||||
$tplVars['pagetitle'] = $title;
|
||||
$tplVars['subtitle'] = $title;
|
||||
@ -72,11 +84,19 @@ $tplVars['subtitle'] = $title;
|
||||
$tplVars['user'] = $user;
|
||||
$tplVars['userid'] = $userid;
|
||||
|
||||
/* Update Private Key */
|
||||
if (POST_SUBMITTEDPK!='' && $currentUser->getId() == $userid) {
|
||||
$userinfo = $userservice->getObjectUserByUsername($user);
|
||||
$tplVars['privateKey'] = $userservice->getNewPrivateKey();
|
||||
}
|
||||
|
||||
if (POST_SUBMITTED!='' && $currentUser->getId() == $userid) {
|
||||
$error = false;
|
||||
$detPass = trim(POST_PASS);
|
||||
$detPassConf = trim(POST_PASSCONF);
|
||||
$detName = trim(POST_NAME);
|
||||
$detPrivateKey = trim(POST_PRIVATEKEY);
|
||||
$detEnablePrivateKey = trim(POST_ENABLEPRIVATEKEY);
|
||||
$detMail = trim(POST_MAIL);
|
||||
$detPage = trim(POST_PAGE);
|
||||
$detDesc = filter(POST_DESC);
|
||||
@ -102,13 +122,19 @@ if (POST_SUBMITTED!='' && $currentUser->getId() == $userid) {
|
||||
$tplVars['error'] = T_('E-mail address is not valid.');
|
||||
}
|
||||
if (!$error) {
|
||||
if (!$userservice->updateUser($userid, $detPass, $detName, $detMail, $detPage, $detDesc)) {
|
||||
if (!$userservice->updateUser($userid, $detPass, $detName, $detMail, $detPage, $detDesc, $detPrivateKey, $detEnablePrivateKey)) {
|
||||
$tplVars['error'] = T_('An error occurred while saving your changes.');
|
||||
} else {
|
||||
$tplVars['msg'] = T_('Changes saved.');
|
||||
}
|
||||
}
|
||||
$userinfo = $userservice->getObjectUserByUsername($user);
|
||||
$tplVars['privateKey'] = $userinfo->getPrivateKey(true);
|
||||
if ($userservice->isPrivateKeyValid($userinfo->getPrivateKey())) {
|
||||
$tplVars['privateKeyIsEnabled'] = 'checked="checked"';
|
||||
} else {
|
||||
$tplVars['privateKeyIsEnabled'] = '';
|
||||
}
|
||||
}
|
||||
|
||||
if (!$userservice->isLoggedOn() || $currentUser->getId() != $userid) {
|
||||
|
43
www/rss.php
43
www/rss.php
@ -64,9 +64,14 @@ if (!isset($rssEntries) || $rssEntries <= 0) {
|
||||
$rssEntries = $maxRssEntries;
|
||||
}
|
||||
|
||||
$privatekey = null;
|
||||
if (isset($_GET['privatekey'])) {
|
||||
$privatekey = $_GET['privatekey'];
|
||||
}
|
||||
|
||||
$watchlist = null;
|
||||
$pagetitle = '';
|
||||
$isTempLogin = false;
|
||||
if ($user && $user != 'all') {
|
||||
if ($user == 'watchlist') {
|
||||
$user = $cat;
|
||||
@ -78,8 +83,24 @@ if ($user && $user != 'all') {
|
||||
} else {
|
||||
if ($userinfo = $userservice->getUserByUsername($user)) {
|
||||
$userid =& $userinfo[$userservice->getFieldName('primary')];
|
||||
/* if user is not logged in and has valid privatekey */
|
||||
if (!$userservice->isLoggedOn()) {
|
||||
if ($privatekey != null) {
|
||||
if ($userservice->loginPrivateKey($privatekey)) {
|
||||
$isTempLogin = true;
|
||||
} else {
|
||||
$tplVars['error'] = sprintf(T_('Failed to Autenticate User with username %s using private key'), $user);
|
||||
header('Content-type: text/html; charset=utf-8');
|
||||
$templateservice->loadTemplate('error.404.tpl', $tplVars);
|
||||
//throw a 404 error
|
||||
exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
$tplVars['error'] = sprintf(T_('User with username %s was not found'), $user);
|
||||
header('Content-type: text/html; charset=utf-8');
|
||||
$templateservice->loadTemplate('error.404.tpl', $tplVars);
|
||||
//throw a 404 error
|
||||
exit();
|
||||
@ -87,7 +108,19 @@ if ($user && $user != 'all') {
|
||||
}
|
||||
$pagetitle .= ": ". $user;
|
||||
} else {
|
||||
$userid = null;
|
||||
if ($privatekey != null) {
|
||||
if ($userservice->loginPrivateKey($privatekey)) {
|
||||
$isTempLogin = true;
|
||||
} else {
|
||||
$tplVars['error'] = sprintf(T_('Failed to Autenticate User with username %s using private key'), $user);
|
||||
header('Content-type: text/html; charset=utf-8');
|
||||
$templateservice->loadTemplate('error.404.tpl', $tplVars);
|
||||
//throw a 404 error
|
||||
exit();
|
||||
}
|
||||
} else {
|
||||
$userid = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($cat) {
|
||||
@ -100,7 +133,8 @@ $tplVars['feeddescription'] = sprintf(T_('Recent bookmarks posted to %s'), $GLOB
|
||||
|
||||
$bookmarks = $bookmarkservice->getBookmarks(
|
||||
0, $rssEntries, $userid, $cat,
|
||||
null, getSortOrder(), $watchlist
|
||||
null, getSortOrder(), $watchlist,
|
||||
null, null, null
|
||||
);
|
||||
|
||||
$bookmarks_tmp = filter($bookmarks['bookmarks']);
|
||||
@ -134,6 +168,11 @@ $tplVars['feedlastupdate'] = date('r', strtotime($latestdate));
|
||||
|
||||
$templateservice->loadTemplate('rss.tpl', $tplVars);
|
||||
|
||||
/* If temporary login, please log out */
|
||||
if ($isTempLogin) {
|
||||
$userservice->logout();
|
||||
}
|
||||
|
||||
if ($usecache) {
|
||||
// Cache output if existing copy has expired
|
||||
$cacheservice->End($hash);
|
||||
|
Loading…
Reference in New Issue
Block a user