mirror of
https://github.com/friendica/friendica
synced 2025-04-27 11:10:12 +00:00
port hubzillas OpenWebAuth - remote authentification
This commit is contained in:
parent
5fb8c758fd
commit
1c7f4e3c63
16 changed files with 1151 additions and 41 deletions
|
@ -17,7 +17,9 @@ use Friendica\Core\System;
|
|||
use Friendica\Core\Worker;
|
||||
use Friendica\Database\DBM;
|
||||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Verify;
|
||||
use Friendica\Protocol\Diaspora;
|
||||
use Friendica\Network\Probe;
|
||||
use Friendica\Util\DateTimeFormat;
|
||||
use Friendica\Util\Network;
|
||||
use Friendica\Util\Temporal;
|
||||
|
@ -978,27 +980,137 @@ class Profile
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the 'zrl' parameter and initiate the remote authentication.
|
||||
*
|
||||
* This method checks if the visitor has a public contact entry and
|
||||
* redirects the visitor to his/her instance to start the magic auth (Authentication)
|
||||
* process.
|
||||
*
|
||||
* @param App $a Application instance.
|
||||
*/
|
||||
public static function zrlInit(App $a)
|
||||
{
|
||||
$my_url = self::getMyURL();
|
||||
$my_url = Network::isUrlValid($my_url);
|
||||
|
||||
if ($my_url) {
|
||||
// Is it a DDoS attempt?
|
||||
// The check fetches the cached value from gprobe to reduce the load for this system
|
||||
$urlparts = parse_url($my_url);
|
||||
if (!local_user()) {
|
||||
// Is it a DDoS attempt?
|
||||
// The check fetches the cached value from gprobe to reduce the load for this system
|
||||
$urlparts = parse_url($my_url);
|
||||
|
||||
$result = Cache::get('gprobe:' . $urlparts['host']);
|
||||
if ((!is_null($result)) && (in_array($result['network'], [NETWORK_FEED, NETWORK_PHANTOM]))) {
|
||||
logger('DDoS attempt detected for ' . $urlparts['host'] . ' by ' . $_SERVER['REMOTE_ADDR'] . '. server data: ' . print_r($_SERVER, true), LOGGER_DEBUG);
|
||||
return;
|
||||
$result = Cache::get('gprobe:' . $urlparts['host']);
|
||||
if ((!is_null($result)) && (in_array($result['network'], [NETWORK_FEED, NETWORK_PHANTOM]))) {
|
||||
logger('DDoS attempt detected for ' . $urlparts['host'] . ' by ' . $_SERVER['REMOTE_ADDR'] . '. server data: ' . print_r($_SERVER, true), LOGGER_DEBUG);
|
||||
return;
|
||||
}
|
||||
|
||||
Worker::add(PRIORITY_LOW, 'GProbe', $my_url);
|
||||
$arr = ['zrl' => $my_url, 'url' => $a->cmd];
|
||||
Addon::callHooks('zrl_init', $arr);
|
||||
|
||||
// Try to find the public contact entry of the visitor.
|
||||
$fields = ["id", "url"];
|
||||
$condition = ['uid' => 0, 'nurl' => normalise_link($my_url)];
|
||||
|
||||
$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);
|
||||
return;
|
||||
}
|
||||
|
||||
if (DBM::is_result($contact) && remote_user() && remote_user() === $contact['id']) {
|
||||
// The visitor is already authenticated.
|
||||
return;
|
||||
}
|
||||
|
||||
logger('Not authenticated. Invoking reverse magic-auth for ' . $my_url, LOGGER_DEBUG);
|
||||
|
||||
// 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);
|
||||
// The other instance needs to know where to redirect.
|
||||
$dest = urlencode(System::baseUrl() . "/" . $query);
|
||||
|
||||
// We need to extract the basebath from the profile url
|
||||
// to redirect the visitors '/magic' module.
|
||||
// Note: We should have the basepath of a contact also in the contact table.
|
||||
$urlarr = explode("/profile/", $contact['url']);
|
||||
$basepath = $urlarr[0];
|
||||
|
||||
if ($basepath != System::baseUrl() && !strstr($dest, '/magic') && !strstr($dest, '/rmagic')) {
|
||||
goaway($basepath . '/magic' . '?f=&owa=1&dest=' . $dest);
|
||||
}
|
||||
}
|
||||
|
||||
Worker::add(PRIORITY_LOW, 'GProbe', $my_url);
|
||||
$arr = ['zrl' => $my_url, 'url' => $a->cmd];
|
||||
Addon::callHooks('zrl_init', $arr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenWebAuth authentication.
|
||||
*
|
||||
* @param string $token
|
||||
*/
|
||||
public static function owtInit($token)
|
||||
{
|
||||
$a = get_app();
|
||||
|
||||
// Clean old verify entries.
|
||||
Verify::purge('owt', '3 MINUTE');
|
||||
|
||||
// Check if the token we got is the same one
|
||||
// we have stored in the database.
|
||||
$visitor_handle = Verify::getMeta('owt', 0, $token);
|
||||
|
||||
if($visitor_handle === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to find the public contact entry of the visitor.
|
||||
$condition = ["uid" => 0, "addr" => $visitor_handle];
|
||||
$visitor = dba::selectFirst("contact", [], $condition);
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
// Authenticate the visitor.
|
||||
$_SESSION['authenticated'] = 1;
|
||||
$_SESSION['visitor_id'] = $visitor['id'];
|
||||
$_SESSION['visitor_handle'] = $visitor['addr'];
|
||||
$_SESSION['visitor_home'] = $visitor['url'];
|
||||
|
||||
$arr = [
|
||||
'visitor' => $visitor,
|
||||
'url' => $a->query_string,
|
||||
'session' => $_SESSION
|
||||
];
|
||||
/**
|
||||
* @hooks magic_auth_success
|
||||
* Called when a magic-auth was successful.
|
||||
* * \e array \b visitor
|
||||
* * \e string \b url
|
||||
* * \e array \b session
|
||||
*/
|
||||
Addon::callHooks('magic_auth_success', $arr);
|
||||
$a->contact = $visitor;
|
||||
|
||||
info(L10n::t('OpenWebAuth: %1$s welcomes %2$s', $a->get_hostname(), $visitor['name']));
|
||||
|
||||
logger('OpenWebAuth: auth success from ' . $visitor['addr'], LOGGER_DEBUG);
|
||||
}
|
||||
|
||||
public static function zrl($s, $force = false)
|
||||
{
|
||||
if (!strlen($s)) {
|
||||
|
@ -1042,4 +1154,26 @@ class Profile
|
|||
|
||||
return $uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stip zrl parameter from a string.
|
||||
*
|
||||
* @param string $s The input string.
|
||||
* @return string The zrl.
|
||||
*/
|
||||
public static function stripZrls($s)
|
||||
{
|
||||
return preg_replace('/[\?&]zrl=(.*?)([\?&]|$)/is', '', $s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stip query parameter from a string.
|
||||
*
|
||||
* @param string $s The input string.
|
||||
* @return string The query parameter.
|
||||
*/
|
||||
public static function stripQueryParam($s, $param)
|
||||
{
|
||||
return preg_replace('/[\?&]' . $param . '=(.*?)(&|$)/ism', '$2', $s);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue