port hubzillas OpenWebAuth - use Contact::getIdForURL to query for contact entry

This commit is contained in:
rabuzarus 2018-06-19 16:15:28 +02:00
parent 9195ea26b1
commit b65e4b278b
5 changed files with 36 additions and 66 deletions

View file

@ -19,7 +19,6 @@ use Friendica\Database\DBM;
use Friendica\Model\Contact; use Friendica\Model\Contact;
use Friendica\Model\Verify; use Friendica\Model\Verify;
use Friendica\Protocol\Diaspora; use Friendica\Protocol\Diaspora;
use Friendica\Network\Probe;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\Temporal; use Friendica\Util\Temporal;
@ -1013,22 +1012,14 @@ class Profile
Addon::callHooks('zrl_init', $arr); Addon::callHooks('zrl_init', $arr);
// Try to find the public contact entry of the visitor. // Try to find the public contact entry of the visitor.
$fields = ["id", "url"]; $cid = Contact::getIdForURL($my_url);
$condition = ['uid' => 0, 'nurl' => normalise_link($my_url)]; if (!$cid) {
$contact = dba::selectFirst('contact',$fields, $condition);
// Not found? Try to probe the visitor.
if (!DBM::is_result($contact)) {
Probe::uri($my_url, '', -1, true, true);
$contact = dba::selectFirst('contact',$fields, $condition);
}
if (!DBM::is_result($contact)) {
logger('No contact record found for ' . $my_url, LOGGER_DEBUG); logger('No contact record found for ' . $my_url, LOGGER_DEBUG);
return; return;
} }
$contact = dba::selectFirst('contact',['id', 'url'], ['id' => $cid]);
if (DBM::is_result($contact) && remote_user() && remote_user() === $contact['id']) { if (DBM::is_result($contact) && remote_user() && remote_user() === $contact['id']) {
// The visitor is already authenticated. // The visitor is already authenticated.
return; return;
@ -1039,12 +1030,12 @@ class Profile
// Try to avoid recursion - but send them home to do a proper magic auth. // Try to avoid recursion - but send them home to do a proper magic auth.
$query = str_replace(array('?zrl=', '&zid='), array('?rzrl=', '&rzrl='), $a->query_string); $query = str_replace(array('?zrl=', '&zid='), array('?rzrl=', '&rzrl='), $a->query_string);
// The other instance needs to know where to redirect. // The other instance needs to know where to redirect.
$dest = urlencode(System::baseUrl() . "/" . $query); $dest = urlencode(System::baseUrl() . '/' . $query);
// We need to extract the basebath from the profile url // We need to extract the basebath from the profile url
// to redirect the visitors '/magic' module. // to redirect the visitors '/magic' module.
// Note: We should have the basepath of a contact also in the contact table. // Note: We should have the basepath of a contact also in the contact table.
$urlarr = explode("/profile/", $contact['url']); $urlarr = explode('/profile/', $contact['url']);
$basepath = $urlarr[0]; $basepath = $urlarr[0];
if ($basepath != System::baseUrl() && !strstr($dest, '/magic') && !strstr($dest, '/rmagic')) { if ($basepath != System::baseUrl() && !strstr($dest, '/magic') && !strstr($dest, '/rmagic')) {
@ -1077,18 +1068,14 @@ class Profile
} }
// Try to find the public contact entry of the visitor. // Try to find the public contact entry of the visitor.
$condition = ["uid" => 0, "addr" => $visitor_handle]; $cid = Contact::getIdForURL($visitor_handle);
$visitor = dba::selectFirst("contact", [], $condition); if(!$cid) {
if (!DBM::is_result($visitor)) {
Probe::uri($visitor_handle, '', -1, true, true);
$visitor = dba::selectFirst("contact", [], $condition);
}
if(!DBM::is_result($visitor)) {
logger('owt: unable to finger ' . $visitor_handle, LOGGER_DEBUG); logger('owt: unable to finger ' . $visitor_handle, LOGGER_DEBUG);
return; return;
} }
$visitor = dba::selectFirst('contact', [], ['id' => $cid]);
// Authenticate the visitor. // Authenticate the visitor.
$_SESSION['authenticated'] = 1; $_SESSION['authenticated'] = 1;
$_SESSION['visitor_id'] = $visitor['id']; $_SESSION['visitor_id'] = $visitor['id'];
@ -1108,6 +1095,7 @@ class Profile
* * \e array \b session * * \e array \b session
*/ */
Addon::callHooks('magic_auth_success', $arr); Addon::callHooks('magic_auth_success', $arr);
$a->contact = $visitor; $a->contact = $visitor;
info(L10n::t('OpenWebAuth: %1$s welcomes %2$s', $a->get_hostname(), $visitor['name'])); info(L10n::t('OpenWebAuth: %1$s welcomes %2$s', $a->get_hostname(), $visitor['name']));

View file

@ -5,8 +5,7 @@
namespace Friendica\Module; namespace Friendica\Module;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Database\DBM; use Friendica\Model\Contact;
use Friendica\Network\Probe;
use Friendica\Util\HTTPSig; use Friendica\Util\HTTPSig;
use Friendica\Util\Network; use Friendica\Util\Network;
@ -35,32 +34,28 @@ class Magic extends BaseModule
// NOTE: I guess $dest isn't just the profile url (could be also // NOTE: I guess $dest isn't just the profile url (could be also
// other profile pages e.g. photo). We need to find a solution // other profile pages e.g. photo). We need to find a solution
// to be able to redirct to other pages than the contact profile. // to be able to redirct to other pages than the contact profile.
$fields = ["id", "nurl", "url"]; $cid = Contact::getIdForURL($dest);
$condition = ["nurl" => normalise_link($dest)];
$contact = dba::selectFirst("contact", $fields, $condition); if (!$cid && !empty($addr)) {
$cid = Contact::getIdForURL($addr);
if (!DBM::is_result($contact)) {
// If we don't have a contact record, try to probe it.
/// @todo: Also check against the $addr.
Probe::uri($dest, '', -1, true, true);
$contact = dba::selectFirst("contact", $fields, $condition);
} }
if (!DBM::is_result($contact)) { if (!$cid) {
logger("No contact record found: " . print_r($_REQUEST, true), LOGGER_DEBUG); logger('No contact record found: ' . print_r($_REQUEST, true), LOGGER_DEBUG);
goaway($dest); goaway($dest);
} }
$contact = dba::selectFirst('contact', ['id', 'nurl', 'url'], ['id' => $cid]);
// Redirect if the contact is already authenticated on this site. // Redirect if the contact is already authenticated on this site.
if (array_key_exists("id", $a->contact) && strpos($contact['nurl'], normalise_link(self::getApp()->get_baseurl())) !== false) { if (array_key_exists('id', $a->contact) && strpos($contact['nurl'], normalise_link(self::getApp()->get_baseurl())) !== false) {
if($test) { if($test) {
$ret['success'] = true; $ret['success'] = true;
$ret['message'] .= 'Local site - you are already authenticated.' . EOL; $ret['message'] .= 'Local site - you are already authenticated.' . EOL;
return $ret; return $ret;
} }
logger("Contact is already authenticated", LOGGER_DEBUG); logger('Contact is already authenticated', LOGGER_DEBUG);
goaway($dest); goaway($dest);
} }
@ -73,7 +68,7 @@ class Magic extends BaseModule
// NOTE: we need another solution because this does only work // NOTE: we need another solution because this does only work
// for friendica contacts :-/ . We should have the basepath // for friendica contacts :-/ . We should have the basepath
// of a contact also in the contact table. // of a contact also in the contact table.
$exp = explode("/profile/", $contact['url']); $exp = explode('/profile/', $contact['url']);
$basepath = $exp[0]; $basepath = $exp[0];
$headers = []; $headers = [];

View file

@ -7,9 +7,8 @@ namespace Friendica\Module;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Database\DBM; use Friendica\Database\DBM;
use Friendica\Model\Contact;
use Friendica\Model\Verify; use Friendica\Model\Verify;
use Friendica\Network\Probe;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\HTTPSig; use Friendica\Util\HTTPSig;
use dba; use dba;
@ -46,17 +45,13 @@ class Owa extends BaseModule
if ($keyId) { if ($keyId) {
// Try to find the public contact entry of the handle. // Try to find the public contact entry of the handle.
$handle = str_replace("acct:", "", $keyId); $handle = str_replace('acct:', '', $keyId);
$fields = ["id", "url", "addr", "pubkey"];
$condition = ["addr" => $handle, "uid" => 0];
$contact = dba::selectFirst("contact", $fields, $condition); $cid = Contact::getIdForURL($handle);
$fields = ['id', 'url', 'addr', 'pubkey'];
$condition = ['id' => $cid];
// Not found? Try to probe with the handle. $contact = dba::selectFirst('contact', $fields, $condition);
if(!DBM::is_result($contact)) {
Probe::uri($handle, '', -1, true, true);
$contact = dba::selectFirst("contact", $fields, $condition);
}
if (DBM::is_result($contact)) { if (DBM::is_result($contact)) {
// Try to verify the signed header with the public key of the contact record // Try to verify the signed header with the public key of the contact record

View file

@ -311,11 +311,10 @@ class Probe
* @param string $network Test for this specific network * @param string $network Test for this specific network
* @param integer $uid User ID for the probe (only used for mails) * @param integer $uid User ID for the probe (only used for mails)
* @param boolean $cache Use cached values? * @param boolean $cache Use cached values?
* @param boolean $insert Insert the contact into the contact table.
* *
* @return array uri data * @return array uri data
*/ */
public static function uri($uri, $network = "", $uid = -1, $cache = true, $insert = false) public static function uri($uri, $network = "", $uid = -1, $cache = true)
{ {
if ($cache) { if ($cache) {
$result = Cache::get("Probe::uri:".$network.":".$uri); $result = Cache::get("Probe::uri:".$network.":".$uri);
@ -464,19 +463,11 @@ class Probe
$condition = ['nurl' => normalise_link($data["url"]), 'self' => false, 'uid' => 0]; $condition = ['nurl' => normalise_link($data["url"]), 'self' => false, 'uid' => 0];
// "$old_fields" will return a "false" when the contact doesn't exist. // "$old_fields" will return a "false" when the contact doesn't exist.
// This won't trigger an insert except $insert is set to true. // This won't trigger an insert. This is intended, since we only need
// This is intended, since we only need public contacts // public contacts for everyone we store items from.
// for everyone we store items from. We don't need to store // We don't need to store every contact on the planet.
// every contact on the planet.
$old_fields = dba::selectFirst('contact', $fieldnames, $condition); $old_fields = dba::selectFirst('contact', $fieldnames, $condition);
// When the contact doesn't exist, the value "true" will trigger an insert
if (!$old_fields && $insert) {
$old_fields = true;
$fields['blocked'] = false;
$fields['pending'] = false;
}
$fields['name-date'] = DateTimeFormat::utcNow(); $fields['name-date'] = DateTimeFormat::utcNow();
$fields['uri-date'] = DateTimeFormat::utcNow(); $fields['uri-date'] = DateTimeFormat::utcNow();
$fields['success_update'] = DateTimeFormat::utcNow(); $fields['success_update'] = DateTimeFormat::utcNow();

View file

@ -26,9 +26,10 @@ class HTTPSig
* *
* @see https://tools.ietf.org/html/rfc5843 * @see https://tools.ietf.org/html/rfc5843
* *
* @param string $body The value to create the digest for * @param string $body The value to create the digest for
* @param boolean $set (optional, default true) * @param boolean $set (optional, default true)
* If set send a Digest HTTP header * If set send a Digest HTTP header
*
* @return string The generated digest of $body * @return string The generated digest of $body
*/ */
public static function generateDigest($body, $set = true) public static function generateDigest($body, $set = true)
@ -119,7 +120,7 @@ class HTTPSig
$algorithm = 'sha512'; $algorithm = 'sha512';
} }
if ($key && function_exists($key)) { /// @todo What function do we check for - maybe we check now for a method !!! if ($key && function_exists($key)) {
$result['signer'] = $sig_block['keyId']; $result['signer'] = $sig_block['keyId'];
$key = $key($sig_block['keyId']); $key = $key($sig_block['keyId']);
} }