removing dfrn stuff
This commit is contained in:
parent
f36e9eada3
commit
4c1709444f
@ -1,813 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Module: dfrn_confirm
|
||||
* Purpose: Friendship acceptance for DFRN contacts
|
||||
*
|
||||
* There are two possible entry points and three scenarios.
|
||||
*
|
||||
* 1. A form was submitted by our user approving a friendship that originated elsewhere.
|
||||
* This may also be called from dfrn_request to automatically approve a friendship.
|
||||
*
|
||||
* 2. We may be the target or other side of the conversation to scenario 1, and will
|
||||
* interact with that process on our own user's behalf.
|
||||
*
|
||||
*/
|
||||
|
||||
function dfrn_confirm_post(&$a,$handsfree = null) {
|
||||
|
||||
if(is_array($handsfree)) {
|
||||
|
||||
/**
|
||||
* We were called directly from dfrn_request due to automatic friend acceptance.
|
||||
* Any $_POST parameters we may require are supplied in the $handsfree array.
|
||||
*
|
||||
*/
|
||||
|
||||
$node = $handsfree['node'];
|
||||
$a->interactive = false; // notice() becomes a no-op since nobody is there to see it
|
||||
|
||||
}
|
||||
else {
|
||||
if($a->argc > 1)
|
||||
$node = $a->argv[1];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Main entry point. Scenario 1. Our user received a friend request notification (perhaps
|
||||
* from another site) and clicked 'Approve'.
|
||||
* $POST['source_url'] is not set. If it is, it indicates Scenario 2.
|
||||
*
|
||||
* We may also have been called directly from dfrn_request ($handsfree != null) due to
|
||||
* this being a page type which supports automatic friend acceptance. That is also Scenario 1
|
||||
* since we are operating on behalf of our registered user to approve a friendship.
|
||||
*
|
||||
*/
|
||||
|
||||
if(! x($_POST,'source_url')) {
|
||||
|
||||
$uid = ((is_array($handsfree)) ? $handsfree['uid'] : local_user());
|
||||
|
||||
if(! $uid) {
|
||||
notice( t('Permission denied.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
$user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if(! $user) {
|
||||
notice( t('Profile not found.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// These data elements may come from either the friend request notification form or $handsfree array.
|
||||
|
||||
if(is_array($handsfree)) {
|
||||
logger('dfrn_confirm: Confirm in handsfree mode');
|
||||
$dfrn_id = $handsfree['dfrn_id'];
|
||||
$intro_id = $handsfree['intro_id'];
|
||||
$duplex = $handsfree['duplex'];
|
||||
$hidden = ((array_key_exists('hidden',$handsfree)) ? intval($handsfree['hidden']) : 0 );
|
||||
$activity = ((array_key_exists('activity',$handsfree)) ? intval($handsfree['activity']) : 0 );
|
||||
}
|
||||
else {
|
||||
$dfrn_id = ((x($_POST,'dfrn_id')) ? notags(trim($_POST['dfrn_id'])) : "");
|
||||
$intro_id = ((x($_POST,'intro_id')) ? intval($_POST['intro_id']) : 0 );
|
||||
$duplex = ((x($_POST,'duplex')) ? intval($_POST['duplex']) : 0 );
|
||||
$cid = ((x($_POST,'contact_id')) ? intval($_POST['contact_id']) : 0 );
|
||||
$hidden = ((x($_POST,'hidden')) ? intval($_POST['hidden']) : 0 );
|
||||
$activity = ((x($_POST,'activity')) ? intval($_POST['activity']) : 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Ensure that dfrn_id has precedence when we go to find the contact record.
|
||||
* We only want to search based on contact id if there is no dfrn_id,
|
||||
* e.g. for OStatus network followers.
|
||||
*
|
||||
*/
|
||||
|
||||
if(strlen($dfrn_id))
|
||||
$cid = 0;
|
||||
|
||||
logger('dfrn_confirm: Confirming request for dfrn_id (issued) ' . $dfrn_id);
|
||||
if($cid)
|
||||
logger('dfrn_confirm: Confirming follower with contact_id: ' . $cid);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* The other person will have been issued an ID when they first requested friendship.
|
||||
* Locate their record. At this time, their record will have both pending and blocked set to 1.
|
||||
* There won't be any dfrn_id if this is a network follower, so use the contact_id instead.
|
||||
*
|
||||
*/
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE ( ( `issued_id` != '' AND `issued_id` = '%s' ) OR ( `id` = %d AND `id` != 0 ) ) AND `uid` = %d AND `duplex` = 0 LIMIT 1",
|
||||
dbesc($dfrn_id),
|
||||
intval($cid),
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if(! count($r)) {
|
||||
logger('dfrn_confirm: Contact not found in DB.');
|
||||
notice( t('Contact not found.') . EOL );
|
||||
notice( t('This may occasionally happen if contact was requested by both persons and it has already been approved.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
$contact = $r[0];
|
||||
|
||||
$contact_id = $contact['id'];
|
||||
$relation = $contact['rel'];
|
||||
$site_pubkey = $contact['site_pubkey'];
|
||||
$dfrn_confirm = $contact['confirm'];
|
||||
$aes_allow = $contact['aes_allow'];
|
||||
|
||||
$network = ((strlen($contact['issued_id'])) ? NETWORK_DFRN : NETWORK_OSTATUS);
|
||||
|
||||
if($contact['network'])
|
||||
$network = $contact['network'];
|
||||
|
||||
if($network === NETWORK_DFRN) {
|
||||
|
||||
/**
|
||||
*
|
||||
* Generate a key pair for all further communications with this person.
|
||||
* We have a keypair for every contact, and a site key for unknown people.
|
||||
* This provides a means to carry on relationships with other people if
|
||||
* any single key is compromised. It is a robust key. We're much more
|
||||
* worried about key leakage than anybody cracking it.
|
||||
*
|
||||
*/
|
||||
require_once('include/crypto.php');
|
||||
|
||||
$res = new_keypair(4096);
|
||||
|
||||
$private_key = $res['prvkey'];
|
||||
$public_key = $res['pubkey'];
|
||||
|
||||
// Save the private key. Send them the public key.
|
||||
|
||||
$r = q("UPDATE `contact` SET `prvkey` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
dbesc($private_key),
|
||||
intval($contact_id),
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
$params = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* Per the DFRN protocol, we will verify both ends by encrypting the dfrn_id with our
|
||||
* site private key (person on the other end can decrypt it with our site public key).
|
||||
* Then encrypt our profile URL with the other person's site public key. They can decrypt
|
||||
* it with their site private key. If the decryption on the other end fails for either
|
||||
* item, it indicates tampering or key failure on at least one site and we will not be
|
||||
* able to provide a secure communication pathway.
|
||||
*
|
||||
* If other site is willing to accept full encryption, (aes_allow is 1 AND we have php5.3
|
||||
* or later) then we encrypt the personal public key we send them using AES-256-CBC and a
|
||||
* random key which is encrypted with their site public key.
|
||||
*
|
||||
*/
|
||||
|
||||
$src_aes_key = random_string();
|
||||
|
||||
$result = '';
|
||||
openssl_private_encrypt($dfrn_id,$result,$user[0]['prvkey']);
|
||||
|
||||
$params['dfrn_id'] = bin2hex($result);
|
||||
$params['public_key'] = $public_key;
|
||||
|
||||
|
||||
$my_url = $a->get_baseurl() . '/profile/' . $user[0]['nickname'];
|
||||
|
||||
openssl_public_encrypt($my_url, $params['source_url'], $site_pubkey);
|
||||
$params['source_url'] = bin2hex($params['source_url']);
|
||||
|
||||
if($aes_allow && function_exists('openssl_encrypt')) {
|
||||
openssl_public_encrypt($src_aes_key, $params['aes_key'], $site_pubkey);
|
||||
$params['aes_key'] = bin2hex($params['aes_key']);
|
||||
$params['public_key'] = bin2hex(openssl_encrypt($public_key,'AES-256-CBC',$src_aes_key));
|
||||
}
|
||||
|
||||
$params['dfrn_version'] = DFRN_PROTOCOL_VERSION ;
|
||||
if($duplex == 1)
|
||||
$params['duplex'] = 1;
|
||||
|
||||
if($user[0]['page-flags'] == PAGE_COMMUNITY)
|
||||
$params['page'] = 1;
|
||||
if($user[0]['page-flags'] == PAGE_PRVGROUP)
|
||||
$params['page'] = 2;
|
||||
|
||||
logger('dfrn_confirm: Confirm: posting data to ' . $dfrn_confirm . ': ' . print_r($params,true), LOGGER_DATA);
|
||||
|
||||
/**
|
||||
*
|
||||
* POST all this stuff to the other site.
|
||||
* Temporarily raise the network timeout to 120 seconds because the default 60
|
||||
* doesn't always give the other side quite enough time to decrypt everything.
|
||||
*
|
||||
*/
|
||||
|
||||
$a->config['system']['curl_timeout'] = 120;
|
||||
|
||||
$res = post_url($dfrn_confirm,$params);
|
||||
|
||||
logger('dfrn_confirm: Confirm: received data: ' . $res, LOGGER_DATA);
|
||||
|
||||
// Now figure out what they responded. Try to be robust if the remote site is
|
||||
// having difficulty and throwing up errors of some kind.
|
||||
|
||||
$leading_junk = substr($res,0,strpos($res,'<?xml'));
|
||||
|
||||
$res = substr($res,strpos($res,'<?xml'));
|
||||
if(! strlen($res)) {
|
||||
|
||||
// No XML at all, this exchange is messed up really bad.
|
||||
// We shouldn't proceed, because the xml parser might choke,
|
||||
// and $status is going to be zero, which indicates success.
|
||||
// We can hardly call this a success.
|
||||
|
||||
notice( t('Response from remote site was not understood.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if(strlen($leading_junk) && get_config('system','debugging')) {
|
||||
|
||||
// This might be more common. Mixed error text and some XML.
|
||||
// If we're configured for debugging, show the text. Proceed in either case.
|
||||
|
||||
notice( t('Unexpected response from remote site: ') . EOL . $leading_junk . EOL );
|
||||
}
|
||||
|
||||
$xml = parse_xml_string($res);
|
||||
$status = (int) $xml->status;
|
||||
$message = unxmlify($xml->message); // human readable text of what may have gone wrong.
|
||||
switch($status) {
|
||||
case 0:
|
||||
info( t("Confirmation completed successfully.") . EOL);
|
||||
if(strlen($message))
|
||||
notice( t('Remote site reported: ') . $message . EOL);
|
||||
break;
|
||||
case 1:
|
||||
// birthday paradox - generate new dfrn_id and fall through.
|
||||
$new_dfrn_id = random_string();
|
||||
$r = q("UPDATE contact SET `issued_id` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
dbesc($new_dfrn_id),
|
||||
intval($contact_id),
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
case 2:
|
||||
notice( t("Temporary failure. Please wait and try again.") . EOL);
|
||||
if(strlen($message))
|
||||
notice( t('Remote site reported: ') . $message . EOL);
|
||||
break;
|
||||
|
||||
|
||||
case 3:
|
||||
notice( t("Introduction failed or was revoked.") . EOL);
|
||||
if(strlen($message))
|
||||
notice( t('Remote site reported: ') . $message . EOL);
|
||||
break;
|
||||
}
|
||||
|
||||
if(($status == 0) && ($intro_id)) {
|
||||
|
||||
// Success. Delete the notification.
|
||||
|
||||
$r = q("DELETE FROM `intro` WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($intro_id),
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
if($status != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* We have now established a relationship with the other site.
|
||||
* Let's make our own personal copy of their profile photo so we don't have
|
||||
* to always load it from their site.
|
||||
*
|
||||
* We will also update the contact record with the nature and scope of the relationship.
|
||||
*
|
||||
*/
|
||||
|
||||
require_once('include/Photo.php');
|
||||
|
||||
$photos = import_profile_photo($contact['photo'],$uid,$contact_id);
|
||||
|
||||
logger('dfrn_confirm: confirm - imported photos');
|
||||
|
||||
if($network === NETWORK_DFRN) {
|
||||
|
||||
$new_relation = CONTACT_IS_FOLLOWER;
|
||||
if(($relation == CONTACT_IS_SHARING) || ($duplex))
|
||||
$new_relation = CONTACT_IS_FRIEND;
|
||||
|
||||
if(($relation == CONTACT_IS_SHARING) && ($duplex))
|
||||
$duplex = 0;
|
||||
|
||||
$r = q("UPDATE `contact` SET
|
||||
`photo` = '%s',
|
||||
`thumb` = '%s',
|
||||
`micro` = '%s',
|
||||
`rel` = %d,
|
||||
`name_date` = '%s',
|
||||
`uri_date` = '%s',
|
||||
`avatar_date` = '%s',
|
||||
`blocked` = 0,
|
||||
`pending` = 0,
|
||||
`duplex` = %d,
|
||||
`hidden` = %d,
|
||||
`network` = 'dfrn' WHERE `id` = %d LIMIT 1
|
||||
",
|
||||
dbesc($photos[0]),
|
||||
dbesc($photos[1]),
|
||||
dbesc($photos[2]),
|
||||
intval($new_relation),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
intval($duplex),
|
||||
intval($hidden),
|
||||
intval($contact_id)
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
// $network !== NETWORK_DFRN
|
||||
|
||||
$network = (($contact['network']) ? $contact['network'] : NETWORK_OSTATUS);
|
||||
$notify = (($contact['notify']) ? $contact['notify'] : '');
|
||||
$poll = (($contact['poll']) ? $contact['poll'] : '');
|
||||
|
||||
if((! $contact['notify']) || (! $contact['poll'])) {
|
||||
$arr = lrdd($contact['url']);
|
||||
if(count($arr)) {
|
||||
foreach($arr as $link) {
|
||||
if($link['@attributes']['rel'] === 'salmon')
|
||||
$notify = $link['@attributes']['href'];
|
||||
if($link['@attributes']['rel'] === NAMESPACE_FEED)
|
||||
$poll = $link['@attributes']['href'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$new_relation = $contact['rel'];
|
||||
$writable = $contact['writable'];
|
||||
|
||||
$r = q("DELETE FROM `intro` WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($intro_id),
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
|
||||
$r = q("UPDATE `contact` SET `photo` = '%s',
|
||||
`thumb` = '%s',
|
||||
`micro` = '%s',
|
||||
`name_date` = '%s',
|
||||
`uri_date` = '%s',
|
||||
`avatar_date` = '%s',
|
||||
`notify` = '%s',
|
||||
`poll` = '%s',
|
||||
`blocked` = 0,
|
||||
`pending` = 0,
|
||||
`network` = '%s',
|
||||
`writable` = %d,
|
||||
`hidden` = %d,
|
||||
`rel` = %d
|
||||
WHERE `id` = %d LIMIT 1
|
||||
",
|
||||
dbesc($photos[0]),
|
||||
dbesc($photos[1]),
|
||||
dbesc($photos[2]),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($notify),
|
||||
dbesc($poll),
|
||||
dbesc($network),
|
||||
intval($writable),
|
||||
intval($hidden),
|
||||
intval($new_relation),
|
||||
intval($contact_id)
|
||||
);
|
||||
}
|
||||
|
||||
if($r === false)
|
||||
notice( t('Unable to set contact photo.') . EOL);
|
||||
|
||||
// reload contact info
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
|
||||
intval($contact_id)
|
||||
);
|
||||
if(count($r))
|
||||
$contact = $r[0];
|
||||
else
|
||||
$contact = null;
|
||||
|
||||
|
||||
if((isset($new_relation) && $new_relation == CONTACT_IS_FRIEND)) {
|
||||
|
||||
// Send a new friend post if we are allowed to...
|
||||
|
||||
$r = q("SELECT `hide_friends` FROM `profile` WHERE `uid` = %d AND `is_default` = 1 LIMIT 1",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if((count($r)) && ($r[0]['hide_friends'] == 0) && ($activity) && (! $hidden)) {
|
||||
|
||||
require_once('include/items.php');
|
||||
|
||||
$self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if(count($self)) {
|
||||
|
||||
$arr = array();
|
||||
$arr['uri'] = $arr['parent_uri'] = item_message_id();
|
||||
$arr['uid'] = $uid;
|
||||
$arr['contact-id'] = $self[0]['id'];
|
||||
$arr['wall'] = 1;
|
||||
$arr['type'] = 'wall';
|
||||
$arr['gravity'] = 0;
|
||||
$arr['origin'] = 1;
|
||||
$arr['author-name'] = $arr['owner-name'] = $self[0]['name'];
|
||||
$arr['author-link'] = $arr['owner-link'] = $self[0]['url'];
|
||||
$arr['author-avatar'] = $arr['owner-avatar'] = $self[0]['thumb'];
|
||||
|
||||
$A = '[url=' . $self[0]['url'] . ']' . $self[0]['name'] . '[/url]';
|
||||
$APhoto = '[url=' . $self[0]['url'] . ']' . '[img]' . $self[0]['thumb'] . '[/img][/url]';
|
||||
|
||||
$B = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]';
|
||||
$BPhoto = '[url=' . $contact['url'] . ']' . '[img]' . $contact['thumb'] . '[/img][/url]';
|
||||
|
||||
$arr['verb'] = ACTIVITY_FRIEND;
|
||||
$arr['obj_type'] = ACTIVITY_OBJ_PERSON;
|
||||
$arr['body'] = sprintf( t('%1$s is now friends with %2$s'), $A, $B)."\n\n\n".$BPhoto;
|
||||
|
||||
$arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $contact['name'] . '</title>'
|
||||
. '<id>' . $contact['url'] . '/' . $contact['name'] . '</id>';
|
||||
$arr['object'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $contact['url'] . '" />' . "\n");
|
||||
$arr['object'] .= xmlify('<link rel="photo" type="image/jpeg" href="' . $contact['thumb'] . '" />' . "\n");
|
||||
$arr['object'] .= '</link></object>' . "\n";
|
||||
|
||||
|
||||
$arr['allow_cid'] = $user[0]['allow_cid'];
|
||||
$arr['allow_gid'] = $user[0]['allow_gid'];
|
||||
$arr['deny_cid'] = $user[0]['deny_cid'];
|
||||
$arr['deny_gid'] = $user[0]['deny_gid'];
|
||||
|
||||
$i = item_store($arr);
|
||||
if($i)
|
||||
proc_run('php',"include/notifier.php","activity","$i");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$g = q("select def_gid from user where uid = %d limit 1",
|
||||
intval($uid)
|
||||
);
|
||||
if($contact && $g && intval($g[0]['def_gid'])) {
|
||||
require_once('include/group.php');
|
||||
group_add_member($uid,'',$contact['id'],$g[0]['def_gid']);
|
||||
}
|
||||
|
||||
// Let's send our user to the contact editor in case they want to
|
||||
// do anything special with this new friend.
|
||||
|
||||
if($handsfree === null)
|
||||
goaway($a->get_baseurl() . '/contacts/' . intval($contact_id));
|
||||
else
|
||||
return;
|
||||
//NOTREACHED
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* End of Scenario 1. [Local confirmation of remote friend request].
|
||||
*
|
||||
* Begin Scenario 2. This is the remote response to the above scenario.
|
||||
* This will take place on the site that originally initiated the friend request.
|
||||
* In the section above where the confirming party makes a POST and
|
||||
* retrieves xml status information, they are communicating with the following code.
|
||||
*
|
||||
*/
|
||||
|
||||
if(x($_POST,'source_url')) {
|
||||
|
||||
// We are processing an external confirmation to an introduction created by our user.
|
||||
|
||||
$public_key = ((x($_POST,'public_key')) ? $_POST['public_key'] : '');
|
||||
$dfrn_id = ((x($_POST,'dfrn_id')) ? hex2bin($_POST['dfrn_id']) : '');
|
||||
$source_url = ((x($_POST,'source_url')) ? hex2bin($_POST['source_url']) : '');
|
||||
$aes_key = ((x($_POST,'aes_key')) ? $_POST['aes_key'] : '');
|
||||
$duplex = ((x($_POST,'duplex')) ? intval($_POST['duplex']) : 0 );
|
||||
$page = ((x($_POST,'page')) ? intval($_POST['page']) : 0 );
|
||||
$version_id = ((x($_POST,'dfrn_version')) ? (float) $_POST['dfrn_version'] : 2.0);
|
||||
|
||||
$forum = (($page == 1) ? 1 : 0);
|
||||
$prv = (($page == 2) ? 1 : 0);
|
||||
|
||||
logger('dfrn_confirm: requestee contacted: ' . $node);
|
||||
|
||||
logger('dfrn_confirm: request: POST=' . print_r($_POST,true), LOGGER_DATA);
|
||||
|
||||
// If $aes_key is set, both of these items require unpacking from the hex transport encoding.
|
||||
|
||||
if(x($aes_key)) {
|
||||
$aes_key = hex2bin($aes_key);
|
||||
$public_key = hex2bin($public_key);
|
||||
}
|
||||
|
||||
// Find our user's account
|
||||
|
||||
$r = q("SELECT * FROM `user` WHERE `nickname` = '%s' LIMIT 1",
|
||||
dbesc($node));
|
||||
|
||||
if(! count($r)) {
|
||||
$message = sprintf(t('No user record found for \'%s\' '), $node);
|
||||
xml_status(3,$message); // failure
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
$my_prvkey = $r[0]['prvkey'];
|
||||
$local_uid = $r[0]['uid'];
|
||||
|
||||
|
||||
if(! strstr($my_prvkey,'PRIVATE KEY')) {
|
||||
$message = t('Our site encryption key is apparently messed up.');
|
||||
xml_status(3,$message);
|
||||
}
|
||||
|
||||
// verify everything
|
||||
|
||||
$decrypted_source_url = "";
|
||||
openssl_private_decrypt($source_url,$decrypted_source_url,$my_prvkey);
|
||||
|
||||
|
||||
if(! strlen($decrypted_source_url)) {
|
||||
$message = t('Empty site URL was provided or URL could not be decrypted by us.');
|
||||
xml_status(3,$message);
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
$ret = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1",
|
||||
dbesc($decrypted_source_url),
|
||||
intval($local_uid)
|
||||
);
|
||||
if(! count($ret)) {
|
||||
if(strstr($decrypted_source_url,'http:'))
|
||||
$newurl = str_replace('http:','https:',$decrypted_source_url);
|
||||
else
|
||||
$newurl = str_replace('https:','http:',$decrypted_source_url);
|
||||
|
||||
$ret = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1",
|
||||
dbesc($newurl),
|
||||
intval($local_uid)
|
||||
);
|
||||
if(! count($ret)) {
|
||||
// this is either a bogus confirmation (?) or we deleted the original introduction.
|
||||
$message = t('Contact record was not found for you on our site.');
|
||||
xml_status(3,$message);
|
||||
return; // NOTREACHED
|
||||
}
|
||||
}
|
||||
|
||||
$relation = $ret[0]['rel'];
|
||||
|
||||
// Decrypt all this stuff we just received
|
||||
|
||||
$foreign_pubkey = $ret[0]['site_pubkey'];
|
||||
$dfrn_record = $ret[0]['id'];
|
||||
|
||||
if(! $foreign_pubkey) {
|
||||
$message = sprintf( t('Site public key not available in contact record for URL %s.'), $newurl);
|
||||
xml_status(3,$message);
|
||||
}
|
||||
|
||||
$decrypted_dfrn_id = "";
|
||||
openssl_public_decrypt($dfrn_id,$decrypted_dfrn_id,$foreign_pubkey);
|
||||
|
||||
if(strlen($aes_key)) {
|
||||
$decrypted_aes_key = "";
|
||||
openssl_private_decrypt($aes_key,$decrypted_aes_key,$my_prvkey);
|
||||
$dfrn_pubkey = openssl_decrypt($public_key,'AES-256-CBC',$decrypted_aes_key);
|
||||
}
|
||||
else {
|
||||
$dfrn_pubkey = $public_key;
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE `dfrn_id` = '%s' LIMIT 1",
|
||||
dbesc($decrypted_dfrn_id)
|
||||
);
|
||||
if(count($r)) {
|
||||
$message = t('The ID provided by your system is a duplicate on our system. It should work if you try again.');
|
||||
xml_status(1,$message); // Birthday paradox - duplicate dfrn_id
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
$r = q("UPDATE `contact` SET `dfrn_id` = '%s', `pubkey` = '%s' WHERE `id` = %d LIMIT 1",
|
||||
dbesc($decrypted_dfrn_id),
|
||||
dbesc($dfrn_pubkey),
|
||||
intval($dfrn_record)
|
||||
);
|
||||
if(! count($r)) {
|
||||
$message = t('Unable to set your contact credentials on our system.');
|
||||
xml_status(3,$message);
|
||||
}
|
||||
|
||||
// It's possible that the other person also requested friendship.
|
||||
// If it is a duplex relationship, ditch the issued_id if one exists.
|
||||
|
||||
if($duplex) {
|
||||
$r = q("UPDATE `contact` SET `issued_id` = '' WHERE `id` = %d LIMIT 1",
|
||||
intval($dfrn_record)
|
||||
);
|
||||
}
|
||||
|
||||
// We're good but now we have to scrape the profile photo and send notifications.
|
||||
|
||||
|
||||
|
||||
$r = q("SELECT `photo` FROM `contact` WHERE `id` = %d LIMIT 1",
|
||||
intval($dfrn_record));
|
||||
|
||||
if(count($r))
|
||||
$photo = $r[0]['photo'];
|
||||
else
|
||||
$photo = $a->get_baseurl() . '/images/person-175.jpg';
|
||||
|
||||
require_once("Photo.php");
|
||||
|
||||
$photos = import_profile_photo($photo,$local_uid,$dfrn_record);
|
||||
|
||||
logger('dfrn_confirm: request - photos imported');
|
||||
|
||||
$new_relation = CONTACT_IS_SHARING;
|
||||
if(($relation == CONTACT_IS_FOLLOWER) || ($duplex))
|
||||
$new_relation = CONTACT_IS_FRIEND;
|
||||
|
||||
if(($relation == CONTACT_IS_FOLLOWER) && ($duplex))
|
||||
$duplex = 0;
|
||||
|
||||
$r = q("UPDATE `contact` SET
|
||||
`photo` = '%s',
|
||||
`thumb` = '%s',
|
||||
`micro` = '%s',
|
||||
`rel` = %d,
|
||||
`name_date` = '%s',
|
||||
`uri_date` = '%s',
|
||||
`avatar_date` = '%s',
|
||||
`blocked` = 0,
|
||||
`pending` = 0,
|
||||
`duplex` = %d,
|
||||
`forum` = %d,
|
||||
`prv` = %d,
|
||||
`network` = '%s' WHERE `id` = %d LIMIT 1
|
||||
",
|
||||
dbesc($photos[0]),
|
||||
dbesc($photos[1]),
|
||||
dbesc($photos[2]),
|
||||
intval($new_relation),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
intval($duplex),
|
||||
intval($forum),
|
||||
intval($prv),
|
||||
dbesc(NETWORK_DFRN),
|
||||
intval($dfrn_record)
|
||||
);
|
||||
if($r === false) { // indicates schema is messed up or total db failure
|
||||
$message = t('Unable to update your contact profile details on our system');
|
||||
xml_status(3,$message);
|
||||
}
|
||||
|
||||
// Otherwise everything seems to have worked and we are almost done. Yay!
|
||||
// Send an email notification
|
||||
|
||||
logger('dfrn_confirm: request: info updated');
|
||||
|
||||
$r = q("SELECT `contact`.*, `user`.* FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
|
||||
WHERE `contact`.`id` = %d LIMIT 1",
|
||||
intval($dfrn_record)
|
||||
);
|
||||
|
||||
if(count($r))
|
||||
$combined = $r[0];
|
||||
|
||||
if((count($r)) && ($r[0]['notify-flags'] & NOTIFY_CONFIRM)) {
|
||||
|
||||
push_lang($r[0]['language']);
|
||||
$tpl = (($new_relation == CONTACT_IS_FRIEND)
|
||||
? get_intltext_template('friend_complete_eml.tpl')
|
||||
: get_intltext_template('intro_complete_eml.tpl'));
|
||||
|
||||
$email_tpl = replace_macros($tpl, array(
|
||||
'$sitename' => $a->config['sitename'],
|
||||
'$siteurl' => $a->get_baseurl(),
|
||||
'$username' => $r[0]['username'],
|
||||
'$email' => $r[0]['email'],
|
||||
'$fn' => $r[0]['name'],
|
||||
'$dfrn_url' => $r[0]['url'],
|
||||
'$uid' => $newuid )
|
||||
);
|
||||
|
||||
$res = mail($r[0]['email'], sprintf( t("Connection accepted at %s") , $a->config['sitename']),
|
||||
$email_tpl,
|
||||
'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n"
|
||||
. 'Content-type: text/plain; charset=UTF-8' . "\n"
|
||||
. 'Content-transfer-encoding: 8bit' );
|
||||
|
||||
if(!$res) {
|
||||
// pointless throwing an error here and confusing the person at the other end of the wire.
|
||||
}
|
||||
pop_lang();
|
||||
}
|
||||
|
||||
// Send a new friend post if we are allowed to...
|
||||
|
||||
if($page && intval(get_pconfig($local_uid,'system','post_joingroup'))) {
|
||||
$r = q("SELECT `hide_friends` FROM `profile` WHERE `uid` = %d AND `is_default` = 1 LIMIT 1",
|
||||
intval($local_uid)
|
||||
);
|
||||
|
||||
if((count($r)) && ($r[0]['hide_friends'] == 0)) {
|
||||
|
||||
require_once('include/items.php');
|
||||
|
||||
$self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1",
|
||||
intval($local_uid)
|
||||
);
|
||||
|
||||
if(count($self)) {
|
||||
|
||||
$arr = array();
|
||||
$arr['uri'] = $arr['parent_uri'] = item_message_id();
|
||||
$arr['uid'] = $local_uid;
|
||||
$arr['contact-id'] = $self[0]['id'];
|
||||
$arr['wall'] = 1;
|
||||
$arr['type'] = 'wall';
|
||||
$arr['gravity'] = 0;
|
||||
$arr['origin'] = 1;
|
||||
$arr['author-name'] = $arr['owner-name'] = $self[0]['name'];
|
||||
$arr['author-link'] = $arr['owner-link'] = $self[0]['url'];
|
||||
$arr['author-avatar'] = $arr['owner-avatar'] = $self[0]['thumb'];
|
||||
|
||||
$A = '[url=' . $self[0]['url'] . ']' . $self[0]['name'] . '[/url]';
|
||||
$APhoto = '[url=' . $self[0]['url'] . ']' . '[img]' . $self[0]['thumb'] . '[/img][/url]';
|
||||
|
||||
$B = '[url=' . $combined['url'] . ']' . $combined['name'] . '[/url]';
|
||||
$BPhoto = '[url=' . $combined['url'] . ']' . '[img]' . $combined['thumb'] . '[/img][/url]';
|
||||
|
||||
$arr['verb'] = ACTIVITY_JOIN;
|
||||
$arr['obj_type'] = ACTIVITY_OBJ_GROUP;
|
||||
$arr['body'] = sprintf( t('%1$s has joined %2$s'), $A, $B)."\n\n\n" .$BPhoto;
|
||||
$arr['object'] = '<object><type>' . ACTIVITY_OBJ_GROUP . '</type><title>' . $combined['name'] . '</title>'
|
||||
. '<id>' . $combined['url'] . '/' . $combined['name'] . '</id>';
|
||||
$arr['object'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $combined['url'] . '" />' . "\n");
|
||||
$arr['object'] .= xmlify('<link rel="photo" type="image/jpeg" href="' . $combined['thumb'] . '" />' . "\n");
|
||||
$arr['object'] .= '</link></object>' . "\n";
|
||||
|
||||
|
||||
$arr['allow_cid'] = $user[0]['allow_cid'];
|
||||
$arr['allow_gid'] = $user[0]['allow_gid'];
|
||||
$arr['deny_cid'] = $user[0]['deny_cid'];
|
||||
$arr['deny_gid'] = $user[0]['deny_gid'];
|
||||
|
||||
$i = item_store($arr);
|
||||
if($i)
|
||||
proc_run('php',"include/notifier.php","activity","$i");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
xml_status(0); // Success
|
||||
return; // NOTREACHED
|
||||
|
||||
////////////////////// End of this scenario ///////////////////////////////////////////////
|
||||
}
|
||||
|
||||
// somebody arrived here by mistake or they are fishing. Send them to the homepage.
|
||||
|
||||
goaway(z_root());
|
||||
// NOTREACHED
|
||||
|
||||
}
|
@ -1,281 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once('library/simplepie/simplepie.inc');
|
||||
require_once('include/items.php');
|
||||
require_once('include/event.php');
|
||||
|
||||
|
||||
function dfrn_notify_post(&$a) {
|
||||
|
||||
$dfrn_id = ((x($_POST,'dfrn_id')) ? notags(trim($_POST['dfrn_id'])) : '');
|
||||
$dfrn_version = ((x($_POST,'dfrn_version')) ? (float) $_POST['dfrn_version'] : 2.0);
|
||||
$challenge = ((x($_POST,'challenge')) ? notags(trim($_POST['challenge'])) : '');
|
||||
$data = ((x($_POST,'data')) ? $_POST['data'] : '');
|
||||
$key = ((x($_POST,'key')) ? $_POST['key'] : '');
|
||||
$dissolve = ((x($_POST,'dissolve')) ? intval($_POST['dissolve']) : 0);
|
||||
$perm = ((x($_POST,'perm')) ? notags(trim($_POST['perm'])) : 'r');
|
||||
$ssl_policy = ((x($_POST,'ssl_policy')) ? notags(trim($_POST['ssl_policy'])): 'none');
|
||||
$page = ((x($_POST,'page')) ? intval($_POST['page']) : 0);
|
||||
|
||||
$forum = (($page == 1) ? 1 : 0);
|
||||
$prv = (($page == 2) ? 1 : 0);
|
||||
|
||||
$writable = (-1);
|
||||
if($dfrn_version >= 2.21) {
|
||||
$writable = (($perm === 'rw') ? 1 : 0);
|
||||
}
|
||||
|
||||
$direction = (-1);
|
||||
if(strpos($dfrn_id,':') == 1) {
|
||||
$direction = intval(substr($dfrn_id,0,1));
|
||||
$dfrn_id = substr($dfrn_id,2);
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM `challenge` WHERE `dfrn_id` = '%s' AND `challenge` = '%s' LIMIT 1",
|
||||
dbesc($dfrn_id),
|
||||
dbesc($challenge)
|
||||
);
|
||||
if(! count($r)) {
|
||||
logger('dfrn_notify: could not match challenge to dfrn_id ' . $dfrn_id . ' challenge=' . $challenge);
|
||||
xml_status(3);
|
||||
}
|
||||
|
||||
$r = q("DELETE FROM `challenge` WHERE `dfrn_id` = '%s' AND `challenge` = '%s' LIMIT 1",
|
||||
dbesc($dfrn_id),
|
||||
dbesc($challenge)
|
||||
);
|
||||
|
||||
// find the local user who owns this relationship.
|
||||
|
||||
$sql_extra = '';
|
||||
switch($direction) {
|
||||
case (-1):
|
||||
$sql_extra = sprintf(" AND ( `issued_id` = '%s' OR `dfrn_id` = '%s' ) ", dbesc($dfrn_id), dbesc($dfrn_id));
|
||||
break;
|
||||
case 0:
|
||||
$sql_extra = sprintf(" AND `issued_id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
|
||||
break;
|
||||
case 1:
|
||||
$sql_extra = sprintf(" AND `dfrn_id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
|
||||
break;
|
||||
default:
|
||||
xml_status(3);
|
||||
break; // NOTREACHED
|
||||
}
|
||||
|
||||
// be careful - $importer will contain both the contact information for the contact
|
||||
// sending us the post, and also the user information for the person receiving it.
|
||||
// since they are mixed together, it is easy to get them confused.
|
||||
|
||||
$r = q("SELECT `contact`.*, `contact`.`uid` AS `importer_uid`,
|
||||
`contact`.`pubkey` AS `cpubkey`,
|
||||
`contact`.`prvkey` AS `cprvkey`,
|
||||
`contact`.`thumb` AS `thumb`,
|
||||
`contact`.`url` as `url`,
|
||||
`contact`.`name` as `senderName`,
|
||||
`user`.*
|
||||
FROM `contact`
|
||||
LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
|
||||
WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0
|
||||
AND `user`.`nickname` = '%s' AND `user`.`account_expired` = 0 $sql_extra LIMIT 1",
|
||||
dbesc($a->argv[1])
|
||||
);
|
||||
|
||||
if(! count($r)) {
|
||||
logger('dfrn_notify: contact not found for dfrn_id ' . $dfrn_id);
|
||||
xml_status(3);
|
||||
//NOTREACHED
|
||||
}
|
||||
|
||||
// $importer in this case contains the contact record for the remote contact joined with the user record of our user.
|
||||
|
||||
$importer = $r[0];
|
||||
|
||||
if((($writable != (-1)) && ($writable != $importer['writable'])) || ($importer['forum'] != $forum) || ($importer['prv'] != $prv)) {
|
||||
q("UPDATE `contact` SET `writable` = %d, forum = %d, prv = %d WHERE `id` = %d LIMIT 1",
|
||||
intval(($writable == (-1)) ? $importer['writable'] : $writable),
|
||||
intval($forum),
|
||||
intval($prv),
|
||||
intval($importer['id'])
|
||||
);
|
||||
if($writable != (-1))
|
||||
$importer['writable'] = $writable;
|
||||
$importer['forum'] = $page;
|
||||
}
|
||||
|
||||
|
||||
// if contact's ssl policy changed, update our links
|
||||
|
||||
fix_contact_ssl_policy($importer,$ssl_policy);
|
||||
|
||||
logger('dfrn_notify: received notify from ' . $importer['name'] . ' for ' . $importer['username']);
|
||||
logger('dfrn_notify: data: ' . $data, LOGGER_DATA);
|
||||
|
||||
if($dissolve == 1) {
|
||||
|
||||
/**
|
||||
* Relationship is dissolved permanently
|
||||
*/
|
||||
|
||||
require_once('include/Contact.php');
|
||||
contact_remove($importer['id']);
|
||||
logger('relationship dissolved : ' . $importer['name'] . ' dissolved ' . $importer['username']);
|
||||
xml_status(0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// If we are setup as a soapbox we aren't accepting input from this person
|
||||
|
||||
if($importer['page-flags'] == PAGE_SOAPBOX)
|
||||
xml_status(0);
|
||||
|
||||
|
||||
if(strlen($key)) {
|
||||
$rawkey = hex2bin(trim($key));
|
||||
logger('rino: md5 raw key: ' . md5($rawkey));
|
||||
$final_key = '';
|
||||
|
||||
if($dfrn_version >= 2.1) {
|
||||
if((($importer['duplex']) && strlen($importer['cprvkey'])) || (! strlen($importer['cpubkey']))) {
|
||||
openssl_private_decrypt($rawkey,$final_key,$importer['cprvkey']);
|
||||
}
|
||||
else {
|
||||
openssl_public_decrypt($rawkey,$final_key,$importer['cpubkey']);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if((($importer['duplex']) && strlen($importer['cpubkey'])) || (! strlen($importer['cprvkey']))) {
|
||||
openssl_public_decrypt($rawkey,$final_key,$importer['cpubkey']);
|
||||
}
|
||||
else {
|
||||
openssl_private_decrypt($rawkey,$final_key,$importer['cprvkey']);
|
||||
}
|
||||
}
|
||||
|
||||
logger('rino: received key : ' . $final_key);
|
||||
$data = aes_decrypt(hex2bin($data),$final_key);
|
||||
logger('rino: decrypted data: ' . $data, LOGGER_DATA);
|
||||
}
|
||||
|
||||
|
||||
$ret = local_delivery($importer,$data);
|
||||
xml_status($ret);
|
||||
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
|
||||
function dfrn_notify_content(&$a) {
|
||||
|
||||
if(x($_GET,'dfrn_id')) {
|
||||
|
||||
// initial communication from external contact, $direction is their direction.
|
||||
// If this is a duplex communication, ours will be the opposite.
|
||||
|
||||
$dfrn_id = notags(trim($_GET['dfrn_id']));
|
||||
$dfrn_version = (float) $_GET['dfrn_version'];
|
||||
|
||||
logger('dfrn_notify: new notification dfrn_id=' . $dfrn_id);
|
||||
|
||||
$direction = (-1);
|
||||
if(strpos($dfrn_id,':') == 1) {
|
||||
$direction = intval(substr($dfrn_id,0,1));
|
||||
$dfrn_id = substr($dfrn_id,2);
|
||||
}
|
||||
|
||||
$hash = random_string();
|
||||
|
||||
$status = 0;
|
||||
|
||||
$r = q("DELETE FROM `challenge` WHERE `expire` < " . intval(time()));
|
||||
|
||||
$r = q("INSERT INTO `challenge` ( `challenge`, `dfrn_id`, `expire` )
|
||||
VALUES( '%s', '%s', %d ) ",
|
||||
dbesc($hash),
|
||||
dbesc($dfrn_id),
|
||||
intval(time() + 90 )
|
||||
);
|
||||
|
||||
logger('dfrn_notify: challenge=' . $hash, LOGGER_DEBUG );
|
||||
|
||||
$sql_extra = '';
|
||||
switch($direction) {
|
||||
case (-1):
|
||||
$sql_extra = sprintf(" AND ( `issued_id` = '%s' OR `dfrn_id` = '%s' ) ", dbesc($dfrn_id), dbesc($dfrn_id));
|
||||
$my_id = $dfrn_id;
|
||||
break;
|
||||
case 0:
|
||||
$sql_extra = sprintf(" AND `issued_id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
|
||||
$my_id = '1:' . $dfrn_id;
|
||||
break;
|
||||
case 1:
|
||||
$sql_extra = sprintf(" AND `dfrn_id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
|
||||
$my_id = '0:' . $dfrn_id;
|
||||
break;
|
||||
default:
|
||||
$status = 1;
|
||||
break; // NOTREACHED
|
||||
}
|
||||
|
||||
$r = q("SELECT `contact`.*, `user`.`nickname`, `user`.`page-flags` FROM `contact` LEFT JOIN `user` ON `user`.`uid` = `contact`.`uid`
|
||||
WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0 AND `user`.`nickname` = '%s'
|
||||
AND `user`.`account_expired` = 0 $sql_extra LIMIT 1",
|
||||
dbesc($a->argv[1])
|
||||
);
|
||||
|
||||
if(! count($r))
|
||||
$status = 1;
|
||||
|
||||
$challenge = '';
|
||||
$encrypted_id = '';
|
||||
$id_str = $my_id . '.' . mt_rand(1000,9999);
|
||||
|
||||
$prv_key = trim($r[0]['prvkey']);
|
||||
$pub_key = trim($r[0]['pubkey']);
|
||||
$dplx = intval($r[0]['duplex']);
|
||||
|
||||
if((($dplx) && (strlen($prv_key))) || ((strlen($prv_key)) && (!(strlen($pub_key))))) {
|
||||
openssl_private_encrypt($hash,$challenge,$prv_key);
|
||||
openssl_private_encrypt($id_str,$encrypted_id,$prv_key);
|
||||
}
|
||||
elseif(strlen($pub_key)) {
|
||||
openssl_public_encrypt($hash,$challenge,$pub_key);
|
||||
openssl_public_encrypt($id_str,$encrypted_id,$pub_key);
|
||||
}
|
||||
else
|
||||
$status = 1;
|
||||
|
||||
$challenge = bin2hex($challenge);
|
||||
$encrypted_id = bin2hex($encrypted_id);
|
||||
|
||||
$rino = ((function_exists('mcrypt_encrypt')) ? 1 : 0);
|
||||
|
||||
$rino_enable = get_config('system','rino_encrypt');
|
||||
|
||||
if(! $rino_enable)
|
||||
$rino = 0;
|
||||
|
||||
if((($r[0]['rel']) && ($r[0]['rel'] != CONTACT_IS_SHARING)) || ($r[0]['page-flags'] == PAGE_COMMUNITY)) {
|
||||
$perm = 'rw';
|
||||
}
|
||||
else {
|
||||
$perm = 'r';
|
||||
}
|
||||
|
||||
header("Content-type: text/xml");
|
||||
|
||||
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n"
|
||||
. '<dfrn_notify>' . "\r\n"
|
||||
. "\t" . '<status>' . $status . '</status>' . "\r\n"
|
||||
. "\t" . '<dfrn_version>' . DFRN_PROTOCOL_VERSION . '</dfrn_version>' . "\r\n"
|
||||
. "\t" . '<rino>' . $rino . '</rino>' . "\r\n"
|
||||
. "\t" . '<perm>' . $perm . '</perm>' . "\r\n"
|
||||
. "\t" . '<dfrn_id>' . $encrypted_id . '</dfrn_id>' . "\r\n"
|
||||
. "\t" . '<challenge>' . $challenge . '</challenge>' . "\r\n"
|
||||
. '</dfrn_notify>' . "\r\n" ;
|
||||
|
||||
killme();
|
||||
}
|
||||
|
||||
}
|
@ -1,562 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
|
||||
require_once('include/items.php');
|
||||
require_once('include/auth.php');
|
||||
|
||||
|
||||
function dfrn_poll_init(&$a) {
|
||||
|
||||
|
||||
$dfrn_id = ((x($_GET,'dfrn_id')) ? $_GET['dfrn_id'] : '');
|
||||
$type = ((x($_GET,'type')) ? $_GET['type'] : 'data');
|
||||
$last_update = ((x($_GET,'last_update')) ? $_GET['last_update'] : '');
|
||||
$destination_url = ((x($_GET,'destination_url')) ? $_GET['destination_url'] : '');
|
||||
$challenge = ((x($_GET,'challenge')) ? $_GET['challenge'] : '');
|
||||
$sec = ((x($_GET,'sec')) ? $_GET['sec'] : '');
|
||||
$dfrn_version = ((x($_GET,'dfrn_version')) ? (float) $_GET['dfrn_version'] : 2.0);
|
||||
$perm = ((x($_GET,'perm')) ? $_GET['perm'] : 'r');
|
||||
|
||||
$direction = (-1);
|
||||
|
||||
|
||||
if(strpos($dfrn_id,':') == 1) {
|
||||
$direction = intval(substr($dfrn_id,0,1));
|
||||
$dfrn_id = substr($dfrn_id,2);
|
||||
}
|
||||
|
||||
if(($dfrn_id === '') && (! x($_POST,'dfrn_id'))) {
|
||||
if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) {
|
||||
killme();
|
||||
}
|
||||
|
||||
$user = '';
|
||||
if($a->argc > 1) {
|
||||
$r = q("SELECT `hidewall`,`nickname` FROM `user` WHERE `user`.`nickname` = '%s' LIMIT 1",
|
||||
dbesc($a->argv[1])
|
||||
);
|
||||
if((! count($r)) || (count($r) && $r[0]['hidewall']))
|
||||
killme();
|
||||
$user = $r[0]['nickname'];
|
||||
}
|
||||
|
||||
logger('dfrn_poll: public feed request from ' . $_SERVER['REMOTE_ADDR'] . ' for ' . $user);
|
||||
header("Content-type: application/atom+xml");
|
||||
echo get_feed_for($a, '', $user,$last_update);
|
||||
killme();
|
||||
}
|
||||
|
||||
if(($type === 'profile') && (! strlen($sec))) {
|
||||
|
||||
$sql_extra = '';
|
||||
switch($direction) {
|
||||
case (-1):
|
||||
$sql_extra = sprintf(" AND ( `dfrn_id` = '%s' OR `issued_id` = '%s' ) ", dbesc($dfrn_id),dbesc($dfrn_id));
|
||||
$my_id = $dfrn_id;
|
||||
break;
|
||||
case 0:
|
||||
$sql_extra = sprintf(" AND `issued_id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
|
||||
$my_id = '1:' . $dfrn_id;
|
||||
break;
|
||||
case 1:
|
||||
$sql_extra = sprintf(" AND `dfrn_id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
|
||||
$my_id = '0:' . $dfrn_id;
|
||||
break;
|
||||
default:
|
||||
goaway(z_root());
|
||||
break; // NOTREACHED
|
||||
}
|
||||
|
||||
$r = q("SELECT `contact`.*, `user`.`username`, `user`.`nickname`
|
||||
FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
|
||||
WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0
|
||||
AND `user`.`nickname` = '%s' $sql_extra LIMIT 1",
|
||||
dbesc($a->argv[1])
|
||||
);
|
||||
|
||||
if(count($r)) {
|
||||
|
||||
$s = fetch_url($r[0]['poll'] . '?dfrn_id=' . $my_id . '&type=profile-check');
|
||||
|
||||
logger("dfrn_poll: old profile returns " . $s, LOGGER_DATA);
|
||||
|
||||
if(strlen($s)) {
|
||||
|
||||
$xml = parse_xml_string($s);
|
||||
|
||||
if((int) $xml->status == 1) {
|
||||
$_SESSION['authenticated'] = 1;
|
||||
if(! x($_SESSION,'remote'))
|
||||
$_SESSION['remote'] = array();
|
||||
|
||||
$_SESSION['remote'][] = array('cid' => $r[0]['id'],'uid' => $r[0]['uid'],'url' => $r[0]['url']);
|
||||
|
||||
$_SESSION['visitor_id'] = $r[0]['id'];
|
||||
$_SESSION['visitor_home'] = $r[0]['url'];
|
||||
$_SESSION['visitor_handle'] = $r[0]['addr'];
|
||||
$_SESSION['visitor_visiting'] = $r[0]['uid'];
|
||||
info( sprintf(t('%s welcomes %s'), $r[0]['username'] , $r[0]['name']) . EOL);
|
||||
// Visitors get 1 day session.
|
||||
$session_id = session_id();
|
||||
$expire = time() + 86400;
|
||||
q("UPDATE `session` SET `expire` = '%s' WHERE `sid` = '%s' LIMIT 1",
|
||||
dbesc($expire),
|
||||
dbesc($session_id)
|
||||
);
|
||||
}
|
||||
}
|
||||
$profile = $r[0]['nickname'];
|
||||
goaway((strlen($destination_url)) ? $destination_url : $a->get_baseurl() . '/profile/' . $profile);
|
||||
}
|
||||
goaway(z_root());
|
||||
|
||||
}
|
||||
|
||||
if($type === 'profile-check' && $dfrn_version < 2.2 ) {
|
||||
|
||||
if((strlen($challenge)) && (strlen($sec))) {
|
||||
|
||||
q("DELETE FROM `profile_check` WHERE `expire` < " . intval(time()));
|
||||
$r = q("SELECT * FROM `profile_check` WHERE `sec` = '%s' ORDER BY `expire` DESC LIMIT 1",
|
||||
dbesc($sec)
|
||||
);
|
||||
if(! count($r)) {
|
||||
xml_status(3, 'No ticket');
|
||||
// NOTREACHED
|
||||
}
|
||||
$orig_id = $r[0]['dfrn_id'];
|
||||
if(strpos($orig_id, ':'))
|
||||
$orig_id = substr($orig_id,2);
|
||||
|
||||
$c = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
|
||||
intval($r[0]['cid'])
|
||||
);
|
||||
if(! count($c)) {
|
||||
xml_status(3, 'No profile');
|
||||
}
|
||||
$contact = $c[0];
|
||||
|
||||
$sent_dfrn_id = hex2bin($dfrn_id);
|
||||
$challenge = hex2bin($challenge);
|
||||
|
||||
$final_dfrn_id = '';
|
||||
|
||||
if(($contact['duplex']) && strlen($contact['prvkey'])) {
|
||||
openssl_private_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['prvkey']);
|
||||
openssl_private_decrypt($challenge,$decoded_challenge,$contact['prvkey']);
|
||||
}
|
||||
else {
|
||||
openssl_public_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['pubkey']);
|
||||
openssl_public_decrypt($challenge,$decoded_challenge,$contact['pubkey']);
|
||||
}
|
||||
|
||||
$final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
|
||||
|
||||
if(strpos($final_dfrn_id,':') == 1)
|
||||
$final_dfrn_id = substr($final_dfrn_id,2);
|
||||
|
||||
if($final_dfrn_id != $orig_id) {
|
||||
logger('profile_check: ' . $final_dfrn_id . ' != ' . $orig_id, LOGGER_DEBUG);
|
||||
// did not decode properly - cannot trust this site
|
||||
xml_status(3, 'Bad decryption');
|
||||
}
|
||||
|
||||
header("Content-type: text/xml");
|
||||
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?><dfrn_poll><status>0</status><challenge>$decoded_challenge</challenge><sec>$sec</sec></dfrn_poll>";
|
||||
killme();
|
||||
// NOTREACHED
|
||||
}
|
||||
else {
|
||||
// old protocol
|
||||
|
||||
switch($direction) {
|
||||
case 1:
|
||||
$dfrn_id = '0:' . $dfrn_id;
|
||||
break;
|
||||
case 0:
|
||||
$dfrn_id = '1:' . $dfrn_id;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
q("DELETE FROM `profile_check` WHERE `expire` < " . intval(time()));
|
||||
$r = q("SELECT * FROM `profile_check` WHERE `dfrn_id` = '%s' ORDER BY `expire` DESC",
|
||||
dbesc($dfrn_id));
|
||||
if(count($r)) {
|
||||
xml_status(1);
|
||||
return; // NOTREACHED
|
||||
}
|
||||
xml_status(0);
|
||||
return; // NOTREACHED
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function dfrn_poll_post(&$a) {
|
||||
|
||||
$dfrn_id = ((x($_POST,'dfrn_id')) ? $_POST['dfrn_id'] : '');
|
||||
$challenge = ((x($_POST,'challenge')) ? $_POST['challenge'] : '');
|
||||
$url = ((x($_POST,'url')) ? $_POST['url'] : '');
|
||||
$sec = ((x($_POST,'sec')) ? $_POST['sec'] : '');
|
||||
$ptype = ((x($_POST,'type')) ? $_POST['type'] : '');
|
||||
$dfrn_version = ((x($_POST,'dfrn_version')) ? (float) $_POST['dfrn_version'] : 2.0);
|
||||
$perm = ((x($_POST,'perm')) ? $_POST['perm'] : 'r');
|
||||
|
||||
if($ptype === 'profile-check') {
|
||||
|
||||
if((strlen($challenge)) && (strlen($sec))) {
|
||||
|
||||
logger('dfrn_poll: POST: profile-check');
|
||||
|
||||
q("DELETE FROM `profile_check` WHERE `expire` < " . intval(time()));
|
||||
$r = q("SELECT * FROM `profile_check` WHERE `sec` = '%s' ORDER BY `expire` DESC LIMIT 1",
|
||||
dbesc($sec)
|
||||
);
|
||||
if(! count($r)) {
|
||||
xml_status(3, 'No ticket');
|
||||
// NOTREACHED
|
||||
}
|
||||
$orig_id = $r[0]['dfrn_id'];
|
||||
if(strpos($orig_id, ':'))
|
||||
$orig_id = substr($orig_id,2);
|
||||
|
||||
$c = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
|
||||
intval($r[0]['cid'])
|
||||
);
|
||||
if(! count($c)) {
|
||||
xml_status(3, 'No profile');
|
||||
}
|
||||
$contact = $c[0];
|
||||
|
||||
$sent_dfrn_id = hex2bin($dfrn_id);
|
||||
$challenge = hex2bin($challenge);
|
||||
|
||||
$final_dfrn_id = '';
|
||||
|
||||
if(($contact['duplex']) && strlen($contact['prvkey'])) {
|
||||
openssl_private_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['prvkey']);
|
||||
openssl_private_decrypt($challenge,$decoded_challenge,$contact['prvkey']);
|
||||
}
|
||||
else {
|
||||
openssl_public_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['pubkey']);
|
||||
openssl_public_decrypt($challenge,$decoded_challenge,$contact['pubkey']);
|
||||
}
|
||||
|
||||
$final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
|
||||
|
||||
if(strpos($final_dfrn_id,':') == 1)
|
||||
$final_dfrn_id = substr($final_dfrn_id,2);
|
||||
|
||||
if($final_dfrn_id != $orig_id) {
|
||||
logger('profile_check: ' . $final_dfrn_id . ' != ' . $orig_id, LOGGER_DEBUG);
|
||||
// did not decode properly - cannot trust this site
|
||||
xml_status(3, 'Bad decryption');
|
||||
}
|
||||
|
||||
header("Content-type: text/xml");
|
||||
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?><dfrn_poll><status>0</status><challenge>$decoded_challenge</challenge><sec>$sec</sec></dfrn_poll>";
|
||||
killme();
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$direction = (-1);
|
||||
if(strpos($dfrn_id,':') == 1) {
|
||||
$direction = intval(substr($dfrn_id,0,1));
|
||||
$dfrn_id = substr($dfrn_id,2);
|
||||
}
|
||||
|
||||
|
||||
$r = q("SELECT * FROM `challenge` WHERE `dfrn_id` = '%s' AND `challenge` = '%s' LIMIT 1",
|
||||
dbesc($dfrn_id),
|
||||
dbesc($challenge)
|
||||
);
|
||||
|
||||
if(! count($r))
|
||||
killme();
|
||||
|
||||
$type = $r[0]['type'];
|
||||
$last_update = $r[0]['last_update'];
|
||||
|
||||
$r = q("DELETE FROM `challenge` WHERE `dfrn_id` = '%s' AND `challenge` = '%s' LIMIT 1",
|
||||
dbesc($dfrn_id),
|
||||
dbesc($challenge)
|
||||
);
|
||||
|
||||
|
||||
$sql_extra = '';
|
||||
switch($direction) {
|
||||
case (-1):
|
||||
$sql_extra = sprintf(" AND `issued_id` = '%s' ", dbesc($dfrn_id));
|
||||
$my_id = $dfrn_id;
|
||||
break;
|
||||
case 0:
|
||||
$sql_extra = sprintf(" AND `issued_id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
|
||||
$my_id = '1:' . $dfrn_id;
|
||||
break;
|
||||
case 1:
|
||||
$sql_extra = sprintf(" AND `dfrn_id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
|
||||
$my_id = '0:' . $dfrn_id;
|
||||
break;
|
||||
default:
|
||||
goaway(z_root());
|
||||
break; // NOTREACHED
|
||||
}
|
||||
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 $sql_extra LIMIT 1");
|
||||
|
||||
|
||||
if(! count($r))
|
||||
killme();
|
||||
|
||||
$contact = $r[0];
|
||||
$owner_uid = $r[0]['uid'];
|
||||
$contact_id = $r[0]['id'];
|
||||
|
||||
|
||||
if($type === 'reputation' && strlen($url)) {
|
||||
$r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1",
|
||||
dbesc($url),
|
||||
intval($owner_uid)
|
||||
);
|
||||
$reputation = 0;
|
||||
$text = '';
|
||||
|
||||
if(count($r)) {
|
||||
$reputation = $r[0]['rating'];
|
||||
$text = $r[0]['reason'];
|
||||
|
||||
if($r[0]['id'] == $contact_id) { // inquiring about own reputation not allowed
|
||||
$reputation = 0;
|
||||
$text = '';
|
||||
}
|
||||
}
|
||||
|
||||
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
|
||||
<reputation>
|
||||
<url>$url</url>
|
||||
<rating>$reputation</rating>
|
||||
<description>$text</description>
|
||||
</reputation>
|
||||
";
|
||||
killme();
|
||||
// NOTREACHED
|
||||
}
|
||||
else {
|
||||
|
||||
// Update the writable flag if it changed
|
||||
logger('dfrn_poll: post request feed: ' . print_r($_POST,true),LOGGER_DATA);
|
||||
if($dfrn_version >= 2.21) {
|
||||
if($perm === 'rw')
|
||||
$writable = 1;
|
||||
else
|
||||
$writable = 0;
|
||||
|
||||
if($writable != $contact['writable']) {
|
||||
q("UPDATE `contact` SET `writable` = %d WHERE `id` = %d LIMIT 1",
|
||||
intval($writable),
|
||||
intval($contact_id)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
header("Content-type: application/atom+xml");
|
||||
$o = get_feed_for($a,$dfrn_id, $a->argv[1], $last_update, $direction);
|
||||
echo $o;
|
||||
killme();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function dfrn_poll_content(&$a) {
|
||||
|
||||
$dfrn_id = ((x($_GET,'dfrn_id')) ? $_GET['dfrn_id'] : '');
|
||||
$type = ((x($_GET,'type')) ? $_GET['type'] : 'data');
|
||||
$last_update = ((x($_GET,'last_update')) ? $_GET['last_update'] : '');
|
||||
$destination_url = ((x($_GET,'destination_url')) ? $_GET['destination_url'] : '');
|
||||
$sec = ((x($_GET,'sec')) ? $_GET['sec'] : '');
|
||||
$dfrn_version = ((x($_GET,'dfrn_version')) ? (float) $_GET['dfrn_version'] : 2.0);
|
||||
$perm = ((x($_GET,'perm')) ? $_GET['perm'] : 'r');
|
||||
|
||||
$direction = (-1);
|
||||
if(strpos($dfrn_id,':') == 1) {
|
||||
$direction = intval(substr($dfrn_id,0,1));
|
||||
$dfrn_id = substr($dfrn_id,2);
|
||||
}
|
||||
|
||||
|
||||
if($dfrn_id != '') {
|
||||
// initial communication from external contact
|
||||
$hash = random_string();
|
||||
|
||||
$status = 0;
|
||||
|
||||
$r = q("DELETE FROM `challenge` WHERE `expire` < " . intval(time()));
|
||||
|
||||
if($type !== 'profile') {
|
||||
$r = q("INSERT INTO `challenge` ( `challenge`, `dfrn_id`, `expire` , `type`, `last_update` )
|
||||
VALUES( '%s', '%s', '%s', '%s', '%s' ) ",
|
||||
dbesc($hash),
|
||||
dbesc($dfrn_id),
|
||||
intval(time() + 60 ),
|
||||
dbesc($type),
|
||||
dbesc($last_update)
|
||||
);
|
||||
}
|
||||
$sql_extra = '';
|
||||
switch($direction) {
|
||||
case (-1):
|
||||
if($type === 'profile')
|
||||
$sql_extra = sprintf(" AND ( `dfrn_id` = '%s' OR `issued_id` = '%s' ) ", dbesc($dfrn_id),dbesc($dfrn_id));
|
||||
else
|
||||
$sql_extra = sprintf(" AND `issued_id` = '%s' ", dbesc($dfrn_id));
|
||||
$my_id = $dfrn_id;
|
||||
break;
|
||||
case 0:
|
||||
$sql_extra = sprintf(" AND `issued_id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
|
||||
$my_id = '1:' . $dfrn_id;
|
||||
break;
|
||||
case 1:
|
||||
$sql_extra = sprintf(" AND `dfrn_id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
|
||||
$my_id = '0:' . $dfrn_id;
|
||||
break;
|
||||
default:
|
||||
goaway(z_root());
|
||||
break; // NOTREACHED
|
||||
}
|
||||
|
||||
$nickname = $a->argv[1];
|
||||
|
||||
$r = q("SELECT `contact`.*, `user`.`username`, `user`.`nickname`
|
||||
FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
|
||||
WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0
|
||||
AND `user`.`nickname` = '%s' $sql_extra LIMIT 1",
|
||||
dbesc($nickname)
|
||||
);
|
||||
|
||||
if(count($r)) {
|
||||
|
||||
$challenge = '';
|
||||
$encrypted_id = '';
|
||||
$id_str = $my_id . '.' . mt_rand(1000,9999);
|
||||
|
||||
if(($r[0]['duplex'] && strlen($r[0]['pubkey'])) || (! strlen($r[0]['prvkey']))) {
|
||||
openssl_public_encrypt($hash,$challenge,$r[0]['pubkey']);
|
||||
openssl_public_encrypt($id_str,$encrypted_id,$r[0]['pubkey']);
|
||||
}
|
||||
else {
|
||||
openssl_private_encrypt($hash,$challenge,$r[0]['prvkey']);
|
||||
openssl_private_encrypt($id_str,$encrypted_id,$r[0]['prvkey']);
|
||||
}
|
||||
|
||||
$challenge = bin2hex($challenge);
|
||||
$encrypted_id = bin2hex($encrypted_id);
|
||||
}
|
||||
else {
|
||||
$status = 1;
|
||||
$challenge = '';
|
||||
$encrypted_id = '';
|
||||
}
|
||||
|
||||
if(($type === 'profile') && (strlen($sec))) {
|
||||
|
||||
// URL reply
|
||||
|
||||
if($dfrn_version < 2.2) {
|
||||
$s = fetch_url($r[0]['poll']
|
||||
. '?dfrn_id=' . $encrypted_id
|
||||
. '&type=profile-check'
|
||||
. '&dfrn_version=' . DFRN_PROTOCOL_VERSION
|
||||
. '&challenge=' . $challenge
|
||||
. '&sec=' . $sec
|
||||
);
|
||||
}
|
||||
else {
|
||||
$s = post_url($r[0]['poll'], array(
|
||||
'dfrn_id' => $encrypted_id,
|
||||
'type' => 'profile-check',
|
||||
'dfrn_version' => DFRN_PROTOCOL_VERSION,
|
||||
'challenge' => $challenge,
|
||||
'sec' => $sec
|
||||
));
|
||||
}
|
||||
|
||||
$profile = ((count($r) && $r[0]['nickname']) ? $r[0]['nickname'] : $nickname);
|
||||
|
||||
switch($destination_url) {
|
||||
case 'profile':
|
||||
$dest = $a->get_baseurl() . '/profile/' . $profile . '?tab=profile';
|
||||
break;
|
||||
case 'photos':
|
||||
$dest = $a->get_baseurl() . '/photos/' . $profile;
|
||||
break;
|
||||
case 'status':
|
||||
case '':
|
||||
$dest = $a->get_baseurl() . '/profile/' . $profile;
|
||||
break;
|
||||
default:
|
||||
$dest = $destination_url;
|
||||
break;
|
||||
}
|
||||
|
||||
logger("dfrn_poll: sec profile: " . $s, LOGGER_DATA);
|
||||
|
||||
if(strlen($s) && strstr($s,'<?xml')) {
|
||||
|
||||
$xml = parse_xml_string($s);
|
||||
|
||||
logger('dfrn_poll: profile: parsed xml: ' . print_r($xml,true), LOGGER_DATA);
|
||||
|
||||
logger('dfrn_poll: secure profile: challenge: ' . $xml->challenge . ' expecting ' . $hash);
|
||||
logger('dfrn_poll: secure profile: sec: ' . $xml->sec . ' expecting ' . $sec);
|
||||
|
||||
|
||||
if(((int) $xml->status == 0) && ($xml->challenge == $hash) && ($xml->sec == $sec)) {
|
||||
$_SESSION['authenticated'] = 1;
|
||||
if(! x($_SESSION,'remote'))
|
||||
$_SESSION['remote'] = array();
|
||||
$_SESSION['remote'][] = array('cid' => $r[0]['id'],'uid' => $r[0]['uid'],'url' => $r[0]['url']);
|
||||
$_SESSION['visitor_id'] = $r[0]['id'];
|
||||
$_SESSION['visitor_home'] = $r[0]['url'];
|
||||
$_SESSION['visitor_visiting'] = $r[0]['uid'];
|
||||
info( sprintf(t('%s welcomes %s'), $r[0]['username'] , $r[0]['name']) . EOL);
|
||||
// Visitors get 1 day session.
|
||||
$session_id = session_id();
|
||||
$expire = time() + 86400;
|
||||
q("UPDATE `session` SET `expire` = '%s' WHERE `sid` = '%s' LIMIT 1",
|
||||
dbesc($expire),
|
||||
dbesc($session_id)
|
||||
);
|
||||
}
|
||||
|
||||
goaway($dest);
|
||||
}
|
||||
goaway($dest);
|
||||
// NOTREACHED
|
||||
|
||||
}
|
||||
else {
|
||||
// XML reply
|
||||
header("Content-type: text/xml");
|
||||
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n"
|
||||
. '<dfrn_poll>' . "\r\n"
|
||||
. "\t" . '<status>' . $status . '</status>' . "\r\n"
|
||||
. "\t" . '<dfrn_version>' . DFRN_PROTOCOL_VERSION . '</dfrn_version>' . "\r\n"
|
||||
. "\t" . '<dfrn_id>' . $encrypted_id . '</dfrn_id>' . "\r\n"
|
||||
. "\t" . '<challenge>' . $challenge . '</challenge>' . "\r\n"
|
||||
. '</dfrn_poll>' . "\r\n" ;
|
||||
killme();
|
||||
// NOTREACHED
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,837 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Module: dfrn_request
|
||||
*
|
||||
* Purpose: Handles communication associated with the issuance of
|
||||
* friend requests.
|
||||
*
|
||||
*/
|
||||
|
||||
if(! function_exists('dfrn_request_init')) {
|
||||
function dfrn_request_init(&$a) {
|
||||
|
||||
if($a->argc > 1)
|
||||
$which = $a->argv[1];
|
||||
|
||||
profile_load($a,$which);
|
||||
return;
|
||||
}}
|
||||
|
||||
|
||||
/**
|
||||
* Function: dfrn_request_post
|
||||
*
|
||||
* Purpose:
|
||||
* Handles multiple scenarios.
|
||||
*
|
||||
* Scenario 1:
|
||||
* Clicking 'submit' on a friend request page.
|
||||
*
|
||||
* Scenario 2:
|
||||
* Following Scenario 1, we are brought back to our home site
|
||||
* in order to link our friend request with our own server cell.
|
||||
* After logging in, we click 'submit' to approve the linkage.
|
||||
*
|
||||
*/
|
||||
|
||||
if(! function_exists('dfrn_request_post')) {
|
||||
function dfrn_request_post(&$a) {
|
||||
|
||||
if(($a->argc != 2) || (! count($a->profile)))
|
||||
return;
|
||||
|
||||
|
||||
if(x($_POST, 'cancel')) {
|
||||
goaway(z_root());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Scenario 2: We've introduced ourself to another cell, then have been returned to our own cell
|
||||
* to confirm the request, and then we've clicked submit (perhaps after logging in).
|
||||
* That brings us here:
|
||||
*
|
||||
*/
|
||||
|
||||
if((x($_POST,'localconfirm')) && ($_POST['localconfirm'] == 1)) {
|
||||
|
||||
/**
|
||||
* Ensure this is a valid request
|
||||
*/
|
||||
|
||||
if(local_user() && ($a->user['nickname'] == $a->argv[1]) && (x($_POST,'dfrn_url'))) {
|
||||
|
||||
|
||||
$dfrn_url = notags(trim($_POST['dfrn_url']));
|
||||
$aes_allow = (((x($_POST,'aes_allow')) && ($_POST['aes_allow'] == 1)) ? 1 : 0);
|
||||
$confirm_key = ((x($_POST,'confirm_key')) ? $_POST['confirm_key'] : "");
|
||||
$hidden = ((x($_POST,'hidden-contact')) ? intval($_POST['hidden-contact']) : 0);
|
||||
$contact_record = null;
|
||||
|
||||
if(x($dfrn_url)) {
|
||||
|
||||
/**
|
||||
* Lookup the contact based on their URL (which is the only unique thing we have at the moment)
|
||||
*/
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND (`url` = '%s' OR `nurl` = '%s') AND `self` = 0 LIMIT 1",
|
||||
intval(local_user()),
|
||||
dbesc($dfrn_url),
|
||||
dbesc(normalise_link($dfrn_url))
|
||||
);
|
||||
|
||||
if(count($r)) {
|
||||
if(strlen($r[0]['dfrn_id'])) {
|
||||
|
||||
/**
|
||||
* We don't need to be here. It has already happened.
|
||||
*/
|
||||
|
||||
notice( t("This introduction has already been accepted.") . EOL );
|
||||
return;
|
||||
}
|
||||
else
|
||||
$contact_record = $r[0];
|
||||
}
|
||||
|
||||
if(is_array($contact_record)) {
|
||||
$r = q("UPDATE `contact` SET hidden = %d WHERE `id` = %d LIMIT 1",
|
||||
intval($hidden),
|
||||
intval($contact_record['id'])
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
/**
|
||||
* Scrape the other site's profile page to pick up the dfrn links, key, fn, and photo
|
||||
*/
|
||||
|
||||
require_once('Scrape.php');
|
||||
|
||||
$parms = scrape_dfrn($dfrn_url);
|
||||
|
||||
if(! count($parms)) {
|
||||
notice( t('Profile location is not valid or does not contain profile information.') . EOL );
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if(! x($parms,'fn'))
|
||||
notice( t('Warning: profile location has no identifiable owner name.') . EOL );
|
||||
if(! x($parms,'photo'))
|
||||
notice( t('Warning: profile location has no profile photo.') . EOL );
|
||||
$invalid = validate_dfrn($parms);
|
||||
if($invalid) {
|
||||
notice( sprintf( tt("%d required parameter was not found at the given location",
|
||||
"%d required parameters were not found at the given location",
|
||||
$invalid), $invalid) . EOL );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$dfrn_request = $parms['dfrn-request'];
|
||||
|
||||
/********* Escape the entire array ********/
|
||||
|
||||
dbesc_array($parms);
|
||||
|
||||
/******************************************/
|
||||
|
||||
/**
|
||||
* Create a contact record on our site for the other person
|
||||
*/
|
||||
|
||||
$r = q("INSERT INTO `contact` ( `uid`, `created`,`url`, `nurl`, `name`, `nick`, `photo`, `site_pubkey`,
|
||||
`request`, `confirm`, `notify`, `poll`, `poco`, `network`, `aes_allow`, `hidden`)
|
||||
VALUES ( %d, '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d)",
|
||||
intval(local_user()),
|
||||
datetime_convert(),
|
||||
dbesc($dfrn_url),
|
||||
dbesc(normalise_link($dfrn_url)),
|
||||
$parms['fn'],
|
||||
$parms['nick'],
|
||||
$parms['photo'],
|
||||
$parms['key'],
|
||||
$parms['dfrn-request'],
|
||||
$parms['dfrn-confirm'],
|
||||
$parms['dfrn-notify'],
|
||||
$parms['dfrn-poll'],
|
||||
$parms['dfrn-poco'],
|
||||
dbesc(NETWORK_DFRN),
|
||||
intval($aes_allow),
|
||||
intval($hidden)
|
||||
);
|
||||
}
|
||||
|
||||
if($r) {
|
||||
info( t("Introduction complete.") . EOL);
|
||||
}
|
||||
|
||||
$r = q("select id from contact where uid = %d and url = '%s' and `site_pubkey` = '%s' limit 1",
|
||||
intval(local_user()),
|
||||
dbesc($dfrn_url),
|
||||
$parms['key'] // this was already escaped
|
||||
);
|
||||
if(count($r)) {
|
||||
$g = q("select def_gid from user where uid = %d limit 1",
|
||||
intval(local_user())
|
||||
);
|
||||
if($g && intval($g[0]['def_gid'])) {
|
||||
require_once('include/group.php');
|
||||
group_add_member(local_user(),'',$r[0]['id'],$g[0]['def_gid']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow the blocked remote notification to complete
|
||||
*/
|
||||
|
||||
if(is_array($contact_record))
|
||||
$dfrn_request = $contact_record['request'];
|
||||
|
||||
if(strlen($dfrn_request) && strlen($confirm_key))
|
||||
$s = fetch_url($dfrn_request . '?confirm_key=' . $confirm_key);
|
||||
|
||||
// (ignore reply, nothing we can do it failed)
|
||||
|
||||
goaway(zid($dfrn_url));
|
||||
return; // NOTREACHED
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// invalid/bogus request
|
||||
|
||||
notice( t('Unrecoverable protocol error.') . EOL );
|
||||
goaway(z_root());
|
||||
return; // NOTREACHED
|
||||
}
|
||||
|
||||
/**
|
||||
* Otherwise:
|
||||
*
|
||||
* Scenario 1:
|
||||
* We are the requestee. A person from a remote cell has made an introduction
|
||||
* on our profile web page and clicked submit. We will use their DFRN-URL to
|
||||
* figure out how to contact their cell.
|
||||
*
|
||||
* Scrape the originating DFRN-URL for everything we need. Create a contact record
|
||||
* and an introduction to show our user next time he/she logs in.
|
||||
* Finally redirect back to the requestor so that their site can record the request.
|
||||
* If our user (the requestee) later confirms this request, a record of it will need
|
||||
* to exist on the requestor's cell in order for the confirmation process to complete..
|
||||
*
|
||||
* It's possible that neither the requestor or the requestee are logged in at the moment,
|
||||
* and the requestor does not yet have any credentials to the requestee profile.
|
||||
*
|
||||
* Who is the requestee? We've already loaded their profile which means their nickname should be
|
||||
* in $a->argv[1] and we should have their complete info in $a->profile.
|
||||
*
|
||||
*/
|
||||
|
||||
if(! (is_array($a->profile) && count($a->profile))) {
|
||||
notice( t('Profile unavailable.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$nickname = $a->profile['nickname'];
|
||||
$notify_flags = $a->profile['notify-flags'];
|
||||
$uid = $a->profile['uid'];
|
||||
$maxreq = intval($a->profile['maxreq']);
|
||||
$contact_record = null;
|
||||
$failed = false;
|
||||
$parms = null;
|
||||
|
||||
|
||||
if( x($_POST,'dfrn_url')) {
|
||||
|
||||
/**
|
||||
* Block friend request spam
|
||||
*/
|
||||
|
||||
if($maxreq) {
|
||||
$r = q("SELECT * FROM `intro` WHERE `datetime` > '%s' AND `uid` = %d",
|
||||
dbesc(datetime_convert('UTC','UTC','now - 24 hours')),
|
||||
intval($uid)
|
||||
);
|
||||
if(count($r) > $maxreq) {
|
||||
notice( sprintf( t('%s has received too many connection requests today.'), $a->profile['name']) . EOL);
|
||||
notice( t('Spam protection measures have been invoked.') . EOL);
|
||||
notice( t('Friends are advised to please try again in 24 hours.') . EOL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Cleanup old introductions that remain blocked.
|
||||
* Also remove the contact record, but only if there is no existing relationship
|
||||
* Do not remove email contacts as these may be awaiting email verification
|
||||
*/
|
||||
|
||||
$r = q("SELECT `intro`.*, `intro`.`id` AS `iid`, `contact`.`id` AS `cid`, `contact`.`rel`
|
||||
FROM `intro` LEFT JOIN `contact` on `intro`.`contact-id` = `contact`.`id`
|
||||
WHERE `intro`.`blocked` = 1 AND `contact`.`self` = 0
|
||||
AND `contact`.`network` != '%s'
|
||||
AND `intro`.`datetime` < UTC_TIMESTAMP() - INTERVAL 30 MINUTE ",
|
||||
dbesc(NETWORK_MAIL2)
|
||||
);
|
||||
if(count($r)) {
|
||||
foreach($r as $rr) {
|
||||
if(! $rr['rel']) {
|
||||
q("DELETE FROM `contact` WHERE `id` = %d LIMIT 1",
|
||||
intval($rr['cid'])
|
||||
);
|
||||
}
|
||||
q("DELETE FROM `intro` WHERE `id` = %d LIMIT 1",
|
||||
intval($rr['iid'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Cleanup any old email intros - which will have a greater lifetime
|
||||
*/
|
||||
|
||||
$r = q("SELECT `intro`.*, `intro`.`id` AS `iid`, `contact`.`id` AS `cid`, `contact`.`rel`
|
||||
FROM `intro` LEFT JOIN `contact` on `intro`.`contact-id` = `contact`.`id`
|
||||
WHERE `intro`.`blocked` = 1 AND `contact`.`self` = 0
|
||||
AND `contact`.`network` = '%s'
|
||||
AND `intro`.`datetime` < UTC_TIMESTAMP() - INTERVAL 3 DAY ",
|
||||
dbesc(NETWORK_MAIL2)
|
||||
);
|
||||
if(count($r)) {
|
||||
foreach($r as $rr) {
|
||||
if(! $rr['rel']) {
|
||||
q("DELETE FROM `contact` WHERE `id` = %d LIMIT 1",
|
||||
intval($rr['cid'])
|
||||
);
|
||||
}
|
||||
q("DELETE FROM `intro` WHERE `id` = %d LIMIT 1",
|
||||
intval($rr['iid'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$email_follow = (x($_POST,'email_follow') ? intval($_POST['email_follow']) : 0);
|
||||
$real_name = (x($_POST,'realname') ? notags(trim($_POST['realname'])) : '');
|
||||
|
||||
$url = trim($_POST['dfrn_url']);
|
||||
if(! strlen($url)) {
|
||||
notice( t("Invalid locator") . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
$hcard = '';
|
||||
|
||||
if($email_follow) {
|
||||
|
||||
if(! validate_email($url)) {
|
||||
notice( t('Invalid email address.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$addr = $url;
|
||||
$name = ($realname) ? $realname : $addr;
|
||||
$nick = substr($addr,0,strpos($addr,'@'));
|
||||
$url = 'http://' . substr($addr,strpos($addr,'@') + 1);
|
||||
$nurl = normalise_url($host);
|
||||
$poll = 'email ' . random_string();
|
||||
$notify = 'smtp ' . random_string();
|
||||
$blocked = 1;
|
||||
$pending = 1;
|
||||
$network = NETWORK_MAIL2;
|
||||
$rel = CONTACT_IS_FOLLOWER;
|
||||
|
||||
$mail_disabled = ((function_exists('imap_open') && (! get_config('system','imap_disabled'))) ? 0 : 1);
|
||||
if(get_config('system','dfrn_only'))
|
||||
$mail_disabled = 1;
|
||||
|
||||
if(! $mail_disabled) {
|
||||
$failed = false;
|
||||
$r = q("SELECT * FROM `mailacct` WHERE `uid` = %d LIMIT 1",
|
||||
intval($uid)
|
||||
);
|
||||
if(! count($r)) {
|
||||
notice( t('This account has not been configured for email. Request failed.') . EOL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("insert into contact ( uid, created, addr, name, nick, url, nurl, poll, notify, blocked, pending, network, rel )
|
||||
values( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d ) ",
|
||||
intval($uid),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($addr),
|
||||
dbesc($name),
|
||||
dbesc($nick),
|
||||
dbesc($url),
|
||||
dbesc($nurl),
|
||||
dbesc($poll),
|
||||
dbesc($notify),
|
||||
intval($blocked),
|
||||
intval($pending),
|
||||
dbesc($network),
|
||||
intval($rel)
|
||||
);
|
||||
|
||||
$r = q("select id from contact where poll = '%s' and uid = %d limit 1",
|
||||
dbesc($poll),
|
||||
intval($uid)
|
||||
);
|
||||
if(count($r)) {
|
||||
$contact_id = $r[0]['id'];
|
||||
|
||||
$g = q("select def_gid from user where uid = %d limit 1",
|
||||
intval($uid)
|
||||
);
|
||||
if($g && intval($g[0]['def_gid'])) {
|
||||
require_once('include/group.php');
|
||||
group_add_member($uid,'',$contact_id,$g[0]['def_gid']);
|
||||
}
|
||||
|
||||
$photo = avatar_img($addr);
|
||||
|
||||
$r = q("UPDATE `contact` SET
|
||||
`photo` = '%s',
|
||||
`thumb` = '%s',
|
||||
`micro` = '%s',
|
||||
`name_date` = '%s',
|
||||
`uri_date` = '%s',
|
||||
`avatar_date` = '%s',
|
||||
`hidden` = 0,
|
||||
WHERE `id` = %d LIMIT 1
|
||||
",
|
||||
dbesc($photos[0]),
|
||||
dbesc($photos[1]),
|
||||
dbesc($photos[2]),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
intval($contact_id)
|
||||
);
|
||||
}
|
||||
|
||||
// contact is created. Now create an introduction
|
||||
|
||||
$hash = random_string();
|
||||
|
||||
$r = q("insert into intro ( uid, `contact-id`, knowyou, note, hash, datetime, blocked )
|
||||
values( %d , %d, %d, '%s', '%s', '%s', %d ) ",
|
||||
intval($uid),
|
||||
intval($contact_id),
|
||||
((x($_POST,'knowyou') && ($_POST['knowyou'] == 1)) ? 1 : 0),
|
||||
dbesc(notags(trim($_POST['dfrn-request-message']))),
|
||||
dbesc($hash),
|
||||
dbesc(datetime_convert()),
|
||||
1
|
||||
);
|
||||
|
||||
// Next send an email verify form to the requestor.
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
// Canonicalise email-style profile locator
|
||||
|
||||
$url = webfinger_dfrn($url,$hcard);
|
||||
|
||||
if(substr($url,0,5) === 'stat:') {
|
||||
$network = NETWORK_OSTATUS;
|
||||
$url = substr($url,5);
|
||||
}
|
||||
else {
|
||||
$network = NETWORK_DFRN;
|
||||
}
|
||||
}
|
||||
|
||||
logger('dfrn_request: url: ' . $url);
|
||||
|
||||
if(! strlen($url)) {
|
||||
notice( t("Unable to resolve your name at the provided location.") . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if($network === NETWORK_DFRN) {
|
||||
$ret = q("SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' AND `self` = 0 LIMIT 1",
|
||||
intval($uid),
|
||||
dbesc($url)
|
||||
);
|
||||
|
||||
if(count($ret)) {
|
||||
if(strlen($ret[0]['issued_id'])) {
|
||||
notice( t('You have already introduced yourself here.') . EOL );
|
||||
return;
|
||||
}
|
||||
elseif($ret[0]['rel'] == CONTACT_IS_FRIEND) {
|
||||
notice( sprintf( t('Apparently you are already friends with %s.'), $a->profile['name']) . EOL);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
$contact_record = $ret[0];
|
||||
$parms = array('dfrn-request' => $ret[0]['request']);
|
||||
}
|
||||
}
|
||||
|
||||
$issued_id = random_string();
|
||||
|
||||
if(is_array($contact_record)) {
|
||||
// There is a contact record but no issued_id, so this
|
||||
// is a reciprocal introduction from a known contact
|
||||
$r = q("UPDATE `contact` SET `issued_id` = '%s' WHERE `id` = %d LIMIT 1",
|
||||
dbesc($issued_id),
|
||||
intval($contact_record['id'])
|
||||
);
|
||||
}
|
||||
else {
|
||||
if(! validate_url($url)) {
|
||||
notice( t('Invalid profile URL.') . EOL);
|
||||
goaway($a->get_baseurl() . '/' . $a->cmd);
|
||||
return; // NOTREACHED
|
||||
}
|
||||
|
||||
if(! allowed_url($url)) {
|
||||
notice( t('Disallowed profile URL.') . EOL);
|
||||
goaway($a->get_baseurl() . '/' . $a->cmd);
|
||||
return; // NOTREACHED
|
||||
}
|
||||
|
||||
|
||||
require_once('Scrape.php');
|
||||
|
||||
$parms = scrape_dfrn(($hcard) ? $hcard : $url);
|
||||
|
||||
if(! count($parms)) {
|
||||
notice( t('Profile location is not valid or does not contain profile information.') . EOL );
|
||||
goaway($a->get_baseurl() . '/' . $a->cmd);
|
||||
}
|
||||
else {
|
||||
if(! x($parms,'fn'))
|
||||
notice( t('Warning: profile location has no identifiable owner name.') . EOL );
|
||||
if(! x($parms,'photo'))
|
||||
notice( t('Warning: profile location has no profile photo.') . EOL );
|
||||
$invalid = validate_dfrn($parms);
|
||||
if($invalid) {
|
||||
notice( sprintf( tt("%d required parameter was not found at the given location",
|
||||
"%d required parameters were not found at the given location",
|
||||
$invalid), $invalid) . EOL );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$parms['url'] = $url;
|
||||
$parms['issued_id'] = $issued_id;
|
||||
|
||||
|
||||
dbesc_array($parms);
|
||||
$r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`,`name`, `nick`, `issued_id`, `photo`, `site_pubkey`,
|
||||
`request`, `confirm`, `notify`, `poll`, `poco`, `network` )
|
||||
VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )",
|
||||
intval($uid),
|
||||
dbesc(datetime_convert()),
|
||||
$parms['url'],
|
||||
dbesc(normalise_link($parms['url'])),
|
||||
$parms['fn'],
|
||||
$parms['nick'],
|
||||
$parms['issued_id'],
|
||||
$parms['photo'],
|
||||
$parms['key'],
|
||||
$parms['dfrn-request'],
|
||||
$parms['dfrn-confirm'],
|
||||
$parms['dfrn-notify'],
|
||||
$parms['dfrn-poll'],
|
||||
$parms['dfrn-poco'],
|
||||
dbesc(NETWORK_DFRN)
|
||||
);
|
||||
|
||||
// find the contact record we just created
|
||||
if($r) {
|
||||
$r = q("SELECT `id` FROM `contact`
|
||||
WHERE `uid` = %d AND `url` = '%s' AND `issued_id` = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
$parms['url'],
|
||||
$parms['issued_id']
|
||||
);
|
||||
if(count($r))
|
||||
$contact_record = $r[0];
|
||||
}
|
||||
|
||||
}
|
||||
if($r === false) {
|
||||
notice( t('Failed to update contact record.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
$hash = random_string() . (string) time(); // Generate a confirm_key
|
||||
|
||||
if(is_array($contact_record)) {
|
||||
$ret = q("INSERT INTO `intro` ( `uid`, `contact-id`, `blocked`, `knowyou`, `note`, `hash`, `datetime`)
|
||||
VALUES ( %d, %d, 1, %d, '%s', '%s', '%s' )",
|
||||
intval($uid),
|
||||
intval($contact_record['id']),
|
||||
((x($_POST,'knowyou') && ($_POST['knowyou'] == 1)) ? 1 : 0),
|
||||
dbesc(notags(trim($_POST['dfrn-request-message']))),
|
||||
dbesc($hash),
|
||||
dbesc(datetime_convert())
|
||||
);
|
||||
}
|
||||
|
||||
// This notice will only be seen by the requestor if the requestor and requestee are on the same server.
|
||||
|
||||
if(! $failed)
|
||||
info( t('Your introduction has been sent.') . EOL );
|
||||
|
||||
// "Homecoming" - send the requestor back to their site to record the introduction.
|
||||
|
||||
$dfrn_url = bin2hex($a->get_baseurl() . '/profile/' . $nickname);
|
||||
$aes_allow = ((function_exists('openssl_encrypt')) ? 1 : 0);
|
||||
|
||||
goaway($parms['dfrn-request'] . "?dfrn_url=$dfrn_url"
|
||||
. '&dfrn_version=' . DFRN_PROTOCOL_VERSION
|
||||
. '&confirm_key=' . $hash
|
||||
. (($aes_allow) ? "&aes_allow=1" : "")
|
||||
);
|
||||
// NOTREACHED
|
||||
// END $network === NETWORK_DFRN
|
||||
}
|
||||
elseif($network === NETWORK_OSTATUS) {
|
||||
|
||||
/**
|
||||
*
|
||||
* OStatus network
|
||||
* Check contact existence
|
||||
* Try and scrape together enough information to create a contact record,
|
||||
* with us as CONTACT_IS_FOLLOWER
|
||||
* Substitute our user's feed URL into $url template
|
||||
* Send the subscriber home to subscribe
|
||||
*
|
||||
*/
|
||||
|
||||
$url = str_replace('{uri}', $a->get_baseurl() . '/dfrn_poll/' . $nickname, $url);
|
||||
goaway($url);
|
||||
// NOTREACHED
|
||||
// END $network === NETWORK_OSTATUS
|
||||
}
|
||||
|
||||
} return;
|
||||
}}
|
||||
|
||||
|
||||
|
||||
|
||||
if(! function_exists('dfrn_request_content')) {
|
||||
function dfrn_request_content(&$a) {
|
||||
|
||||
if(($a->argc != 2) || (! count($a->profile)))
|
||||
return "";
|
||||
|
||||
|
||||
// "Homecoming". Make sure we're logged in to this site as the correct user. Then offer a confirm button
|
||||
// to send us to the post section to record the introduction.
|
||||
|
||||
if(x($_GET,'dfrn_url')) {
|
||||
|
||||
if(! local_user()) {
|
||||
info( t("Please login to confirm introduction.") . EOL );
|
||||
|
||||
/* setup the return URL to come back to this page if they use openid */
|
||||
|
||||
$stripped = str_replace('q=','',$a->query_string);
|
||||
$_SESSION['return_url'] = trim($stripped,'/');
|
||||
|
||||
return login();
|
||||
}
|
||||
|
||||
// Edge case, but can easily happen in the wild. This person is authenticated,
|
||||
// but not as the person who needs to deal with this request.
|
||||
|
||||
if ($a->user['nickname'] != $a->argv[1]) {
|
||||
notice( t("Incorrect identity currently logged in. Please login to <strong>this</strong> profile.") . EOL);
|
||||
return login();
|
||||
}
|
||||
|
||||
$dfrn_url = notags(trim(hex2bin($_GET['dfrn_url'])));
|
||||
$aes_allow = (((x($_GET,'aes_allow')) && ($_GET['aes_allow'] == 1)) ? 1 : 0);
|
||||
$confirm_key = (x($_GET,'confirm_key') ? $_GET['confirm_key'] : "");
|
||||
$tpl = get_markup_template("dfrn_req_confirm.tpl");
|
||||
$o = replace_macros($tpl,array(
|
||||
'$dfrn_url' => $dfrn_url,
|
||||
'$aes_allow' => (($aes_allow) ? '<input type="hidden" name="aes_allow" value="1" />' : "" ),
|
||||
'$hidethem' => t('Hide this contact'),
|
||||
'$hidechecked' => '',
|
||||
'$confirm_key' => $confirm_key,
|
||||
'$welcome' => sprintf( t('Welcome home %s.'), $a->user['username']),
|
||||
'$please' => sprintf( t('Please confirm your introduction/connection request to %s.'), $dfrn_url),
|
||||
'$submit' => t('Confirm'),
|
||||
'$uid' => $_SESSION['uid'],
|
||||
'$nickname' => $a->user['nickname'],
|
||||
'dfrn_rawurl' => $_GET['dfrn_url']
|
||||
));
|
||||
return $o;
|
||||
|
||||
}
|
||||
elseif((x($_GET,'confirm_key')) && strlen($_GET['confirm_key'])) {
|
||||
|
||||
// we are the requestee and it is now safe to send our user their introduction,
|
||||
// We could just unblock it, but first we have to jump through a few hoops to
|
||||
// send an email, or even to find out if we need to send an email.
|
||||
|
||||
$intro = q("SELECT * FROM `intro` WHERE `hash` = '%s' LIMIT 1",
|
||||
dbesc($_GET['confirm_key'])
|
||||
);
|
||||
|
||||
if(count($intro)) {
|
||||
|
||||
$r = q("SELECT `contact`.*, `user`.* FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
|
||||
WHERE `contact`.`id` = %d LIMIT 1",
|
||||
intval($intro[0]['contact-id'])
|
||||
);
|
||||
|
||||
$auto_confirm = false;
|
||||
|
||||
if(count($r)) {
|
||||
if(($r[0]['page-flags'] != PAGE_NORMAL) && ($r[0]['page-flags'] != PAGE_PRVGROUP))
|
||||
$auto_confirm = true;
|
||||
|
||||
if(! $auto_confirm) {
|
||||
require_once('include/enotify.php');
|
||||
notification(array(
|
||||
'type' => NOTIFY_INTRO,
|
||||
'notify_flags' => $r[0]['notify-flags'],
|
||||
'language' => $r[0]['language'],
|
||||
'to_name' => $r[0]['username'],
|
||||
'to_email' => $r[0]['email'],
|
||||
'uid' => $r[0]['uid'],
|
||||
'link' => $a->get_baseurl() . '/notifications/intros',
|
||||
'source_name' => ((strlen(stripslashes($r[0]['name']))) ? stripslashes($r[0]['name']) : t('[Name Withheld]')),
|
||||
'source_link' => $r[0]['url'],
|
||||
'source_photo' => $r[0]['photo'],
|
||||
'verb' => ACTIVITY_REQ_FRIEND,
|
||||
'otype' => 'intro'
|
||||
));
|
||||
}
|
||||
|
||||
if($auto_confirm) {
|
||||
require_once('mod/dfrn_confirm.php');
|
||||
$handsfree = array(
|
||||
'uid' => $r[0]['uid'],
|
||||
'node' => $r[0]['nickname'],
|
||||
'dfrn_id' => $r[0]['issued_id'],
|
||||
'intro_id' => $intro[0]['id'],
|
||||
'duplex' => (($r[0]['page-flags'] == PAGE_FREELOVE) ? 1 : 0),
|
||||
'activity' => intval(get_pconfig($r[0]['uid'],'system','post_newfriend'))
|
||||
);
|
||||
dfrn_confirm_post($a,$handsfree);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(! $auto_confirm) {
|
||||
|
||||
// If we are auto_confirming, this record will have already been nuked
|
||||
// in dfrn_confirm_post()
|
||||
|
||||
$r = q("UPDATE `intro` SET `blocked` = 0 WHERE `hash` = '%s' LIMIT 1",
|
||||
dbesc($_GET['confirm_key'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
killme();
|
||||
return; // NOTREACHED
|
||||
}
|
||||
else {
|
||||
|
||||
/**
|
||||
* Normal web request. Display our user's introduction form.
|
||||
*/
|
||||
|
||||
if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) {
|
||||
notice( t('Public access denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to auto-fill the profile address
|
||||
*/
|
||||
|
||||
if(local_user()) {
|
||||
if(strlen($a->path)) {
|
||||
$myaddr = $a->get_baseurl() . '/profile/' . $a->user['nickname'];
|
||||
}
|
||||
else {
|
||||
$myaddr = $a->user['nickname'] . '@' . substr(z_root(), strpos(z_root(),'://') + 3 );
|
||||
}
|
||||
}
|
||||
elseif(x($_GET,'addr')) {
|
||||
$myaddr = hex2bin($_GET['addr']);
|
||||
}
|
||||
else {
|
||||
/* $_GET variables are already urldecoded */
|
||||
$myaddr = ((x($_GET,'address')) ? $_GET['address'] : '');
|
||||
}
|
||||
|
||||
// last, try a zid
|
||||
if(! strlen($myaddr))
|
||||
$myaddr = get_my_url();
|
||||
|
||||
|
||||
$target_addr = $a->profile['nickname'] . '@' . substr(z_root(), strpos(z_root(),'://') + 3 );
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* The auto_request form only has the profile address
|
||||
* because nobody is going to read the comments and
|
||||
* it doesn't matter if they know you or not.
|
||||
*
|
||||
*/
|
||||
|
||||
if($a->profile['page-flags'] == PAGE_NORMAL)
|
||||
$tpl = get_markup_template('dfrn_request.tpl');
|
||||
else
|
||||
$tpl = get_markup_template('auto_request.tpl');
|
||||
|
||||
$page_desc .= t("Please enter your 'Identity Address' from one of the following supported communications networks:");
|
||||
|
||||
|
||||
$emailnet = '';
|
||||
|
||||
$invite_desc = t('If you are not yet a member of the free social web, <a href="http://dir.friendica.com/siteinfo">follow this link to find a public Friendica site and join us today</a>.');
|
||||
|
||||
$o .= replace_macros($tpl,array(
|
||||
'$header' => t('Friend/Connection Request'),
|
||||
'$desc' => t('Examples: jojo@zothub.com, bob@example.com'),
|
||||
'$pls_answer' => t('Please answer the following:'),
|
||||
'$does_know' => sprintf( t('Does %s know you?'),$a->profile['name']),
|
||||
'$yes' => t('Yes'),
|
||||
'$no' => t('No'),
|
||||
'$add_note' => t('Add a personal note:'),
|
||||
'$page_desc' => $page_desc,
|
||||
'$friendica' => t('Friendica'),
|
||||
'$statusnet' => t('StatusNet/Federated Social Web'),
|
||||
'$diaspora' => t('Diaspora'),
|
||||
'$diasnote' => sprintf (t(' - please do not use this form. Instead, enter %s into your Diaspora search bar.'),$target_addr),
|
||||
'$your_address' => t('Your webbie (web-id):'),
|
||||
'$invite_desc' => $invite_desc,
|
||||
'$emailnet' => $emailnet,
|
||||
'$submit' => t('Submit Request'),
|
||||
'$cancel' => t('Cancel'),
|
||||
'$nickname' => $a->argv[1],
|
||||
'$name' => $a->profile['name'],
|
||||
'$myaddr' => $myaddr
|
||||
));
|
||||
return $o;
|
||||
}
|
||||
|
||||
return; // Somebody is fishing.
|
||||
}}
|
@ -1 +1 @@
|
||||
2012-12-19.174
|
||||
2012-12-20.175
|
||||
|
Reference in New Issue
Block a user