aboutsummaryrefslogtreecommitdiffstats
path: root/include/network.php
diff options
context:
space:
mode:
authorredmatrix <git@macgirvin.com>2016-03-16 18:00:13 -0700
committerredmatrix <git@macgirvin.com>2016-03-16 18:00:13 -0700
commit38eb79705e4de252f29e56543de8a287132b488e (patch)
tree4f9a638d10820d820166778c851cf63c984fb4b3 /include/network.php
parent4188419b30ca1ceba597ad336f751f1b01d161a3 (diff)
downloadvolse-hubzilla-38eb79705e4de252f29e56543de8a287132b488e.tar.gz
volse-hubzilla-38eb79705e4de252f29e56543de8a287132b488e.tar.bz2
volse-hubzilla-38eb79705e4de252f29e56543de8a287132b488e.zip
lots of work on federated channel discovery
Diffstat (limited to 'include/network.php')
-rw-r--r--include/network.php294
1 files changed, 237 insertions, 57 deletions
diff --git a/include/network.php b/include/network.php
index 7399b4526..7d41a7eb7 100644
--- a/include/network.php
+++ b/include/network.php
@@ -1043,75 +1043,184 @@ function discover_by_url($url,$arr = null) {
}
+
+function convert_salmon_key($key) {
+
+ if(strstr($key,','))
+ $rawkey = substr($key,strpos($key,',')+1);
+ else
+ $rawkey = substr($key,5);
+
+ $key_info = explode('.',$rawkey);
+
+ $m = base64url_decode($key_info[1]);
+ $e = base64url_decode($key_info[2]);
+
+ logger('key details: ' . print_r($key_info,true), LOGGER_DEBUG);
+ $salmon_key = metopem($m,$e);
+ return $salmon_key;
+
+}
+
+
function discover_by_webbie($webbie) {
require_once('library/HTML5/Parser.php');
+ $result = array();
+ $network = null;
+ $diaspora = false;
+ $gnusoc = false;
+
+ $has_salmon = false;
+ $salmon_key = false;
+ $atom_feed = false;
+ $diaspora_base = '';
+ $diaspora_guid = '';
+ $diaspora_key = '';
+ $dfrn = false;
+
$webbie = strtolower($webbie);
$x = webfinger_rfc7033($webbie,true);
if($x && array_key_exists('links',$x) && $x['links']) {
foreach($x['links'] as $link) {
- if(array_key_exists('rel',$link) && $link['rel'] == 'http://purl.org/zot/protocol') {
- logger('discover_by_webbie: zot found for ' . $webbie, LOGGER_DEBUG);
- if(array_key_exists('zot',$x) && $x['zot']['success'])
- $i = import_xchan($x['zot']);
- else {
- $z = z_fetch_url($link['href']);
- if($z['success']) {
- $j = json_decode($z['body'],true);
- $i = import_xchan($j);
- return true;
+ if(array_key_exists('rel',$link)) {
+ if($link['rel'] == 'http://purl.org/zot/protocol') {
+ logger('discover_by_webbie: zot found for ' . $webbie, LOGGER_DEBUG);
+ if(array_key_exists('zot',$x) && $x['zot']['success'])
+ $i = import_xchan($x['zot']);
+ else {
+ $z = z_fetch_url($link['href']);
+ if($z['success']) {
+ $j = json_decode($z['body'],true);
+ $i = import_xchan($j);
+ return true;
+ }
+ }
+ }
+ if($link['rel'] == 'magic-public-key') {
+ if(substr($link['href'],0,5) === 'data:') {
+ $salmon_key = convert_salmon_key($link['href']);
}
}
+ if($link['rel'] == 'salmon') {
+ $has_salmon = true;
+ }
+ if($link['rel'] == 'http://schemas.google.com/g/2010#updates-from') {
+ $atom_feed = $link['href'];
+ }
}
}
}
- $arr = array('address' => $webbie, 'success' => false);
- call_hooks('discover_by_webbie', $arr);
+
+ logger('webfing: ' . print_r($x,true));
+
+ $arr = array('address' => $webbie, 'success' => false, 'webfinger' => $x);
+ call_hooks('discover_channel_webfinger', $arr);
if($arr['success'])
return true;
- $result = array();
- $network = null;
- $diaspora = false;
+ if($salmon_key && $has_salmon && $atom_feed) {
+
+ $gnusoc = true;
+ $addr = $x['address'];
- $diaspora_base = '';
- $diaspora_guid = '';
- $diaspora_key = '';
- $dfrn = false;
+ $m = parse_url($x['location']);
+
+ $k = z_fetch_url($atom_feed);
+ if($k['success'])
+ $feed_meta = feed_meta($k['body']);
+ if($feed_meta && $feed_meta['author']) {
+ $r = q("select * from xchan where xchan_hash = '%s' limit 1",
+ dbesc($addr)
+ );
+ if($r) {
+ $r = q("update xchan set xchan_name = '%s', xchan_network = '%s', xchan_name_date = '%s' where xchan_hash = '%s' limit 1",
+ dbesc(($feed_meta['author']['author_name']) ? $feed_meta['author']['author_name'] : $x['nickname']),
+ dbesc('gnusoc'),
+ dbesc(datetime_convert()),
+ dbesc($addr)
+ );
+ }
+ else {
- $x = old_webfinger($webbie);
- if($x) {
- logger('old_webfinger: ' . print_r($x,true));
- foreach($x as $link) {
- if($link['@attributes']['rel'] === NAMESPACE_DFRN)
- $dfrn = unamp($link['@attributes']['href']);
- if($link['@attributes']['rel'] === 'salmon')
- $notify = unamp($link['@attributes']['href']);
- if($link['@attributes']['rel'] === NAMESPACE_FEED)
- $poll = unamp($link['@attributes']['href']);
- if($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard')
- $hcard = unamp($link['@attributes']['href']);
- if($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page')
- $profile = unamp($link['@attributes']['href']);
- if($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0')
- $poco = unamp($link['@attributes']['href']);
- if($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') {
- $diaspora_base = unamp($link['@attributes']['href']);
- $diaspora = true;
+ $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_pubkey, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
+ dbesc($addr),
+ dbesc($x['location']),
+ dbesc($salmon_key),
+ dbesc($addr),
+ dbesc($x['location']),
+ dbesc(($feed_meta['author']['author_name']) ? $feed_meta['author']['author_name'] : $x['nickname']),
+ dbesc('gnusoc'),
+ dbescdate(datetime_convert())
+ );
}
- if($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') {
- $diaspora_guid = unamp($link['@attributes']['href']);
- $diaspora = true;
+
+ $r = q("select * from hubloc where hubloc_hash = '%s' limit 1",
+ dbesc($addr)
+ );
+
+ if(! $r) {
+
+ $r = q("insert into hubloc ( hubloc_guid, hubloc_hash, hubloc_addr, hubloc_network, hubloc_url, hubloc_host, hubloc_callback, hubloc_updated, hubloc_primary ) values ('%s','%s','%s','%s','%s','%s','%s','%s', 1)",
+ dbesc($x['location']),
+ dbesc($addr),
+ dbesc($addr),
+ dbesc('gnusoc'),
+ dbesc($m['scheme'] . '://' . $m['host']),
+ dbesc($m['host']),
+ dbesc($salmon),
+ dbescdate(datetime_convert())
+ );
}
- if($link['@attributes']['rel'] === 'diaspora-public-key') {
- $diaspora_key = base64_decode(unamp($link['@attributes']['href']));
- if(strstr($diaspora_key,'RSA '))
- $pubkey = rsatopem($diaspora_key);
- else
- $pubkey = $diaspora_key;
- $diaspora = true;
+ $photos = import_xchan_photo($feed_meta['author']['author_photo'],$addr);
+ $r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
+ dbescdate(datetime_convert()),
+ dbesc($photos[0]),
+ dbesc($photos[1]),
+ dbesc($photos[2]),
+ dbesc($photos[3]),
+ dbesc($addr)
+ );
+ return true;
+
+ }
+ }
+ else {
+
+ $x = old_webfinger($webbie);
+ if($x) {
+ logger('old_webfinger: ' . print_r($x,true));
+ foreach($x as $link) {
+ if($link['@attributes']['rel'] === NAMESPACE_DFRN)
+ $dfrn = unamp($link['@attributes']['href']);
+ if($link['@attributes']['rel'] === 'salmon')
+ $notify = unamp($link['@attributes']['href']);
+ if($link['@attributes']['rel'] === NAMESPACE_FEED)
+ $poll = unamp($link['@attributes']['href']);
+ if($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard')
+ $hcard = unamp($link['@attributes']['href']);
+ if($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page')
+ $profile = unamp($link['@attributes']['href']);
+ if($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0')
+ $poco = unamp($link['@attributes']['href']);
+ if($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') {
+ $diaspora_base = unamp($link['@attributes']['href']);
+ $diaspora = true;
+ }
+ if($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') {
+ $diaspora_guid = unamp($link['@attributes']['href']);
+ $diaspora = true;
+ }
+ if($link['@attributes']['rel'] === 'diaspora-public-key') {
+ $diaspora_key = base64_decode(unamp($link['@attributes']['href']));
+ if(strstr($diaspora_key,'RSA '))
+ $pubkey = rsatopem($diaspora_key);
+ else
+ $pubkey = $diaspora_key;
+ $diaspora = true;
+ }
}
}
@@ -1167,7 +1276,7 @@ function discover_by_webbie($webbie) {
}
else {
- $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_pubkey, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_instance_url, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
+ $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_pubkey, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
dbesc($addr),
dbesc($guid),
dbesc($pubkey),
@@ -1175,7 +1284,6 @@ function discover_by_webbie($webbie) {
dbesc($profile),
dbesc($vcard['fn']),
dbesc($network),
- dbesc(z_root()),
dbescdate(datetime_convert())
);
}
@@ -1199,7 +1307,7 @@ function discover_by_webbie($webbie) {
}
$photos = import_xchan_photo($vcard['photo'],$addr);
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
- dbescdate(datetime_convert('UTC','UTC',$arr['photo_updated'])),
+ dbescdate(datetime_convert()),
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
@@ -1209,7 +1317,7 @@ function discover_by_webbie($webbie) {
return true;
}
-
+ }
return false;
/*
@@ -1278,10 +1386,6 @@ LSIeXnd14lQYK/uxW/8cTFjcmddsKxeXysoQxbSa9VdDK+KkpZdgYXYrTTofXs6v+
)
*/
-
-
-
- }
}
@@ -1308,13 +1412,89 @@ function webfinger_rfc7033($webbie,$zot = false) {
$s = z_fetch_url('https://' . $rhs . '/.well-known/webfinger?f=&resource=' . $resource . (($zot) ? '&zot=1' : ''));
- if($s['success'])
+ if($s['success']) {
$j = json_decode($s['body'],true);
+
+ // We could have a number of URL aliases and webbies
+ // make an executive decision about the most likely "best" of each
+ // by comparing against some examples from known networks we're likely to encounter.
+ // Otherwise we have to store every alias that we may ever encounter and
+ // validate every URL we ever find against every possible alias
+
+ // @fixme pump.io is going to be a real bugger since it doesn't return subject or aliases
+ // or provide lookup by url
+
+ $j['address'] = find_webfinger_address($j,$rhs);
+ $j['location'] = find_webfinger_location($j,$rhs);
+ if($j['address'])
+ $j['nickname'] = substr($j['address'],0,strpos($j['address'],'@'));
+ }
else
return false;
+
return($j);
}
+function find_webfinger_address($j,$rhs) {
+ if(is_array($j) && ($j)) {
+ if(strpos($j['subject'],'acct:') !== false && strpos($j['subject'],'@' . $rhs))
+ return str_replace('acct:','',$j['subject']);
+ if($j['aliases']) {
+ foreach($j['aliases'] as $alias) {
+ if(strpos($alias,'acct:') !== false && strpos($alias,'@' . $rhs)) {
+ return str_replace('acct:','',$alias);
+ }
+ }
+ }
+ }
+ return '';
+}
+
+
+function find_webfinger_location($j,$rhs) {
+ if(is_array($j) && ($j)) {
+ if(strpos($j['subject'],'http') === 0) {
+ $x = match_webfinger_location($j['subject'],$rhs);
+ if($x)
+ return $x;
+ }
+ if($j['aliases']) {
+ foreach($j['aliases'] as $alias) {
+ if(strpos($alias,'http') === 0) {
+ $x = match_webfinger_location($alias,$rhs);
+ if($x)
+ return($x);
+ }
+ }
+ }
+ }
+ return '';
+}
+
+function match_webfinger_location($s,$h) {
+
+ // GNU-social and the older StatusNet
+ if(preg_match('|' . $h . '/user/([0-9]*?)$|',$s))
+ return $s;
+ // Redmatrix / hubzilla
+ if(preg_match('|' . $h . '/channel/|',$s))
+ return $s;
+ // Friendica
+ if(preg_match('|' . $h . '/profile/|',$s))
+ return $s;
+
+ $arr = array('test' => $s, 'host' => $h, 'success' => false);
+ call_hooks('match_webfinger_location',$arr);
+ if($arr['success'])
+ return $s;
+ return '';
+}
+
+
+
+
+
+
function old_webfinger($webbie) {