Merge pull request #9586 from annando/inbox-status
Don't transmit to archived inboxes
This commit is contained in:
commit
1342825401
8 changed files with 73 additions and 21 deletions
|
@ -1,6 +1,6 @@
|
||||||
-- ------------------------------------------
|
-- ------------------------------------------
|
||||||
-- Friendica 2020.12-dev (Red Hot Poker)
|
-- Friendica 2020.12-dev (Red Hot Poker)
|
||||||
-- DB_UPDATE_VERSION 1378
|
-- DB_UPDATE_VERSION 1379
|
||||||
-- ------------------------------------------
|
-- ------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@ -332,6 +332,7 @@ CREATE TABLE IF NOT EXISTS `apcontact` (
|
||||||
INDEX `alias` (`alias`(190)),
|
INDEX `alias` (`alias`(190)),
|
||||||
INDEX `followers` (`followers`(190)),
|
INDEX `followers` (`followers`(190)),
|
||||||
INDEX `baseurl` (`baseurl`(190)),
|
INDEX `baseurl` (`baseurl`(190)),
|
||||||
|
INDEX `sharedinbox` (`sharedinbox`(190)),
|
||||||
INDEX `gsid` (`gsid`),
|
INDEX `gsid` (`gsid`),
|
||||||
FOREIGN KEY (`gsid`) REFERENCES `gserver` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
|
FOREIGN KEY (`gsid`) REFERENCES `gserver` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='ActivityPub compatible contacts - used in the ActivityPub implementation';
|
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='ActivityPub compatible contacts - used in the ActivityPub implementation';
|
||||||
|
@ -1057,7 +1058,7 @@ CREATE TABLE IF NOT EXISTS `photo` (
|
||||||
INDEX `uid_album_scale_created` (`uid`,`album`(32),`scale`,`created`),
|
INDEX `uid_album_scale_created` (`uid`,`album`(32),`scale`,`created`),
|
||||||
INDEX `uid_album_resource-id_created` (`uid`,`album`(32),`resource-id`,`created`),
|
INDEX `uid_album_resource-id_created` (`uid`,`album`(32),`resource-id`,`created`),
|
||||||
INDEX `resource-id` (`resource-id`),
|
INDEX `resource-id` (`resource-id`),
|
||||||
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
||||||
FOREIGN KEY (`contact-id`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
|
FOREIGN KEY (`contact-id`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='photo storage';
|
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='photo storage';
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ use Friendica\Protocol\ActivityNamespace;
|
||||||
use Friendica\Protocol\ActivityPub;
|
use Friendica\Protocol\ActivityPub;
|
||||||
use Friendica\Util\Crypto;
|
use Friendica\Util\Crypto;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
|
use Friendica\Util\HTTPSignature;
|
||||||
use Friendica\Util\JsonLD;
|
use Friendica\Util\JsonLD;
|
||||||
use Friendica\Util\Network;
|
use Friendica\Util\Network;
|
||||||
|
|
||||||
|
@ -148,6 +149,7 @@ class APContact
|
||||||
|
|
||||||
$data = ActivityPub::fetchContent($url);
|
$data = ActivityPub::fetchContent($url);
|
||||||
if (empty($data)) {
|
if (empty($data)) {
|
||||||
|
self::markForArchival($fetched_contact ?: []);
|
||||||
return $fetched_contact;
|
return $fetched_contact;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,10 +352,54 @@ class APContact
|
||||||
return $apcontact;
|
return $apcontact;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the given AP Contact as "to archive"
|
||||||
|
*
|
||||||
|
* @param array $apcontact
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function markForArchival(array $apcontact)
|
||||||
|
{
|
||||||
|
if (!empty($apcontact['inbox'])) {
|
||||||
|
Logger::info('Set inbox status to failure', ['inbox' => $apcontact['inbox']]);
|
||||||
|
HTTPSignature::setInboxStatus($apcontact['inbox'], false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($apcontact['sharedinbox'])) {
|
||||||
|
// Check if there are any available inboxes
|
||||||
|
$available = DBA::exists('apcontact', ["`sharedinbox` = ? AnD `inbox` IN (SELECT `url` FROM `inbox-status` WHERE `success` > `failure`)",
|
||||||
|
$apcontact['sharedinbox']]);
|
||||||
|
if (!$available) {
|
||||||
|
// If all known personal inboxes are failing then set their shared inbox to failure as well
|
||||||
|
Logger::info('Set shared inbox status to failure', ['sharedinbox' => $apcontact['sharedinbox']]);
|
||||||
|
HTTPSignature::setInboxStatus($apcontact['sharedinbox'], false, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unmark the given AP Contact as "to archive"
|
||||||
|
*
|
||||||
|
* @param array $apcontact
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function unmarkForArchival(array $apcontact)
|
||||||
|
{
|
||||||
|
if (!empty($apcontact['inbox'])) {
|
||||||
|
Logger::info('Set inbox status to success', ['inbox' => $apcontact['inbox']]);
|
||||||
|
HTTPSignature::setInboxStatus($apcontact['inbox'], true);
|
||||||
|
}
|
||||||
|
if (!empty($apcontact['sharedinbox'])) {
|
||||||
|
Logger::info('Set shared inbox status to success', ['sharedinbox' => $apcontact['sharedinbox']]);
|
||||||
|
HTTPSignature::setInboxStatus($apcontact['sharedinbox'], true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unarchive inboxes
|
* Unarchive inboxes
|
||||||
*
|
*
|
||||||
* @param string $url inbox url
|
* @param string $url inbox url
|
||||||
|
* @param boolean $shared Shared Inbox
|
||||||
*/
|
*/
|
||||||
private static function unarchiveInbox($url, $shared)
|
private static function unarchiveInbox($url, $shared)
|
||||||
{
|
{
|
||||||
|
@ -361,15 +407,6 @@ class APContact
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$now = DateTimeFormat::utcNow();
|
HTTPSignature::setInboxStatus($url, true, $shared);
|
||||||
|
|
||||||
$fields = ['archive' => false, 'success' => $now, 'shared' => $shared];
|
|
||||||
|
|
||||||
if (!DBA::exists('inbox-status', ['url' => $url])) {
|
|
||||||
$fields = array_merge($fields, ['url' => $url, 'created' => $now]);
|
|
||||||
DBA::replace('inbox-status', $fields);
|
|
||||||
} else {
|
|
||||||
DBA::update('inbox-status', $fields, ['url' => $url]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,8 @@ class Receiver
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
APContact::unMarkForArchival($apcontact);
|
||||||
|
|
||||||
$http_signer = HTTPSignature::getSigner($body, $header);
|
$http_signer = HTTPSignature::getSigner($body, $header);
|
||||||
if (empty($http_signer)) {
|
if (empty($http_signer)) {
|
||||||
Logger::warning('Invalid HTTP signature, message will be discarded.');
|
Logger::warning('Invalid HTTP signature, message will be discarded.');
|
||||||
|
@ -233,6 +235,7 @@ class Receiver
|
||||||
|
|
||||||
$profile = APContact::getByURL($object_id);
|
$profile = APContact::getByURL($object_id);
|
||||||
if (!empty($profile['type'])) {
|
if (!empty($profile['type'])) {
|
||||||
|
APContact::unMarkForArchival($profile);
|
||||||
return 'as:' . $profile['type'];
|
return 'as:' . $profile['type'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -670,7 +670,7 @@ class Transmitter
|
||||||
*
|
*
|
||||||
* @return boolean "true" if inbox is archived
|
* @return boolean "true" if inbox is archived
|
||||||
*/
|
*/
|
||||||
private static function archivedInbox($url)
|
public static function archivedInbox($url)
|
||||||
{
|
{
|
||||||
return DBA::exists('inbox-status', ['url' => $url, 'archive' => true]);
|
return DBA::exists('inbox-status', ['url' => $url, 'archive' => true]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -314,14 +314,15 @@ class HTTPSignature
|
||||||
*
|
*
|
||||||
* @param string $url The URL of the inbox
|
* @param string $url The URL of the inbox
|
||||||
* @param boolean $success Transmission status
|
* @param boolean $success Transmission status
|
||||||
|
* @param boolean $shared The inbox is a shared inbox
|
||||||
*/
|
*/
|
||||||
static private function setInboxStatus($url, $success)
|
static public function setInboxStatus($url, $success, $shared = false)
|
||||||
{
|
{
|
||||||
$now = DateTimeFormat::utcNow();
|
$now = DateTimeFormat::utcNow();
|
||||||
|
|
||||||
$status = DBA::selectFirst('inbox-status', [], ['url' => $url]);
|
$status = DBA::selectFirst('inbox-status', [], ['url' => $url]);
|
||||||
if (!DBA::isResult($status)) {
|
if (!DBA::isResult($status)) {
|
||||||
DBA::insert('inbox-status', ['url' => $url, 'created' => $now]);
|
DBA::insert('inbox-status', ['url' => $url, 'created' => $now, 'shared' => $shared]);
|
||||||
$status = DBA::selectFirst('inbox-status', [], ['url' => $url]);
|
$status = DBA::selectFirst('inbox-status', [], ['url' => $url]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,16 @@ class APDelivery
|
||||||
*/
|
*/
|
||||||
public static function execute($cmd, $target_id, $inbox, $uid)
|
public static function execute($cmd, $target_id, $inbox, $uid)
|
||||||
{
|
{
|
||||||
Logger::log('Invoked: ' . $cmd . ': ' . $target_id . ' to ' . $inbox, Logger::DEBUG);
|
if (ActivityPub\Transmitter::archivedInbox($inbox)) {
|
||||||
|
Logger::info('Inbox is archived', ['cmd' => $cmd, 'inbox' => $inbox, 'id' => $target_id, 'uid' => $uid]);
|
||||||
|
if (in_array($cmd, [Delivery::POST])) {
|
||||||
|
$item = Item::selectFirst(['uri-id'], ['id' => $target_id]);
|
||||||
|
Post\DeliveryData::incrementQueueFailed($item['uri-id'] ?? 0);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::info('Invoked', ['cmd' => $cmd, 'inbox' => $inbox, 'id' => $target_id, 'uid' => $uid]);
|
||||||
|
|
||||||
$success = true;
|
$success = true;
|
||||||
|
|
||||||
|
|
|
@ -193,9 +193,9 @@ class Delivery
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't deliver our items to blocked or pending contacts, and not to ourselves either
|
// We don't deliver our items to blocked, archived or pending contacts, and not to ourselves either
|
||||||
$contact = DBA::selectFirst('contact', [],
|
$contact = DBA::selectFirst('contact', [],
|
||||||
['id' => $contact_id, 'blocked' => false, 'pending' => false, 'self' => false]
|
['id' => $contact_id, 'archive' => false, 'blocked' => false, 'pending' => false, 'self' => false]
|
||||||
);
|
);
|
||||||
if (!DBA::isResult($contact)) {
|
if (!DBA::isResult($contact)) {
|
||||||
self::setFailedQueue($cmd, $target_item);
|
self::setFailedQueue($cmd, $target_item);
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
|
|
||||||
if (!defined('DB_UPDATE_VERSION')) {
|
if (!defined('DB_UPDATE_VERSION')) {
|
||||||
define('DB_UPDATE_VERSION', 1378);
|
define('DB_UPDATE_VERSION', 1379);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
@ -395,6 +395,7 @@ return [
|
||||||
"alias" => ["alias(190)"],
|
"alias" => ["alias(190)"],
|
||||||
"followers" => ["followers(190)"],
|
"followers" => ["followers(190)"],
|
||||||
"baseurl" => ["baseurl(190)"],
|
"baseurl" => ["baseurl(190)"],
|
||||||
|
"sharedinbox" => ["sharedinbox(190)"],
|
||||||
"gsid" => ["gsid"]
|
"gsid" => ["gsid"]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
@ -1081,7 +1082,7 @@ return [
|
||||||
"comment" => "photo storage",
|
"comment" => "photo storage",
|
||||||
"fields" => [
|
"fields" => [
|
||||||
"id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"],
|
"id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"],
|
||||||
"uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "foreign" => ["user" => "uid"], "comment" => "Owner User id"],
|
"uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "foreign" => ["user" => "uid", "on delete" => "restrict"], "comment" => "Owner User id"],
|
||||||
"contact-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id", "on delete" => "restrict"], "comment" => "contact.id"],
|
"contact-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id", "on delete" => "restrict"], "comment" => "contact.id"],
|
||||||
"guid" => ["type" => "char(16)", "not null" => "1", "default" => "", "comment" => "A unique identifier for this photo"],
|
"guid" => ["type" => "char(16)", "not null" => "1", "default" => "", "comment" => "A unique identifier for this photo"],
|
||||||
"resource-id" => ["type" => "char(32)", "not null" => "1", "default" => "", "comment" => ""],
|
"resource-id" => ["type" => "char(32)", "not null" => "1", "default" => "", "comment" => ""],
|
||||||
|
|
Loading…
Reference in a new issue