Merge pull request #13310 from MrPetovan/bug/13217-mirroring-blocked

Prevent post mirroring by blocked users
This commit is contained in:
Michael Vogel 2023-08-05 20:27:17 +02:00 committed by GitHub
commit a6449da557
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 86 additions and 42 deletions

View file

@ -1,6 +1,6 @@
-- ------------------------------------------ -- ------------------------------------------
-- Friendica 2023.09-dev (Giant Rhubarb) -- Friendica 2023.09-dev (Giant Rhubarb)
-- DB_UPDATE_VERSION 1523 -- DB_UPDATE_VERSION 1524
-- ------------------------------------------ -- ------------------------------------------
@ -1834,8 +1834,8 @@ CREATE TABLE IF NOT EXISTS `user-contact` (
`rel` tinyint unsigned COMMENT 'The kind of the relation between the user and the contact', `rel` tinyint unsigned COMMENT 'The kind of the relation between the user and the contact',
`info` mediumtext COMMENT '', `info` mediumtext COMMENT '',
`notify_new_posts` boolean COMMENT '', `notify_new_posts` boolean COMMENT '',
`remote_self` boolean COMMENT '', `remote_self` tinyint unsigned COMMENT '0 => No mirroring, 1-2 => Mirror as own post, 3 => Mirror as reshare',
`fetch_further_information` tinyint unsigned COMMENT '', `fetch_further_information` tinyint unsigned COMMENT '0 => None, 1 => Fetch information, 3 => Fetch keywords, 2 => Fetch both',
`ffi_keyword_denylist` text COMMENT '', `ffi_keyword_denylist` text COMMENT '',
`subhub` boolean COMMENT '', `subhub` boolean COMMENT '',
`hub-verify` varbinary(383) COMMENT '', `hub-verify` varbinary(383) COMMENT '',

View file

@ -36,7 +36,7 @@ use Friendica\Model\Contact;
* @property-read int $rel * @property-read int $rel
* @property-read string $info * @property-read string $info
* @property-read bool $notifyNewPosts * @property-read bool $notifyNewPosts
* @property-read bool $isRemoteSelf * @property-read int $remoteSelf
* @property-read int $fetchFurtherInformation * @property-read int $fetchFurtherInformation
* @property-read string $ffiKeywordDenylist * @property-read string $ffiKeywordDenylist
* @property-read bool $subhub * @property-read bool $subhub
@ -47,6 +47,16 @@ use Friendica\Model\Contact;
*/ */
class LocalRelationship extends \Friendica\BaseEntity class LocalRelationship extends \Friendica\BaseEntity
{ {
// Fetch Further Information options, not a binary flag
const FFI_NONE = 0;
const FFI_INFORMATION = 1;
const FFI_KEYWORD = 3;
const FFI_BOTH = 2;
const MIRROR_DEACTIVATED = 0;
const MIRROR_OWN_POST = 2;
const MIRROR_NATIVE_RESHARE = 3;
/** @var int */ /** @var int */
protected $userId; protected $userId;
/** @var int */ /** @var int */
@ -67,9 +77,9 @@ class LocalRelationship extends \Friendica\BaseEntity
protected $info; protected $info;
/** @var bool */ /** @var bool */
protected $notifyNewPosts; protected $notifyNewPosts;
/** @var bool */ /** @var int One of MIRROR_* */
protected $isRemoteSelf; protected $remoteSelf;
/** @var int */ /** @var int One of FFI_* */
protected $fetchFurtherInformation; protected $fetchFurtherInformation;
/** @var string */ /** @var string */
protected $ffiKeywordDenylist; protected $ffiKeywordDenylist;
@ -84,7 +94,7 @@ class LocalRelationship extends \Friendica\BaseEntity
/** @var int */ /** @var int */
protected $priority; protected $priority;
public function __construct(int $userId, int $contactId, bool $blocked = false, bool $ignored = false, bool $collapsed = false, bool $hidden = false, bool $pending = false, int $rel = Contact::NOTHING, string $info = '', bool $notifyNewPosts = false, bool $isRemoteSelf = false, int $fetchFurtherInformation = 0, string $ffiKeywordDenylist = '', bool $subhub = false, string $hubVerify = '', string $protocol = Protocol::PHANTOM, ?int $rating = null, ?int $priority = null) public function __construct(int $userId, int $contactId, bool $blocked = false, bool $ignored = false, bool $collapsed = false, bool $hidden = false, bool $pending = false, int $rel = Contact::NOTHING, string $info = '', bool $notifyNewPosts = false, int $remoteSelf = self::MIRROR_DEACTIVATED, int $fetchFurtherInformation = self::FFI_NONE, string $ffiKeywordDenylist = '', bool $subhub = false, string $hubVerify = '', string $protocol = Protocol::PHANTOM, ?int $rating = null, ?int $priority = null)
{ {
$this->userId = $userId; $this->userId = $userId;
$this->contactId = $contactId; $this->contactId = $contactId;
@ -96,7 +106,7 @@ class LocalRelationship extends \Friendica\BaseEntity
$this->rel = $rel; $this->rel = $rel;
$this->info = $info; $this->info = $info;
$this->notifyNewPosts = $notifyNewPosts; $this->notifyNewPosts = $notifyNewPosts;
$this->isRemoteSelf = $isRemoteSelf; $this->remoteSelf = $remoteSelf;
$this->fetchFurtherInformation = $fetchFurtherInformation; $this->fetchFurtherInformation = $fetchFurtherInformation;
$this->ffiKeywordDenylist = $ffiKeywordDenylist; $this->ffiKeywordDenylist = $ffiKeywordDenylist;
$this->subhub = $subhub; $this->subhub = $subhub;

View file

@ -45,8 +45,8 @@ class LocalRelationship extends BaseFactory implements ICanCreateFromTableRow
$row['rel'] ?? Contact::NOTHING, $row['rel'] ?? Contact::NOTHING,
$row['info'] ?? '', $row['info'] ?? '',
$row['notify_new_posts'] ?? false, $row['notify_new_posts'] ?? false,
$row['remote_self'] ?? false, $row['remote_self'] ?? Entity\LocalRelationship::MIRROR_DEACTIVATED,
$row['fetch_further_information'] ?? 0, $row['fetch_further_information'] ?? Entity\LocalRelationship::FFI_NONE,
$row['ffi_keyword_denylist'] ?? '', $row['ffi_keyword_denylist'] ?? '',
$row['subhub'] ?? false, $row['subhub'] ?? false,
$row['hub-verify'] ?? '', $row['hub-verify'] ?? '',

View file

@ -100,7 +100,7 @@ class LocalRelationship extends \Friendica\BaseRepository
'rel' => $localRelationship->rel, 'rel' => $localRelationship->rel,
'info' => $localRelationship->info, 'info' => $localRelationship->info,
'notify_new_posts' => $localRelationship->notifyNewPosts, 'notify_new_posts' => $localRelationship->notifyNewPosts,
'remote_self' => $localRelationship->isRemoteSelf, 'remote_self' => $localRelationship->remoteSelf,
'fetch_further_information' => $localRelationship->fetchFurtherInformation, 'fetch_further_information' => $localRelationship->fetchFurtherInformation,
'ffi_keyword_denylist' => $localRelationship->ffiKeywordDenylist, 'ffi_keyword_denylist' => $localRelationship->ffiKeywordDenylist,
'subhub' => $localRelationship->subhub, 'subhub' => $localRelationship->subhub,

View file

@ -23,6 +23,7 @@ namespace Friendica\Model;
use Friendica\Contact\Avatar; use Friendica\Contact\Avatar;
use Friendica\Contact\Introduction\Exception\IntroductionNotFoundException; use Friendica\Contact\Introduction\Exception\IntroductionNotFoundException;
use Friendica\Contact\LocalRelationship\Entity\LocalRelationship;
use Friendica\Content\Conversation as ConversationContent; use Friendica\Content\Conversation as ConversationContent;
use Friendica\Content\Pager; use Friendica\Content\Pager;
use Friendica\Content\Text\HTML; use Friendica\Content\Text\HTML;
@ -111,10 +112,14 @@ class Contact
* @} * @}
*/ */
const MIRROR_DEACTIVATED = 0; /** @deprecated Use Entity\LocalRelationship::MIRROR_DEACTIVATED instead */
const MIRROR_FORWARDED = 1; // Deprecated, now does the same like MIRROR_OWN_POST const MIRROR_DEACTIVATED = LocalRelationship::MIRROR_DEACTIVATED;
const MIRROR_OWN_POST = 2; /** @deprecated Now does the same as MIRROR_OWN_POST */
const MIRROR_NATIVE_RESHARE = 3; const MIRROR_FORWARDED = 1;
/** @deprecated Use Entity\LocalRelationship::MIRROR_OWN_POST instead */
const MIRROR_OWN_POST = LocalRelationship::MIRROR_OWN_POST;
/** @deprecated Use Entity\LocalRelationship::MIRROR_NATIVE_RESHARE instead */
const MIRROR_NATIVE_RESHARE = LocalRelationship::MIRROR_NATIVE_RESHARE;
/** /**
* @param array $fields Array of selected fields, empty for all * @param array $fields Array of selected fields, empty for all

View file

@ -21,6 +21,7 @@
namespace Friendica\Model; namespace Friendica\Model;
use Friendica\Contact\LocalRelationship\Entity\LocalRelationship;
use Friendica\Content\Text\BBCode; use Friendica\Content\Text\BBCode;
use Friendica\Content\Text\HTML; use Friendica\Content\Text\HTML;
use Friendica\Core\Hook; use Friendica\Core\Hook;
@ -2333,12 +2334,7 @@ class Item
return; return;
} }
$cdata = Contact::getPublicAndUserContactID($item['author-id'], $item['uid']); if (!DBA::exists('contact', ['id' => $cdata['user'], 'remote_self' => LocalRelationship::MIRROR_NATIVE_RESHARE])) {
if (empty($cdata['user']) || ($cdata['user'] != $item['contact-id'])) {
return;
}
if (!DBA::exists('contact', ['id' => $cdata['user'], 'remote_self' => Contact::MIRROR_NATIVE_RESHARE])) {
return; return;
} }
@ -2346,6 +2342,10 @@ class Item
return; return;
} }
if (User::getById($item['uid'], ['blocked'])['blocked'] ?? false) {
return;
}
Logger::info('Automatically reshare item', ['uid' => $item['uid'], 'id' => $item['id'], 'guid' => $item['guid'], 'uri-id' => $item['uri-id']]); Logger::info('Automatically reshare item', ['uid' => $item['uid'], 'id' => $item['id'], 'guid' => $item['guid'], 'uri-id' => $item['uri-id']]);
self::performActivity($item['id'], 'announce', $item['uid']); self::performActivity($item['id'], 'announce', $item['uid']);
@ -2353,7 +2353,7 @@ class Item
public static function isRemoteSelf(array $contact, array &$datarray): bool public static function isRemoteSelf(array $contact, array &$datarray): bool
{ {
if ($contact['remote_self'] != Contact::MIRROR_OWN_POST) { if ($contact['remote_self'] != LocalRelationship::MIRROR_OWN_POST) {
return false; return false;
} }
@ -2380,6 +2380,11 @@ class Item
return false; return false;
} }
if (User::getById($contact['uid'], ['blocked'])['blocked'] ?? false) {
Logger::info('User is blocked', ['contact' => $contact]);
return false;
}
$datarray2 = $datarray; $datarray2 = $datarray;
Logger::info('remote-self start', ['contact' => $contact['url'], 'remote_self' => $contact['remote_self'], 'item' => $datarray]); Logger::info('remote-self start', ['contact' => $contact['url'], 'remote_self' => $contact['remote_self'], 'item' => $datarray]);
@ -3222,7 +3227,7 @@ class Item
$shared_html = substr($s, $pos + strlen(BBCode::SHARED_ANCHOR)); $shared_html = substr($s, $pos + strlen(BBCode::SHARED_ANCHOR));
$s = substr($s, 0, $pos); $s = substr($s, 0, $pos);
} }
$s = self::addGallery($s, $attachments, $item['uri-id']); $s = self::addGallery($s, $attachments, $item['uri-id']);
$s = self::addVisualAttachments($attachments, $item, $s, false); $s = self::addVisualAttachments($attachments, $item, $s, false);
$s = self::addLinkAttachment($item['uri-id'], $attachments, $body, $s, false, $shared_links); $s = self::addLinkAttachment($item['uri-id'], $attachments, $body, $s, false, $shared_links);
@ -3628,9 +3633,9 @@ class Item
} }
$author = [ $author = [
'uid' => 0, 'uid' => 0,
'id' => $item['author-id'], 'id' => $item['author-id'],
'network' => $item['author-network'], 'network' => $item['author-network'],
'url' => $item['author-link'], 'url' => $item['author-link'],
'alias' => $item['author-alias'] 'alias' => $item['author-alias']
]; ];
@ -3721,9 +3726,9 @@ class Item
if (!empty($plink) && ($item['private'] == self::PRIVATE)) { if (!empty($plink) && ($item['private'] == self::PRIVATE)) {
$author = [ $author = [
'uid' => 0, 'uid' => 0,
'id' => $item['author-id'], 'id' => $item['author-id'],
'network' => $item['author-network'], 'network' => $item['author-network'],
'url' => $item['author-link'], 'url' => $item['author-link'],
'alias' => $item['author-alias'], 'alias' => $item['author-alias'],
]; ];

View file

@ -283,10 +283,10 @@ class Profile extends BaseModule
$localRelationship->fetchFurtherInformation, $localRelationship->fetchFurtherInformation,
$this->t('Fetch information like preview pictures, title and teaser from the feed item. You can activate this if the feed doesn\'t contain much text. Keywords are taken from the meta header in the feed item and are posted as hash tags.'), $this->t('Fetch information like preview pictures, title and teaser from the feed item. You can activate this if the feed doesn\'t contain much text. Keywords are taken from the meta header in the feed item and are posted as hash tags.'),
[ [
'0' => $this->t('Disabled'), Entity\LocalRelationship::FFI_NONE => $this->t('Disabled'),
'1' => $this->t('Fetch information'), Entity\LocalRelationship::FFI_INFORMATION => $this->t('Fetch information'),
'3' => $this->t('Fetch keywords'), Entity\LocalRelationship::FFI_KEYWORD => $this->t('Fetch keywords'),
'2' => $this->t('Fetch information and keywords') Entity\LocalRelationship::FFI_BOTH => $this->t('Fetch information and keywords')
] ]
]; ];
} }
@ -394,7 +394,7 @@ class Profile extends BaseModule
'$remote_self' => [ '$remote_self' => [
'remote_self', 'remote_self',
$this->t('Mirror postings from this contact'), $this->t('Mirror postings from this contact'),
$localRelationship->isRemoteSelf, $localRelationship->remoteSelf,
$this->t('Mark this contact as remote_self, this will cause friendica to repost new entries from this contact.'), $this->t('Mark this contact as remote_self, this will cause friendica to repost new entries from this contact.'),
$remote_self_options $remote_self_options
], ],

View file

@ -25,6 +25,7 @@ use DOMDocument;
use DOMElement; use DOMElement;
use DOMXPath; use DOMXPath;
use Friendica\App; use Friendica\App;
use Friendica\Contact\LocalRelationship\Entity\LocalRelationship;
use Friendica\Content\PageInfo; use Friendica\Content\PageInfo;
use Friendica\Content\Text\BBCode; use Friendica\Content\Text\BBCode;
use Friendica\Content\Text\HTML; use Friendica\Content\Text\HTML;
@ -566,8 +567,10 @@ class Feed
continue; continue;
} }
$fetch_further_information = $contact['fetch_further_information'] ?? LocalRelationship::FFI_NONE;
$preview = ''; $preview = '';
if (!empty($contact['fetch_further_information']) && ($contact['fetch_further_information'] < 3)) { if (in_array($fetch_further_information, [LocalRelationship::FFI_INFORMATION, LocalRelationship::FFI_BOTH])) {
// Handle enclosures and treat them as preview picture // Handle enclosures and treat them as preview picture
foreach ($attachments as $attachment) { foreach ($attachments as $attachment) {
if ($attachment['mimetype'] == 'image/jpeg') { if ($attachment['mimetype'] == 'image/jpeg') {
@ -611,7 +614,12 @@ class Feed
} }
} }
$data = PageInfo::queryUrl($item['plink'], false, $preview, ($contact['fetch_further_information'] == 2), $contact['ffi_keyword_denylist'] ?? ''); $data = PageInfo::queryUrl(
$item['plink'],
false,
$fetch_further_information == LocalRelationship::FFI_BOTH,
$contact['ffi_keyword_denylist'] ?? ''
);
if (!empty($data)) { if (!empty($data)) {
// Take the data that was provided by the feed if the query is empty // Take the data that was provided by the feed if the query is empty
@ -630,7 +638,7 @@ class Feed
// We always strip the title since it will be added in the page information // We always strip the title since it will be added in the page information
$item['title'] = ''; $item['title'] = '';
$item['body'] = $item['body'] . "\n" . PageInfo::getFooterFromData($data, false); $item['body'] = $item['body'] . "\n" . PageInfo::getFooterFromData($data, false);
$taglist = $contact['fetch_further_information'] == 2 ? PageInfo::getTagsFromUrl($item['plink'], $preview, $contact['ffi_keyword_denylist'] ?? '') : []; $taglist = $fetch_further_information == LocalRelationship::FFI_BOTH ? PageInfo::getTagsFromUrl($item['plink'], $preview, $contact['ffi_keyword_denylist'] ?? '') : [];
$item['object-type'] = Activity\ObjectType::BOOKMARK; $item['object-type'] = Activity\ObjectType::BOOKMARK;
$attachments = []; $attachments = [];
@ -662,7 +670,7 @@ class Feed
$item['body'] = '[abstract]' . HTML::toBBCode($summary, $basepath) . "[/abstract]\n" . $item['body']; $item['body'] = '[abstract]' . HTML::toBBCode($summary, $basepath) . "[/abstract]\n" . $item['body'];
} }
if (!empty($contact['fetch_further_information']) && ($contact['fetch_further_information'] == 3)) { if ($fetch_further_information == LocalRelationship::FFI_KEYWORD) {
if (empty($taglist)) { if (empty($taglist)) {
$taglist = PageInfo::getTagsFromUrl($item['plink'], $preview, $contact['ffi_keyword_denylist'] ?? ''); $taglist = PageInfo::getTagsFromUrl($item['plink'], $preview, $contact['ffi_keyword_denylist'] ?? '');
} }

View file

@ -45,10 +45,10 @@ class PollContacts
if (!empty($abandon_days)) { if (!empty($abandon_days)) {
$condition = DBA::mergeConditions($condition, $condition = DBA::mergeConditions($condition,
["`uid` != ? AND `uid` IN (SELECT `uid` FROM `user` WHERE NOT `account_expired` AND NOT `account_removed` AND `last-activity` > ?)", 0, DateTimeFormat::utc('now - ' . $abandon_days . ' days')]); ["`uid` != ? AND `uid` IN (SELECT `uid` FROM `user` WHERE NOT `blocked` AND NOT `account_expired` AND NOT `account_removed` AND `last-activity` > ?)", 0, DateTimeFormat::utc('now - ' . $abandon_days . ' days')]);
} else { } else {
$condition = DBA::mergeConditions($condition, $condition = DBA::mergeConditions($condition,
["`uid` != ? AND `uid` IN (SELECT `uid` FROM `user` WHERE NOT `account_expired` AND NOT `account_removed`)", 0]); ["`uid` != ? AND `uid` IN (SELECT `uid` FROM `user` WHERE NOT `blocked` AND NOT `account_expired` AND NOT `account_removed`)", 0]);
} }
$contacts = DBA::select('contact', ['id', 'nick', 'name', 'network', 'archive', 'last-update', 'priority', 'rating'], $condition); $contacts = DBA::select('contact', ['id', 'nick', 'name', 'network', 'archive', 'last-update', 'priority', 'rating'], $condition);

View file

@ -56,7 +56,7 @@ use Friendica\Database\DBA;
// This file is required several times during the test in DbaDefinition which justifies this condition // This file is required several times during the test in DbaDefinition which justifies this condition
if (!defined('DB_UPDATE_VERSION')) { if (!defined('DB_UPDATE_VERSION')) {
define('DB_UPDATE_VERSION', 1523); define('DB_UPDATE_VERSION', 1524);
} }
return [ return [
@ -1826,8 +1826,8 @@ return [
"rel" => ["type" => "tinyint unsigned", "comment" => "The kind of the relation between the user and the contact"], "rel" => ["type" => "tinyint unsigned", "comment" => "The kind of the relation between the user and the contact"],
"info" => ["type" => "mediumtext", "comment" => ""], "info" => ["type" => "mediumtext", "comment" => ""],
"notify_new_posts" => ["type" => "boolean", "comment" => ""], "notify_new_posts" => ["type" => "boolean", "comment" => ""],
"remote_self" => ["type" => "boolean", "comment" => ""], "remote_self" => ["type" => "tinyint unsigned", "comment" => "0 => No mirroring, 1-2 => Mirror as own post, 3 => Mirror as reshare"],
"fetch_further_information" => ["type" => "tinyint unsigned", "comment" => ""], "fetch_further_information" => ["type" => "tinyint unsigned", "comment" => "0 => None, 1 => Fetch information, 3 => Fetch keywords, 2 => Fetch both"],
"ffi_keyword_denylist" => ["type" => "text", "comment" => ""], "ffi_keyword_denylist" => ["type" => "text", "comment" => ""],
"subhub" => ["type" => "boolean", "comment" => ""], "subhub" => ["type" => "boolean", "comment" => ""],
"hub-verify" => ["type" => "varbinary(383)", "comment" => ""], "hub-verify" => ["type" => "varbinary(383)", "comment" => ""],

View file

@ -1333,3 +1333,19 @@ function update_1520(): int
return Update::SUCCESS; return Update::SUCCESS;
} }
/**
* user-contact.remote_self was wrongly declared as boolean, possibly truncating integer values from contact.remote_self
*
* @return int
* @throws Exception
*/
function update_1524(): int
{
$contacts = DBA::select('contact', ['uid', 'uri-id', 'remote_self'], ["`uid` != ?", 0]);
while ($contact = DBA::fetch($contacts)) {
Contact\User::insertForContactArray($contact);
}
return Update::SUCCESS;
}