summaryrefslogtreecommitdiff
path: root/classes
diff options
context:
space:
mode:
Diffstat (limited to 'classes')
-rw-r--r--classes/Consumer.php30
-rw-r--r--classes/File.php17
-rw-r--r--classes/Memcached_DataObject.php53
-rw-r--r--classes/Notice.php35
-rw-r--r--classes/Oauth_application.php17
-rw-r--r--classes/Profile_role.php1
-rw-r--r--classes/Session.php43
-rw-r--r--classes/User.php204
-rw-r--r--classes/status_network.ini1
-rw-r--r--classes/statusnet.ini3
10 files changed, 305 insertions, 99 deletions
diff --git a/classes/Consumer.php b/classes/Consumer.php
index ad64a8491..ce399f278 100644
--- a/classes/Consumer.php
+++ b/classes/Consumer.php
@@ -36,4 +36,34 @@ class Consumer extends Memcached_DataObject
return $cons;
}
+ /**
+ * Delete a Consumer and related tokens and nonces
+ *
+ * XXX: Should this happen in an OAuthDataStore instead?
+ *
+ */
+ function delete()
+ {
+ // XXX: Is there any reason NOT to do this kind of cleanup?
+
+ $this->_deleteTokens();
+ $this->_deleteNonces();
+
+ parent::delete();
+ }
+
+ function _deleteTokens()
+ {
+ $token = new Token();
+ $token->consumer_key = $this->consumer_key;
+ $token->delete();
+ }
+
+ function _deleteNonces()
+ {
+ $nonce = new Nonce();
+ $nonce->consumer_key = $this->consumer_key;
+ $nonce->delete();
+ }
+
}
diff --git a/classes/File.php b/classes/File.php
index 34e4632a8..307fdb686 100644
--- a/classes/File.php
+++ b/classes/File.php
@@ -176,8 +176,22 @@ class File extends Memcached_DataObject
return "$nickname-$datestamp-$random.$ext";
}
+ /**
+ * Validation for as-saved base filenames
+ */
+ static function validFilename($filename)
+ {
+ return preg_match('/^[A-Za-z0-9._-]+$/', $filename);
+ }
+
+ /**
+ * @throws ClientException on invalid filename
+ */
static function path($filename)
{
+ if (!self::validFilename($filename)) {
+ throw new ClientException("Invalid filename");
+ }
$dir = common_config('attachments', 'dir');
if ($dir[strlen($dir)-1] != '/') {
@@ -189,6 +203,9 @@ class File extends Memcached_DataObject
static function url($filename)
{
+ if (!self::validFilename($filename)) {
+ throw new ClientException("Invalid filename");
+ }
if(common_config('site','private')) {
return common_local_url('getfile',
diff --git a/classes/Memcached_DataObject.php b/classes/Memcached_DataObject.php
index 2cc6377f8..ab65c30ce 100644
--- a/classes/Memcached_DataObject.php
+++ b/classes/Memcached_DataObject.php
@@ -147,6 +147,7 @@ class Memcached_DataObject extends DB_DataObject
{
$result = parent::insert();
if ($result) {
+ $this->fixupTimestamps();
$this->encache(); // in case of cached negative lookups
}
return $result;
@@ -159,6 +160,7 @@ class Memcached_DataObject extends DB_DataObject
}
$result = parent::update($orig);
if ($result) {
+ $this->fixupTimestamps();
$this->encache();
}
return $result;
@@ -366,7 +368,7 @@ class Memcached_DataObject extends DB_DataObject
}
/**
- * sends query to database - this is the private one that must work
+ * sends query to database - this is the private one that must work
* - internal functions use this rather than $this->query()
*
* Overridden to do logging.
@@ -428,7 +430,7 @@ class Memcached_DataObject extends DB_DataObject
//
// WARNING WARNING if we end up actually using multiple DBs at a time
// we'll need some fancier logic here.
- if (!$exists && !empty($_DB_DATAOBJECT['CONNECTIONS'])) {
+ if (!$exists && !empty($_DB_DATAOBJECT['CONNECTIONS']) && php_sapi_name() == 'cli') {
foreach ($_DB_DATAOBJECT['CONNECTIONS'] as $index => $conn) {
if (!empty($conn)) {
$conn->disconnect();
@@ -529,4 +531,51 @@ class Memcached_DataObject extends DB_DataObject
return $c->delete($cacheKey);
}
+
+ function fixupTimestamps()
+ {
+ // Fake up timestamp columns
+ $columns = $this->table();
+ foreach ($columns as $name => $type) {
+ if ($type & DB_DATAOBJECT_MYSQLTIMESTAMP) {
+ $this->$name = common_sql_now();
+ }
+ }
+ }
+
+ function debugDump()
+ {
+ common_debug("debugDump: " . common_log_objstring($this));
+ }
+
+ function raiseError($message, $type = null, $behaviour = null)
+ {
+ throw new ServerException("DB_DataObject error [$type]: $message");
+ }
+
+ static function cacheGet($keyPart)
+ {
+ $c = self::memcache();
+
+ if (empty($c)) {
+ return false;
+ }
+
+ $cacheKey = common_cache_key($keyPart);
+
+ return $c->get($cacheKey);
+ }
+
+ static function cacheSet($keyPart, $value)
+ {
+ $c = self::memcache();
+
+ if (empty($c)) {
+ return false;
+ }
+
+ $cacheKey = common_cache_key($keyPart);
+
+ return $c->set($cacheKey, $value);
+ }
}
diff --git a/classes/Notice.php b/classes/Notice.php
index 0966697e2..42878d94f 100644
--- a/classes/Notice.php
+++ b/classes/Notice.php
@@ -140,7 +140,7 @@ class Notice extends Memcached_DataObject
foreach(array_unique($hashtags) as $hashtag) {
/* elide characters we don't want in the tag */
$this->saveTag($hashtag);
- self::blow('profile:notice_ids_tagged:%d:%s', $this->profile_id, $tag->tag);
+ self::blow('profile:notice_ids_tagged:%d:%s', $this->profile_id, $hashtag);
}
return true;
}
@@ -326,9 +326,7 @@ class Notice extends Memcached_DataObject
# XXX: someone clever could prepend instead of clearing the cache
$notice->blowOnInsert();
- $qm = QueueManager::get();
-
- $qm->enqueue($notice, 'distrib');
+ $notice->distribute();
return $notice;
}
@@ -1374,8 +1372,6 @@ class Notice extends Memcached_DataObject
}
$reply->free();
-
- return $ids;
}
function clearRepeats()
@@ -1445,4 +1441,31 @@ class Notice extends Memcached_DataObject
$gi->free();
}
+
+ function distribute()
+ {
+ if (common_config('queue', 'inboxes')) {
+ // If there's a failure, we want to _force_
+ // distribution at this point.
+ try {
+ $qm = QueueManager::get();
+ $qm->enqueue($this, 'distrib');
+ } catch (Exception $e) {
+ // If the exception isn't transient, this
+ // may throw more exceptions as DQH does
+ // its own enqueueing. So, we ignore them!
+ try {
+ $handler = new DistribQueueHandler();
+ $handler->handle($this);
+ } catch (Exception $e) {
+ common_log(LOG_ERR, "emergency redistribution resulted in " . $e->getMessage());
+ }
+ // Re-throw so somebody smarter can handle it.
+ throw $e;
+ }
+ } else {
+ $handler = new DistribQueueHandler();
+ $handler->handle($this);
+ }
+ }
}
diff --git a/classes/Oauth_application.php b/classes/Oauth_application.php
index a6b539087..748b64220 100644
--- a/classes/Oauth_application.php
+++ b/classes/Oauth_application.php
@@ -137,4 +137,21 @@ class Oauth_application extends Memcached_DataObject
}
}
+ function delete()
+ {
+ $this->_deleteAppUsers();
+
+ $consumer = $this->getConsumer();
+ $consumer->delete();
+
+ parent::delete();
+ }
+
+ function _deleteAppUsers()
+ {
+ $oauser = new Oauth_application_user();
+ $oauser->application_id = $this->id;
+ $oauser->delete();
+ }
+
}
diff --git a/classes/Profile_role.php b/classes/Profile_role.php
index 74aca3730..bf2c453ed 100644
--- a/classes/Profile_role.php
+++ b/classes/Profile_role.php
@@ -48,6 +48,7 @@ class Profile_role extends Memcached_DataObject
return Memcached_DataObject::pkeyGet('Profile_role', $kv);
}
+ const OWNER = 'owner';
const MODERATOR = 'moderator';
const ADMINISTRATOR = 'administrator';
const SANDBOXED = 'sandboxed';
diff --git a/classes/Session.php b/classes/Session.php
index 79a69a96e..2422f8b68 100644
--- a/classes/Session.php
+++ b/classes/Session.php
@@ -64,8 +64,12 @@ class Session extends Memcached_DataObject
$session = Session::staticGet('id', $id);
if (empty($session)) {
+ self::logdeb("Couldn't find '$id'");
return '';
} else {
+ self::logdeb("Found '$id', returning " .
+ strlen($session->session_data) .
+ " chars of data");
return (string)$session->session_data;
}
}
@@ -77,14 +81,24 @@ class Session extends Memcached_DataObject
$session = Session::staticGet('id', $id);
if (empty($session)) {
+ self::logdeb("'$id' doesn't yet exist; inserting.");
$session = new Session();
$session->id = $id;
$session->session_data = $session_data;
$session->created = common_sql_now();
- return $session->insert();
+ $result = $session->insert();
+
+ if (!$result) {
+ common_log_db_error($session, 'INSERT', __FILE__);
+ self::logdeb("Failed to insert '$id'.");
+ } else {
+ self::logdeb("Successfully inserted '$id' (result = $result).");
+ }
+ return $result;
} else {
+ self::logdeb("'$id' already exists; updating.");
if (strcmp($session->session_data, $session_data) == 0) {
self::logdeb("Not writing session '$id'; unchanged");
return true;
@@ -95,7 +109,16 @@ class Session extends Memcached_DataObject
$session->session_data = $session_data;
- return $session->update($orig);
+ $result = $session->update($orig);
+
+ if (!$result) {
+ common_log_db_error($session, 'UPDATE', __FILE__);
+ self::logdeb("Failed to update '$id'.");
+ } else {
+ self::logdeb("Successfully updated '$id' (result = $result).");
+ }
+
+ return $result;
}
}
}
@@ -106,8 +129,17 @@ class Session extends Memcached_DataObject
$session = Session::staticGet('id', $id);
- if (!empty($session)) {
- return $session->delete();
+ if (empty($session)) {
+ self::logdeb("Can't find '$id' to delete.");
+ } else {
+ $result = $session->delete();
+ if (!$result) {
+ common_log_db_error($session, 'DELETE', __FILE__);
+ self::logdeb("Failed to delete '$id'.");
+ } else {
+ self::logdeb("Successfully deleted '$id' (result = $result).");
+ }
+ return $result;
}
}
@@ -132,7 +164,10 @@ class Session extends Memcached_DataObject
$session->free();
+ self::logdeb("Found " . count($ids) . " ids to delete.");
+
foreach ($ids as $id) {
+ self::logdeb("Destroying session '$id'.");
self::destroy($id);
}
}
diff --git a/classes/User.php b/classes/User.php
index 6ea975202..0ab816b57 100644
--- a/classes/User.php
+++ b/classes/User.php
@@ -209,8 +209,6 @@ class User extends Memcached_DataObject
$profile = new Profile();
- $profile->query('BEGIN');
-
if(!empty($email))
{
$email = common_canonical_email($email);
@@ -220,7 +218,7 @@ class User extends Memcached_DataObject
$profile->nickname = $nickname;
if(! User::allowed_nickname($nickname)){
common_log(LOG_WARNING, sprintf("Attempted to register a nickname that is not allowed: %s", $profile->nickname),
- __FILE__);
+ __FILE__);
}
$profile->profileurl = common_profile_url($nickname);
@@ -248,22 +246,10 @@ class User extends Memcached_DataObject
$profile->created = common_sql_now();
- $id = $profile->insert();
-
- if (empty($id)) {
- common_log_db_error($profile, 'INSERT', __FILE__);
- return false;
- }
-
$user = new User();
- $user->id = $id;
$user->nickname = $nickname;
- if (!empty($password)) { // may not have a password for OpenID users
- $user->password = common_munge_password($password, $id);
- }
-
// Users who respond to invite email have proven their ownership of that address
if (!empty($code)) {
@@ -282,109 +268,129 @@ class User extends Memcached_DataObject
$user->inboxed = 1;
$user->created = common_sql_now();
- $user->uri = common_user_uri($user);
-
- $result = $user->insert();
- if (!$result) {
- common_log_db_error($user, 'INSERT', __FILE__);
- return false;
- }
-
- // Everyone gets an inbox
+ if (Event::handle('StartUserRegister', array(&$user, &$profile))) {
- $inbox = new Inbox();
+ $profile->query('BEGIN');
- $inbox->user_id = $user->id;
- $inbox->notice_ids = '';
+ $id = $profile->insert();
- $result = $inbox->insert();
+ if (empty($id)) {
+ common_log_db_error($profile, 'INSERT', __FILE__);
+ return false;
+ }
- if (!$result) {
- common_log_db_error($inbox, 'INSERT', __FILE__);
- return false;
- }
+ $user->id = $id;
+ $user->uri = common_user_uri($user);
+ if (!empty($password)) { // may not have a password for OpenID users
+ $user->password = common_munge_password($password, $id);
+ }
- // Everyone is subscribed to themself
+ $result = $user->insert();
- $subscription = new Subscription();
- $subscription->subscriber = $user->id;
- $subscription->subscribed = $user->id;
- $subscription->created = $user->created;
+ if (!$result) {
+ common_log_db_error($user, 'INSERT', __FILE__);
+ return false;
+ }
- $result = $subscription->insert();
+ // Everyone gets an inbox
- if (!$result) {
- common_log_db_error($subscription, 'INSERT', __FILE__);
- return false;
- }
+ $inbox = new Inbox();
- if (!empty($email) && !$user->email) {
+ $inbox->user_id = $user->id;
+ $inbox->notice_ids = '';
- $confirm = new Confirm_address();
- $confirm->code = common_confirmation_code(128);
- $confirm->user_id = $user->id;
- $confirm->address = $email;
- $confirm->address_type = 'email';
+ $result = $inbox->insert();
- $result = $confirm->insert();
if (!$result) {
- common_log_db_error($confirm, 'INSERT', __FILE__);
+ common_log_db_error($inbox, 'INSERT', __FILE__);
return false;
}
- }
- if (!empty($code) && $user->email) {
- $user->emailChanged();
- }
+ // Everyone is subscribed to themself
- // Default system subscription
+ $subscription = new Subscription();
+ $subscription->subscriber = $user->id;
+ $subscription->subscribed = $user->id;
+ $subscription->created = $user->created;
- $defnick = common_config('newuser', 'default');
+ $result = $subscription->insert();
- if (!empty($defnick)) {
- $defuser = User::staticGet('nickname', $defnick);
- if (empty($defuser)) {
- common_log(LOG_WARNING, sprintf("Default user %s does not exist.", $defnick),
- __FILE__);
- } else {
- $defsub = new Subscription();
- $defsub->subscriber = $user->id;
- $defsub->subscribed = $defuser->id;
- $defsub->created = $user->created;
+ if (!$result) {
+ common_log_db_error($subscription, 'INSERT', __FILE__);
+ return false;
+ }
+
+ if (!empty($email) && !$user->email) {
+
+ $confirm = new Confirm_address();
+ $confirm->code = common_confirmation_code(128);
+ $confirm->user_id = $user->id;
+ $confirm->address = $email;
+ $confirm->address_type = 'email';
- $result = $defsub->insert();
+ $result = $confirm->insert();
if (!$result) {
- common_log_db_error($defsub, 'INSERT', __FILE__);
+ common_log_db_error($confirm, 'INSERT', __FILE__);
return false;
}
}
- }
- $profile->query('COMMIT');
+ if (!empty($code) && $user->email) {
+ $user->emailChanged();
+ }
+
+ // Default system subscription
- if (!empty($email) && !$user->email) {
- mail_confirm_address($user, $confirm->code, $profile->nickname, $email);
- }
+ $defnick = common_config('newuser', 'default');
- // Welcome message
+ if (!empty($defnick)) {
+ $defuser = User::staticGet('nickname', $defnick);
+ if (empty($defuser)) {
+ common_log(LOG_WARNING, sprintf("Default user %s does not exist.", $defnick),
+ __FILE__);
+ } else {
+ $defsub = new Subscription();
+ $defsub->subscriber = $user->id;
+ $defsub->subscribed = $defuser->id;
+ $defsub->created = $user->created;
- $welcome = common_config('newuser', 'welcome');
+ $result = $defsub->insert();
- if (!empty($welcome)) {
- $welcomeuser = User::staticGet('nickname', $welcome);
- if (empty($welcomeuser)) {
- common_log(LOG_WARNING, sprintf("Welcome user %s does not exist.", $defnick),
- __FILE__);
- } else {
- $notice = Notice::saveNew($welcomeuser->id,
- sprintf(_('Welcome to %1$s, @%2$s!'),
- common_config('site', 'name'),
- $user->nickname),
- 'system');
+ if (!$result) {
+ common_log_db_error($defsub, 'INSERT', __FILE__);
+ return false;
+ }
+ }
+ }
+ $profile->query('COMMIT');
+
+ if (!empty($email) && !$user->email) {
+ mail_confirm_address($user, $confirm->code, $profile->nickname, $email);
+ }
+
+ // Welcome message
+
+ $welcome = common_config('newuser', 'welcome');
+
+ if (!empty($welcome)) {
+ $welcomeuser = User::staticGet('nickname', $welcome);
+ if (empty($welcomeuser)) {
+ common_log(LOG_WARNING, sprintf("Welcome user %s does not exist.", $defnick),
+ __FILE__);
+ } else {
+ $notice = Notice::saveNew($welcomeuser->id,
+ sprintf(_('Welcome to %1$s, @%2$s!'),
+ common_config('site', 'name'),
+ $user->nickname),
+ 'system');
+
+ }
}
+
+ Event::handle('EndUserRegister', array(&$profile, &$user));
}
return $user;
@@ -925,4 +931,30 @@ class User extends Memcached_DataObject
return $share;
}
}
+
+ static function siteOwner()
+ {
+ $owner = self::cacheGet('user:site_owner');
+
+ if ($owner === false) { // cache miss
+
+ $pr = new Profile_role();
+
+ $pr->role = Profile_role::OWNER;
+
+ $pr->orderBy('created');
+
+ $pr->limit(1);
+
+ if ($pr->find(true)) {
+ $owner = User::staticGet('id', $pr->profile_id);
+ } else {
+ $owner = null;
+ }
+
+ self::cacheSet('user:site_owner', $owner);
+ }
+
+ return $owner;
+ }
}
diff --git a/classes/status_network.ini b/classes/status_network.ini
index 8123265e4..adb71cba7 100644
--- a/classes/status_network.ini
+++ b/classes/status_network.ini
@@ -11,6 +11,7 @@ theme = 2
logo = 2
created = 142
modified = 384
+tags = 34
[status_network__keys]
nickname = K
diff --git a/classes/statusnet.ini b/classes/statusnet.ini
index 6203650a6..4ace4407b 100644
--- a/classes/statusnet.ini
+++ b/classes/statusnet.ini
@@ -353,7 +353,7 @@ notice_id = K
id = 129
owner = 129
consumer_key = 130
-name = 130
+name = 2
description = 2
icon = 130
source_url = 2
@@ -367,6 +367,7 @@ modified = 384
[oauth_application__keys]
id = N
+name = U
[oauth_application_user]
profile_id = 129