diff --git a/data/tables.sql b/data/tables.sql
index 59f15f2..32457b7 100644
--- a/data/tables.sql
+++ b/data/tables.sql
@@ -73,8 +73,7 @@ CREATE TABLE `sc_users` (
`email` varchar(50) NOT NULL default '',
`homepage` varchar(255) default NULL,
`uContent` text,
- `privateKey` varchar(32) NULL,
- `enablePrivateKey` int(1) default '0',
+ `privateKey` varchar(33) default NULL,
PRIMARY KEY (`uId`),
UNIQUE KEY `privateKey` (`privateKey`)
) CHARACTER SET utf8 COLLATE utf8_general_ci ;
diff --git a/data/templates/editprofile.tpl.php b/data/templates/editprofile.tpl.php
index f083322..16fbc94 100644
--- a/data/templates/editprofile.tpl.php
+++ b/data/templates/editprofile.tpl.php
@@ -32,7 +32,7 @@ $this->includeTemplate($GLOBALS['top_include']);
|
- getEnablePrivateKey()==1) echo 'checked="checked"'; ?>> |
+ > |
diff --git a/data/templates/rss.tpl.php b/data/templates/rss.tpl.php
index e6e66f7..6be5425 100644
--- a/data/templates/rss.tpl.php
+++ b/data/templates/rss.tpl.php
@@ -3,7 +3,7 @@ echo '<' . '?xml version="1.0" encoding="utf-8" ?' . ">\n";
?>
-
+
@@ -23,4 +23,4 @@ echo '<' . '?xml version="1.0" encoding="utf-8" ?' . ">\n";
-
\ No newline at end of file
+
diff --git a/data/templates/top.inc.php b/data/templates/top.inc.php
index b1ffa14..40d69be 100644
--- a/data/templates/top.inc.php
+++ b/data/templates/top.inc.php
@@ -5,14 +5,13 @@
-
+
';
+ $size = count($rsschannels);
+ for ($i = 0; $i < $size; $i++) {
+ echo ' '."\n";
}
}
?>
diff --git a/src/SemanticScuttle/Model/User.php b/src/SemanticScuttle/Model/User.php
index 124bce3..c9debd9 100644
--- a/src/SemanticScuttle/Model/User.php
+++ b/src/SemanticScuttle/Model/User.php
@@ -36,7 +36,6 @@ class SemanticScuttle_Model_User
var $datetime;
var $isAdmin;
var $privateKey;
- var $enablePrivateKey;
/**
* Create a new user object
@@ -86,22 +85,6 @@ class SemanticScuttle_Model_User
return $this->privateKey;
}
- /**
- * Returns private key flag
- *
- * @return integer private key 1=enabled, 0=disabled
- */
- public function getEnablePrivateKey()
- {
- // Look for value only if not already set
- if (!isset($this->enablePrivateKey)) {
- $us = SemanticScuttle_Service_Factory::get('User');
- $user = $us->getUser($this->id);
- $this->enablePrivateKey = $user['enablePrivateKey'];
- }
- return $this->enablePrivateKey;
- }
-
/**
* Returns full user name as specified in the profile.
*
diff --git a/src/SemanticScuttle/Service/Bookmark.php b/src/SemanticScuttle/Service/Bookmark.php
index 3e4bfcc..8194cf1 100644
--- a/src/SemanticScuttle/Service/Bookmark.php
+++ b/src/SemanticScuttle/Service/Bookmark.php
@@ -303,7 +303,9 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
function editAllowed($bookmark)
{
if (!is_numeric($bookmark)
- && (!is_array($bookmark) || !isset($bookmark['bId']) || !is_numeric($bookmark['bId']))
+ && (!is_array($bookmark)
+ || !isset($bookmark['bId'])
+ || !is_numeric($bookmark['bId']))
) {
return false;
}
@@ -667,26 +669,26 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
* each bookmark array contains two additional keys:
* 'hasVoted' and 'vote'.
*
- * @param integer $start Page number
- * @param integer $perpage Number of bookmarks per page
- * @param integer $user User ID
- * @param mixed $tags Array of tags or tags separated
- * by "+" signs
- * @param string $terms Search terms separated by spaces
- * @param string $sortOrder One of the following values:
- * "date_asc", "date_desc",
- * "title_desc", "title_asc",
- * "url_desc", "url_asc",
- * "voting_asc", "voting_desc"
- * @param boolean $watched True if only watched bookmarks
- * shall be returned (FIXME)
- * @param integer $startdate Filter for creation date.
- * SQL-DateTime value
- * "YYYY-MM-DD hh:ii:ss'
- * @param integer $enddate Filter for creation date.
- * SQL-DateTime value
- * "YYYY-MM-DD hh:ii:ss'
- * @param string $hash Filter by URL hash
+ * @param integer $start Page number
+ * @param integer $perpage Number of bookmarks per page
+ * @param integer $user User ID
+ * @param mixed $tags Array of tags or tags separated
+ * by "+" signs
+ * @param string $terms Search terms separated by spaces
+ * @param string $sortOrder One of the following values:
+ * "date_asc", "date_desc",
+ * "title_desc", "title_asc",
+ * "url_desc", "url_asc",
+ * "voting_asc", "voting_desc"
+ * @param boolean $watched True if only watched bookmarks
+ * shall be returned (FIXME)
+ * @param integer $startdate Filter for creation date.
+ * SQL-DateTime value
+ * "YYYY-MM-DD hh:ii:ss'
+ * @param integer $enddate Filter for creation date.
+ * SQL-DateTime value
+ * "YYYY-MM-DD hh:ii:ss'
+ * @param string $hash Filter by URL hash
*
* @return array Array with two keys: 'bookmarks' and 'total'.
* First contains an array of bookmarks, 'total'
@@ -705,15 +707,16 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
if ($userservice->isLoggedOn()) {
// All public bookmarks, user's own bookmarks
// and any shared with user
- $privacy = ' ((B.bStatus = 0) OR (B.uId = '. $sId .')';
- $watchlist = $userservice->getWatchlist($sId);
- foreach ($watchlist as $watchuserID) {
- $privacy .= ' OR (B.uId = '. $watchuserID .' AND B.bStatus = 1)';
+ $privacy = ' AND ((B.bStatus = 0) OR (B.uId = '. $sId .')';
+ $watchnames = $userservice->getWatchNames($sId, true);
+ foreach ($watchnames as $watchuser) {
+ $privacy .= ' OR (U.username = "'. $watchuser;
+ $privacy .= '" AND B.bStatus = 1)';
}
$privacy .= ')';
} else {
// Just public bookmarks
- $privacy = ' B.bStatus = 0';
+ $privacy = ' AND B.bStatus = 0';
}
// Set up the tags, if need be.
@@ -727,20 +730,17 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
}
// Set up the SQL query.
- $query_1 = 'SELECT DISTINCT(B.bHash), ';
- $query_1.= '(select '. $userservice->getFieldName('username');
- $query_1.= ' from '. $userservice->getTableName();
- $query_1.= ' where uId=B.uId';
- $query_1.= ') as '. $userservice->getFieldName('username') .', ';
-
+ $query_1 = 'SELECT DISTINCT ';
if (SQL_LAYER == 'mysql4') {
$query_1 .= 'SQL_CALC_FOUND_ROWS ';
}
- $query_1 .= 'B.*';
+ $query_1 .= 'B.*, U.'. $userservice->getFieldName('username');
- $query_2 = ' FROM '. $this->getTableName() .' AS B';
+ $query_2 = ' FROM '. $userservice->getTableName() .' AS U'
+ . ', '. $this->getTableName() .' AS B';
- $query_3 = ' WHERE '. $privacy;
+ $query_3 = ' WHERE B.uId = U.'. $userservice->getFieldName('primary');
+ $query_3 .= $privacy;
if ($GLOBALS['enableVoting'] && $GLOBALS['hideBelowVoting'] !== null
&& !$userservice->isAdmin($userservice->getCurrentUserId())
@@ -749,11 +749,9 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
}
if (is_null($watched)) {
-/*
if (!is_null($user)) {
$query_3 .= ' AND B.uId = '. $user;
}
-*/
} else {
$arrWatch = $userservice->getWatchlist($user);
if (count($arrWatch) > 0) {
@@ -769,14 +767,20 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
}
$query_5 = '';
+ if ($hash == null) {
+ $query_5.= ' GROUP BY B.bHash';
+ }
+
//Voting system
//needs to be directly after FROM bookmarks
if ($GLOBALS['enableVoting'] && $userservice->isLoggedOn()) {
$cuid = $userservice->getCurrentUserId();
$vs = SemanticScuttle_Service_Factory::get('Vote');
- $query_1 .= ', (select !ISNULL(bId) from '.$vs->getTableName().' where bId=B.bId and uId='.(int)$cuid.') as hasVoted, (select vote from '.$vs->getTableName().' where bId=B.bId and uId='.(int)$cuid.') as vote';
-
+ $query_1 .= ', !ISNULL(V.bId) as hasVoted, V.vote as vote';
+ $query_2 .= ' LEFT JOIN ' . $vs->getTableName() . ' AS V'
+ . ' ON B.bId = V.bId'
+ . ' AND V.uId = ' . (int)$cuid;
}
switch($sortOrder) {
@@ -805,11 +809,6 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
$query_5 .= ' ORDER BY B.' . $GLOBALS['dateOrderField'] . ' DESC ';
}
- // Add GROUP BY only if tag is given
- if ($tagcount > 0) {
- $query_5 = ' GROUP BY B.bHash' . $query_5;
- }
-
// Handle the parts of the query that depend on any tags that are present.
$query_4 = '';
for ($i = 0; $i < $tagcount; $i ++) {
@@ -859,9 +858,9 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
$query_4 .= ' OR B.bPrivateNote LIKE "'
. $this->db->sql_escape($aTerms[$i])
.'%"';
- $query_4 .= ' OR B.uId = (select '.$userservice->getFieldName('primary').' from '.$userservice->getTableName().' where '.$userservice->getFieldName('username').'="'
+ $query_4 .= ' OR U.username = "'
. $this->db->sql_escape($aTerms[$i])
- . '")';
+ . '"'; //exact match for username
if ($dotags) {
$query_4 .= ' OR T.tag LIKE "'
. $this->db->sql_escape($aTerms[$i])
diff --git a/src/SemanticScuttle/Service/User.php b/src/SemanticScuttle/Service/User.php
index 71bbad3..3f2d5c7 100644
--- a/src/SemanticScuttle/Service/User.php
+++ b/src/SemanticScuttle/Service/User.php
@@ -577,6 +577,13 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
*/
public function loginPrivateKey($username, $privatekey)
{
+ /* Check for size, only 32 char keys will work */
+ /* Failsafe to hopefully lessen hackability and */
+ /* deactivated keys (preceded by dash) */
+ if (strlen($privatekey) != 32) {
+ return false;
+ }
+
$query = 'SELECT '. $this->getFieldName('primary') .' FROM '
. $this->getTableName() .' WHERE '
. $this->getFieldName('username') .' = "'
@@ -789,33 +796,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 $privateKey Key for RSS auth
- * @param integer $enablePrivateKey Flag to enable Private RSS
+ * @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, $privateKey=null, $enablePrivateKey=0
- ) {
+ 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);
- // set new private key if enabled but user forgot to generate
- if ($enablePrivateKey == 1) {
- $privateKey = $this->getNewPrivateKey();
- }
$values = array(
'username' => $username,
'password' => $password,
'email' => $email,
'uDatetime' => $datetime,
'uModified' => $datetime,
- 'privateKey' => $privateKey,
- 'enablePrivateKey' => $enablePrivateKey
+ 'privateKey' => $privateKey
);
$sql = 'INSERT INTO '. $this->getTableName()
. ' '. $this->db->sql_build_array('INSERT', $values);
@@ -839,39 +839,52 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
/**
* Update User Record
*
- * @param string $uId User ID
- * @param string $password User Password
- * @param string $name User Name
- * @param string $email Email Address
- * @param string $homepage Homepage URL
- * @param string $uContent Content
- * @param string $privateKey RSS Private Key
- * @param integer $enablePrivateKey Flag to enable RSS Private Key
+ * @param string $uId User ID
+ * @param string $password User Password
+ * @param string $name User Name
+ * @param string $email Email Address
+ * @param string $homepage Homepage URL
+ * @param string $uContent Content
+ * @param string $privateKey RSS Private Key
+ * @param string $enablePrivateRSS RSS Private Key
*
* @return boolean true if it successful, false if not
*/
function updateUser(
$uId, $password, $name, $email, $homepage, $uContent,
- $privateKey=null, $enablePrivateKey=0
+ $privateKey=null, $enablePrivateRSS=0
) {
if (!is_numeric($uId)) {
return false;
}
+ // prepend - to privateKey if disabled
+ if ($privateKey!=null and strlen($privateKey)==32 and $enablePrivateRSS==0) {
+ $privateKey = "-".$privateKey;
+ }
+
+ // remove - from privateKey if enabling
+ if ($privateKey!=null and strlen($privateKey)==33 and $enablePrivateRSS==1) {
+ $privateKey = substr($privateKey, 1, 32);
+ }
+
+ // if new user is enabling Private RSS, create new key
+ if ($privateKey==null and $enablePrivateRSS==1) {
+ $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, 'privateKey' => $privateKey,
- 'enablePrivateKey' => $enablePrivateKey);
+ 'uContent' => $uContent, 'privateKey' => $privateKey);
} else {
$updates = array ('uModified' => $moddatetime,
'password' => $this->sanitisePassword($password),
'name' => $name, 'email' => $email, 'homepage' => $homepage,
- 'uContent' => $uContent, 'privateKey' => $privateKey,
- 'enablePrivateKey' => $enablePrivateKey);
+ 'uContent' => $uContent, 'privateKey' => $privateKey);
}
$sql = 'UPDATE '. $this->getTableName() .' SET '
. $this->db->sql_build_array('UPDATE', $updates) .' WHERE '
diff --git a/tests/BookmarkTest.php b/tests/BookmarkTest.php
index f54fe9a..c13ab17 100644
--- a/tests/BookmarkTest.php
+++ b/tests/BookmarkTest.php
@@ -1164,7 +1164,7 @@ class BookmarkTest extends TestBase
//create bookmarks for main user and other one
$this->addBookmark($uid, $address, 0);
- $this->addBookmark($friendPublic1, $address, 1);//1 is shared
+ $this->addBookmark($friendPublic1, $address, 1);//1 is shared
//log main user in
$this->us->setCurrentUserId($uid);
@@ -1342,6 +1342,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->assertNull($bookmarks['bookmarks'][1]);
+
+ }
}
diff --git a/tests/UserTest.php b/tests/UserTest.php
index a73285b..b626170 100644
--- a/tests/UserTest.php
+++ b/tests/UserTest.php
@@ -221,6 +221,57 @@ class UserTest extends TestBase
$this->assertTrue($this->us->privateKeyExists($randKey));
}
+
+
+
+ /**
+ * Test loginPrivateKey() function returns righ
+ *
+ * @return void
+ */
+ public function testLoginWithPrivateKey()
+ {
+ /* 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 credentials - both invalid login and key */
+ $this->assertFalse(
+ $this->us->loginPrivateKey('userdoesnot', '02848248084082408240824802408248')
+ );
+
+ /* test valid credentials with private key enabled */
+ $this->assertTrue(
+ $this->us->loginPrivateKey('testusername', $randKey)
+ );
+
+ /* test valid credentials with private key enabled but invalid key */
+ $this->assertFalse(
+ $this->us->loginPrivateKey('testusername', '123')
+ );
+
+ /* 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('seconduser', $randKey2)
+ );
+
+ /* test valid credentials with private key disabled and invalid key */
+ $this->assertFalse(
+ $this->us->loginPrivateKey('seconduser', '-1')
+ );
+ $this->assertFalse(
+ $this->us->loginPrivateKey('seconduser', null)
+ );
+ }
+
}
diff --git a/tests/prepare.php b/tests/prepare.php
index 6afc284..214bc32 100644
--- a/tests/prepare.php
+++ b/tests/prepare.php
@@ -36,4 +36,4 @@ if ($GLOBALS['debugMode'] == true
. '!!! The combination of debugMode and dbtype==mysql4'
. ' will wreck some tests' . "\n\n";
}
-?>
\ No newline at end of file
+?>
diff --git a/www/bookmarks.php b/www/bookmarks.php
index fe8c9fd..52145c4 100644
--- a/www/bookmarks.php
+++ b/www/bookmarks.php
@@ -259,7 +259,7 @@ if ($templatename == 'editbookmark.tpl') {
)
);
if ($userservice->isLoggedOn()) {
- if ($currentUser->getPrivateKey() <> null && $currentUser->getEnablePrivateKey() == 1) {
+ if (strlen($currentUser->getPrivateKey()) == 32) {
array_push(
$tplVars['rsschannels'],
array(
diff --git a/www/index.php b/www/index.php
index ea28345..f1fc81b 100644
--- a/www/index.php
+++ b/www/index.php
@@ -44,12 +44,12 @@ $tplVars['rsschannels'] = array(
);
if ($userservice->isLoggedOn()) {
$currentUsername = $currentUser->getUsername();
- if ($currentUser->getPrivateKey() <> null && $currentUser->getEnablePrivateKey() == 1) {
+ if ($currentUser->getPrivateKey() <> null && strlen($currentUser->getPrivateKey()) == 32) {
array_push(
$tplVars['rsschannels'],
array(
filter($sitename . sprintf(T_(': (private) ')) . $sitename),
- createURL('rss', filter($currentUsername, 'url') . '?sort='.getSortOrder().'&privatekey='.$currentUser->getPrivateKey())
+ createURL('rss', filter($currentUsername, 'url') . '?sort='.getSortOrder().'&privatekey='.$currentUser->getPrivateKey())
)
);
}
diff --git a/www/profile.php b/www/profile.php
index a1b1841..06cc52d 100644
--- a/www/profile.php
+++ b/www/profile.php
@@ -66,7 +66,6 @@ if ($user) {
if ($userservice->isLoggedOn() && $user == $currentUser->getUsername()) {
$title = T_('My Profile');
$tplVars['privateKey'] = $currentUser->getPrivateKey();
- $tplVars['enablePrivateKey'] = $currentUser->getPrivateKey();
} else {
$title = T_('Profile') .': '. $user;
$tplVars['privateKey'] = '';
diff --git a/www/rss.php b/www/rss.php
index 3138c2d..5f20fd1 100644
--- a/www/rss.php
+++ b/www/rss.php
@@ -82,6 +82,11 @@ if ($user && $user != 'all') {
if ($privatekey != null) {
if ($userservice->loginPrivateKey($user, $privatekey)) {
$isTempLogin = true;
+ } else {
+ $tplVars['error'] = sprintf(T_('Failed to Autenticate User with username %s using private key'), $user);
+ $templateservice->loadTemplate('error.404.tpl', $tplVars);
+ //throw a 404 error
+ exit();
}
}
}