summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--actions/block.php46
-rw-r--r--actions/deleteuser.php4
-rw-r--r--actions/groupblock.php4
-rw-r--r--db/notice_source.sql1
-rw-r--r--lib/default.php3
-rw-r--r--lib/httpclient.php14
-rw-r--r--lib/mail.php10
-rw-r--r--lib/profileformaction.php13
-rw-r--r--lib/redirectingaction.php9
-rw-r--r--lib/router.php5
-rw-r--r--lib/util.php9
-rw-r--r--plugins/Facebook/facebookutil.php12
-rw-r--r--plugins/OStatus/lib/discoveryhints.php2
-rw-r--r--plugins/RequireValidatedEmail/README14
-rw-r--r--plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php50
-rw-r--r--plugins/UserFlag/clearflag.php2
-rw-r--r--plugins/UserFlag/flagprofile.php2
17 files changed, 173 insertions, 27 deletions
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/db/notice_source.sql b/db/notice_source.sql
index f9c525679..fbcdd6568 100644
--- a/db/notice_source.sql
+++ b/db/notice_source.sql
@@ -54,6 +54,7 @@ VALUES
('tr.im','tr.im','http://tr.im/', now()),
('triklepost', 'Tricklepost', 'http://github.com/zcopley/tricklepost/tree/master', now()),
('tweenky','Tweenky','http://beta.tweenky.com/', now()),
+ ('TweetDeck', 'TweetDeck', 'http://www.tweetdeck.com/', now()),
('twhirl','Twhirl','http://www.twhirl.org/', now()),
('twibble','twibble','http://www.twibble.de/', now()),
('Twidge','Twidge','http://software.complete.org/twidge', now()),
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());
}
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/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);
}
diff --git a/plugins/Facebook/facebookutil.php b/plugins/Facebook/facebookutil.php
index 83664995a..ab2d42726 100644
--- a/plugins/Facebook/facebookutil.php
+++ b/plugins/Facebook/facebookutil.php
@@ -104,9 +104,13 @@ function facebookBroadcastNotice($notice)
$status = "$prefix $notice->content";
+ common_debug("FacebookPlugin - checking for publish_stream permission for user $user->id");
+
$can_publish = $facebook->api_client->users_hasAppPermission('publish_stream',
$fbuid);
+ common_debug("FacebookPlugin - checking for status_update permission for user $user->id");
+
$can_update = $facebook->api_client->users_hasAppPermission('status_update',
$fbuid);
if (!empty($attachments) && $can_publish == 1) {
@@ -114,15 +118,15 @@ function facebookBroadcastNotice($notice)
$facebook->api_client->stream_publish($status, $fbattachment,
null, null, $fbuid);
common_log(LOG_INFO,
- "Posted notice $notice->id w/attachment " .
+ "FacebookPlugin - Posted notice $notice->id w/attachment " .
"to Facebook user's stream (fbuid = $fbuid).");
} elseif ($can_update == 1 || $can_publish == 1) {
$facebook->api_client->users_setStatus($status, $fbuid, false, true);
common_log(LOG_INFO,
- "Posted notice $notice->id to Facebook " .
+ "FacebookPlugin - Posted notice $notice->id to Facebook " .
"as a status update (fbuid = $fbuid).");
} else {
- $msg = "Not sending notice $notice->id to Facebook " .
+ $msg = "FacebookPlugin - Not sending notice $notice->id to Facebook " .
"because user $user->nickname hasn't given the " .
'Facebook app \'status_update\' or \'publish_stream\' permission.';
common_log(LOG_WARNING, $msg);
@@ -138,7 +142,7 @@ function facebookBroadcastNotice($notice)
$code = $e->getCode();
- $msg = "Facebook returned error code $code: " .
+ $msg = "FacebookPlugin - Facebook returned error code $code: " .
$e->getMessage() . ' - ' .
"Unable to update Facebook status (notice $notice->id) " .
"for $user->nickname (user id: $user->id)!";
diff --git a/plugins/OStatus/lib/discoveryhints.php b/plugins/OStatus/lib/discoveryhints.php
index ca54a0f5f..34c9be277 100644
--- a/plugins/OStatus/lib/discoveryhints.php
+++ b/plugins/OStatus/lib/discoveryhints.php
@@ -84,7 +84,7 @@ class DiscoveryHints {
$hints['fullname'] = implode(' ', $hcard['n']);
}
- if (array_key_exists('photo', $hcard)) {
+ if (array_key_exists('photo', $hcard) && count($hcard['photo'])) {
$hints['avatar'] = $hcard['photo'][0];
}
diff --git a/plugins/RequireValidatedEmail/README b/plugins/RequireValidatedEmail/README
index 46ee24d5f..84b1485b2 100644
--- a/plugins/RequireValidatedEmail/README
+++ b/plugins/RequireValidatedEmail/README
@@ -12,6 +12,20 @@ registered prior to that timestamp.
addPlugin('RequireValidatedEmail',
array('grandfatherCutoff' => 'Dec 7, 2009');
+You can also exclude the validation checks from OpenID accounts
+connected to a trusted provider, by providing a list of regular
+expressions to match their provider URLs.
+
+For example, to trust WikiHow and Wikipedia users:
+
+ addPlugin('RequireValidatedEmailPlugin', array(
+ 'trustedOpenIDs' => array(
+ '!^http://\w+\.wikihow\.com/!',
+ '!^http://\w+\.wikipedia\.org/!',
+ ),
+ ));
+
+
Todo:
* add a more visible indicator that validation is still outstanding
diff --git a/plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php b/plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php
index ccefa14f6..009a2f78e 100644
--- a/plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php
+++ b/plugins/RequireValidatedEmail/RequireValidatedEmailPlugin.php
@@ -37,6 +37,20 @@ class RequireValidatedEmailPlugin extends Plugin
// without the validation requirement.
public $grandfatherCutoff=null;
+ // If OpenID plugin is installed, users with a verified OpenID
+ // association whose provider URL matches one of these regexes
+ // will be considered to be sufficiently valid for our needs.
+ //
+ // For example, to trust WikiHow and Wikipedia OpenID users:
+ //
+ // addPlugin('RequireValidatedEmailPlugin', array(
+ // 'trustedOpenIDs' => array(
+ // '!^http://\w+\.wikihow\.com/!',
+ // '!^http://\w+\.wikipedia\.org/!',
+ // ),
+ // ));
+ public $trustedOpenIDs=array();
+
function __construct()
{
parent::__construct();
@@ -90,13 +104,17 @@ class RequireValidatedEmailPlugin extends Plugin
*/
protected function validated($user)
{
- if ($this->grandfathered($user)) {
- return true;
- }
-
// The email field is only stored after validation...
// Until then you'll find them in confirm_address.
- return !empty($user->email);
+ $knownGood = !empty($user->email) ||
+ $this->grandfathered($user) ||
+ $this->hasTrustedOpenID($user);
+
+ // Give other plugins a chance to override, if they can validate
+ // that somebody's ok despite a non-validated email.
+ Event::handle('RequireValidatedEmailPlugin_Override', array($user, &$knownGood));
+
+ return $knownGood;
}
/**
@@ -118,6 +136,28 @@ class RequireValidatedEmailPlugin extends Plugin
return false;
}
+ /**
+ * Override for RequireValidatedEmail plugin. If we have a user who's
+ * not validated an e-mail, but did come from a trusted provider,
+ * we'll consider them ok.
+ */
+ function hasTrustedOpenID($user)
+ {
+ if ($this->trustedOpenIDs && class_exists('User_openid')) {
+ foreach ($this->trustedOpenIDs as $regex) {
+ $oid = new User_openid();
+ $oid->user_id = $user->id;
+ $oid->find();
+ while ($oid->fetch()) {
+ if (preg_match($regex, $oid->canonical)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
function onPluginVersion(&$versions)
{
$versions[] = array('name' => 'Require Validated Email',
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();
}
}
}