Issue 6477: Automatically repair self contact avatar
authorMichael <heluecht@pirati.ca>
Wed, 19 Jun 2019 17:05:29 +0000 (17:05 +0000)
committerMichael <heluecht@pirati.ca>
Wed, 19 Jun 2019 17:05:29 +0000 (17:05 +0000)
src/Model/Contact.php
src/Model/User.php
src/Module/Xrd.php
src/Protocol/ActivityPub/Transmitter.php
view/templates/tag_slap.tpl [deleted file]
view/templates/xrd_person.tpl

index a7914a1..9e3f2a1 100644 (file)
@@ -593,11 +593,13 @@ class Contact extends BaseObject
                        return;
                }
 
+               $file_suffix = 'jpg';
+
                $fields = ['name' => $profile['name'], 'nick' => $user['nickname'],
                        'avatar-date' => $self['avatar-date'], 'location' => Profile::formatLocation($profile),
                        'about' => $profile['about'], 'keywords' => $profile['pub_keywords'],
-                       'gender' => $profile['gender'], 'avatar' => $profile['photo'],
-                       'contact-type' => $user['account-type'], 'xmpp' => $profile['xmpp']];
+                       'gender' => $profile['gender'], 'contact-type' => $user['account-type'],
+                       'xmpp' => $profile['xmpp']];
 
                $avatar = Photo::selectFirst(['resource-id', 'type'], ['uid' => $uid, 'profile' => true]);
                if (DBA::isResult($avatar)) {
@@ -609,8 +611,6 @@ class Contact extends BaseObject
                        $types = Image::supportedTypes();
                        if (isset($types[$avatar['type']])) {
                                $file_suffix = $types[$avatar['type']];
-                       } else {
-                               $file_suffix = 'jpg';
                        }
 
                        // We are adding a timestamp value so that other systems won't use cached content
@@ -629,6 +629,7 @@ class Contact extends BaseObject
                        $fields['micro'] = System::baseUrl() . '/images/person-48.jpg';
                }
 
+               $fields['avatar'] = System::baseUrl() . '/photo/profile/' .$uid . '.' . $file_suffix;
                $fields['forum'] = $user['page-flags'] == User::PAGE_FLAGS_COMMUNITY;
                $fields['prv'] = $user['page-flags'] == User::PAGE_FLAGS_PRVGROUP;
 
@@ -661,8 +662,8 @@ class Contact extends BaseObject
                        DBA::update('contact', $fields, ['uid' => 0, 'nurl' => $self['nurl']]);
 
                        // Update the profile
-                       $fields = ['photo' => System::baseUrl() . '/photo/profile/' .$uid . '.jpg',
-                               'thumb' => System::baseUrl() . '/photo/avatar/' . $uid .'.jpg'];
+                       $fields = ['photo' => System::baseUrl() . '/photo/profile/' .$uid . '.' . $file_suffix,
+                               'thumb' => System::baseUrl() . '/photo/avatar/' . $uid .'.' . $file_suffix];
                        DBA::update('profile', $fields, ['uid' => $uid, 'is-default' => true]);
                }
        }
@@ -1725,7 +1726,7 @@ class Contact extends BaseObject
         */
        public static function updateAvatar($avatar, $uid, $cid, $force = false)
        {
-               $contact = DBA::selectFirst('contact', ['avatar', 'photo', 'thumb', 'micro', 'nurl'], ['id' => $cid]);
+               $contact = DBA::selectFirst('contact', ['avatar', 'photo', 'thumb', 'micro', 'nurl'], ['id' => $cid, 'self' => false]);
                if (!DBA::isResult($contact)) {
                        return false;
                } else {
@@ -2153,7 +2154,7 @@ class Contact extends BaseObject
                        return false;
                }
 
-               $fields = ['url', 'name', 'nick', 'photo', 'network', 'blocked'];
+               $fields = ['url', 'name', 'nick', 'avatar', 'photo', 'network', 'blocked'];
                $pub_contact = DBA::selectFirst('contact', $fields, ['id' => $datarray['author-id']]);
                if (!DBA::isResult($pub_contact)) {
                        // Should never happen
@@ -2167,16 +2168,16 @@ class Contact extends BaseObject
 
                $url = defaults($datarray, 'author-link', $pub_contact['url']);
                $name = $pub_contact['name'];
-               $photo = $pub_contact['photo'];
+               $photo = defaults($pub_contact, 'avatar', $pub_contact["photo"]);
                $nick = $pub_contact['nick'];
                $network = $pub_contact['network'];
 
                if (!empty($contact)) {
-            // Contact is blocked at user-level
-                   if (!empty($contact['id']) && !empty($importer['id']) &&
-                       self::isBlockedByUser($contact['id'], $importer['id'])) {
-                       return false;
-            }
+                       // Contact is blocked at user-level
+                       if (!empty($contact['id']) && !empty($importer['id']) &&
+                               self::isBlockedByUser($contact['id'], $importer['id'])) {
+                               return false;
+                       }
 
                        // Make sure that the existing contact isn't archived
                        self::unmarkForArchival($contact);
index b733563..de69310 100644 (file)
@@ -16,6 +16,7 @@ use Friendica\Core\Protocol;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
+use Friendica\Model\Photo;
 use Friendica\Object\Image;
 use Friendica\Util\Crypto;
 use Friendica\Util\DateTimeFormat;
@@ -149,10 +150,11 @@ class User
         * @brief Get owner data by user id
         *
         * @param int $uid
+        * @param boolean $check_valid Test if data is invalid and correct it
         * @return boolean|array
         * @throws Exception
         */
-       public static function getOwnerDataById($uid) {
+       public static function getOwnerDataById($uid, $check_valid = true) {
                $r = DBA::fetchFirst("SELECT
                        `contact`.*,
                        `user`.`prvkey` AS `uprvkey`,
@@ -180,12 +182,34 @@ class User
                        return false;
                }
 
+               if (!$check_valid) {
+                       return $r;
+               }
+
                // Check if the returned data is valid, otherwise fix it. See issue #6122
+
+               // Check for correct url and normalised nurl
                $url = System::baseUrl() . '/profile/' . $r['nickname'];
-               $addr = $r['nickname'] . '@' . substr(System::baseUrl(), strpos(System::baseUrl(), '://') + 3);
+               $repair = ($r['url'] != $url) || ($r['nurl'] != Strings::normaliseLink($r['url']));
+
+               if (!$repair) {
+                       // Check if "addr" is present and correct
+                       $addr = $r['nickname'] . '@' . substr(System::baseUrl(), strpos(System::baseUrl(), '://') + 3);
+                       $repair = ($addr != $r['addr']);
+               }
+
+               if (!$repair) {
+                       // Check if the avatar field is filled and the photo directs to the correct path
+                       $avatar = Photo::selectFirst(['resource-id'], ['uid' => $uid, 'profile' => true]);
+                       if (DBA::isResult($avatar)) {
+                               $repair = empty($r['avatar']) || !strpos($r['photo'], $avatar['resource-id']);
+                       }
+               }
 
-               if (($addr != $r['addr']) || ($r['url'] != $url) || ($r['nurl'] != Strings::normaliseLink($r['url']))) {
+               if ($repair) {
                        Contact::updateSelfFromUserID($uid);
+                       // Return the corrected data and avoid a loop
+                       $r = self::getOwnerDataById($uid, false);
                }
 
                return $r;
index b6bd875..0618a5d 100644 (file)
@@ -4,9 +4,11 @@ namespace Friendica\Module;
 
 use Friendica\BaseModule;
 use Friendica\Core\Hook;
+use Friendica\Database\DBA;
 use Friendica\Core\Renderer;
 use Friendica\Core\System;
 use Friendica\Model\User;
+use Friendica\Model\Photo;
 use Friendica\Protocol\Salmon;
 use Friendica\Util\Strings;
 
@@ -61,67 +63,69 @@ class Xrd extends BaseModule
                        throw new \Friendica\Network\HTTPException\NotFoundException();
                }
 
-               $profileURL = $app->getBaseURL() . '/profile/' . $user['nickname'];
-               $alias = str_replace('/profile/', '/~', $profileURL);
+               $owner = User::getOwnerDataById($user['uid']);
 
-               $addr = 'acct:' . $user['nickname'] . '@' . $app->getHostName();
-               if ($app->getURLPath()) {
-                       $addr .= '/' . $app->getURLPath();
+               $alias = str_replace('/profile/', '/~', $owner['url']);
+
+               $avatar = Photo::selectFirst(['type'], ['uid' => $owner['uid'], 'profile' => true]);
+
+               if (!DBA::isResult($avatar)) {
+                       $avatar = ['type' => 'image/jpeg'];
                }
 
                if ($mode == 'xml') {
-                       self::printXML($addr, $alias, $profileURL, $app->getBaseURL(), $user);
+                       self::printXML($alias, $app->getBaseURL(), $user, $owner, $avatar);
                } else {
-                       self::printJSON($addr, $alias, $profileURL, $app->getBaseURL(), $user);
+                       self::printJSON($alias, $app->getBaseURL(), $owner, $avatar);
                }
        }
 
-       private static function printJSON($uri, $alias, $orofileURL, $baseURL, $user)
+       private static function printJSON($alias, $baseURL, $owner, $avatar)
        {
-               $salmon_key = Salmon::salmonKey($user['spubkey']);
+               $salmon_key = Salmon::salmonKey($owner['spubkey']);
 
                header('Access-Control-Allow-Origin: *');
                header('Content-type: application/json; charset=utf-8');
 
                $json = [
-                       'subject' => $uri,
+                       'subject' => 'acct:' . $owner['addr'],
                        'aliases' => [
                                $alias,
-                               $orofileURL,
+                               $owner['url'],
                        ],
                        'links'   => [
                                [
                                        'rel'  => NAMESPACE_DFRN,
-                                       'href' => $orofileURL,
+                                       'href' => $owner['url'],
                                ],
                                [
                                        'rel'  => NAMESPACE_FEED,
                                        'type' => 'application/atom+xml',
-                                       'href' => $baseURL . '/dfrn_poll/' . $user['nickname'],
+                                       'href' => $owner['notify'],
                                ],
                                [
                                        'rel'  => 'http://webfinger.net/rel/profile-page',
                                        'type' => 'text/html',
-                                       'href' => $orofileURL,
+                                       'href' => $owner['url'],
                                ],
                                [
                                        'rel'  => 'self',
                                        'type' => 'application/activity+json',
-                                       'href' => $orofileURL,
+                                       'href' => $owner['url'],
                                ],
                                [
                                        'rel'  => 'http://microformats.org/profile/hcard',
                                        'type' => 'text/html',
-                                       'href' => $baseURL . '/hcard/' . $user['nickname'],
+                                       'href' => $baseURL . '/hcard/' . $owner['nickname'],
                                ],
                                [
                                        'rel'  => NAMESPACE_POCO,
-                                       'href' => $baseURL . '/poco/' . $user['nickname'],
+                                       'href' => $owner['poco'],
                                ],
                                [
                                        'rel'  => 'http://webfinger.net/rel/avatar',
-                                       'type' => 'image/jpeg',
-                                       'href' => $baseURL . '/photo/profile/' . $user['uid'] . '.jpg',
+                                       'type' => $avatar['type'],
+                                       'href' => $owner['photo'],
                                ],
                                [
                                        'rel'  => 'http://joindiaspora.com/seed_location',
@@ -130,15 +134,15 @@ class Xrd extends BaseModule
                                ],
                                [
                                        'rel'  => 'salmon',
-                                       'href' => $baseURL . '/salmon/' . $user['nickname'],
+                                       'href' => $baseURL . '/salmon/' . $owner['nickname'],
                                ],
                                [
                                        'rel'  => 'http://salmon-protocol.org/ns/salmon-replies',
-                                       'href' => $baseURL . '/salmon/' . $user['nickname'],
+                                       'href' => $baseURL . '/salmon/' . $owner['nickname'],
                                ],
                                [
                                        'rel'  => 'http://salmon-protocol.org/ns/salmon-mention',
-                                       'href' => $baseURL . '/salmon/' . $user['nickname'] . '/mention',
+                                       'href' => $baseURL . '/salmon/' . $owner['nickname'] . '/mention',
                                ],
                                [
                                        'rel'      => 'http://ostatus.org/schema/1.0/subscribe',
@@ -160,9 +164,9 @@ class Xrd extends BaseModule
                exit();
        }
 
-       private static function printXML($uri, $alias, $profileURL, $baseURL, $user)
+       private static function printXML($alias, $baseURL, $user, $owner, $avatar)
        {
-               $salmon_key = Salmon::salmonKey($user['spubkey']);
+               $salmon_key = Salmon::salmonKey($owner['spubkey']);
 
                header('Access-Control-Allow-Origin: *');
                header('Content-type: text/xml');
@@ -170,16 +174,17 @@ class Xrd extends BaseModule
                $tpl = Renderer::getMarkupTemplate('xrd_person.tpl');
 
                $o = Renderer::replaceMacros($tpl, [
-                       '$nick'        => $user['nickname'],
-                       '$accturi'     => $uri,
+                       '$nick'        => $owner['nickname'],
+                       '$accturi'     => 'acct:' . $owner['addr'],
                        '$alias'       => $alias,
-                       '$profile_url' => $profileURL,
-                       '$hcard_url'   => $baseURL . '/hcard/' . $user['nickname'],
-                       '$atom'        => $baseURL . '/dfrn_poll/' . $user['nickname'],
-                       '$poco_url'    => $baseURL . '/poco/' . $user['nickname'],
-                       '$photo'       => $baseURL . '/photo/profile/' . $user['uid'] . '.jpg',
-                       '$salmon'      => $baseURL . '/salmon/' . $user['nickname'],
-                       '$salmen'      => $baseURL . '/salmon/' . $user['nickname'] . '/mention',
+                       '$profile_url' => $owner['url'],
+                       '$hcard_url'   => $baseURL . '/hcard/' . $owner['nickname'],
+                       '$atom'        => $owner['notify'],
+                       '$poco_url'    => $owner['poco'],
+                       '$photo'       => $owner['photo'],
+                       '$type'        => $avatar['type'],
+                       '$salmon'      => $baseURL . '/salmon/' . $owner['nickname'],
+                       '$salmen'      => $baseURL . '/salmon/' . $owner['nickname'] . '/mention',
                        '$subscribe'   => $baseURL . '/follow?url={uri}',
                        '$openwebauth' => $baseURL . '/owa',
                        '$modexp'      => 'data:application/magic-public-key,' . $salmon_key
index 81b8bc1..cafdfc7 100644 (file)
@@ -229,11 +229,6 @@ class Transmitter
                        return [];
                }
 
-               // On old installations and never changed contacts this might not be filled
-               if (empty($contact['avatar'])) {
-                       $contact['avatar'] = $contact['photo'];
-               }
-
                $data = ['@context' => ActivityPub::CONTEXT];
                $data['id'] = $contact['url'];
                $data['diaspora:guid'] = $user['guid'];
@@ -254,7 +249,7 @@ class Transmitter
                        'publicKeyPem' => $user['pubkey']];
                $data['endpoints'] = ['sharedInbox' => System::baseUrl() . '/inbox'];
                $data['icon'] = ['type' => 'Image',
-                       'url' => $contact['avatar']];
+                       'url' => $contact['photo']];
 
                $data['generator'] = self::getService();
 
diff --git a/view/templates/tag_slap.tpl b/view/templates/tag_slap.tpl
deleted file mode 100644 (file)
index ac492b6..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-
-       <entry>
-               <author>
-                       <name>{{$name}}</name>
-                       <uri>{{$profile_page}}</uri>
-                       <link rel="photo"  type="image/jpeg" media:width="80" media:height="80" href="{{$thumb}}" />
-                       <link rel="avatar" type="image/jpeg" media:width="80" media:height="80" href="{{$thumb}}" />
-               </author>
-
-               <id>{{$item_id}}</id>
-               <title>{{$title}}</title>
-               <published>{{$published}}</published>
-               <content type="{{$type}}" >{{$content nofilter}}</content>
-               <link rel="mentioned" href="{{$accturi}}" />
-               <as:actor>
-               <as:object-type>http://activitystrea.ms/schema/1.0/person</as:object-type>
-               <id>{{$profile_page}}</id>
-               <title></title>
-               <link rel="avatar" type="image/jpeg" media:width="175" media:height="175" href="{{$photo}}"/>
-               <link rel="avatar" type="image/jpeg" media:width="80" media:height="80" href="{{$thumb}}"/>
-               <poco:preferredUsername>{{$nick}}</poco:preferredUsername>
-               <poco:displayName>{{$name}}</poco:displayName>
-               </as:actor>
-               <as:verb>{{$verb}}</as:verb>
-               <as:object>
-               <as:object-type></as:object-type>
-               </as:object>
-               <as:target>
-               <as:object-type></as:object-type>
-               </as:target>
-       </entry>
index 578698b..0fb81b0 100644 (file)
@@ -18,7 +18,7 @@
     <Link rel="http://portablecontacts.net/spec/1.0"
           href="{{$poco_url}}" />
     <Link rel="http://webfinger.net/rel/avatar"
-          type="image/jpeg"
+          type="{{$type}}"
           href="{{$photo}}" />
     <Link rel="http://joindiaspora.com/seed_location"
           type="text/html"