X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=plugins%2FRSSCloud%2FRSSCloudRequestNotify.php;h=e9c0eab5f881e6a4ed6046806e9fdcd5ce34c17c;hb=64cdbe6c5578df1dc49d8e3dd72451ab0ac96bd2;hp=8b5deb13655f7b52d5403c2b47e8ede80ebbd93c;hpb=8980bebcb38eaaca934141b1828e243609577a51;p=quix0rs-gnu-social.git diff --git a/plugins/RSSCloud/RSSCloudRequestNotify.php b/plugins/RSSCloud/RSSCloudRequestNotify.php index 8b5deb1365..e9c0eab5f8 100644 --- a/plugins/RSSCloud/RSSCloudRequestNotify.php +++ b/plugins/RSSCloud/RSSCloudRequestNotify.php @@ -1,5 +1,4 @@ + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + **/ class RSSCloudRequestNotifyAction extends Action { /** @@ -46,24 +54,40 @@ class RSSCloudRequestNotifyAction extends Action { parent::prepare($args); - $this->ip = $_SERVER['REMOTE_ADDR']; - $this->port = $this->arg('port'); - $this->path = $this->arg('path'); + $this->ip = $_SERVER['REMOTE_ADDR']; + $this->port = $this->arg('port'); + $this->path = $this->arg('path'); + + if ($this->path[0] != '/') { + $this->path = '/' . $this->path; + } + $this->protocol = $this->arg('protocol'); $this->procedure = $this->arg('notifyProcedure'); $this->domain = $this->arg('domain'); - - $this->feeds = $this->getFeeds(); + + $this->feeds = $this->getFeeds(); return true; } + /** + * Handle the request + * + * Checks for all the required parameters for a subscription, + * validates that the feed being subscribed to is real, and then + * saves the subsctiption. + * + * @param array $args $_REQUEST data (unused) + * + * @return void + */ function handle($args) { parent::handle($args); if ($_SERVER['REQUEST_METHOD'] != 'POST') { - $this->showResult(false, 'Request must be POST.'); + $this->showResult(false, _m('Request must be POST.')); return; } @@ -73,16 +97,16 @@ class RSSCloudRequestNotifyAction extends Action $missing[] = 'port'; } - $path = $this->arg('path'); - if (empty($this->path)) { $missing[] = 'path'; } - $protocol = $this->arg('protocol'); - if (empty($this->protocol)) { $missing[] = 'protocol'; + } else if (strtolower($this->protocol) != 'http-post') { + $msg = _m('Only http-post notifications are supported at this time.'); + $this->showResult(false, $msg); + return; } if (!isset($this->procedure)) { @@ -90,52 +114,64 @@ class RSSCloudRequestNotifyAction extends Action } if (!empty($missing)) { - $msg = 'The following parameters were missing from the request body: ' . - implode(', ', $missing) . '.'; + // TRANS: %s is a comma separated list of parameters. + $msg = sprintf(_m('The following parameters were missing from the request body: %s.'),implode(', ', $missing)); $this->showResult(false, $msg); return; } if (empty($this->feeds)) { - $this->showResult(false, - 'You must provide at least one valid profile feed url (url1, url2, url3 ... urlN).'); + $msg = _m('You must provide at least one valid profile feed url ' . + '(url1, url2, url3 ... urlN).'); + $this->showResult(false, $msg); return; } // We have to validate everything before saving anything. - // We only return one success or failure no matter how + // We only return one success or failure no matter how // many feeds the subscriber is trying to subscribe to - foreach ($this->feeds as $feed) { - + if (!$this->validateFeed($feed)) { - $msg = 'Feed subscription failed - Not a valid feed.'; + + $nh = $this->getNotifyUrl(); + common_log(LOG_WARNING, + "RSSCloud plugin - $nh tried to subscribe to invalid feed: $feed"); + + $msg = _m('Feed subscription failed: Not a valid feed.'); $this->showResult(false, $msg); return; } - + if (!$this->testNotificationHandler($feed)) { - $msg = 'Feed subscription failed - ' . - 'notification handler doesn\'t respond correctly.'; + $msg = _m('Feed subscription failed - ' . + 'notification handler doesn\'t respond correctly.'); $this->showResult(false, $msg); - return; + return; } - } foreach ($this->feeds as $feed) { $this->saveSubscription($feed); - } - - // XXX: What to do about deleting stale subscriptions? 25 hours seems harsh. - // WordPress doesn't ever remove subscriptions. + } - $msg = 'Thanks for the registration. It worked. When the feed(s) update(s) we\'ll notify you. ' . - ' Don\'t forget to re-register after 24 hours, your subscription will expire in 25.'; + // XXX: What to do about deleting stale subscriptions? + // 25 hours seems harsh. WordPress doesn't ever remove + // subscriptions. + $msg = _m('Thanks for the subscription. ' . + 'When the feed(s) update(s), you will be notified.'); - $this->showResult(true, $msg); + $this->showResult(true, $msg); } + /** + * Validate that the requested feed is one we serve + * up via RSSCloud. + * + * @param string $feed the feed in question + * + * @return void + */ function validateFeed($feed) { $user = $this->userFromFeed($feed); @@ -147,57 +183,87 @@ class RSSCloudRequestNotifyAction extends Action return true; } - + /** + * Pull all of the urls (url1, url2, url3...urlN) that + * the subscriber wants to subscribe to. + * + * @return array $feeds the list of feeds + */ function getFeeds() { $feeds = array(); - - while (list($key, $feed) = each ($this->args)) { + + while (list($key, $feed) = each($this->args)) { if (preg_match('/^url\d*$/', $key)) { $feeds[] = $feed; - } + } } return $feeds; } + /** + * Test that a notification handler is there and is reponding + * correctly. This is called before adding a subscription. + * + * @param string $feed the feed to verify + * + * @return boolean success result + */ function testNotificationHandler($feed) - { - common_debug("RSSCloudPlugin - testNotificationHandler()"); - + { + $notifyUrl = $this->getNotifyUrl(); + $notifier = new RSSCloudNotifier(); - + if (isset($this->domain)) { - - //get - - $this->url = 'http://' . $this->domain . ':' . $this->port . '/' . $this->path; - - common_debug('domain set need to send challenge'); - - } else { - - //post - - $this->url = 'http://' . $this->ip . ':' . $this->port . '/' . $this->path; - - //return $notifier->postUpdate($endpoint, $feed); + // 'domain' param set, so we have to use GET and send a challenge + common_log(LOG_INFO, + 'RSSCloud plugin - Testing notification handler with challenge: ' . + $notifyUrl); + return $notifier->challenge($notifyUrl, $feed); - } + } else { + common_log(LOG_INFO, 'RSSCloud plugin - Testing notification handler: ' . + $notifyUrl); - return true; + return $notifier->postUpdate($notifyUrl, $feed); + } + } + /** + * Build the URL for the notification handler based on the + * parameters passed in with the subscription request. + * + * @return string notification handler url + */ + function getNotifyUrl() + { + if (isset($this->domain)) { + return 'http://' . $this->domain . ':' . $this->port . $this->path; + } else { + return 'http://' . $this->ip . ':' . $this->port . $this->path; + } } + /** + * Uses the nickname part of the subscribed feed URL to figure out + * whethere there's really a user with such a feed. Used to + * validate feeds before adding a subscription. + * + * @param string $feed the feed in question + * + * @return boolean success + */ function userFromFeed($feed) { - // We only do profile feeds - - $path = common_path('api/statuses/user_timeline/'); - $valid = '%^' . $path . '(?.*)\.rss$%'; + // We only do canonical RSS2 profile feeds (specified by ID), e.g.: + // http://www.example.com/api/statuses/user_timeline/2.rss + $path = common_path('api/statuses/user_timeline/'); + $valid = '%^' . $path . '(?.*)\.rss$%'; if (preg_match($valid, $feed, $matches)) { - $user = User::staticGet('nickname', $matches['nickname']); + $user = User::staticGet('id', $matches['id']); if (!empty($user)) { return $user; } @@ -206,52 +272,59 @@ class RSSCloudRequestNotifyAction extends Action return false; } + /** + * Save an RSSCloud subscription + * + * @param string $feed a valid profile feed + * + * @return boolean success result + */ function saveSubscription($feed) { $user = $this->userFromFeed($feed); - - common_debug('user = ' . $user->id); - - $sub = RSSCloudSubscription::getSubscription($user->id, $this->url); - + + $notifyUrl = $this->getNotifyUrl(); + + $sub = RSSCloudSubscription::getSubscription($user->id, $notifyUrl); + if ($sub) { - common_debug("already subscribed to that!"); + common_log(LOG_INFO, "RSSCloud plugin - $notifyUrl refreshed subscription" . + " to user $user->nickname (id: $user->id)."); } else { - common_debug('No feed for user ' . $user->id . ' notify: ' . $this->url); - } - - common_debug('RSSPlugin - saveSubscription'); - // turn debugging high - DB_DataObject::debugLevel(5); - - $sub = new RSSCloudSubscription(); - - $sub->subscribed = $user->id; - $sub->url = $this->url; - $sub->created = common_sql_now(); - - // auto timestamp doesn't seem to work for me - - $sub->modified = common_sql_now(); - - if (!$sub->insert()) { - common_log_db_error($sub, 'INSERT', __FILE__); - return false; + + $sub = new RSSCloudSubscription(); + + $sub->subscribed = $user->id; + $sub->url = $notifyUrl; + $sub->created = common_sql_now(); + + if (!$sub->insert()) { + common_log_db_error($sub, 'INSERT', __FILE__); + return false; + } + + common_log(LOG_INFO, "RSSCloud plugin - $notifyUrl subscribed" . + " to user $user->nickname (id: $user->id)"); } - DB_DataObject::debugLevel(); - + return true; } + /** + * Show an XML message indicating the subscription + * was successful or failed. + * + * @param boolean $success whether it was good or bad + * @param string $msg the message to output + * + * @return boolean success result + */ function showResult($success, $msg) { $this->startXML(); - $this->elementStart('notifyResult', array('success' => ($success) ? 'true' : 'false', - 'msg' => $msg)); + $this->elementStart('notifyResult', + array('success' => ($success) ? 'true' : 'false', + 'msg' => $msg)); $this->endXML(); } - } - - -