Exemplo n.º 1
0
function private_messages_fetch_conversation($channel_id, $messageitem_id, $updateseen = false)
{
    // find the parent_mid of the message being requested
    $r = q("SELECT parent_mid from mail WHERE channel_id = %d and id = %d limit 1", intval($channel_id), intval($messageitem_id));
    if (!$r) {
        return array();
    }
    $messages = q("select * from mail where parent_mid = '%s' and channel_id = %d order by created asc", dbesc($r[0]['parent_mid']), intval($channel_id));
    if (!$messages) {
        return array();
    }
    $chans = array();
    foreach ($messages as $rr) {
        $s = "'" . dbesc(trim($rr['from_xchan'])) . "'";
        if (!in_array($s, $chans)) {
            $chans[] = $s;
        }
        $s = "'" . dbesc(trim($rr['to_xchan'])) . "'";
        if (!in_array($s, $chans)) {
            $chans[] = $s;
        }
    }
    $c = q("select * from xchan where xchan_hash in (" . implode(',', $chans) . ")");
    foreach ($messages as $k => $message) {
        $messages[$k]['from'] = find_xchan_in_array($message['from_xchan'], $c);
        $messages[$k]['to'] = find_xchan_in_array($message['to_xchan'], $c);
        if (intval($messages[$k]['mail_obscured'])) {
            if ($messages[$k]['title']) {
                $messages[$k]['title'] = base64url_decode(str_rot47($messages[$k]['title']));
            }
            if ($messages[$k]['body']) {
                $messages[$k]['body'] = base64url_decode(str_rot47($messages[$k]['body']));
            }
        }
    }
    if ($updateseen) {
        $r = q("UPDATE `mail` SET mail_seen = 1 where mail_seen = 0 and parent_mid = '%s' AND channel_id = %d", dbesc($r[0]['parent_mid']), intval($channel_id));
    }
    return $messages;
}
Exemplo n.º 2
0
/**
 * @brief Create an array representing the important channel information
 * which would be necessary to create a nomadic identity clone. This includes
 * most channel resources and connection information with the exception of content.
 *
 * @param int $channel_id
 *     Channel_id to export
 * @param boolean $items
 *     Include channel posts (wall items), default false
 *
 * @returns array
 *     See function for details
 */
function identity_basic_export($channel_id, $items = false)
{
    /*
     * Red basic channel export
     */
    $ret = array();
    $ret['compatibility'] = array('project' => PLATFORM_NAME, 'version' => RED_VERSION, 'database' => DB_UPDATE_VERSION);
    $r = q("select * from channel where channel_id = %d limit 1", intval($channel_id));
    if ($r) {
        $ret['channel'] = $r[0];
    }
    $r = q("select * from profile where uid = %d", intval($channel_id));
    if ($r) {
        $ret['profile'] = $r;
    }
    $xchans = array();
    $r = q("select * from abook where abook_channel = %d ", intval($channel_id));
    if ($r) {
        $ret['abook'] = $r;
        foreach ($r as $rr) {
            $xchans[] = $rr['abook_xchan'];
        }
        stringify_array_elms($xchans);
    }
    if ($xchans) {
        $r = q("select * from xchan where xchan_hash in ( " . implode(',', $xchans) . " ) ");
        if ($r) {
            $ret['xchan'] = $r;
        }
        $r = q("select * from hubloc where hubloc_hash in ( " . implode(',', $xchans) . " ) ");
        if ($r) {
            $ret['hubloc'] = $r;
        }
    }
    $r = q("select * from `groups` where uid = %d ", intval($channel_id));
    if ($r) {
        $ret['group'] = $r;
    }
    $r = q("select * from group_member where uid = %d ", intval($channel_id));
    if ($r) {
        $ret['group_member'] = $r;
    }
    $r = q("select * from pconfig where uid = %d", intval($channel_id));
    if ($r) {
        $ret['config'] = $r;
    }
    $r = q("select type, data, os_storage from photo where scale = 4 and profile = 1 and uid = %d limit 1", intval($channel_id));
    if ($r) {
        $ret['photo'] = array('type' => $r[0]['type'], 'data' => $r[0]['os_storage'] ? base64url_encode(file_get_contents($r[0]['data'])) : base64url_encode($r[0]['data']));
    }
    // All other term types will be included in items, if requested.
    $r = q("select * from term where type in (%d,%d) and uid = %d", intval(TERM_SAVEDSEARCH), intval(TERM_THING), intval($channel_id));
    if ($r) {
        $ret['term'] = $r;
    }
    // add psuedo-column obj_baseurl to aid in relocations
    $r = q("select obj.*, '%s' as obj_baseurl from obj where obj_channel = %d", dbesc(z_root()), intval($channel_id));
    if ($r) {
        $ret['obj'] = $r;
    }
    $r = q("select * from app where app_channel = %d", intval($channel_id));
    if ($r) {
        $ret['app'] = $r;
    }
    $r = q("select * from chatroom where cr_uid = %d", intval($channel_id));
    if ($r) {
        $ret['chatroom'] = $r;
    }
    $r = q("select * from event where uid = %d", intval($channel_id));
    if ($r) {
        $ret['event'] = $r;
    }
    $r = q("select * from item where resource_type = 'event' and uid = %d", intval($channel_id));
    if ($r) {
        $ret['event_item'] = array();
        xchan_query($r);
        $r = fetch_post_tags($r, true);
        foreach ($r as $rr) {
            $ret['event_item'][] = encode_item($rr, true);
        }
    }
    $x = menu_list($channel_id);
    if ($x) {
        $ret['menu'] = array();
        for ($y = 0; $y < count($x); $y++) {
            $m = menu_fetch($x[$y]['menu_name'], $channel_id, $ret['channel']['channel_hash']);
            if ($m) {
                $ret['menu'][] = menu_element($m);
            }
        }
    }
    $x = menu_list($channel_id);
    if ($x) {
        $ret['menu'] = array();
        for ($y = 0; $y < count($x); $y++) {
            $m = menu_fetch($x[$y]['menu_name'], $channel_id, $ret['channel']['channel_hash']);
            if ($m) {
                $ret['menu'][] = menu_element($m);
            }
        }
    }
    $addon = array('channel_id' => $channel_id, 'data' => $ret);
    call_hooks('identity_basic_export', $addon);
    $ret = $addon['data'];
    if (!$items) {
        return $ret;
    }
    $r = q("select * from likes where channel_id = %d", intval($channel_id));
    if ($r) {
        $ret['likes'] = $r;
    }
    $r = q("select * from conv where uid = %d", intval($channel_id));
    if ($r) {
        for ($x = 0; $x < count($r); $x++) {
            $r[$x]['subject'] = base64url_decode(str_rot47($r[$x]['subject']));
        }
        $ret['conv'] = $r;
    }
    $r = q("select * from mail where mail.uid = %d", intval($channel_id));
    if ($r) {
        $m = array();
        foreach ($r as $rr) {
            xchan_mail_query($rr);
            $m[] = mail_encode($rr, true);
        }
        $ret['mail'] = $m;
    }
    $r = q("select item_id.*, item.mid from item_id left join item on item_id.iid = item.id where item_id.uid = %d", intval($channel_id));
    if ($r) {
        $ret['item_id'] = $r;
    }
    //$key = get_config('system','prvkey');
    /** @warning this may run into memory limits on smaller systems */
    /** export three months of posts. If you want to export and import all posts you have to start with 
     * the first year and export/import them in ascending order. 
     *
     * Don't export linked resource items. we'll have to pull those out separately.
     */
    $r = q("select * from item where item_wall = 1 and item_deleted = 0 and uid = %d and created > %s - INTERVAL %s and resource_type = '' order by created", intval($channel_id), db_utcnow(), db_quoteinterval('3 MONTH'));
    if ($r) {
        $ret['item'] = array();
        xchan_query($r);
        $r = fetch_post_tags($r, true);
        foreach ($r as $rr) {
            $ret['item'][] = encode_item($rr, true);
        }
    }
    return $ret;
}
Exemplo n.º 3
0
function unobscure_mail(&$item)
{
    if (array_key_exists('mail_obscured', $item) && intval($item['mail_obscured'])) {
        if ($item['title']) {
            $item['title'] = base64url_decode(str_rot47($item['title']));
        }
        if ($item['body']) {
            $item['body'] = base64url_decode(str_rot47($item['body']));
        }
    }
}
Exemplo n.º 4
0
function get_mail_elements($x)
{
    $arr = array();
    $arr['body'] = $x['body'] ? htmlspecialchars($x['body'], ENT_COMPAT, 'UTF-8', false) : '';
    $arr['title'] = $x['title'] ? htmlspecialchars($x['title'], ENT_COMPAT, 'UTF-8', false) : '';
    $arr['conv_guid'] = $x['conv_guid'] ? htmlspecialchars($x['conv_guid'], ENT_COMPAT, 'UTF-8', false) : '';
    $arr['created'] = datetime_convert('UTC', 'UTC', $x['created']);
    if (!array_key_exists('expires', $x) || $x['expires'] === NULL_DATE) {
        $arr['expires'] = NULL_DATE;
    } else {
        $arr['expires'] = datetime_convert('UTC', 'UTC', $x['expires']);
    }
    $arr['mail_flags'] = 0;
    if ($x['flags'] && is_array($x['flags'])) {
        if (in_array('recalled', $x['flags'])) {
            $arr['mail_recalled'] = 1;
        }
        if (in_array('replied', $x['flags'])) {
            $arr['mail_replied'] = 1;
        }
        if (in_array('isreply', $x['flags'])) {
            $arr['mail_isreply'] = 1;
        }
        if (in_array('seen', $x['flags'])) {
            $arr['mail_seen'] = 1;
        }
        if (in_array('deleted', $x['flags'])) {
            $arr['mail_deleted'] = 1;
        }
    }
    $key = get_config('system', 'pubkey');
    $arr['mail_obscured'] = 1;
    if ($arr['body']) {
        $arr['body'] = str_rot47(base64url_encode($arr['body']));
    }
    if ($arr['title']) {
        $arr['title'] = str_rot47(base64url_encode($arr['title']));
    }
    if ($arr['created'] > datetime_convert()) {
        $arr['created'] = datetime_convert();
    }
    $arr['mid'] = $x['message_id'] ? htmlspecialchars($x['message_id'], ENT_COMPAT, 'UTF-8', false) : '';
    $arr['parent_mid'] = $x['message_parent'] ? htmlspecialchars($x['message_parent'], ENT_COMPAT, 'UTF-8', false) : '';
    if ($x['attach']) {
        $arr['attach'] = activity_sanitise($x['attach']);
    }
    if (($xchan_hash = import_author_xchan($x['from'])) !== false) {
        $arr['from_xchan'] = $xchan_hash;
    } else {
        return array();
    }
    if (($xchan_hash = import_author_xchan($x['to'])) !== false) {
        $arr['to_xchan'] = $xchan_hash;
    } else {
        return array();
    }
    return $arr;
}
Exemplo n.º 5
0
function import_conv($channel, $convs)
{
    if ($channel && $convs) {
        foreach ($convs as $conv) {
            if ($conv['deleted']) {
                q("delete from conv where guid = '%s' and uid = %d limit 1", dbesc($conv['guid']), intval($channel['channel_id']));
                continue;
            }
            unset($conv['id']);
            $conv['uid'] = $channel['channel_id'];
            $conv['subject'] = str_rot47(base64url_encode($conv['subject']));
            $r = q("select id from conv where guid = '%s' and uid = %d limit 1", dbesc($conv['guid']), intval($channel['channel_id']));
            if ($r) {
                continue;
            }
            dbesc_array($conv);
            $r = dbq("INSERT INTO conv (`" . implode("`, `", array_keys($conv)) . "`) VALUES ('" . implode("', '", array_values($conv)) . "')");
        }
    }
}
Exemplo n.º 6
0
function diaspora_send_mail($item, $owner, $contact)
{
    $a = get_app();
    $myaddr = $owner['channel_address'] . '@' . App::get_hostname();
    $r = q("select * from conv where guid = '%s' and uid = %d limit 1", dbesc($item['conv_guid']), intval($item['channel_id']));
    if (!count($r)) {
        logger('diaspora_send_mail: conversation not found.');
        return;
    }
    $z = q("select from_xchan from mail where conv_guid = '%s' and channel_id = %d and mid = parent_mid limit 1", dbesc($item['conv_guid']), intval($item['channel_id']));
    $conv_owner = $z && $z[0]['from_xchan'] === $owner['channel_hash'] ? true : false;
    $cnv = $r[0];
    $cnv['subject'] = base64url_decode(str_rot47($cnv['subject']));
    $conv = array('guid' => xmlify($cnv['guid']), 'subject' => xmlify($cnv['subject']), 'created_at' => xmlify(datetime_convert('UTC', 'UTC', $cnv['created'], 'Y-m-d H:i:s \\U\\T\\C')), 'diaspora_handle' => xmlify($cnv['creator']), 'participant_handles' => xmlify($cnv['recips']));
    if (array_key_exists('mail_obscured', $item) && intval($item['mail_obscured'])) {
        if ($item['title']) {
            $item['title'] = base64url_decode(str_rot47($item['title']));
        }
        if ($item['body']) {
            $item['body'] = base64url_decode(str_rot47($item['body']));
        }
    }
    // the parent_guid needs to be the conversation guid
    $parent_ptr = $cnv['guid'];
    $body = bb2diaspora($item['body']);
    $created = datetime_convert('UTC', 'UTC', $item['created'], 'Y-m-d H:i:s \\U\\T\\C');
    $signed_text = $item['mid'] . ';' . $parent_ptr . ';' . $body . ';' . $created . ';' . $myaddr . ';' . $cnv['guid'];
    $sig = base64_encode(rsa_sign($signed_text, $owner['channel_prvkey'], 'sha256'));
    $msg = array('guid' => xmlify($item['mid']), 'parent_guid' => xmlify($parent_ptr), 'parent_author_signature' => $conv_owner ? xmlify($sig) : null, 'author_signature' => xmlify($sig), 'text' => xmlify($body), 'created_at' => xmlify($created), 'diaspora_handle' => xmlify($myaddr), 'conversation_guid' => xmlify($cnv['guid']));
    if ($item['mail_isreply']) {
        $tpl = get_markup_template('diaspora_message.tpl', 'addon/diaspora');
        $xmsg = replace_macros($tpl, array('$msg' => $msg));
    } else {
        $conv['messages'] = array($msg);
        $tpl = get_markup_template('diaspora_conversation.tpl', 'addon/diaspora');
        $xmsg = replace_macros($tpl, array('$conv' => $conv));
    }
    logger('diaspora_conversation: ' . print_r($xmsg, true), LOGGER_DATA);
    $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($xmsg, $owner, $contact, $owner['channel_prvkey'], $contact['xchan_pubkey'], false)));
    return diaspora_queue($owner, $contact, $slap, false, $item['mid']);
}
Exemplo n.º 7
0
function diaspora_message($importer, $xml, $msg)
{
    $a = get_app();
    $msg_guid = notags(unxmlify($xml['guid']));
    $msg_parent_guid = notags(unxmlify($xml['parent_guid']));
    $msg_parent_author_signature = notags(unxmlify($xml['parent_author_signature']));
    $msg_author_signature = notags(unxmlify($xml['author_signature']));
    $msg_text = unxmlify($xml['text']);
    $msg_created_at = datetime_convert('UTC', 'UTC', notags(unxmlify($xml['created_at'])));
    $msg_diaspora_handle = notags(diaspora_get_author($xml));
    $msg_conversation_guid = notags(unxmlify($xml['conversation_guid']));
    $parent_uri = $msg_parent_guid;
    $contact = diaspora_get_contact_by_handle($importer['channel_id'], $msg_diaspora_handle);
    if (!$contact) {
        logger('diaspora_message: cannot find contact: ' . $msg_diaspora_handle);
        return;
    }
    if (!perm_is_allowed($importer['channel_id'], $contact['xchan_hash'], 'post_mail')) {
        logger('Ignoring this author.');
        return 202;
    }
    $conversation = null;
    $c = q("select * from conv where uid = %d and guid = '%s' limit 1", intval($importer['channel_id']), dbesc($msg_conversation_guid));
    if ($c) {
        $conversation = $c[0];
    } else {
        logger('diaspora_message: conversation not available.');
        return;
    }
    $reply = 0;
    $subject = $conversation['subject'];
    //this is already encoded
    $body = diaspora2bb($msg_text);
    $maxlen = get_max_import_size();
    if ($maxlen && mb_strlen($body) > $maxlen) {
        $body = mb_substr($body, 0, $maxlen, 'UTF-8');
        logger('message length exceeds max_import_size: truncated');
    }
    $parent_ptr = $msg_parent_guid;
    if ($parent_ptr === $conversation['guid']) {
        // this should always be the case
        $x = q("select mid from mail where conv_guid = '%s' and channel_id = %d order by id asc limit 1", dbesc($conversation['guid']), intval($importer['channel_id']));
        if ($x) {
            $parent_ptr = $x[0]['mid'];
        }
    }
    $author_signed_data = $msg_guid . ';' . $msg_parent_guid . ';' . $msg_text . ';' . unxmlify($xml['created_at']) . ';' . $msg_diaspora_handle . ';' . $msg_conversation_guid;
    $author_signature = base64_decode($msg_author_signature);
    $person = find_diaspora_person_by_handle($msg_diaspora_handle);
    if (is_array($person) && x($person, 'xchan_pubkey')) {
        $key = $person['xchan_pubkey'];
    } else {
        logger('diaspora_message: unable to find author details');
        return;
    }
    if (!rsa_verify($author_signed_data, $author_signature, $key, 'sha256')) {
        logger('diaspora_message: verification failed.');
        return;
    }
    $r = q("select id from mail where mid = '%s' and channel_id = %d limit 1", dbesc($msg_guid), intval($importer['channel_id']));
    if ($r) {
        logger('diaspora_message: duplicate message already delivered.', LOGGER_DEBUG);
        return;
    }
    $key = get_config('system', 'pubkey');
    // $subject is a copy of the already obscured subject from the conversation structure
    if ($body) {
        $body = str_rot47(base64url_encode($body));
    }
    q("insert into mail ( `account_id`, `channel_id`, `convid`, `conv_guid`, `from_xchan`,`to_xchan`,`title`,`body`,`mail_obscured`,`mid`,`parent_mid`,`created`, mail_isreply) values ( %d, %d, %d, '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', %d)", intval($importer['channel_account_id']), intval($importer['channel_id']), intval($conversation['id']), dbesc($conversation['guid']), dbesc($person['xchan_hash']), dbesc($importer['xchan_hash']), dbesc($subject), dbesc($body), intval(1), dbesc($msg_guid), dbesc($parent_ptr), dbesc($msg_created_at), intval(1));
    q("update conv set updated = '%s' where id = %d", dbesc(datetime_convert()), intval($conversation['id']));
    $z = q("select * from mail where mid = '%s' and channel_id = %d limit 1", dbesc($msg_guid), intval($importer['channel_id']));
    \Zotlabs\Lib\Enotify::submit(array('from_xchan' => $person['xchan_hash'], 'to_xchan' => $importer['channel_hash'], 'type' => NOTIFY_MAIL, 'item' => $z[0], 'verb' => ACTIVITY_POST, 'otype' => 'mail'));
    return;
}