aboutsummaryrefslogtreecommitdiff
path: root/src/SemanticScuttle
diff options
context:
space:
mode:
Diffstat (limited to 'src/SemanticScuttle')
-rw-r--r--src/SemanticScuttle/Config.php109
-rw-r--r--src/SemanticScuttle/Environment.php52
-rw-r--r--src/SemanticScuttle/Model/Bookmark.php17
-rw-r--r--src/SemanticScuttle/Model/User.php26
-rw-r--r--src/SemanticScuttle/Service/Bookmark.php1
-rw-r--r--src/SemanticScuttle/Service/Bookmark2Tag.php4
-rw-r--r--src/SemanticScuttle/Service/Tag.php4
-rw-r--r--src/SemanticScuttle/Service/User.php219
-rw-r--r--src/SemanticScuttle/constants.php14
-rw-r--r--src/SemanticScuttle/header.php18
10 files changed, 408 insertions, 56 deletions
diff --git a/src/SemanticScuttle/Config.php b/src/SemanticScuttle/Config.php
new file mode 100644
index 0000000..0773310
--- /dev/null
+++ b/src/SemanticScuttle/Config.php
@@ -0,0 +1,109 @@
+<?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
+ */
+
+/**
+ * Configuration handling
+ *
+ * @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_Config
+{
+ /**
+ * Prefix for configuration files.
+ * Used to inject stream wrapper protocol for unit testing
+ *
+ * @var string
+ */
+ public $filePrefix = '';
+
+
+
+ /**
+ * Finds the correct data directory
+ *
+ * @return string Full path to the data directory with a trailing slash
+ */
+ protected function getDataDir()
+ {
+ if ('@data_dir@' == '@' . 'data_dir@') {
+ //non pear-install
+ $datadir = dirname(__FILE__) . '/../../data/';
+ } else {
+ //pear installation; files are in include path
+ $datadir = '@data_dir@/SemanticScuttle/';
+ }
+
+ return $datadir;
+ }
+
+
+
+ /**
+ * Tries to find a configuration file by looking in different
+ * places:
+ * - pear data_dir/SemanticScuttle/config-$hostname.php
+ * - pear data_dir/SemanticScuttle/config.php
+ * - /etc/semanticscuttle/config-$hostname.php
+ * - /etc/semanticscuttle/config.php
+ *
+ * Paths with host name have priority.
+ *
+ * @return array Array with config file path as first value
+ * and default config file path as second value.
+ * Any may be NULL if not found
+ */
+ public function findFiles()
+ {
+ //use basename to prevent path injection
+ $host = basename($_SERVER['HTTP_HOST']);
+ $datadir = $this->getDataDir();
+
+ $arFiles = array(
+ $datadir . 'config.' . $host . '.php',
+ '/etc/semanticscuttle/config.' . $host . '.php',
+ $datadir . 'config.php',
+ '/etc/semanticscuttle/config.php',
+ );
+
+ $configfile = null;
+ foreach ($arFiles as $file) {
+ if (file_exists($this->filePrefix . $file)) {
+ $configfile = $file;
+ break;
+ }
+ }
+
+ //find default file
+ $arDefaultFiles = array_unique(
+ array(
+ substr($configfile, 0, -3) . 'default.php',
+ $datadir . 'config.default.php',
+ '/etc/semanticscuttle/config.default.php',
+ )
+ );
+ $defaultfile = null;
+ foreach ($arDefaultFiles as $file) {
+ if (file_exists($this->filePrefix . $file)) {
+ $defaultfile = $file;
+ break;
+ }
+ }
+ return array($configfile, $defaultfile);
+ }
+}
+
+?> \ No newline at end of file
diff --git a/src/SemanticScuttle/Environment.php b/src/SemanticScuttle/Environment.php
new file mode 100644
index 0000000..e5fe3de
--- /dev/null
+++ b/src/SemanticScuttle/Environment.php
@@ -0,0 +1,52 @@
+<?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
+ */
+
+/**
+ * Server environment handling methods
+ *
+ * @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_Environment
+{
+ /**
+ * Determines the correct $_SERVER['PATH_INFO'] value
+ *
+ * @return string New value
+ */
+ public static function getServerPathInfo()
+ {
+ /* old code that does not work today.
+ if you find that this code helps you, tell us
+ and send us the output of var_export($_SERVER);
+ // Correct bugs with PATH_INFO (maybe for Apache 1 or CGI) -- for 1&1 host...
+ if (isset($_SERVER['PATH_INFO']) && isset($_SERVER['ORIG_PATH_INFO'])) {
+ if (strlen($_SERVER["PATH_INFO"])<strlen($_SERVER["ORIG_PATH_INFO"])) {
+ $_SERVER["PATH_INFO"] = $_SERVER["ORIG_PATH_INFO"];
+ }
+ if (strcasecmp($_SERVER["PATH_INFO"], $_SERVER["SCRIPT_NAME"]) == 0) {
+ unset($_SERVER["PATH_INFO"]);
+ }
+ if (strpos($_SERVER["PATH_INFO"], '.php') !== false) {
+ unset($_SERVER["PATH_INFO"]);
+ }
+ }
+ */
+
+ return $_SERVER['PATH_INFO'];
+ }
+}
+?> \ No newline at end of file
diff --git a/src/SemanticScuttle/Model/Bookmark.php b/src/SemanticScuttle/Model/Bookmark.php
index 8bda0b3..1330642 100644
--- a/src/SemanticScuttle/Model/Bookmark.php
+++ b/src/SemanticScuttle/Model/Bookmark.php
@@ -24,6 +24,23 @@
class SemanticScuttle_Model_Bookmark
{
/**
+ * Status "public" / visible for all
+ */
+ const SPUBLIC = 0;
+
+ /**
+ * Status "shared" / visible for people on your watchlist
+ */
+ const SWATCHLIST = 1;
+
+ /**
+ * Status "private" / visible for yourself only
+ */
+ const SPRIVATE = 2;
+
+
+
+ /**
* Checks if the given URL is valid and may be used with this
* SemanticScuttle installation.
*
diff --git a/src/SemanticScuttle/Model/User.php b/src/SemanticScuttle/Model/User.php
index 500f5b1..3aa617b 100644
--- a/src/SemanticScuttle/Model/User.php
+++ b/src/SemanticScuttle/Model/User.php
@@ -35,6 +35,7 @@ class SemanticScuttle_Model_User
var $content;
var $datetime;
var $isAdmin;
+ var $privateKey;
/**
* Create a new user object
@@ -69,6 +70,29 @@ class SemanticScuttle_Model_User
}
/**
+ * 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.
*
* @return string Full name
@@ -182,4 +206,4 @@ class SemanticScuttle_Model_User
}
}
-?> \ No newline at end of file
+?>
diff --git a/src/SemanticScuttle/Service/Bookmark.php b/src/SemanticScuttle/Service/Bookmark.php
index 919ca7a..17ab7ba 100644
--- a/src/SemanticScuttle/Service/Bookmark.php
+++ b/src/SemanticScuttle/Service/Bookmark.php
@@ -427,6 +427,7 @@ class SemanticScuttle_Service_Bookmark extends SemanticScuttle_DbService
$existence[$hashes[$row['bHash']]] = $row['count'] > 0;
}
+ $this->db->sql_freeresult($dbresult);
return $existence;
}
diff --git a/src/SemanticScuttle/Service/Bookmark2Tag.php b/src/SemanticScuttle/Service/Bookmark2Tag.php
index a10cb61..04ee43d 100644
--- a/src/SemanticScuttle/Service/Bookmark2Tag.php
+++ b/src/SemanticScuttle/Service/Bookmark2Tag.php
@@ -99,7 +99,7 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
$tags_count = is_array($tags)?count($tags):0;
for ($i = 0; $i < $tags_count; $i++) {
- $tags[$i] = trim(strtolower($tags[$i]));
+ $tags[$i] = trim(utf8_strtolower($tags[$i]));
if ($fromApi) {
include_once 'SemanticScuttle/functions.php';
$tags[$i] = convertTag($tags[$i], 'in');
@@ -584,7 +584,7 @@ class SemanticScuttle_Service_Bookmark2Tag extends SemanticScuttle_DbService
if (is_int($days)) {
$query .= ' AND B.bDatetime > "'
- . date('Y-m-d H:i:s', time() - (86400 * $days))
+ . gmdate('Y-m-d H:i:s', time() - (86400 * $days))
. '"';
}
diff --git a/src/SemanticScuttle/Service/Tag.php b/src/SemanticScuttle/Service/Tag.php
index 25d3888..8325285 100644
--- a/src/SemanticScuttle/Service/Tag.php
+++ b/src/SemanticScuttle/Service/Tag.php
@@ -141,10 +141,10 @@ class SemanticScuttle_Service_Tag extends SemanticScuttle_DbService
//normalize
if(!is_array($tags)) {
- $tags = strtolower(trim($tags));
+ $tags = utf8_strtolower(trim($tags));
} else {
for($i=0; $i<count($tags); $i++) {
- $tags[$i] = strtolower(trim($tags[$i]));
+ $tags[$i] = utf8_strtolower(trim($tags[$i]));
}
}
return $tags;
diff --git a/src/SemanticScuttle/Service/User.php b/src/SemanticScuttle/Service/User.php
index 0e437c2..7550ed2 100644
--- a/src/SemanticScuttle/Service/User.php
+++ b/src/SemanticScuttle/Service/User.php
@@ -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) {
@@ -280,6 +293,22 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
}
/**
+ * 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
*
* @param boolean $refresh Reload the user from database
@@ -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);
@@ -510,6 +539,46 @@ 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) {
+ $this->setCurrentUserId($row[$this->getFieldName('primary')], false);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
* Logs the user off
*
* @return void
@@ -519,7 +588,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) {
@@ -603,11 +673,12 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
return false;
}
- $arrWatch = array();
+ $retval = true;
if ($this->db->sql_numrows($dbresult) == 0)
- return false;
- else
- return true;
+ $retval = false;
+
+ $this->db->sql_freeresult($dbresult);
+ return $retval;
}
function setWatchStatus($subjectUserID) {
@@ -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;
diff --git a/src/SemanticScuttle/constants.php b/src/SemanticScuttle/constants.php
index f8567d9..fcb2d90 100644
--- a/src/SemanticScuttle/constants.php
+++ b/src/SemanticScuttle/constants.php
@@ -69,16 +69,6 @@ define('PAGE_WATCHLIST', "watchlist");
// installations on the same host server
define('INSTALLATION_ID', md5($GLOBALS['dbname'].$GLOBALS['tableprefix']));
-// Correct bugs with PATH_INFO (maybe for Apache 1 or CGI) -- for 1&1 host...
-if (isset($_SERVER['PATH_INFO']) && isset($_SERVER['ORIG_PATH_INFO'])) {
- if (strlen($_SERVER["PATH_INFO"])<strlen($_SERVER["ORIG_PATH_INFO"])) {
- $_SERVER["PATH_INFO"] = $_SERVER["ORIG_PATH_INFO"];
- }
- if (strcasecmp($_SERVER["PATH_INFO"], $_SERVER["SCRIPT_NAME "]) == 0) {
- unset($_SERVER["PATH_INFO"]);
- }
- if (strpos($_SERVER["PATH_INFO"], '.php') !== false) {
- unset($_SERVER["PATH_INFO"]);
- }
-}
+//currently not needed
+//$_SERVER['PATH_INFO'] = SemanticScuttle_Environment::getServerPathInfo();
?>
diff --git a/src/SemanticScuttle/header.php b/src/SemanticScuttle/header.php
index 6c0d4df..694df54 100644
--- a/src/SemanticScuttle/header.php
+++ b/src/SemanticScuttle/header.php
@@ -25,8 +25,20 @@ if ('@data_dir@' == '@' . 'data_dir@') {
//FIXME: when you have multiple installations, the www_dir will be wrong
$wwwdir = '@www_dir@/SemanticScuttle/';
}
+require_once dirname(__FILE__) . '/Environment.php';
+require_once dirname(__FILE__) . '/Config.php';
-if (!file_exists($datadir . '/config.php')) {
+$cfg = new SemanticScuttle_Config();
+list($configfile, $defaultfile) = $cfg->findFiles();
+if ($defaultfile === null) {
+ header('HTTP/1.0 500 Internal Server Error');
+ die(
+ 'No default configuration file config.default.php found.'
+ . ' This is really, really strange'
+ . "\n"
+ );
+}
+if ($configfile === null) {
header('HTTP/1.0 500 Internal Server Error');
die(
'Please copy "config.php.dist" to "config.php" in data/ folder.'
@@ -39,8 +51,8 @@ set_include_path(
);
// 1 // First requirements part (before debug management)
-require_once $datadir . '/config.default.php';
-require_once $datadir . '/config.php';
+require_once $defaultfile;
+require_once $configfile;
if (isset($_GET['unittestMode']) && $_GET['unittestMode'] == 1
) {