Enable multi-auth in dfrn autoRedir

Update checks to account for a user being authenticated to multiple
contacts on the local server at the same time.
It was also necessary to remove a looping procection to make this work
correcly with browsers that open multiple connections because the
information about what contacts are authenticated is stored in the PHP
session.
This commit is contained in:
Dean Townsley 2019-06-22 12:34:54 -05:00
parent b5e195b415
commit 042fcfeb50

View file

@ -2899,7 +2899,12 @@ class DFRN
{
// prevent looping
if (!empty($_REQUEST['redir'])) {
return;
Logger::log('autoRedir might be looping because is redir', Logger::DEBUG);
// looping prevention also appears to sometimes prevent authentication for images
// because browser may have multiple connections open and load an image on a connection
// whose session wasn't updated when a previous redirect authenticated
// Leaving commented in case looping reappears
//return;
}
if ((! $contact_nick) || ($contact_nick === $a->user['nickname'])) {
@ -2923,6 +2928,9 @@ class DFRN
$baseurl = substr($baseurl, $domain_st + 3);
$nurl = Strings::normaliseLink($baseurl);
$r = DBA::selectFirst("user", ["uid"], ["nickname" => DBA::escape($contact_nick)], []);
$contact_uid = $r["uid"];
/// @todo Why is there a query for "url" *and* "nurl"? Especially this normalising is strange.
$r = q("SELECT `id` FROM `contact` WHERE `uid` = (SELECT `uid` FROM `user` WHERE `nickname` = '%s' LIMIT 1)
AND `nick` = '%s' AND NOT `self` AND (`url` LIKE '%%%s%%' OR `nurl` LIKE '%%%s%%') AND NOT `blocked` AND NOT `pending` LIMIT 1",
@ -2931,9 +2939,18 @@ class DFRN
DBA::escape($baseurl),
DBA::escape($nurl)
);
if ((! DBA::isResult($r)) || $r[0]['id'] == remote_user()) {
if ((! DBA::isResult($r))) {
return;
}
// test if redirect authentication already succeeded
// Note that "contact" in the sense used in $contact_nick and the sense in the $remote[]["cid"]
// in the session are opposite. In the session variable the user currently fetching is the contact
// while $contact_nick is the nick of tho user who owns the stuff being fetched.
foreach (\Friendica\Core\Session::get('remote', []) as $visitor) {
if ($visitor['uid'] == $contact_uid && $visitor['cid'] == $r[0]['id']) {
return;
}
}
$r = q("SELECT * FROM contact WHERE nick = '%s'
AND network = '%s' AND uid = %d AND url LIKE '%%%s%%' LIMIT 1",