]> git.mxchange.org Git - friendica.git/commitdiff
Merge pull request #4727 from tobiasd/20180402-register
authorHypolite Petovan <mrpetovan@gmail.com>
Tue, 3 Apr 2018 14:39:53 +0000 (10:39 -0400)
committerGitHub <noreply@github.com>
Tue, 3 Apr 2018 14:39:53 +0000 (10:39 -0400)
added TOS module

composer.lock
mod/dfrn_notify.php
mod/lostpass.php
mod/salmon.php
src/Protocol/DFRN.php
src/Protocol/Diaspora.php
src/Worker/Delivery.php

index 72417f8e32eddb5482691858c8dca2e207846011..28199f4f5139d364e49b28c9ace7dbfc2ed7dc9e 100644 (file)
         },
         {
             "name": "divineomega/password_exposed",
-            "version": "v2.4.0",
+            "version": "v2.5.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/DivineOmega/password_exposed.git",
-                "reference": "7e26898a280662529b3e5e472b16fcbda167ffce"
+                "reference": "c928bf722eb02398df11076add60df070cb55581"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/DivineOmega/password_exposed/zipball/7e26898a280662529b3e5e472b16fcbda167ffce",
-                "reference": "7e26898a280662529b3e5e472b16fcbda167ffce",
+                "url": "https://api.github.com/repos/DivineOmega/password_exposed/zipball/c928bf722eb02398df11076add60df070cb55581",
+                "reference": "c928bf722eb02398df11076add60df070cb55581",
                 "shasum": ""
             },
             "require": {
                 }
             ],
             "description": "This PHP package provides a `password_exposed` helper function, that uses the haveibeenpwned.com API to check if a password has been exposed in a data breach.",
-            "time": "2018-03-14T09:17:40+00:00"
+            "time": "2018-04-02T18:16:36+00:00"
         },
         {
             "name": "ezyang/htmlpurifier",
index 073226b82998598e5f95f611c48646f53e51c0a7..7eddd4f3d576e05b59b787a2fb4eb05321b14176 100644 (file)
@@ -12,15 +12,58 @@ use Friendica\Core\System;
 use Friendica\Database\DBM;
 use Friendica\Model\Contact;
 use Friendica\Protocol\DFRN;
+use Friendica\Protocol\Diaspora;
 
 require_once 'include/items.php';
 
 function dfrn_notify_post(App $a) {
        logger(__function__, LOGGER_TRACE);
 
-       if (empty($_POST)) {
-               require_once 'mod/salmon.php';
-               salmon_post($a);
+       $postdata = file_get_contents('php://input');
+
+       if (empty($_POST) || !empty($postdata)) {
+               $data = json_decode($postdata);
+               if (is_object($data)) {
+                       $nick = defaults($a->argv, 1, '');
+                       $user = dba::selectFirst('user', [], ['nickname' => $nick, 'account_expired' => false, 'account_removed' => false]);
+                       if (!DBM::is_result($user)) {
+                               System::httpExit(500);
+                       }
+                       $msg = Diaspora::decodeRaw($user, $postdata);
+
+                       // Check if the user has got this contact
+                       $cid = Contact::getIdForURL($msg['author'], $user['uid']);
+                       if (!$cid) {
+                               // Otherwise there should be a public contact
+                               $cid = Contact::getIdForURL($msg['author']);
+                               if (!$cid) {
+                                       logger('Contact not found for address ' . $msg['author']);
+                                       System::xmlExit(3, 'Contact not found');
+                               }
+                       }
+
+                       // We now have some contact, so we fetch it
+                       $importer = dba::fetch_first("SELECT *, `name` as `senderName`
+                                                       FROM `contact`
+                                                       WHERE NOT `blocked` AND `id` = ? LIMIT 1",
+                                                       $cid);
+
+                       // This should never fail
+                       if (!DBM::is_result($importer)) {
+                               logger('Contact not found for address ' . $msg['author']);
+                               System::xmlExit(3, 'Contact not found');
+                       }
+
+                       // Set the user id. This is important if this is a public contact
+                       $importer['importer_uid']  = $user['uid'];
+
+                       // Now we should be able to import it
+                       $ret = DFRN::import($msg['message'], $importer);
+                       System::xmlExit($ret, 'Done');
+               } else {
+                       require_once 'mod/salmon.php';
+                       salmon_post($a, $postdata);
+               }
        }
 
        $dfrn_id      = ((x($_POST,'dfrn_id'))      ? notags(trim($_POST['dfrn_id']))   : '');
index 56ad7e30ef0e71225e73d6423a569d1b30568059..af4518ca16246292a9b8a18f8461797d9e9646e1 100644 (file)
@@ -69,6 +69,7 @@ function lostpass_post(App $a)
        notification([
                'type'     => SYSTEM_EMAIL,
                'to_email' => $user['email'],
+               'uid'      => $user['uid'],
                'subject'  => L10n::t('Password reset requested at %s', $sitename),
                'preamble' => $preamble,
                'body'     => $body
@@ -164,6 +165,7 @@ function lostpass_generate_password($user)
                notification([
                        'type'     => SYSTEM_EMAIL,
                        'to_email' => $user['email'],
+                       'uid'      => $user['uid'],
                        'subject'  => L10n::t('Your password has been changed at %s', $sitename),
                        'preamble' => $preamble,
                        'body'     => $body
index 2b6014adf590b36d832130c53951396156dadb02..22da151cf8e1c93f44d3478fee2c1b0e23c6e129 100644 (file)
@@ -13,9 +13,11 @@ use Friendica\Util\Crypto;
 
 require_once 'include/items.php';
 
-function salmon_post(App $a) {
+function salmon_post(App $a, $xml = '') {
 
-       $xml = file_get_contents('php://input');
+       if (empty($xml)) {
+               $xml = file_get_contents('php://input');
+       }
 
        logger('new salmon ' . $xml, LOGGER_DATA);
 
index 429c5051ffb4a9006e52d86f3f3b04785817a04f..734fbde628f096427333003ef5f98574ddca18f0 100644 (file)
@@ -31,6 +31,7 @@ use Friendica\Util\Crypto;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Network;
 use Friendica\Util\XML;
+use Friendica\Protocol\Diaspora;
 use dba;
 use DOMDocument;
 use DOMXPath;
@@ -1145,13 +1146,20 @@ class DFRN
         * @param string $atom     Content that will be transmitted
         * @param bool   $dissolve (to be documented)
         *
-        * @return int Deliver status. -1 means an error.
+        * @return int Deliver status. Negative values mean an error.
         * @todo Add array type-hint for $owner, $contact
         */
        public static function deliver($owner, $contact, $atom, $dissolve = false)
        {
                $a = get_app();
 
+               // At first try the Diaspora transport layer
+               $ret = self::transmit($owner, $contact, $atom);
+               if ($ret >= 200) {
+                       logger('Delivery via Diaspora transport layer was successful with status ' . $ret);
+                       return $ret;
+               }
+
                $idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
 
                if ($contact['duplex'] && $contact['dfrn-id']) {
@@ -1195,13 +1203,13 @@ class DFRN
                $xml = $ret['body'];
 
                $curl_stat = $a->get_curl_code();
-               if (!$curl_stat) {
+               if (empty($curl_stat)) {
                        return -3; // timed out
                }
 
                logger('dfrn_deliver: ' . $xml, LOGGER_DATA);
 
-               if (! $xml) {
+               if (empty($xml)) {
                        return 3;
                }
 
@@ -1214,7 +1222,7 @@ class DFRN
                $res = XML::parseString($xml);
 
                if ((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id))) {
-                       return (($res->status) ? $res->status : 3);
+                       return ($res->status ? $res->status : 3);
                }
 
                $postvars     = [];
@@ -1337,11 +1345,11 @@ class DFRN
                logger('dfrn_deliver: ' . "RECEIVED: " . $xml, LOGGER_DATA);
 
                $curl_stat = $a->get_curl_code();
-               if ((!$curl_stat) || (!strlen($xml))) {
+               if (empty($curl_stat) || empty($xml)) {
                        return -9; // timed out
                }
 
-               if (($curl_stat == 503) && (stristr($a->get_curl_headers(), 'retry-after'))) {
+               if (($curl_stat == 503) && stristr($a->get_curl_headers(), 'retry-after')) {
                        return -10;
                }
 
@@ -1353,7 +1361,7 @@ class DFRN
 
                $res = XML::parseString($xml);
 
-               if (!isset($res->status)) {
+               if (empty($res->status)) {
                        return -11;
                }
 
@@ -1368,6 +1376,79 @@ class DFRN
                return intval($res->status);
        }
 
+       /**
+        * @brief Transmits atom content to the contacts via the Diaspora transport layer
+        *
+        * @param array  $owner    Owner record
+        * @param array  $contact  Contact record of the receiver
+        * @param string $atom     Content that will be transmitted
+        *
+        * @return int Deliver status. Negative values mean an error.
+        */
+       public static function transmit($owner, $contact, $atom, $public_batch = false)
+       {
+               $a = get_app();
+
+               if (empty($contact['addr'])) {
+                       logger('Empty contact handle for ' . $contact['id'] . ' - ' . $contact['url'] . ' - trying to update it.');
+                       if (Contact::updateFromProbe($contact['id'])) {
+                               $new_contact = dba::selectFirst('contact', ['addr'], ['id' => $contact['id']]);
+                               $contact['addr'] = $new_contact['addr'];
+                       }
+
+                       if (empty($contact['addr'])) {
+                               logger('Unable to find contact handle for ' . $contact['id'] . ' - ' . $contact['url']);
+                               return -21;
+                       }
+               }
+
+               $fcontact = Diaspora::personByHandle($contact['addr']);
+               if (empty($fcontact)) {
+                       logger('Unable to find contact details for ' . $contact['id'] . ' - ' . $contact['addr']);
+                       return -21;
+               }
+
+               $envelope = Diaspora::buildMessage($atom, $owner, $contact, $owner['uprvkey'], $fcontact['pubkey'], $public_batch);
+
+               $dest_url = ($public_batch ? $fcontact["batch"] : $contact["notify"]);
+
+               $content_type = ($public_batch ? "application/magic-envelope+xml" : "application/json");
+
+               $xml = Network::post($dest_url, $envelope, ["Content-Type: ".$content_type]);
+
+               $curl_stat = $a->get_curl_code();
+               if (empty($curl_stat) || empty($xml)) {
+                       logger('Empty answer from ' . $contact['id'] . ' - ' . $dest_url);
+                       return -9; // timed out
+               }
+
+               if (($curl_stat == 503) && (stristr($a->get_curl_headers(), 'retry-after'))) {
+                       return -10;
+               }
+
+               if (strpos($xml, '<?xml') === false) {
+                       logger('No valid XML returned from ' . $contact['id'] . ' - ' . $dest_url);
+                       logger('Returned XML: ' . $xml, LOGGER_DATA);
+                       return 3;
+               }
+
+               $res = XML::parseString($xml);
+
+               if (empty($res->status)) {
+                       return -11;
+               }
+
+               if (!empty($res->message)) {
+                       logger('Transmit to ' . $dest_url . ' returned status '.$res->status.' - '.$res->message, LOGGER_DEBUG);
+               }
+
+               if ($res->status == 200) {
+                       Contact::unmarkForArchival($contact);
+               }
+
+               return intval($res->status);
+       }
+
        /**
         * @brief Add new birthday event for this person
         *
@@ -1433,7 +1514,7 @@ class DFRN
                $contact_old = dba::fetch_first("SELECT `id`, `uid`, `url`, `network`, `avatar-date`, `avatar`, `name-date`, `uri-date`, `addr`,
                                `name`, `nick`, `about`, `location`, `keywords`, `xmpp`, `bdyear`, `bd`, `hidden`, `contact-type`
                                FROM `contact` WHERE `uid` = ? AND `nurl` = ? AND `network` != ?",
-                       $importer["uid"],
+                       $importer["importer_uid"],
                        normalise_link($author["link"]),
                        NETWORK_STATUSNET
                );
@@ -1443,7 +1524,7 @@ class DFRN
                        $author["network"] = $contact_old["network"];
                } else {
                        if (!$onlyfetch) {
-                               logger("Contact ".$author["link"]." wasn't found for user ".$importer["uid"]." XML: ".$xml, LOGGER_DEBUG);
+                               logger("Contact ".$author["link"]." wasn't found for user ".$importer["importer_uid"]." XML: ".$xml, LOGGER_DEBUG);
                        }
 
                        $author["contact-id"] = $importer["id"];
@@ -1639,7 +1720,7 @@ class DFRN
 
                        Contact::updateAvatar(
                                $author['avatar'],
-                               $importer['uid'],
+                               $importer['importer_uid'],
                                $contact['id'],
                                (strtotime($contact['avatar-date']) > strtotime($contact_old['avatar-date']) || ($author['avatar'] != $contact_old['avatar']))
                        );
@@ -1657,7 +1738,7 @@ class DFRN
                        $poco["contact-type"] = $contact["contact-type"];
                        $gcid = GContact::update($poco);
 
-                       GContact::link($gcid, $importer["uid"], $contact["id"]);
+                       GContact::link($gcid, $importer["importer_uid"], $contact["id"]);
                }
 
                return $author;
@@ -2617,7 +2698,7 @@ class DFRN
                                if ((x($ev, "desc") || x($ev, "summary")) && x($ev, "start")) {
                                        logger("Event in item ".$item["uri"]." was found.", LOGGER_DEBUG);
                                        $ev["cid"]     = $importer["id"];
-                                       $ev["uid"]     = $importer["uid"];
+                                       $ev["uid"]     = $importer["importer_uid"];
                                        $ev["uri"]     = $item["uri"];
                                        $ev["edited"]  = $item["edited"];
                                        $ev["private"] = $item["private"];
@@ -2626,7 +2707,7 @@ class DFRN
                                        $r = q(
                                                "SELECT `id` FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
                                                dbesc($item["uri"]),
-                                               intval($importer["uid"])
+                                               intval($importer["importer_uid"])
                                        );
                                        if (DBM::is_result($r)) {
                                                $ev["id"] = $r[0]["id"];
@@ -2681,6 +2762,14 @@ class DFRN
                                return true;
                        }
                } else { // $entrytype == DFRN_TOP_LEVEL
+                       if ($importer["readonly"]) {
+                               logger('ignoring read-only contact '.$importer["id"]);
+                               return;
+                       }
+                       if ($importer["uid"] == 0) {
+                               logger("Contact ".$importer["id"]." isn't known to user ".$importer["importer_uid"].". The post will be ignored.", LOGGER_DEBUG);
+                               return;
+                       }
                        if (!link_compare($item["owner-link"], $importer["url"])) {
                                /*
                                 * The item owner info is not our contact. It's OK and is to be expected if this is a tgroup delivery,
@@ -2736,10 +2825,10 @@ class DFRN
                        return false;
                }
 
-               $condition = ["`uri` = ? AND `uid` = ? AND NOT `file` LIKE '%[%'", $uri, $importer["uid"]];
+               $condition = ["`uri` = ? AND `uid` = ? AND NOT `file` LIKE '%[%'", $uri, $importer["importer_uid"]];
                $item = dba::selectFirst('item', ['id', 'parent', 'contact-id'], $condition);
                if (!DBM::is_result($item)) {
-                       logger("Item with uri " . $uri . " for user " . $importer["uid"] . " wasn't found.", LOGGER_DEBUG);
+                       logger("Item with uri " . $uri . " for user " . $importer["importer_uid"] . " wasn't found.", LOGGER_DEBUG);
                        return;
                }
 
@@ -2808,7 +2897,7 @@ class DFRN
                $xpath->registerNamespace("statusnet", NAMESPACE_STATUSNET);
 
                $header = [];
-               $header["uid"] = $importer["uid"];
+               $header["uid"] = $importer["importer_uid"];
                $header["network"] = NETWORK_DFRN;
                $header["type"] = "remote";
                $header["wall"] = 0;
@@ -2827,7 +2916,7 @@ class DFRN
                        self::fetchauthor($xpath, $doc->firstChild, $importer, "dfrn:owner", false, $xml);
                }
 
-               logger("Import DFRN message for user " . $importer["uid"] . " from contact " . $importer["id"], LOGGER_DEBUG);
+               logger("Import DFRN message for user " . $importer["importer_uid"] . " from contact " . $importer["id"], LOGGER_DEBUG);
 
                // The account type is new since 3.5.1
                if ($xpath->query("/atom:feed/dfrn:account_type")->length > 0) {
@@ -2853,21 +2942,16 @@ class DFRN
                        self::processRelocation($xpath, $relocation, $importer);
                }
 
-               if ($importer["readonly"]) {
-                       // We aren't receiving stuff from this person. But we will quietly ignore them
-                       // rather than a blatant "go away" message.
-                       logger('ignoring contact '.$importer["id"]);
-                       return 403;
-               }
-
-               $mails = $xpath->query("/atom:feed/dfrn:mail");
-               foreach ($mails as $mail) {
-                       self::processMail($xpath, $mail, $importer);
-               }
+               if (($importer["uid"] != 0) && !$importer["readonly"]) {
+                       $mails = $xpath->query("/atom:feed/dfrn:mail");
+                       foreach ($mails as $mail) {
+                               self::processMail($xpath, $mail, $importer);
+                       }
 
-               $suggestions = $xpath->query("/atom:feed/dfrn:suggest");
-               foreach ($suggestions as $suggestion) {
-                       self::processSuggestion($xpath, $suggestion, $importer);
+                       $suggestions = $xpath->query("/atom:feed/dfrn:suggest");
+                       foreach ($suggestions as $suggestion) {
+                               self::processSuggestion($xpath, $suggestion, $importer);
+                       }
                }
 
                $deletions = $xpath->query("/atom:feed/at:deleted-entry");
@@ -2895,7 +2979,7 @@ class DFRN
                                self::processEntry($header, $xpath, $entry, $importer, $xml);
                        }
                }
-               logger("Import done for user " . $importer["uid"] . " from contact " . $importer["id"], LOGGER_DEBUG);
+               logger("Import done for user " . $importer["importer_uid"] . " from contact " . $importer["id"], LOGGER_DEBUG);
                return 200;
        }
 
index 23bc575dd071ac8ce5d75df0bf9fabdc5a049c65..d5d60a1541260bb1f0a00c0b1db8887c8286de50 100644 (file)
@@ -82,15 +82,19 @@ class Diaspora
 
                        // All servers who wants content with this tag
                        $tagserverlist = [];
-                       $tagserver = dba::select('gserver-tag', ['gserver-id'], ['tag' => $taglist]);
-                       while ($server = dba::fetch($tagserver)) {
-                               $tagserverlist[] = $server['gserver-id'];
+                       if (!empty($taglist)) {
+                               $tagserver = dba::select('gserver-tag', ['gserver-id'], ['tag' => $taglist]);
+                               while ($server = dba::fetch($tagserver)) {
+                                       $tagserverlist[] = $server['gserver-id'];
+                               }
                        }
 
                        // All adresses with the given id
-                       $servers = dba::select('gserver', ['url'], ['relay-subscribe' => true, 'relay-scope' => 'tags', 'id' => $tagserverlist]);
-                       while ($server = dba::fetch($servers)) {
-                               $serverlist[$server['url']] = $server['url'];
+                       if (!empty($tagserverlist)) {
+                               $servers = dba::select('gserver', ['url'], ['relay-subscribe' => true, 'relay-scope' => 'tags', 'id' => $tagserverlist]);
+                               while ($server = dba::fetch($servers)) {
+                                       $serverlist[$server['url']] = $server['url'];
+                               }
                        }
                }
 
@@ -3205,7 +3209,7 @@ class Diaspora
         *
         * @return string The message that will be transmitted to other servers
         */
-       private static function buildMessage($msg, $user, $contact, $prvkey, $pubkey, $public = false)
+       public static function buildMessage($msg, $user, $contact, $prvkey, $pubkey, $public = false)
        {
                // The message is put into an envelope with the sender's signature
                $envelope = self::buildMagicEnvelope($msg, $user);
index dc6caab3db9c95fe0cdece3100077ed633c7ac4c..e98d66a08b46952627fccac390a764df29aa2ecb 100644 (file)
@@ -321,7 +321,9 @@ class Delivery {
                                if ($deliver_status < 0) {
                                        logger('notifier: delivery failed: queuing message');
                                        Queue::add($contact['id'], NETWORK_DFRN, $atom, false, $target_item['guid']);
+                               }
 
+                               if ($deliver_status < 200) {
                                        // The message could not be delivered. We mark the contact as "dead"
                                        Contact::markForArchival($contact);
                                } else {