From bb94b78e8997ba1b66ddde7ad46653bfa6f958e6 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 4 May 2010 18:43:32 -0700 Subject: Handle timeout more gracefully in background pings Added a 2-second default timeout for XMLRPC/extended pings, configurable as [ping,timeout]. No longer repeating the entire ping section if we had an HTTP error during a submission. For now, dropping the bad item and continuing on with others. (Todo: individual retry and cleaner discards of blacklisted broken-for-now sites.) --- lib/default.php | 3 ++- lib/ping.php | 10 +++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/default.php b/lib/default.php index fa4ece10a..ab5f294de 100644 --- a/lib/default.php +++ b/lib/default.php @@ -188,7 +188,8 @@ $default = 'cache' => array('base' => null), 'ping' => - array('notify' => array()), + array('notify' => array(), + 'timeout' => 2), 'inboxes' => array('enabled' => true), # ignored after 0.9.x 'newuser' => diff --git a/lib/ping.php b/lib/ping.php index 735af9ef1..be2933ae3 100644 --- a/lib/ping.php +++ b/lib/ping.php @@ -45,7 +45,15 @@ function ping_broadcast_notice($notice) { $tags)); $request = HTTPClient::start(); - $httpResponse = $request->post($notify_url, array('Content-Type: text/xml'), $req); + $request->setConfig('connect_timeout', common_config('ping', 'timeout')); + $request->setConfig('timeout', common_config('ping', 'timeout')); + try { + $httpResponse = $request->post($notify_url, array('Content-Type: text/xml'), $req); + } catch (Exception $e) { + common_log(LOG_ERR, + "Exception pinging $notify_url: " . $e->getMessage()); + continue; + } if (!$httpResponse || mb_strlen($httpResponse->getBody()) == 0) { common_log(LOG_WARNING, -- cgit v1.2.3-54-g00ecf From c2bda7726c05c6c7f5ef4f9519e56f107bc4e1e5 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 5 May 2010 13:11:36 -0700 Subject: XMPP debugging: log the message source when discarding empty or unrecognized messages. --- lib/xmppmanager.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/xmppmanager.php b/lib/xmppmanager.php index cca54db08..829eaa36c 100644 --- a/lib/xmppmanager.php +++ b/lib/xmppmanager.php @@ -253,12 +253,12 @@ class XmppManager extends IoManager $from = jabber_normalize_jid($pl['from']); if ($pl['type'] != 'chat') { - $this->log(LOG_WARNING, "Ignoring message of type ".$pl['type']." from $from."); + $this->log(LOG_WARNING, "Ignoring message of type ".$pl['type']." from $from: " . $pl['xml']->toString()); return; } if (mb_strlen($pl['body']) == 0) { - $this->log(LOG_WARNING, "Ignoring message with empty body from $from."); + $this->log(LOG_WARNING, "Ignoring message with empty body from $from: " . $pl['xml']->toString()); return; } -- cgit v1.2.3-54-g00ecf From fba140f4e0246a244664f0c0fb2361b027508d35 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Fri, 7 May 2010 16:32:24 -0700 Subject: Fix for repeats from the API having null source attribution --- actions/apidirectmessagenew.php | 8 -------- actions/apistatusesretweet.php | 2 +- actions/apistatusesupdate.php | 12 ------------ lib/apiaction.php | 9 +++++++++ lib/apiauth.php | 3 +-- 5 files changed, 11 insertions(+), 23 deletions(-) (limited to 'lib') diff --git a/actions/apidirectmessagenew.php b/actions/apidirectmessagenew.php index b9ac92d77..65d065648 100644 --- a/actions/apidirectmessagenew.php +++ b/actions/apidirectmessagenew.php @@ -52,7 +52,6 @@ require_once INSTALLDIR . '/lib/apiauth.php'; class ApiDirectMessageNewAction extends ApiAuthAction { - var $source = null; var $other = null; var $content = null; @@ -76,13 +75,6 @@ class ApiDirectMessageNewAction extends ApiAuthAction return; } - $this->source = $this->trimmed('source'); // Not supported by Twitter. - - $reserved_sources = array('web', 'omb', 'mail', 'xmpp', 'api'); - if (empty($this->source) || in_array($this->source, $reserved_sources)) { - $source = 'api'; - } - $this->content = $this->trimmed('text'); $this->user = $this->auth_user; diff --git a/actions/apistatusesretweet.php b/actions/apistatusesretweet.php index 128c881e2..9aa337485 100644 --- a/actions/apistatusesretweet.php +++ b/actions/apistatusesretweet.php @@ -79,7 +79,7 @@ class ApiStatusesRetweetAction extends ApiAuthAction $this->user = $this->auth_user; - if ($this->user->id == $notice->profile_id) { + if ($this->user->id == $this->original->profile_id) { $this->clientError(_('Cannot repeat your own notice.'), 400, $this->format); return false; diff --git a/actions/apistatusesupdate.php b/actions/apistatusesupdate.php index d4ef6b550..e3e579b0d 100644 --- a/actions/apistatusesupdate.php +++ b/actions/apistatusesupdate.php @@ -64,8 +64,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction var $lat = null; var $lon = null; - static $reserved_sources = array('web', 'omb', 'mail', 'xmpp', 'api'); - /** * Take arguments for running * @@ -80,19 +78,9 @@ class ApiStatusesUpdateAction extends ApiAuthAction parent::prepare($args); $this->status = $this->trimmed('status'); - $this->source = $this->trimmed('source'); $this->lat = $this->trimmed('lat'); $this->lon = $this->trimmed('long'); - // try to set the source attr from OAuth app - if (empty($this->source)) { - $this->source = $this->oauth_source; - } - - if (empty($this->source) || in_array($this->source, self::$reserved_sources)) { - $this->source = 'api'; - } - $this->in_reply_to_status_id = intval($this->trimmed('in_reply_to_status_id')); diff --git a/lib/apiaction.php b/lib/apiaction.php index 59dc47c23..f87b04611 100644 --- a/lib/apiaction.php +++ b/lib/apiaction.php @@ -63,9 +63,12 @@ class ApiAction extends Action var $count = null; var $max_id = null; var $since_id = null; + var $source = null; var $access = self::READ_ONLY; // read (default) or read-write + static $reserved_sources = array('web', 'omb', 'ostatus', 'mail', 'xmpp', 'api'); + /** * Initialization. * @@ -89,6 +92,12 @@ class ApiAction extends Action header('X-StatusNet-Warning: since parameter is disabled; use since_id'); } + $this->source = $this->trimmed('source'); + + if (empty($this->source) || in_array($this->source, self::$reserved_sources)) { + $this->source = 'api'; + } + return true; } diff --git a/lib/apiauth.php b/lib/apiauth.php index e78de618e..95acbbd7b 100644 --- a/lib/apiauth.php +++ b/lib/apiauth.php @@ -54,7 +54,6 @@ class ApiAuthAction extends ApiAction { var $auth_user_nickname = null; var $auth_user_password = null; - var $oauth_source = null; /** * Take arguments for running, looks for an OAuth request, @@ -162,7 +161,7 @@ class ApiAuthAction extends ApiAction // set the source attr - $this->oauth_source = $app->name; + $this->source = $app->name; $appUser = Oauth_application_user::staticGet('token', $access_token); -- cgit v1.2.3-54-g00ecf From 45392bef3382cd0bad30ebcd343d1cdd21e16f08 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 11 May 2010 12:16:13 -0700 Subject: Installer tweak for Windows: normalize line endings to platform standard in generated config.php Added a comment that the writable directory checks are insufficient to catch ACL problems on Windows; need a better check for that. --- lib/installer.php | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib') diff --git a/lib/installer.php b/lib/installer.php index 589a19a66..58ffbfef7 100644 --- a/lib/installer.php +++ b/lib/installer.php @@ -128,6 +128,7 @@ abstract class Installer $pass = false; } + // @fixme this check seems to be insufficient with Windows ACLs if (!is_writable(INSTALLDIR)) { $this->warning(sprintf('Cannot write config file to: %s

', INSTALLDIR), sprintf('On your server, try this command: chmod a+w %s', INSTALLDIR)); @@ -409,6 +410,10 @@ abstract class Installer "\$config['db']['database'] = '{$this->db['database']}';\n\n". ($this->db['type'] == 'pgsql' ? "\$config['db']['quote_identifiers'] = true;\n\n":''). "\$config['db']['type'] = '{$this->db['type']}';\n\n"; + + // Normalize line endings for Windows servers + $cfg = str_replace("\n", PHP_EOL, $cfg); + // write configuration file out to install directory $res = file_put_contents(INSTALLDIR.'/config.php', $cfg); -- cgit v1.2.3-54-g00ecf From 3d00cfd47fe5458a531df1b78b1833eb17321393 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 11 May 2010 12:22:14 -0700 Subject: Windows server fix: Use platform EOL in debug log file --- lib/util.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/util.php b/lib/util.php index c0013bb3d..efede1d4b 100644 --- a/lib/util.php +++ b/lib/util.php @@ -1365,7 +1365,7 @@ function common_log_line($priority, $msg) { static $syslog_priorities = array('LOG_EMERG', 'LOG_ALERT', 'LOG_CRIT', 'LOG_ERR', 'LOG_WARNING', 'LOG_NOTICE', 'LOG_INFO', 'LOG_DEBUG'); - return date('Y-m-d H:i:s') . ' ' . $syslog_priorities[$priority] . ': ' . $msg . "\n"; + return date('Y-m-d H:i:s') . ' ' . $syslog_priorities[$priority] . ': ' . $msg . PHP_EOL; } function common_request_id() -- cgit v1.2.3-54-g00ecf From d9fddff5395e77287c4de0796fd072b3073f1eb9 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Wed, 5 May 2010 22:35:16 -0700 Subject: Add xmlns:statusnet and statusnet:notice_info element to Atom entries for notices --- classes/Notice.php | 17 +++++++++++++++-- lib/atomnoticefeed.php | 9 ++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/classes/Notice.php b/classes/Notice.php index 0b1b2e402..9a9172cba 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1171,7 +1171,7 @@ class Notice extends Memcached_DataObject return $groups; } - function asAtomEntry($namespace=false, $source=false, $author=true) + function asAtomEntry($namespace=false, $source=false, $author=true, $cur=null) { $profile = $this->getProfile(); @@ -1184,7 +1184,8 @@ class Notice extends Memcached_DataObject 'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/', 'xmlns:media' => 'http://purl.org/syndication/atommedia', 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0', - 'xmlns:ostatus' => 'http://ostatus.org/schema/1.0'); + 'xmlns:ostatus' => 'http://ostatus.org/schema/1.0', + 'xmlns:statusnet' => 'http://status.net/ont/'); } else { $attrs = array(); } @@ -1210,6 +1211,18 @@ class Notice extends Memcached_DataObject $xs->element('icon', null, $profile->avatarUrl(AVATAR_PROFILE_SIZE)); $xs->element('updated', null, common_date_w3dtf($this->created)); + + $noticeInfoAttr = array( + 'local_id' => $this->id, // local notice ID (useful to clients for ordering) + 'source' => $this->source // the client name (source attribution) + // @todo source source_link + ); + + if (!empty($cur)) { + $noticeInfoAttr['favorited'] = ($cur->hasFave($this)) ? 'true' : 'false'; + } + + $xs->element('statusnet:notice_info', $noticeInfoAttr, null); } if ($source) { diff --git a/lib/atomnoticefeed.php b/lib/atomnoticefeed.php index e4df731fe..35a45118c 100644 --- a/lib/atomnoticefeed.php +++ b/lib/atomnoticefeed.php @@ -79,6 +79,11 @@ class AtomNoticeFeed extends Atom10Feed 'ostatus', 'http://ostatus.org/schema/1.0' ); + + $this->addNamespace( + 'statusnet', + 'http://status.net/ont/' + ); } /** @@ -110,7 +115,9 @@ class AtomNoticeFeed extends Atom10Feed $source = $this->showSource(); $author = $this->showAuthor(); - $this->addEntryRaw($notice->asAtomEntry(false, $source, $author)); + $cur = common_current_user(); + + $this->addEntryRaw($notice->asAtomEntry(false, $source, $author, $cur)); } function showSource() -- cgit v1.2.3-54-g00ecf From c78f67aa7367acab5f9156ecf8963e2d5243e400 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 6 May 2010 00:20:10 -0700 Subject: Refactor and centralize notice source link calculation --- actions/twitapisearchatom.php | 15 ++++++++++-- classes/Notice.php | 39 +++++++++++++++++++++++++++++- lib/apiaction.php | 51 ++++++++++----------------------------- lib/noticelist.php | 56 ++++++++++++++++++++----------------------- 4 files changed, 90 insertions(+), 71 deletions(-) (limited to 'lib') diff --git a/actions/twitapisearchatom.php b/actions/twitapisearchatom.php index 24aa619bd..3eb54ccc3 100644 --- a/actions/twitapisearchatom.php +++ b/actions/twitapisearchatom.php @@ -342,10 +342,21 @@ class TwitapisearchatomAction extends ApiAction 'rel' => 'related', 'href' => $profile->avatarUrl())); - // TODO: Here is where we'd put in a link to an atom feed for threads + // @todo: Here is where we'd put in a link to an atom feed for threads + + $source = null; + + $ns = $notice->getSource(); + if ($ns) { + if (!empty($ns->name) && !empty($ns->url)) { + $source = '' . $ns->name . ''; + } else { + $source = $ns->code; + } + } $this->element("twitter:source", null, - htmlentities($this->sourceLink($notice->source))); + htmlentities($source)); $this->elementStart('author'); diff --git a/classes/Notice.php b/classes/Notice.php index 9a9172cba..2c2c87d56 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -703,7 +703,7 @@ class Notice extends Memcached_DataObject /** * Is this notice part of an active conversation? - * + * * @return boolean true if other messages exist in the same * conversation, false if this is the only one */ @@ -1809,4 +1809,41 @@ class Notice extends Memcached_DataObject return $result; } + + /** + * Get the source of the notice + * + * @return Notice_source $ns A notice source object. 'code' is the only attribute + * guaranteed to be populated. + */ + function getSource() + { + $ns = new Notice_source(); + if (!empty($this->source)) { + switch ($this->source) { + case 'web': + case 'xmpp': + case 'mail': + case 'omb': + case 'system': + case 'api': + $ns->code = $this->source; + break; + default: + $ns = Notice_source::staticGet($this->source); + if (!$ns) { + $ns = new Notice_source(); + $ns->code = $this->source; + $app = Oauth_application::staticGet('name', $this->source); + if ($app) { + $ns->name = $app->name; + $ns->url = $app->source_url; + } + } + break; + } + } + return $ns; + } + } diff --git a/lib/apiaction.php b/lib/apiaction.php index f87b04611..7a6a5549b 100644 --- a/lib/apiaction.php +++ b/lib/apiaction.php @@ -260,7 +260,19 @@ class ApiAction extends Action $twitter_status['created_at'] = $this->dateTwitter($notice->created); $twitter_status['in_reply_to_status_id'] = ($notice->reply_to) ? intval($notice->reply_to) : null; - $twitter_status['source'] = $this->sourceLink($notice->source); + + $source = null; + + $ns = $notice->getSource(); + if ($ns) { + if (!empty($ns->name) && !empty($ns->url)) { + $source = '' . $ns->name . ''; + } else { + $source = $ns->code; + } + } + + $twitter_status['source'] = $source; $twitter_status['id'] = intval($notice->id); $replier_profile = null; @@ -1298,43 +1310,6 @@ class ApiAction extends Action } } - function sourceLink($source) - { - $source_name = _($source); - switch ($source) { - case 'web': - case 'xmpp': - case 'mail': - case 'omb': - case 'api': - break; - default: - - $name = null; - $url = null; - - $ns = Notice_source::staticGet($source); - - if ($ns) { - $name = $ns->name; - $url = $ns->url; - } else { - $app = Oauth_application::staticGet('name', $source); - if ($app) { - $name = $app->name; - $url = $app->source_url; - } - } - - if (!empty($name) && !empty($url)) { - $source_name = '' . $name . ''; - } - - break; - } - return $source_name; - } - /** * Returns query argument or default value if not found. Certain * parameters used throughout the API are lightly scrubbed and diff --git a/lib/noticelist.php b/lib/noticelist.php index 4f997a328..e0d8bf560 100644 --- a/lib/noticelist.php +++ b/lib/noticelist.php @@ -480,48 +480,44 @@ class NoticeListItem extends Widget function showNoticeSource() { - if ($this->notice->source) { + $ns = $this->notice->getSource(); + + if ($ns) { + $source_name = _($ns->code); $this->out->text(' '); $this->out->elementStart('span', 'source'); $this->out->text(_('from')); - $source_name = _($this->notice->source); $this->out->text(' '); - switch ($this->notice->source) { - case 'web': - case 'xmpp': - case 'mail': - case 'omb': - case 'system': - case 'api': - $this->out->element('span', 'device', $source_name); - break; - default: - $name = $source_name; - $url = null; + // if $ns->name and $ns->url are populated we have + // configured a source attr somewhere + if (empty($ns->name) && empty($ns->url)) { + // otherwise it's from normal channel such as web or api + $this->out->element('span', 'device', $source_name); + } else { + $name = null; + $url = null; + $title = null; if (Event::handle('StartNoticeSourceLink', array($this->notice, &$name, &$url, &$title))) { - $ns = Notice_source::staticGet($this->notice->source); - - if ($ns) { - $name = $ns->name; - $url = $ns->url; - } else { - $app = Oauth_application::staticGet('name', $this->notice->source); - if ($app) { - $name = $app->name; - $url = $app->source_url; - } - } + $name = $source_name; + $url = $ns->url; } Event::handle('EndNoticeSourceLink', array($this->notice, &$name, &$url, &$title)); if (!empty($name) && !empty($url)) { $this->out->elementStart('span', 'device'); - $this->out->element('a', array('href' => $url, - 'rel' => 'external', - 'title' => $title), - $name); + + $attrs = array( + 'href' => $url, + 'rel' => 'external' + ); + + if (isset($title)) { + $attrs['title'] = $title; + } + + $this->out->element('a', $attrs, $name); $this->out->elementEnd('span'); } else { $this->out->element('span', 'device', $name); -- cgit v1.2.3-54-g00ecf From 0dfef88cacde19cf0afaefbd422a7f5230091064 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 6 May 2010 00:55:17 -0700 Subject: HTML entity encode source link URLs in plain XML output and add rel="nofollow" to them --- actions/twitapisearchatom.php | 2 +- lib/apiaction.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/actions/twitapisearchatom.php b/actions/twitapisearchatom.php index 3eb54ccc3..6c740c490 100644 --- a/actions/twitapisearchatom.php +++ b/actions/twitapisearchatom.php @@ -349,7 +349,7 @@ class TwitapisearchatomAction extends ApiAction $ns = $notice->getSource(); if ($ns) { if (!empty($ns->name) && !empty($ns->url)) { - $source = '' . $ns->name . ''; + $source = '' . $ns->name . ''; } else { $source = $ns->code; } diff --git a/lib/apiaction.php b/lib/apiaction.php index 7a6a5549b..f3efff402 100644 --- a/lib/apiaction.php +++ b/lib/apiaction.php @@ -266,13 +266,13 @@ class ApiAction extends Action $ns = $notice->getSource(); if ($ns) { if (!empty($ns->name) && !empty($ns->url)) { - $source = '' . $ns->name . ''; + $source = '' . $ns->name . ''; } else { $source = $ns->code; } } - $twitter_status['source'] = $source; + $twitter_status['source'] = htmlentities($source); $twitter_status['id'] = intval($notice->id); $replier_profile = null; -- cgit v1.2.3-54-g00ecf From 6187266205a55db0298e02df7d6996a735d42eba Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 6 May 2010 19:52:25 +0000 Subject: - OStatusPlugin should return true if it doesn't need to handle source attribution - Remove stray break statement from NoticeList --- lib/noticelist.php | 1 - plugins/OStatus/OStatusPlugin.php | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/noticelist.php b/lib/noticelist.php index e0d8bf560..d22010335 100644 --- a/lib/noticelist.php +++ b/lib/noticelist.php @@ -522,7 +522,6 @@ class NoticeListItem extends Widget } else { $this->out->element('span', 'device', $name); } - break; } $this->out->elementEnd('span'); } diff --git a/plugins/OStatus/OStatusPlugin.php b/plugins/OStatus/OStatusPlugin.php index 5167842ca..5b153216e 100644 --- a/plugins/OStatus/OStatusPlugin.php +++ b/plugins/OStatus/OStatusPlugin.php @@ -452,6 +452,7 @@ class OStatusPlugin extends Plugin return false; } } + return true; } /** -- cgit v1.2.3-54-g00ecf From 3708341857a8ae26c2936df53fede09aa17b09f8 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 6 May 2010 20:25:20 +0000 Subject: Allow OStatusPlugin to set the source attribution title --- lib/noticelist.php | 51 ++++++++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 27 deletions(-) (limited to 'lib') diff --git a/lib/noticelist.php b/lib/noticelist.php index d22010335..81da9edc0 100644 --- a/lib/noticelist.php +++ b/lib/noticelist.php @@ -489,40 +489,37 @@ class NoticeListItem extends Widget $this->out->text(_('from')); $this->out->text(' '); - // if $ns->name and $ns->url are populated we have - // configured a source attr somewhere - if (empty($ns->name) && empty($ns->url)) { - // otherwise it's from normal channel such as web or api - $this->out->element('span', 'device', $source_name); - } else { - $name = null; - $url = null; - $title = null; + $name = $source_name; + $url = $ns->url; + $title = null; - if (Event::handle('StartNoticeSourceLink', array($this->notice, &$name, &$url, &$title))) { - $name = $source_name; - $url = $ns->url; - } - Event::handle('EndNoticeSourceLink', array($this->notice, &$name, &$url, &$title)); + if (Event::handle('StartNoticeSourceLink', array($this->notice, &$name, &$url, &$title))) { + $name = $source_name; + $url = $ns->url; + } + Event::handle('EndNoticeSourceLink', array($this->notice, &$name, &$url, &$title)); - if (!empty($name) && !empty($url)) { - $this->out->elementStart('span', 'device'); + // if $ns->name and $ns->url are populated we have + // configured a source attr somewhere + if (!empty($name) && !empty($url)) { - $attrs = array( - 'href' => $url, - 'rel' => 'external' - ); + $this->out->elementStart('span', 'device'); - if (isset($title)) { - $attrs['title'] = $title; - } + $attrs = array( + 'href' => $url, + 'rel' => 'external' + ); - $this->out->element('a', $attrs, $name); - $this->out->elementEnd('span'); - } else { - $this->out->element('span', 'device', $name); + if (!empty($title)) { + $attrs['title'] = $title; } + + $this->out->element('a', $attrs, $name); + $this->out->elementEnd('span'); + } else { + $this->out->element('span', 'device', $name); } + $this->out->elementEnd('span'); } } -- cgit v1.2.3-54-g00ecf From 5ea019c41ac4d6c161f3c8f287d405971d4aadea Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 6 May 2010 21:36:13 +0000 Subject: Remove errant double HTML entity encoding in API source attribution --- actions/twitapisearchatom.php | 9 ++++++--- classes/Notice.php | 2 +- lib/apiaction.php | 8 ++++++-- 3 files changed, 13 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/actions/twitapisearchatom.php b/actions/twitapisearchatom.php index 6c740c490..51e8a8881 100644 --- a/actions/twitapisearchatom.php +++ b/actions/twitapisearchatom.php @@ -349,14 +349,17 @@ class TwitapisearchatomAction extends ApiAction $ns = $notice->getSource(); if ($ns) { if (!empty($ns->name) && !empty($ns->url)) { - $source = '' . $ns->name . ''; + $source = '' + . htmlspecialchars($ns->name) + . ''; } else { $source = $ns->code; } } - $this->element("twitter:source", null, - htmlentities($source)); + $this->element("twitter:source", null, $source); $this->elementStart('author'); diff --git a/classes/Notice.php b/classes/Notice.php index 196501279..0dc7e10e7 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1220,7 +1220,7 @@ class Notice extends Memcached_DataObject $ns = $this->getSource(); if ($ns) { if (!empty($ns->url)) { - $noticeInfoAttr['source_link'] = htmlentities($ns->url); + $noticeInfoAttr['source_link'] = $ns->url; } } diff --git a/lib/apiaction.php b/lib/apiaction.php index f3efff402..68198effc 100644 --- a/lib/apiaction.php +++ b/lib/apiaction.php @@ -266,13 +266,17 @@ class ApiAction extends Action $ns = $notice->getSource(); if ($ns) { if (!empty($ns->name) && !empty($ns->url)) { - $source = '' . $ns->name . ''; + $source = '' + . htmlspecialchars($ns->name) + . ''; } else { $source = $ns->code; } } - $twitter_status['source'] = htmlentities($source); + $twitter_status['source'] = $source; $twitter_status['id'] = intval($notice->id); $replier_profile = null; -- cgit v1.2.3-54-g00ecf From 74a89b1fc37067d91d31bd66922053361eb4e616 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 19 May 2010 10:10:55 -0700 Subject: Locale switch cleanup: use common_switch_locale() which is safer for updating gettext state. Also moved a few calls to reduce chance of hitting an exception before switching back. Should help with problems where xmppdaemon would get stuck in wrong locale. --- lib/mail.php | 20 ++++++++++---------- lib/util.php | 17 +++++++++++++++++ plugins/Facebook/facebookutil.php | 6 +++--- plugins/TwitterBridge/twitter.php | 6 +++--- 4 files changed, 33 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/mail.php b/lib/mail.php index 5fc584e28..a4065e8d5 100644 --- a/lib/mail.php +++ b/lib/mail.php @@ -224,9 +224,6 @@ function mail_subscribe_notify_profile($listenee, $other) if ($other->hasRight(Right::EMAILONSUBSCRIBE) && $listenee->email && $listenee->emailnotifysub) { - // use the recipient's localization - common_init_locale($listenee->language); - $profile = $listenee->getProfile(); $name = $profile->getBestName(); @@ -236,6 +233,9 @@ function mail_subscribe_notify_profile($listenee, $other) $recipients = $listenee->email; + // use the recipient's localization + common_switch_locale($listenee->language); + $headers = _mail_prepare_headers('subscribe', $listenee->nickname, $other->nickname); $headers['From'] = mail_notify_from(); $headers['To'] = $name . ' <' . $listenee->email . '>'; @@ -271,7 +271,7 @@ function mail_subscribe_notify_profile($listenee, $other) common_local_url('emailsettings')); // reset localization - common_init_locale(); + common_switch_locale(); mail_send($recipients, $headers, $body); } } @@ -473,7 +473,7 @@ function mail_confirm_sms($code, $nickname, $address) function mail_notify_nudge($from, $to) { - common_init_locale($to->language); + common_switch_locale($to->language); // TRANS: Subject for 'nudge' notification email $subject = sprintf(_('You\'ve been nudged by %s'), $from->nickname); @@ -491,7 +491,7 @@ function mail_notify_nudge($from, $to) $from->nickname, common_local_url('all', array('nickname' => $to->nickname)), common_config('site', 'name')); - common_init_locale(); + common_switch_locale(); $headers = _mail_prepare_headers('nudge', $to->nickname, $from->nickname); @@ -525,7 +525,7 @@ function mail_notify_message($message, $from=null, $to=null) return true; } - common_init_locale($to->language); + common_switch_locale($to->language); // TRANS: Subject for direct-message notification email $subject = sprintf(_('New private message from %s'), $from->nickname); @@ -549,7 +549,7 @@ function mail_notify_message($message, $from=null, $to=null) $headers = _mail_prepare_headers('message', $to->nickname, $from->nickname); - common_init_locale(); + common_switch_locale(); return mail_to_user($to, $subject, $body, $headers); } @@ -577,7 +577,7 @@ function mail_notify_fave($other, $user, $notice) $bestname = $profile->getBestName(); - common_init_locale($other->language); + common_switch_locale($other->language); // TRANS: Subject for favorite notification email $subject = sprintf(_('%s (@%s) added your notice as a favorite'), $bestname, $user->nickname); @@ -605,7 +605,7 @@ function mail_notify_fave($other, $user, $notice) $headers = _mail_prepare_headers('fave', $other->nickname, $user->nickname); - common_init_locale(); + common_switch_locale(); mail_to_user($other, $subject, $body, $headers); } diff --git a/lib/util.php b/lib/util.php index efede1d4b..597da22c0 100644 --- a/lib/util.php +++ b/lib/util.php @@ -34,6 +34,14 @@ function common_user_error($msg, $code=400) $err->showPage(); } +/** + * This should only be used at setup; processes switching languages + * to send text to other users should use common_switch_locale(). + * + * @param string $language Locale language code (optional; empty uses + * current user's preference or site default) + * @return mixed success + */ function common_init_locale($language=null) { if(!$language) { @@ -50,6 +58,15 @@ function common_init_locale($language=null) return $ok; } +/** + * Initialize locale and charset settings and gettext with our message catalog, + * using the current user's language preference or the site default. + * + * This should generally only be run at framework initialization; code switching + * languages at runtime should call common_switch_language(). + * + * @access private + */ function common_init_language() { mb_internal_encoding('UTF-8'); diff --git a/plugins/Facebook/facebookutil.php b/plugins/Facebook/facebookutil.php index ac532e18b..83664995a 100644 --- a/plugins/Facebook/facebookutil.php +++ b/plugins/Facebook/facebookutil.php @@ -272,12 +272,12 @@ function remove_facebook_app($flink) function mail_facebook_app_removed($user) { - common_init_locale($user->language); - $profile = $user->getProfile(); $site_name = common_config('site', 'name'); + common_switch_locale($user->language); + $subject = sprintf( _m('Your %1$s Facebook application access has been disabled.', $site_name)); @@ -291,7 +291,7 @@ function mail_facebook_app_removed($user) "re-installing the %2\$s Facebook application.\n\nRegards,\n\n%2\$s"), $user->nickname, $site_name); - common_init_locale(); + common_switch_locale(); return mail_to_user($user, $subject, $body); } diff --git a/plugins/TwitterBridge/twitter.php b/plugins/TwitterBridge/twitter.php index 21adc7a90..896eee2da 100644 --- a/plugins/TwitterBridge/twitter.php +++ b/plugins/TwitterBridge/twitter.php @@ -335,10 +335,10 @@ function remove_twitter_link($flink) function mail_twitter_bridge_removed($user) { - common_init_locale($user->language); - $profile = $user->getProfile(); + common_switch_locale($user->language); + $subject = sprintf(_m('Your Twitter bridge has been disabled.')); $site_name = common_config('site', 'name'); @@ -354,7 +354,7 @@ function mail_twitter_bridge_removed($user) common_local_url('twittersettings'), common_config('site', 'name')); - common_init_locale(); + common_switch_locale(); return mail_to_user($user, $subject, $body); } -- cgit v1.2.3-54-g00ecf From 708d22848ecffdb80ca2cd9e5f4a7f84d5ae3189 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 19 May 2010 16:19:06 -0700 Subject: Quick fix for creating OpenID accounts authenticating against a MediaWiki site; trim the 'User:' etc from the final path segment before generating a nickname from it. Avoids ending up with nicks like 'userbrion' on your first OpenID login! --- lib/util.php | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib') diff --git a/lib/util.php b/lib/util.php index 597da22c0..59d5132ec 100644 --- a/lib/util.php +++ b/lib/util.php @@ -1925,6 +1925,15 @@ function common_url_to_nickname($url) $path = preg_replace('@/$@', '', $parts['path']); $path = preg_replace('@^/@', '', $path); $path = basename($path); + + // Hack for MediaWiki user pages, in the form: + // http://example.com/wiki/User:Myname + // ('User' may be localized.) + if (strpos($path, ':')) { + $parts = array_filter(explode(':', $path)); + $path = $parts[count($parts) - 1]; + } + if ($path) { return common_nicknamize($path); } -- cgit v1.2.3-54-g00ecf From 68305d4b6848cec6afe887ee2a5735515060770e Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 20 May 2010 12:46:36 -0700 Subject: Added block link to subscription notification emails; block action can now take a profile ID on the URL; added profile details to block page so there's an indication of who you're blocking before you pull the trigger. Fixed typo in RedirectingAction when no return-to data provided in form submission. RedirectingAction::returnToArgs() has been renamed to returnToPrevious() to avoid conflict with Action::returnToArgs() which returns arguments to be passed to other actions as return-to arguments. All callers should now be updated. More profile settings actions will now redirect through a login form if visited as a GET request, as would be expected from a bookmark, link sent in e-mail etc. --- actions/block.php | 46 ++++++++++++++++++++++++++++++++++++++-- actions/deleteuser.php | 4 ++-- actions/groupblock.php | 4 ++-- lib/mail.php | 10 +++++++-- lib/profileformaction.php | 13 ++++++++++-- lib/redirectingaction.php | 9 ++++---- lib/router.php | 5 +++++ plugins/UserFlag/clearflag.php | 2 +- plugins/UserFlag/flagprofile.php | 2 +- 9 files changed, 79 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/actions/block.php b/actions/block.php index 7f609c253..239a50868 100644 --- a/actions/block.php +++ b/actions/block.php @@ -87,13 +87,15 @@ class BlockAction extends ProfileFormAction { if ($_SERVER['REQUEST_METHOD'] == 'POST') { if ($this->arg('no')) { - $this->returnToArgs(); + $this->returnToPrevious(); } elseif ($this->arg('yes')) { $this->handlePost(); - $this->returnToArgs(); + $this->returnToPrevious(); } else { $this->showPage(); } + } else { + $this->showPage(); } } @@ -118,6 +120,12 @@ class BlockAction extends ProfileFormAction */ function areYouSureForm() { + // @fixme if we ajaxify the confirmation form, skip the preview on ajax hits + $profile = new ArrayWrapper(array($this->profile)); + $preview = new ProfileList($profile, $this); + $preview->show(); + + $id = $this->profile->id; $this->elementStart('form', array('id' => 'block-' . $id, 'method' => 'post', @@ -175,4 +183,38 @@ class BlockAction extends ProfileFormAction $this->autofocus('form_action-yes'); } + /** + * Override for form session token checks; on our first hit we're just + * requesting confirmation, which doesn't need a token. We need to be + * able to take regular GET requests from email! + * + * @throws ClientException if token is bad on POST request or if we have + * confirmation parameters which could trigger something. + */ + function checkSessionToken() + { + if ($_SERVER['REQUEST_METHOD'] == 'POST' || + $this->arg('yes') || + $this->arg('no')) { + + return parent::checkSessionToken(); + } + } + + /** + * If we reached this form without returnto arguments, return to the + * current user's subscription list. + * + * @return string URL + */ + function defaultReturnTo() + { + $user = common_current_user(); + if ($user) { + return common_local_url('subscribers', + array('nickname' => $user->nickname)); + } else { + return common_local_url('public'); + } + } } diff --git a/actions/deleteuser.php b/actions/deleteuser.php index 42ef4b9f5..c0a8b20e2 100644 --- a/actions/deleteuser.php +++ b/actions/deleteuser.php @@ -92,10 +92,10 @@ class DeleteuserAction extends ProfileFormAction { if ($_SERVER['REQUEST_METHOD'] == 'POST') { if ($this->arg('no')) { - $this->returnToArgs(); + $this->returnToPrevious(); } elseif ($this->arg('yes')) { $this->handlePost(); - $this->returnToArgs(); + $this->returnToPrevious(); } else { $this->showPage(); } diff --git a/actions/groupblock.php b/actions/groupblock.php index fc95c0e66..2e06dc324 100644 --- a/actions/groupblock.php +++ b/actions/groupblock.php @@ -117,7 +117,7 @@ class GroupblockAction extends RedirectingAction parent::handle($args); if ($_SERVER['REQUEST_METHOD'] == 'POST') { if ($this->arg('no')) { - $this->returnToArgs(); + $this->returnToPrevious(); } elseif ($this->arg('yes')) { $this->blockProfile(); } elseif ($this->arg('blockto')) { @@ -195,7 +195,7 @@ class GroupblockAction extends RedirectingAction return false; } - $this->returnToArgs(); + $this->returnToPrevious(); } /** diff --git a/lib/mail.php b/lib/mail.php index a4065e8d5..ab5742e33 100644 --- a/lib/mail.php +++ b/lib/mail.php @@ -245,6 +245,11 @@ function mail_subscribe_notify_profile($listenee, $other) $other->getBestName(), common_config('site', 'name')); + $blocklink = sprintf(_("If you believe this account is being used abusively, " . + "you can block them from your subscribers list and " . + "report as spam to site administrators at %s"), + common_local_url('block', array('profileid' => $other->id))); + // TRANS: Main body of new-subscriber notification e-mail $body = sprintf(_('%1$s is now listening to your notices on %2$s.'."\n\n". "\t".'%3$s'."\n\n". @@ -264,9 +269,10 @@ function mail_subscribe_notify_profile($listenee, $other) ($other->homepage) ? // TRANS: Profile info line in new-subscriber notification e-mail sprintf(_("Homepage: %s"), $other->homepage) . "\n" : '', - ($other->bio) ? + (($other->bio) ? // TRANS: Profile info line in new-subscriber notification e-mail - sprintf(_("Bio: %s"), $other->bio) . "\n\n" : '', + sprintf(_("Bio: %s"), $other->bio) . "\n" : '') . + "\n\n" . $blocklink . "\n", common_config('site', 'name'), common_local_url('emailsettings')); diff --git a/lib/profileformaction.php b/lib/profileformaction.php index 0ffafe5fb..51c89a922 100644 --- a/lib/profileformaction.php +++ b/lib/profileformaction.php @@ -60,7 +60,16 @@ class ProfileFormAction extends RedirectingAction $this->checkSessionToken(); if (!common_logged_in()) { - $this->clientError(_('Not logged in.')); + if ($_SERVER['REQUEST_METHOD'] == 'POST') { + $this->clientError(_('Not logged in.')); + } else { + // Redirect to login. + common_set_returnto($this->selfUrl()); + $user = common_current_user(); + if (Event::handle('RedirectToLogin', array($this, $user))) { + common_redirect(common_local_url('login'), 303); + } + } return false; } @@ -97,7 +106,7 @@ class ProfileFormAction extends RedirectingAction if ($_SERVER['REQUEST_METHOD'] == 'POST') { $this->handlePost(); - $this->returnToArgs(); + $this->returnToPrevious(); } } diff --git a/lib/redirectingaction.php b/lib/redirectingaction.php index f11585274..3a358f891 100644 --- a/lib/redirectingaction.php +++ b/lib/redirectingaction.php @@ -53,12 +53,13 @@ class RedirectingAction extends Action * * To be called only after successful processing. * - * @fixme rename this -- it obscures Action::returnToArgs() which - * returns a list of arguments, and is a bit confusing. + * Note: this was named returnToArgs() up through 0.9.2, which + * caused problems because there's an Action::returnToArgs() + * already which does something different. * * @return void */ - function returnToArgs() + function returnToPrevious() { // Now, gotta figure where we go back to $action = false; @@ -77,7 +78,7 @@ class RedirectingAction extends Action if ($action) { common_redirect(common_local_url($action, $args, $params), 303); } else { - $url = $this->defaultReturnToUrl(); + $url = $this->defaultReturnTo(); } common_redirect($url, 303); } diff --git a/lib/router.php b/lib/router.php index a9d07276f..afe44f92a 100644 --- a/lib/router.php +++ b/lib/router.php @@ -136,6 +136,11 @@ class Router $m->connect('main/'.$a, array('action' => $a)); } + // Also need a block variant accepting ID on URL for mail links + $m->connect('main/block/:profileid', + array('action' => 'block'), + array('profileid' => '[0-9]+')); + $m->connect('main/sup/:seconds', array('action' => 'sup'), array('seconds' => '[0-9]+')); diff --git a/plugins/UserFlag/clearflag.php b/plugins/UserFlag/clearflag.php index bd6732e2d..f032527ed 100644 --- a/plugins/UserFlag/clearflag.php +++ b/plugins/UserFlag/clearflag.php @@ -81,7 +81,7 @@ class ClearflagAction extends ProfileFormAction if ($_SERVER['REQUEST_METHOD'] == 'POST') { $this->handlePost(); if (!$this->boolean('ajax')) { - $this->returnToArgs(); + $this->returnToPrevious(); } } } diff --git a/plugins/UserFlag/flagprofile.php b/plugins/UserFlag/flagprofile.php index 2d0f0abb9..018c1e8ac 100644 --- a/plugins/UserFlag/flagprofile.php +++ b/plugins/UserFlag/flagprofile.php @@ -87,7 +87,7 @@ class FlagprofileAction extends ProfileFormAction if ($_SERVER['REQUEST_METHOD'] == 'POST') { $this->handlePost(); if (!$this->boolean('ajax')) { - $this->returnToArgs(); + $this->returnToPrevious(); } } } -- cgit v1.2.3-54-g00ecf From 2c12d837c693a816541d32dd044de5277a46336d Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 21 May 2010 10:12:39 -0700 Subject: Disable SSL peer/hostname verification for HTTPClient unless we've configured a trusted CA bundle like this: $config['http']['ssl_cafile'] = '/usr/lib/ssl/certs/ca-certificates.crt'; The previous state was failing on all HTTPS hits due to HTTP_Request2 library turning on the validation check but not specifying a CA file. --- lib/default.php | 3 +++ lib/httpclient.php | 14 +++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/default.php b/lib/default.php index ab5f294de..950c6018d 100644 --- a/lib/default.php +++ b/lib/default.php @@ -304,4 +304,7 @@ $default = array('subscribers' => true, 'members' => true, 'peopletag' => true), + 'http' => // HTTP client settings when contacting other sites + array('ssl_cafile' => false // To enable SSL cert validation, point to a CA bundle (eg '/usr/lib/ssl/certs/ca-certificates.crt') + ), ); diff --git a/lib/httpclient.php b/lib/httpclient.php index 384626ae0..b69f718e5 100644 --- a/lib/httpclient.php +++ b/lib/httpclient.php @@ -132,7 +132,19 @@ class HTTPClient extends HTTP_Request2 // ought to be investigated to see if we can handle // it gracefully in that case as well. $this->config['protocol_version'] = '1.0'; - + + // Default state of OpenSSL seems to have no trusted + // SSL certificate authorities, which breaks hostname + // verification and means we have a hard time communicating + // with other sites' HTTPS interfaces. + // + // Turn off verification unless we've configured a CA bundle. + if (common_config('http', 'ssl_cafile')) { + $this->config['ssl_cafile'] = common_config('http', 'ssl_cafile'); + } else { + $this->config['ssl_verify_peer'] = false; + } + parent::__construct($url, $method, $config); $this->setHeader('User-Agent', $this->userAgent()); } -- cgit v1.2.3-54-g00ecf