]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Last objectification of MagicEnvelope. Smarter SalmonAction
authorMikael Nordfeldth <mmn@hethane.se>
Sat, 31 May 2014 09:29:55 +0000 (11:29 +0200)
committerMikael Nordfeldth <mmn@hethane.se>
Sat, 31 May 2014 10:00:46 +0000 (12:00 +0200)
plugins/OStatus/lib/magicenvelope.php
plugins/OStatus/lib/salmonaction.php

index b49a8b4d3a307686b949a2177d85e47d7a3b91db..9990053904c495d6b6fdc0b380c9ce90939b8b7d 100644 (file)
@@ -162,63 +162,64 @@ class MagicEnvelope
         return $string;
     }
 
-    /**
+    /*
      * Extract the contained XML payload, and insert a copy of the envelope
      * signature data as an <me:provenance> section.
      *
-     * @return string representation of modified XML document
+     * @return DOMDocument of Atom entry
      *
      * @fixme in case of XML parsing errors, this will spew to the error log or output
      */
-    public function unfold()
+    public function getPayload()
     {
         $dom = new DOMDocument();
-        $dom->loadXML(Magicsig::base64_url_decode($this->data));
-
-        if ($dom->documentElement->tagName != 'entry') {
-            return false;
+        if (!$dom->loadXML(Magicsig::base64_url_decode($this->data))) {
+            throw new ServerException('Malformed XML in Salmon payload');
         }
 
-        $prov = $dom->createElementNS(self::NS, 'me:provenance');
-        $prov->setAttribute('xmlns:me', self::NS);
-        $data = $dom->createElementNS(self::NS, 'me:data', $this->data);
-        $data->setAttribute('type', $this->data_type);
-        $prov->appendChild($data);
-        $enc = $dom->createElementNS(self::NS, 'me:encoding', $this->encoding);
-        $prov->appendChild($enc);
-        $alg = $dom->createElementNS(self::NS, 'me:alg', $this->alg);
-        $prov->appendChild($alg);
-        $sig = $dom->createElementNS(self::NS, 'me:sig', $this->sig);
-        $prov->appendChild($sig);
-
-        $dom->documentElement->appendChild($prov);
-
-        return $dom->saveXML();
+        switch ($this->data_type) {
+        case 'application/atom+xml':
+            if ($dom->documentElement->namespaceURI !== Activity::ATOM
+                    || $dom->documentElement->tagName !== 'entry') {
+                throw new ServerException(_m('Salmon post must be an Atom entry.'));
+            }
+            $prov = $dom->createElementNS(self::NS, 'me:provenance');
+            $prov->setAttribute('xmlns:me', self::NS);
+            $data = $dom->createElementNS(self::NS, 'me:data', $this->data);
+            $data->setAttribute('type', $this->data_type);
+            $prov->appendChild($data);
+            $enc = $dom->createElementNS(self::NS, 'me:encoding', $this->encoding);
+            $prov->appendChild($enc);
+            $alg = $dom->createElementNS(self::NS, 'me:alg', $this->alg);
+            $prov->appendChild($alg);
+            $sig = $dom->createElementNS(self::NS, 'me:sig', $this->sig);
+            $prov->appendChild($sig);
+    
+            $dom->documentElement->appendChild($prov);
+            break;
+        default:
+            throw new ServerException('Unknown Salmon payload data type');
+        }
+        return $dom;
     }
 
     /**
-     * Find the author URI referenced in the given Atom entry.
+     * Find the author URI referenced in the payload Atom entry.
      *
-     * @param string $text string containing Atom entry XML
-     * @return mixed URI string or false if XML parsing fails, or null if no author URI can be found
-     *
-     * @fixme XML parsing failures will spew to error logs/output
+     * @return string URI for author
+     * @throws ServerException on failure
      */
-    public function getAuthorUri($text) {
-        $doc = new DOMDocument();
-        if (!$doc->loadXML($text)) {
-            return FALSE;
-        }
-
-        if ($doc->documentElement->tagName == 'entry') {
-            $authors = $doc->documentElement->getElementsByTagName('author');
-            foreach ($authors as $author) {
-                $uris = $author->getElementsByTagName('uri');
-                foreach ($uris as $uri) {
-                    return $uri->nodeValue;
-                }
+    public function getAuthorUri() {
+        $doc = $this->getPayload();
+
+        $authors = $doc->documentElement->getElementsByTagName('author');
+        foreach ($authors as $author) {
+            $uris = $author->getElementsByTagName('uri');
+            foreach ($uris as $uri) {
+                return $uri->nodeValue;
             }
         }
+        throw new ServerException('No author URI found in Salmon payload data');
     }
 
     /**
@@ -241,11 +242,8 @@ class MagicEnvelope
             return false;
         }
 
-        // $this->data is base64_url_encoded and should contain XML which is passed to getAuthorUri
-        $text = Magicsig::base64_url_decode($this->data);
-        $signer_uri = $this->getAuthorUri($text);
-
         try {
+            $signer_uri = $this->getAuthorUri();
             $magicsig = $this->getKeyPair($signer_uri);
         } catch (Exception $e) {
             common_log(LOG_DEBUG, "Salmon error: ".$e->getMessage());
index dcd7f00fd169bf238a480a85f08dfa67d65de5df..4366822ffdb3c1f8695a44d902c76b1dc3c0a0b3 100644 (file)
@@ -26,6 +26,8 @@ if (!defined('GNUSOCIAL')) { exit(1); }
 
 class SalmonAction extends Action
 {
+    protected $needPost = true;
+
     var $xml      = null;
     var $activity = null;
     var $target   = null;
@@ -36,12 +38,7 @@ class SalmonAction extends Action
 
         parent::prepare($args);
 
-        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-            // TRANS: Client error. POST is a HTTP command. It should not be translated.
-            $this->clientError(_m('This method requires a POST.'));
-        }
-
-        if (empty($_SERVER['CONTENT_TYPE']) || $_SERVER['CONTENT_TYPE'] != 'application/magic-envelope+xml') {
+        if (!isset($_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".'));
         }
@@ -54,16 +51,9 @@ class SalmonAction extends Action
             $this->clientError(_m('Salmon signature verification failed.'));
         }
 
-        $xml = $magic_env->unfold();    // return the enveloped XML (the actual data)
-        $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.'));
-        }
+        $entry = $magic_env->getPayload();
 
-        $this->activity = new Activity($dom->documentElement);
+        $this->activity = new Activity($entry->documentElement);
         return true;
     }