Merge pull request #5974 from annando/ap-receiver
AP: Transmitting and receiving with non AP contacts
This commit is contained in:
commit
ec9f1563f9
2
boot.php
2
boot.php
|
@ -41,7 +41,7 @@ define('FRIENDICA_PLATFORM', 'Friendica');
|
||||||
define('FRIENDICA_CODENAME', 'The Tazmans Flax-lily');
|
define('FRIENDICA_CODENAME', 'The Tazmans Flax-lily');
|
||||||
define('FRIENDICA_VERSION', '2018.12-dev');
|
define('FRIENDICA_VERSION', '2018.12-dev');
|
||||||
define('DFRN_PROTOCOL_VERSION', '2.23');
|
define('DFRN_PROTOCOL_VERSION', '2.23');
|
||||||
define('DB_UPDATE_VERSION', 1288);
|
define('DB_UPDATE_VERSION', 1289);
|
||||||
define('NEW_UPDATE_ROUTINE_VERSION', 1170);
|
define('NEW_UPDATE_ROUTINE_VERSION', 1170);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
"indexes": {
|
"indexes": {
|
||||||
"PRIMARY": ["url"],
|
"PRIMARY": ["url"],
|
||||||
"addr": ["addr(32)"],
|
"addr": ["addr(32)"],
|
||||||
|
"alias": ["alias(190)"],
|
||||||
"url": ["followers(190)"]
|
"url": ["followers(190)"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -419,8 +419,9 @@ class Receiver
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array($receiver, [$followers, self::PUBLIC_COLLECTION]) && !empty($actor)) {
|
if (in_array($receiver, [$followers, self::PUBLIC_COLLECTION]) && !empty($actor)) {
|
||||||
|
$networks = [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS];
|
||||||
$condition = ['nurl' => normalise_link($actor), 'rel' => [Contact::SHARING, Contact::FRIEND],
|
$condition = ['nurl' => normalise_link($actor), 'rel' => [Contact::SHARING, Contact::FRIEND],
|
||||||
'network' => Protocol::ACTIVITYPUB, 'archive' => false, 'pending' => false];
|
'network' => $networks, 'archive' => false, 'pending' => false];
|
||||||
$contacts = DBA::select('contact', ['uid'], $condition);
|
$contacts = DBA::select('contact', ['uid'], $condition);
|
||||||
while ($contact = DBA::fetch($contacts)) {
|
while ($contact = DBA::fetch($contacts)) {
|
||||||
if ($contact['uid'] != 0) {
|
if ($contact['uid'] != 0) {
|
||||||
|
|
|
@ -308,6 +308,12 @@ class Transmitter
|
||||||
*/
|
*/
|
||||||
private static function createPermissionBlockForItem($item)
|
private static function createPermissionBlockForItem($item)
|
||||||
{
|
{
|
||||||
|
// Will be activated in a later step
|
||||||
|
// $networks = [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS];
|
||||||
|
|
||||||
|
// For now only send to these contacts:
|
||||||
|
$networks = [Protocol::ACTIVITYPUB, Protocol::OSTATUS];
|
||||||
|
|
||||||
$data = ['to' => [], 'cc' => []];
|
$data = ['to' => [], 'cc' => []];
|
||||||
|
|
||||||
$data = array_merge($data, self::fetchPermissionBlockFromConversation($item));
|
$data = array_merge($data, self::fetchPermissionBlockFromConversation($item));
|
||||||
|
@ -316,8 +322,6 @@ class Transmitter
|
||||||
|
|
||||||
$terms = Term::tagArrayFromItemId($item['id'], TERM_MENTION);
|
$terms = Term::tagArrayFromItemId($item['id'], TERM_MENTION);
|
||||||
|
|
||||||
$contacts[$item['author-link']] = $item['author-link'];
|
|
||||||
|
|
||||||
if (!$item['private']) {
|
if (!$item['private']) {
|
||||||
$data['to'][] = ActivityPub::PUBLIC_COLLECTION;
|
$data['to'][] = ActivityPub::PUBLIC_COLLECTION;
|
||||||
if (!empty($actor_profile['followers'])) {
|
if (!empty($actor_profile['followers'])) {
|
||||||
|
@ -326,13 +330,8 @@ class Transmitter
|
||||||
|
|
||||||
foreach ($terms as $term) {
|
foreach ($terms as $term) {
|
||||||
$profile = APContact::getByURL($term['url'], false);
|
$profile = APContact::getByURL($term['url'], false);
|
||||||
if (!empty($profile) && empty($contacts[$profile['url']])) {
|
if (!empty($profile)) {
|
||||||
$data['to'][] = $profile['url'];
|
$data['to'][] = $profile['url'];
|
||||||
$contacts[$profile['url']] = $profile['url'];
|
|
||||||
|
|
||||||
if (($key = array_search($profile['url'], $data['cc'])) !== false) {
|
|
||||||
unset($data['cc'][$key]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -343,21 +342,17 @@ class Transmitter
|
||||||
foreach ($terms as $term) {
|
foreach ($terms as $term) {
|
||||||
$cid = Contact::getIdForURL($term['url'], $item['uid']);
|
$cid = Contact::getIdForURL($term['url'], $item['uid']);
|
||||||
if (!empty($cid) && in_array($cid, $receiver_list)) {
|
if (!empty($cid) && in_array($cid, $receiver_list)) {
|
||||||
$contact = DBA::selectFirst('contact', ['url'], ['id' => $cid, 'network' => Protocol::ACTIVITYPUB]);
|
$contact = DBA::selectFirst('contact', ['url'], ['id' => $cid, 'network' => $networks]);
|
||||||
$data['to'][] = $contact['url'];
|
if (DBA::isResult($contact) && !empty($profile = APContact::getByURL($contact['url'], false))) {
|
||||||
$contacts[$contact['url']] = $contact['url'];
|
$data['to'][] = $profile['url'];
|
||||||
|
|
||||||
if (($key = array_search($profile['url'], $data['cc'])) !== false) {
|
|
||||||
unset($data['cc'][$key]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($receiver_list as $receiver) {
|
foreach ($receiver_list as $receiver) {
|
||||||
$contact = DBA::selectFirst('contact', ['url'], ['id' => $receiver, 'network' => Protocol::ACTIVITYPUB]);
|
$contact = DBA::selectFirst('contact', ['url'], ['id' => $receiver, 'network' => $networks]);
|
||||||
if (DBA::isResult($contact) && empty($contacts[$contact['url']])) {
|
if (DBA::isResult($contact) && !empty($profile = APContact::getByURL($contact['url'], false))) {
|
||||||
$data['cc'][] = $contact['url'];
|
$data['cc'][] = $profile['url'];
|
||||||
$contacts[$contact['url']] = $contact['url'];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -370,32 +365,28 @@ class Transmitter
|
||||||
}
|
}
|
||||||
|
|
||||||
$profile = APContact::getByURL($parent['author-link'], false);
|
$profile = APContact::getByURL($parent['author-link'], false);
|
||||||
if (!empty($profile) && ($parent['uri'] == $item['thr-parent'])) {
|
if (!empty($profile)) {
|
||||||
$data['to'][] = $profile['url'];
|
if ($parent['uri'] == $item['thr-parent']) {
|
||||||
$contacts[$profile['url']] = $profile['url'];
|
$data['to'][] = $profile['url'];
|
||||||
|
} else {
|
||||||
if (($key = array_search($profile['url'], $data['cc'])) !== false) {
|
$data['cc'][] = $profile['url'];
|
||||||
unset($data['cc'][$key]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($profile) && empty($contacts[$profile['url']])) {
|
|
||||||
$data['cc'][] = $profile['url'];
|
|
||||||
$contacts[$profile['url']] = $profile['url'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($item['gravity'] != GRAVITY_PARENT) {
|
if ($item['gravity'] != GRAVITY_PARENT) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$profile = APContact::getByURL($parent['owner-link'], false);
|
$profile = APContact::getByURL($parent['owner-link'], false);
|
||||||
if (!empty($profile) && empty($contacts[$profile['url']])) {
|
if (!empty($profile)) {
|
||||||
$data['cc'][] = $profile['url'];
|
$data['cc'][] = $profile['url'];
|
||||||
$contacts[$profile['url']] = $profile['url'];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBA::close($parents);
|
DBA::close($parents);
|
||||||
|
|
||||||
|
$data['to'] = array_unique($data['to']);
|
||||||
|
$data['cc'] = array_unique($data['cc']);
|
||||||
|
|
||||||
if (($key = array_search($item['author-link'], $data['to'])) !== false) {
|
if (($key = array_search($item['author-link'], $data['to'])) !== false) {
|
||||||
unset($data['to'][$key]);
|
unset($data['to'][$key]);
|
||||||
}
|
}
|
||||||
|
@ -404,30 +395,50 @@ class Transmitter
|
||||||
unset($data['cc'][$key]);
|
unset($data['cc'][$key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ['to' => array_values(array_unique($data['to'])), 'cc' => array_values(array_unique($data['cc']))];
|
foreach ($data['to'] as $to) {
|
||||||
|
if (($key = array_search($to, $data['cc'])) !== false) {
|
||||||
|
unset($data['cc'][$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['to' => array_values($data['to']), 'cc' => array_values($data['cc'])];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches a list of inboxes of followers of a given user
|
* Fetches a list of inboxes of followers of a given user
|
||||||
*
|
*
|
||||||
* @param integer $uid User ID
|
* @param integer $uid User ID
|
||||||
|
* @param boolean $personal fetch personal inboxes
|
||||||
*
|
*
|
||||||
* @return array of follower inboxes
|
* @return array of follower inboxes
|
||||||
*/
|
*/
|
||||||
public static function fetchTargetInboxesforUser($uid)
|
public static function fetchTargetInboxesforUser($uid, $personal = false)
|
||||||
{
|
{
|
||||||
$inboxes = [];
|
$inboxes = [];
|
||||||
|
|
||||||
$condition = ['uid' => $uid, 'network' => Protocol::ACTIVITYPUB, 'archive' => false, 'pending' => false];
|
// Will be activated in a later step
|
||||||
|
// $networks = [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS];
|
||||||
|
|
||||||
|
// For now only send to these contacts:
|
||||||
|
$networks = [Protocol::ACTIVITYPUB, Protocol::OSTATUS];
|
||||||
|
|
||||||
|
$condition = ['uid' => $uid, 'network' => $networks, 'archive' => false, 'pending' => false];
|
||||||
|
|
||||||
if (!empty($uid)) {
|
if (!empty($uid)) {
|
||||||
$condition['rel'] = [Contact::FOLLOWER, Contact::FRIEND];
|
$condition['rel'] = [Contact::FOLLOWER, Contact::FRIEND];
|
||||||
}
|
}
|
||||||
|
|
||||||
$contacts = DBA::select('contact', ['notify', 'batch'], $condition);
|
$contacts = DBA::select('contact', ['url'], $condition);
|
||||||
while ($contact = DBA::fetch($contacts)) {
|
while ($contact = DBA::fetch($contacts)) {
|
||||||
$contact = defaults($contact, 'batch', $contact['notify']);
|
$profile = APContact::getByURL($contact['url'], false);
|
||||||
$inboxes[$contact] = $contact;
|
if (!empty($profile)) {
|
||||||
|
if (empty($profile['sharedinbox']) || $personal) {
|
||||||
|
$target = $profile['inbox'];
|
||||||
|
} else {
|
||||||
|
$target = $profile['sharedinbox'];
|
||||||
|
}
|
||||||
|
$inboxes[$target] = $target;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DBA::close($contacts);
|
DBA::close($contacts);
|
||||||
|
|
||||||
|
@ -439,10 +450,11 @@ class Transmitter
|
||||||
*
|
*
|
||||||
* @param array $item
|
* @param array $item
|
||||||
* @param integer $uid User ID
|
* @param integer $uid User ID
|
||||||
|
* @param boolean $personal fetch personal inboxes
|
||||||
*
|
*
|
||||||
* @return array with inboxes
|
* @return array with inboxes
|
||||||
*/
|
*/
|
||||||
public static function fetchTargetInboxes($item, $uid)
|
public static function fetchTargetInboxes($item, $uid, $personal = false)
|
||||||
{
|
{
|
||||||
$permissions = self::createPermissionBlockForItem($item);
|
$permissions = self::createPermissionBlockForItem($item);
|
||||||
if (empty($permissions)) {
|
if (empty($permissions)) {
|
||||||
|
@ -452,9 +464,9 @@ class Transmitter
|
||||||
$inboxes = [];
|
$inboxes = [];
|
||||||
|
|
||||||
if ($item['gravity'] == GRAVITY_ACTIVITY) {
|
if ($item['gravity'] == GRAVITY_ACTIVITY) {
|
||||||
$item_profile = APContact::getByURL($item['author-link']);
|
$item_profile = APContact::getByURL($item['author-link'], false);
|
||||||
} else {
|
} else {
|
||||||
$item_profile = APContact::getByURL($item['owner-link']);
|
$item_profile = APContact::getByURL($item['owner-link'], false);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (['to', 'cc', 'bto', 'bcc'] as $element) {
|
foreach (['to', 'cc', 'bto', 'bcc'] as $element) {
|
||||||
|
@ -464,11 +476,15 @@ class Transmitter
|
||||||
|
|
||||||
foreach ($permissions[$element] as $receiver) {
|
foreach ($permissions[$element] as $receiver) {
|
||||||
if ($receiver == $item_profile['followers']) {
|
if ($receiver == $item_profile['followers']) {
|
||||||
$inboxes = self::fetchTargetInboxesforUser($uid);
|
$inboxes = self::fetchTargetInboxesforUser($uid, $personal);
|
||||||
} else {
|
} else {
|
||||||
$profile = APContact::getByURL($receiver);
|
$profile = APContact::getByURL($receiver, false);
|
||||||
if (!empty($profile)) {
|
if (!empty($profile)) {
|
||||||
$target = defaults($profile, 'sharedinbox', $profile['inbox']);
|
if (empty($profile['sharedinbox']) || $personal) {
|
||||||
|
$target = $profile['inbox'];
|
||||||
|
} else {
|
||||||
|
$target = $profile['sharedinbox'];
|
||||||
|
}
|
||||||
$inboxes[$target] = $target;
|
$inboxes[$target] = $target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -512,6 +512,7 @@ class Notifier
|
||||||
private static function activityPubDelivery($a, $cmd, $item_id, $uid, $target_item, $parent)
|
private static function activityPubDelivery($a, $cmd, $item_id, $uid, $target_item, $parent)
|
||||||
{
|
{
|
||||||
$inboxes = [];
|
$inboxes = [];
|
||||||
|
$personal = false;
|
||||||
|
|
||||||
if ($target_item['origin']) {
|
if ($target_item['origin']) {
|
||||||
$inboxes = ActivityPub\Transmitter::fetchTargetInboxes($target_item, $uid);
|
$inboxes = ActivityPub\Transmitter::fetchTargetInboxes($target_item, $uid);
|
||||||
|
@ -520,11 +521,14 @@ class Notifier
|
||||||
logger('Remote item ' . $item_id . ' with URL ' . $target_item['uri'] . ' is no AP post. It will not be distributed.', LOGGER_DEBUG);
|
logger('Remote item ' . $item_id . ' with URL ' . $target_item['uri'] . ' is no AP post. It will not be distributed.', LOGGER_DEBUG);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
// Remote items are transmitted via the personal inboxes.
|
||||||
|
// Doing so ensures that the dedicated receiver will get the message.
|
||||||
|
$personal = true;
|
||||||
logger('Remote item ' . $item_id . ' with URL ' . $target_item['uri'] . ' will be distributed.', LOGGER_DEBUG);
|
logger('Remote item ' . $item_id . ' with URL ' . $target_item['uri'] . ' will be distributed.', LOGGER_DEBUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($parent['origin']) {
|
if ($parent['origin']) {
|
||||||
$parent_inboxes = ActivityPub\Transmitter::fetchTargetInboxes($parent, $uid);
|
$parent_inboxes = ActivityPub\Transmitter::fetchTargetInboxes($parent, $uid, $personal);
|
||||||
$inboxes = array_merge($inboxes, $parent_inboxes);
|
$inboxes = array_merge($inboxes, $parent_inboxes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue