]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - plugins/OStatus/lib/salmonaction.php
* i18n/L10n update
[quix0rs-gnu-social.git] / plugins / OStatus / lib / salmonaction.php
index 4e5ed7fe6aa8672618393cbaae4129c155fb585f..41bdb489284a75072682c3351f7f748995682711 100644 (file)
@@ -38,25 +38,38 @@ class SalmonAction extends Action
         parent::prepare($args);
 
         if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-            $this->clientError(_('This method requires a POST.'));
+            // TRANS: Client error. POST is a HTTP command. It should not be translated.
+            $this->clientError(_m('This method requires a POST.'));
         }
 
-        if ($_SERVER['CONTENT_TYPE'] != 'application/atom+xml') {
-            $this->clientError(_('Salmon requires application/atom+xml'));
+        if (empty($_SERVER['CONTENT_TYPE']) || $_SERVER['CONTENT_TYPE'] != 'application/magic-envelope+xml') {
+            // TRANS: Client error. Do not translate "application/magic-envelope+xml"
+            $this->clientError(_m('Salmon requires "application/magic-envelope+xml".'));
         }
 
         $xml = file_get_contents('php://input');
 
-        $dom = DOMDocument::loadXML($xml);
+        // Check the signature
+        $salmon = new Salmon;
+        if (!$salmon->verifyMagicEnv($xml)) {
+            common_log(LOG_DEBUG, "Salmon signature verification failed.");
+            // TRANS: Client error.
+            $this->clientError(_m('Salmon signature verification failed.'));
+        } else {
+            $magic_env = new MagicEnvelope();
+            $env = $magic_env->parse($xml);
+            $xml = $magic_env->unfold($env);
+        }
 
+        $dom = DOMDocument::loadXML($xml);
         if ($dom->documentElement->namespaceURI != Activity::ATOM ||
             $dom->documentElement->localName != 'entry') {
             common_log(LOG_DEBUG, "Got invalid Salmon post: $xml");
+            // TRANS: Client error.
             $this->clientError(_m('Salmon post must be an Atom entry.'));
         }
-        // XXX: check the signature
 
-        $this->act = new Activity($dom->documentElement);
+        $this->activity = new Activity($dom->documentElement);
         return true;
     }
 
@@ -68,10 +81,9 @@ class SalmonAction extends Action
     {
         StatusNet::setApi(true); // Send smaller error pages
 
-        // TODO : Insert new $xml -> notice code
-
+        common_log(LOG_DEBUG, "Got a " . $this->activity->verb);
         if (Event::handle('StartHandleSalmon', array($this->activity))) {
-            switch ($this->act->verb)
+            switch ($this->activity->verb)
             {
             case ActivityVerb::POST:
                 $this->handlePost();
@@ -95,8 +107,15 @@ class SalmonAction extends Action
             case ActivityVerb::JOIN:
                 $this->handleJoin();
                 break;
+            case ActivityVerb::LEAVE:
+                $this->handleLeave();
+                break;
+            case ActivityVerb::UPDATE_PROFILE:
+                $this->handleUpdateProfile();
+                break;
             default:
-                throw new ClientException(_("Unimplemented."));
+                // TRANS: Client exception.
+                throw new ClientException(_m("Unrecognized activity type."));
             }
             Event::handle('EndHandleSalmon', array($this->activity));
         }
@@ -104,48 +123,65 @@ class SalmonAction extends Action
 
     function handlePost()
     {
-        throw new ClientException(_("Unimplemented!"));
+        // TRANS: Client exception.
+        throw new ClientException(_m("This target doesn't understand posts."));
     }
 
     function handleFollow()
     {
-        throw new ClientException(_("Unimplemented!"));
+        // TRANS: Client exception.
+        throw new ClientException(_m("This target doesn't understand follows."));
     }
 
     function handleUnfollow()
     {
-        throw new ClientException(_("Unimplemented!"));
+        // TRANS: Client exception.
+        throw new ClientException(_m("This target doesn't understand unfollows."));
     }
 
     function handleFavorite()
     {
-        throw new ClientException(_("Unimplemented!"));
+        // TRANS: Client exception.
+        throw new ClientException(_m("This target doesn't understand favorites."));
     }
 
-    /**
-     * Remote user doesn't like one of our posts after all!
-     * Confirm the post is ours, and delete a local favorite event.
-     */
-
     function handleUnfavorite()
     {
-        throw new ClientException(_("Unimplemented!"));
+        // TRANS: Client exception.
+        throw new ClientException(_m("This target doesn't understand unfavorites."));
     }
 
-    /**
-     * Hmmmm
-     */
     function handleShare()
     {
-        throw new ClientException(_("Unimplemented!"));
+        // TRANS: Client exception.
+        throw new ClientException(_m("This target doesn't understand share events."));
+    }
+
+    function handleJoin()
+    {
+        // TRANS: Client exception.
+        throw new ClientException(_m("This target doesn't understand joins."));
+    }
+
+    function handleLeave()
+    {
+        // TRANS: Client exception.
+        throw new ClientException(_m("This target doesn't understand leave events."));
     }
 
     /**
-     * Hmmmm
+     * Remote user sent us an update to their profile.
+     * If we already know them, accept the updates.
      */
-    function handleJoin()
+    function handleUpdateProfile()
     {
-        throw new ClientException(_("Unimplemented!"));
+        $oprofile = Ostatus_profile::getActorProfile($this->activity);
+        if ($oprofile) {
+            common_log(LOG_INFO, "Got a profile-update ping from $oprofile->uri");
+            $oprofile->updateFromActivityObject($this->activity->actor);
+        } else {
+            common_log(LOG_INFO, "Ignoring profile-update ping from unknown " . $this->activity->actor->id);
+        }
     }
 
     /**
@@ -153,57 +189,20 @@ class SalmonAction extends Action
      */
     function ensureProfile()
     {
-        $actor = $this->act->actor;
+        $actor = $this->activity->actor;
         if (empty($actor->id)) {
             common_log(LOG_ERR, "broken actor: " . var_export($actor, true));
-            throw new Exception("Received a salmon slap from unidentified actor.");
+            common_log(LOG_ERR, "activity with no actor: " . var_export($this->activity, true));
+            // TRANS: Exception.
+            throw new Exception(_m('Received a salmon slap from unidentified actor.'));
         }
 
-        return Ostatus_profile::ensureActorProfile($this->act);
+        return Ostatus_profile::ensureActivityObjectProfile($actor);
     }
 
     function saveNotice()
     {
         $oprofile = $this->ensureProfile();
-
-        // Get (safe!) HTML and text versions of the content
-
-        require_once(INSTALLDIR.'/extlib/HTMLPurifier/HTMLPurifier.auto.php');
-
-        $html = $this->act->object->content;
-
-        $rendered = HTMLPurifier::purify($html);
-        $content = html_entity_decode(strip_tags($rendered));
-
-        $options = array('is_local' => Notice::REMOTE_OMB,
-                         'uri' => $this->act->object->id,
-                         'url' => $this->act->object->link,
-                         'rendered' => $rendered);
-
-        if (!empty($this->act->context->location)) {
-            $options['lat'] = $location->lat;
-            $options['lon'] = $location->lon;
-            if ($location->location_id) {
-                $options['location_ns'] = $location->location_ns;
-                $options['location_id'] = $location->location_id;
-            }
-        }
-
-        if (!empty($this->act->context->replyToID)) {
-            $orig = Notice::staticGet('uri',
-                                      $this->act->context->replyToID);
-            if (!empty($orig)) {
-                $options['reply_to'] = $orig->id;
-            }
-        }
-
-        if (!empty($this->act->time)) {
-            $options['created'] = common_sql_time($this->act->time);
-        }
-
-        return Notice::saveNew($oprofile->profile_id,
-                               $content,
-                               'ostatus+salmon',
-                               $options);
+        return $oprofile->processPost($this->activity, 'salmon');
     }
 }