Fix "redir" loop

This commit is contained in:
Michael 2019-09-23 22:13:20 +00:00
parent c0afa761ac
commit 5254147ccc
7 changed files with 93 additions and 39 deletions

View file

@ -413,7 +413,7 @@ function public_contact()
*
* @return int|bool visitor_id or false
*/
function remote_user()
function remote_user($uid = 0)
{
// You cannot be both local and remote.
// Unncommented by rabuzarus because remote authentication to local
@ -422,13 +422,22 @@ function remote_user()
// return false;
// }
if (empty($_SESSION)) {
if (empty($_SESSION['authenticated'])) {
return false;
}
if (!empty($_SESSION['authenticated']) && !empty($_SESSION['visitor_id'])) {
if (!empty($uid) && !empty($_SESSION['remote'])) {
foreach ($_SESSION['remote'] as $visitor) {
if ($visitor['uid'] == $uid) {
return $visitor['cid'];
}
}
}
if (!empty($_SESSION['visitor_id'])) {
return intval($_SESSION['visitor_id']);
}
return false;
}

View file

@ -154,17 +154,8 @@ function photos_post(App $a)
if (local_user() && (local_user() == $page_owner_uid)) {
$can_post = true;
} elseif ($community_page && remote_user()) {
$contact_id = 0;
if (!empty($_SESSION['remote']) && is_array($_SESSION['remote'])) {
foreach ($_SESSION['remote'] as $v) {
if ($v['uid'] == $page_owner_uid) {
$contact_id = $v['cid'];
break;
}
}
}
} elseif ($community_page && remote_user($page_owner_uid)) {
$contact_id = remote_user($page_owner_uid);
if ($contact_id > 0) {
if (DBA::exists('contact', ['id' => $contact_id, 'uid' => $page_owner_uid, 'blocked' => false, 'pending' => false])) {

View file

@ -15,16 +15,16 @@ function redir_init(App $a) {
$url = defaults($_GET, 'url', '');
$quiet = !empty($_GET['quiet']) ? '&quiet=1' : '';
$con_url = defaults($_GET, 'conurl', '');
if ($a->argc > 1 && intval($a->argv[1])) {
$cid = intval($a->argv[1]);
} elseif (local_user() && !empty($con_url)) {
$cid = Contact::getIdForURL($con_url, local_user());
} else {
$cid = 0;
}
// Try magic auth before the legacy stuff
redir_magic($a, $cid, $url);
if (!empty($cid)) {
$fields = ['id', 'uid', 'nurl', 'url', 'addr', 'name', 'network', 'poll', 'issued-id', 'dfrn-id', 'duplex', 'pending'];
$contact = DBA::selectFirst('contact', $fields, ['id' => $cid, 'uid' => [0, local_user()]]);
@ -140,3 +140,62 @@ function redir_init(App $a) {
notice(L10n::t('Contact not found.'));
$a->internalRedirect();
}
function redir_magic($a, $cid, $url)
{
$visitor = Profile::getMyURL();
if (!empty($visitor)) {
Logger::info('Got my url', ['visitor' => $visitor]);
}
if (empty(visitor) && remote_user()) {
$contact = DBA::selectFirst('contact', ['url'], ['id' => remote_user()]);
if (!empty($contact['url'])) {
$visitor = $contact['url'];
Logger::info('Got remote user', ['visitor' => $visitor]);
}
}
if (empty(visitor) && local_user()) {
$contact = DBA::selectFirst('contact', ['url'], ['id' => local_user()]);
if (!empty($contact['url'])) {
$visitor = $contact['url'];
Logger::info('Got local user', ['visitor' => $visitor]);
}
}
$contact = DBA::selectFirst('contact', ['url'], ['id' => $cid]);
if (!DBA::isResult($contact)) {
Logger::info('Contact not found', ['id' => $cid]);
// Shouldn't happen under normal conditions
notice(L10n::t('Contact not found.'));
if (!empty($url)) {
$a->redirect($url);
} else {
$a->internalRedirect();
}
} else {
$contact_url = $contact['url'];
$target_url = defaults($url, $contact_url);
}
$basepath = Contact::getBasepath($contact_url);
// We don't use magic auth when there is no visitor, we are on the same system or we visit our own stuff
if (empty($visitor) || Strings::compareLink($basepath, System::baseUrl()) || Strings::compareLink($contact_url, $visitor)) {
Logger::info('Redirecting without magic', ['target' => $target_url, 'visitor' => $visitor, 'contact' => $contact_url]);
$a->redirect($target_url);
}
// Test for magic auth on the target system
$serverret = Network::curl($basepath . '/magic');
if ($serverret->isSuccess()) {
$separator = strpos($target_url, '?') ? '&' : '?';
$target_url .= $separator . 'zrl=' . urlencode($visitor);
Logger::info('Redirecting with magic', ['target' => $target_url, 'visitor' => $visitor, 'contact' => $contact_url]);
$a->redirect($target_url);
} else {
Logger::info('No magic for contact', ['contact' => $contact_url]);
}
}

View file

@ -337,16 +337,9 @@ class Widget
return;
}
$cid = $zcid = 0;
$zcid = 0;
if (!empty($_SESSION['remote'])) {
foreach ($_SESSION['remote'] as $visitor) {
if ($visitor['uid'] == $profile_uid) {
$cid = $visitor['cid'];
break;
}
}
}
$cid = remote_user($profile_uid);
if (!$cid) {
if (Profile::getMyURL()) {

View file

@ -9,8 +9,10 @@ use Friendica\App;
use Friendica\Core\Session\CacheSessionHandler;
use Friendica\Core\Session\DatabaseSessionHandler;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\User;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Strings;
/**
* High-level Session service class
@ -120,6 +122,16 @@ class Session
'addr' => defaults($_SERVER, 'REMOTE_ADDR', '0.0.0.0'),
]);
$remote_contacts = DBA::select('contact', ['id', 'uid'], ['nurl' => Strings::normaliseLink($_SESSION['my_url']), 'rel' => [Contact::FOLLOWER, Contact::FRIEND]]);
while ($contact = DBA::fetch($remote_contacts)) {
if (($contact['uid'] == 0) || Contact::isBlockedByUser($contact['id'], $contact['uid'])) {
continue;
}
$_SESSION['remote'][] = ['cid' => $contact['id'], 'uid' => $contact['uid'], 'url' => $_SESSION['my_url']];
}
DBA::close($remote_contacts);
$member_since = strtotime($user_record['register_date']);
self::set('new_member', time() < ($member_since + ( 60 * 60 * 24 * 14)));

View file

@ -248,7 +248,7 @@ class Profile
*/
public static function getByNickname($nickname, $uid = 0, $profile_id = 0)
{
if (remote_user() && !empty($_SESSION['remote'])) {
if (remote_user($uid) && !empty($_SESSION['remote'])) {
foreach ($_SESSION['remote'] as $visitor) {
if ($visitor['uid'] == $uid) {
$contact = DBA::selectFirst('contact', ['profile-id'], ['id' => $visitor['cid']]);

View file

@ -33,7 +33,7 @@ class Security extends BaseObject
return true;
}
if (remote_user()) {
if (remote_user($owner)) {
// use remembered decision and avoid a DB lookup for each and every display item
// DO NOT use this function if there are going to be multiple owners
// We have a contact-id for an authenticated remote user, this block determines if the contact
@ -44,17 +44,7 @@ class Security extends BaseObject
} elseif ($verified === 1) {
return false;
} else {
$cid = 0;
if (!empty($_SESSION['remote'])) {
foreach ($_SESSION['remote'] as $visitor) {
if ($visitor['uid'] == $owner) {
$cid = $visitor['cid'];
break;
}
}
}
$cid = remote_user($owner);
if (!$cid) {
return false;
}