Пример #1
0
function contactgroup_content(&$a)
{
    if (!local_user()) {
        killme();
    }
    if (argc() > 2 && intval(argv(1)) && argv(2)) {
        $r = q("SELECT abook_xchan from abook where abook_xchan = '%s' and abook_channel = %d and not ( abook_flags & %d ) limit 1", dbesc(argv(2)), intval(local_user()), intval(ABOOK_FLAG_SELF));
        if ($r) {
            $change = $r[0]['abook_xchan'];
        }
    }
    if (argc() > 1 && intval(argv(1))) {
        $r = q("SELECT * FROM `groups` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", intval(argv(1)), intval(local_user()));
        if (!$r) {
            killme();
        }
        $group = $r[0];
        $members = group_get_members($group['id']);
        $preselected = array();
        if (count($members)) {
            foreach ($members as $member) {
                $preselected[] = $member['xchan_hash'];
            }
        }
        if ($change) {
            if (in_array($change, $preselected)) {
                group_rmv_member(local_user(), $group['name'], $change);
            } else {
                group_add_member(local_user(), $group['name'], $change);
            }
        }
    }
    killme();
}
Пример #2
0
function contactgroup_content(&$a)
{
    if (!local_user()) {
        killme();
    }
    if ($a->argc > 2 && intval($a->argv[1]) && intval($a->argv[2])) {
        $r = q("SELECT `id` FROM `contact` WHERE `id` = %d AND `uid` = %d and `self` = 0 and `blocked` = 0 AND `pending` = 0 LIMIT 1", intval($a->argv[2]), intval(local_user()));
        if (count($r)) {
            $change = intval($a->argv[2]);
        }
    }
    if ($a->argc > 1 && intval($a->argv[1])) {
        $r = q("SELECT * FROM `group` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", intval($a->argv[1]), intval(local_user()));
        if (!count($r)) {
            killme();
        }
        $group = $r[0];
        $members = group_get_members($group['id']);
        $preselected = array();
        if (count($members)) {
            foreach ($members as $member) {
                $preselected[] = $member['id'];
            }
        }
        if ($change) {
            if (in_array($change, $preselected)) {
                group_rmv_member(local_user(), $group['name'], $change);
            } else {
                group_add_member(local_user(), $group['name'], $change);
            }
        }
    }
    killme();
}
Пример #3
0
 function get()
 {
     if (!local_channel()) {
         killme();
     }
     if (argc() > 2 && intval(argv(1)) && argv(2)) {
         $r = q("SELECT abook_xchan from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1", dbesc(base64url_decode(argv(2))), intval(local_channel()));
         if ($r) {
             $change = $r[0]['abook_xchan'];
         }
     }
     if (argc() > 1 && intval(argv(1))) {
         $r = q("SELECT * FROM `groups` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", intval(argv(1)), intval(local_channel()));
         if (!$r) {
             killme();
         }
         $group = $r[0];
         $members = group_get_members($group['id']);
         $preselected = array();
         if (count($members)) {
             foreach ($members as $member) {
                 $preselected[] = $member['xchan_hash'];
             }
         }
         if ($change) {
             if (in_array($change, $preselected)) {
                 group_rmv_member(local_channel(), $group['gname'], $change);
             } else {
                 group_add_member(local_channel(), $group['gname'], $change);
             }
         }
     }
     killme();
 }
Пример #4
0
function group_content(&$a)
{
    if (!local_user()) {
        notice(t('Permission denied') . EOL);
        return;
    }
    // Switch to text mod interface if we have more than 'n' contacts or group members
    $switchtotext = get_pconfig(local_user(), 'system', 'groupedit_image_limit');
    if ($switchtotext === false) {
        $switchtotext = get_config('system', 'groupedit_image_limit');
    }
    if ($switchtotext === false) {
        $switchtotext = 400;
    }
    if ($a->argc == 2 && $a->argv[1] === 'new') {
        $tpl = get_markup_template('group_new.tpl');
        $o .= replace_macros($tpl, array('$desc' => t('Create a group of contacts/friends.'), '$name' => t('Group Name: '), '$submit' => t('Submit')));
        return $o;
    }
    if ($a->argc == 3 && $a->argv[1] === 'drop') {
        if (intval($a->argv[2])) {
            $r = q("SELECT `name` FROM `group` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($a->argv[2]), intval(local_user()));
            if (count($r)) {
                $result = group_rmv(local_user(), $r[0]['name']);
            }
            if ($result) {
                info(t('Group removed.') . EOL);
            } else {
                notice(t('Unable to remove group.') . EOL);
            }
        }
        goaway($a->get_baseurl() . '/group');
        // NOTREACHED
    }
    if ($a->argc > 2 && intval($a->argv[1]) && intval($a->argv[2])) {
        $r = q("SELECT `id` FROM `contact` WHERE `id` = %d AND `uid` = %d and `self` = 0 and `blocked` = 0 AND `pending` = 0 LIMIT 1", intval($a->argv[2]), intval(local_user()));
        if (count($r)) {
            $change = intval($a->argv[2]);
        }
    }
    if ($a->argc > 1 && intval($a->argv[1])) {
        require_once 'include/acl_selectors.php';
        $r = q("SELECT * FROM `group` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", intval($a->argv[1]), intval(local_user()));
        if (!count($r)) {
            notice(t('Group not found.') . EOL);
            goaway($a->get_baseurl() . '/contacts');
        }
        $group = $r[0];
        $members = group_get_members($group['id']);
        $preselected = array();
        if (count($members)) {
            foreach ($members as $member) {
                $preselected[] = $member['id'];
            }
        }
        if ($change) {
            if (in_array($change, $preselected)) {
                group_rmv_member(local_user(), $group['name'], $change);
            } else {
                group_add_member(local_user(), $group['name'], $change);
            }
            $members = group_get_members($group['id']);
            $preselected = array();
            if (count($members)) {
                foreach ($members as $member) {
                    $preselected[] = $member['id'];
                }
            }
        }
        $drop_tpl = get_markup_template('group_drop.tpl');
        $drop_txt = replace_macros($drop_tpl, array('$id' => $group['id'], '$delete' => t('Delete')));
        $celeb = $a->user['page-flags'] == PAGE_SOAPBOX || $a->user['page-flags'] == PAGE_COMMUNITY ? true : false;
        $tpl = get_markup_template('group_edit.tpl');
        $o .= replace_macros($tpl, array('$gid' => $group['id'], '$name' => $group['name'], '$drop' => $drop_txt, '$desc' => t('Click on a contact to add or remove.'), '$title' => t('Group Editor'), '$gname' => t('Group Name: '), '$submit' => t('Submit')));
    }
    if (!isset($group)) {
        return;
    }
    $o .= '<div id="group-update-wrapper">';
    if ($change) {
        $o = '';
    }
    $o .= '<h3>' . t('Members') . '</h3>';
    $o .= '<div id="group-members">';
    $textmode = $switchtotext && count($members) > $switchtotext ? true : false;
    foreach ($members as $member) {
        if ($member['url']) {
            $member['click'] = 'groupChangeMember(' . $group['id'] . ',' . $member['id'] . '); return true;';
            $o .= micropro($member, true, 'mpgroup', $textmode);
        } else {
            group_rmv_member(local_user(), $group['name'], $member['id']);
        }
    }
    $o .= '</div><div id="group-members-end"></div>';
    $o .= '<hr id="group-separator" />';
    $o .= '<h3>' . t('All Contacts') . '</h3>';
    $o .= '<div id="group-all-contacts">';
    $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `blocked` = 0 and `pending` = 0 and `self` = 0 ORDER BY `name` ASC", intval(local_user()));
    if (count($r)) {
        $textmode = $switchtotext && count($r) > $switchtotext ? true : false;
        foreach ($r as $member) {
            if (!in_array($member['id'], $preselected)) {
                $member['click'] = 'groupChangeMember(' . $group['id'] . ',' . $member['id'] . '); return true;';
                $o .= micropro($member, true, 'mpall', $textmode);
            }
        }
    }
    $o .= '</div><div id="group-all-contacts-end"></div>';
    if ($change) {
        echo $o;
        killme();
    }
    $o .= '</div>';
    return $o;
}
Пример #5
0
 function get()
 {
     $change = false;
     logger('mod_group: ' . \App::$cmd, LOGGER_DEBUG);
     if (!local_channel()) {
         notice(t('Permission denied') . EOL);
         return;
     }
     // Switch to text mode interface if we have more than 'n' contacts or group members
     $switchtotext = get_pconfig(local_channel(), 'system', 'groupedit_image_limit');
     if ($switchtotext === false) {
         $switchtotext = get_config('system', 'groupedit_image_limit');
     }
     if ($switchtotext === false) {
         $switchtotext = 400;
     }
     $tpl = get_markup_template('group_edit.tpl');
     $context = array('$submit' => t('Submit'));
     if (argc() == 2 && argv(1) === 'new') {
         return replace_macros($tpl, $context + array('$title' => t('Create a group of channels.'), '$gname' => array('groupname', t('Privacy group name: '), '', ''), '$gid' => 'new', '$public' => array('public', t('Members are visible to other channels'), false, ''), '$form_security_token' => get_form_security_token("group_edit")));
     }
     if (argc() == 3 && argv(1) === 'drop') {
         check_form_security_token_redirectOnErr('/group', 'group_drop', 't');
         if (intval(argv(2))) {
             $r = q("SELECT `name` FROM `groups` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval(argv(2)), intval(local_channel()));
             if ($r) {
                 $result = group_rmv(local_channel(), $r[0]['gname']);
             }
             if ($result) {
                 info(t('Privacy group removed.') . EOL);
             } else {
                 notice(t('Unable to remove privacy group.') . EOL);
             }
         }
         goaway(z_root() . '/group');
         // NOTREACHED
     }
     if (argc() > 2 && intval(argv(1)) && argv(2)) {
         check_form_security_token_ForbiddenOnErr('group_member_change', 't');
         $r = q("SELECT abook_xchan from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 limit 1", dbesc(base64url_decode(argv(2))), intval(local_channel()));
         if (count($r)) {
             $change = base64url_decode(argv(2));
         }
     }
     if (argc() > 1 && intval(argv(1))) {
         require_once 'include/acl_selectors.php';
         $r = q("SELECT * FROM `groups` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", intval(argv(1)), intval(local_channel()));
         if (!$r) {
             notice(t('Privacy group not found.') . EOL);
             goaway(z_root() . '/connections');
         }
         $group = $r[0];
         $members = group_get_members($group['id']);
         $preselected = array();
         if (count($members)) {
             foreach ($members as $member) {
                 if (!in_array($member['xchan_hash'], $preselected)) {
                     $preselected[] = $member['xchan_hash'];
                 }
             }
         }
         if ($change) {
             if (in_array($change, $preselected)) {
                 group_rmv_member(local_channel(), $group['gname'], $change);
             } else {
                 group_add_member(local_channel(), $group['gname'], $change);
             }
             $members = group_get_members($group['id']);
             $preselected = array();
             if (count($members)) {
                 foreach ($members as $member) {
                     $preselected[] = $member['xchan_hash'];
                 }
             }
         }
         $drop_tpl = get_markup_template('group_drop.tpl');
         $drop_txt = replace_macros($drop_tpl, array('$id' => $group['id'], '$delete' => t('Delete'), '$form_security_token' => get_form_security_token("group_drop")));
         $context = $context + array('$title' => t('Privacy group editor'), '$gname' => array('groupname', t('Privacy group name: '), $group['gname'], ''), '$gid' => $group['id'], '$drop' => $drop_txt, '$public' => array('public', t('Members are visible to other channels'), $group['visible'], ''), '$form_security_token' => get_form_security_token('group_edit'));
     }
     if (!isset($group)) {
         return;
     }
     $groupeditor = array('label_members' => t('Members'), 'members' => array(), 'label_contacts' => t('All Connected Channels'), 'contacts' => array());
     $sec_token = addslashes(get_form_security_token('group_member_change'));
     $textmode = $switchtotext && count($members) > $switchtotext ? true : false;
     foreach ($members as $member) {
         if ($member['xchan_url']) {
             $member['archived'] = intval($member['abook_archived']) ? true : false;
             $member['click'] = 'groupChangeMember(' . $group['id'] . ',\'' . base64url_encode($member['xchan_hash']) . '\',\'' . $sec_token . '\'); return false;';
             $groupeditor['members'][] = micropro($member, true, 'mpgroup', $textmode);
         } else {
             group_rmv_member(local_channel(), $group['gname'], $member['xchan_hash']);
         }
     }
     $r = q("SELECT abook.*, xchan.* FROM `abook` left join xchan on abook_xchan = xchan_hash WHERE `abook_channel` = %d AND abook_self = 0 and abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 order by xchan_name asc", intval(local_channel()));
     if (count($r)) {
         $textmode = $switchtotext && count($r) > $switchtotext ? true : false;
         foreach ($r as $member) {
             if (!in_array($member['xchan_hash'], $preselected)) {
                 $member['archived'] = intval($member['abook_archived']) ? true : false;
                 $member['click'] = 'groupChangeMember(' . $group['id'] . ',\'' . base64url_encode($member['xchan_hash']) . '\',\'' . $sec_token . '\'); return false;';
                 $groupeditor['contacts'][] = micropro($member, true, 'mpall', $textmode);
             }
         }
     }
     $context['$groupeditor'] = $groupeditor;
     $context['$desc'] = t('Click on a channel to add or remove.');
     if ($change) {
         $tpl = get_markup_template('groupeditor.tpl');
         echo replace_macros($tpl, $context);
         killme();
     }
     return replace_macros($tpl, $context);
 }
Пример #6
0
/**
 * @brief Create a new channel.
 *
 * Also creates the related xchan, hubloc, profile, and "self" abook records,
 * and an empty "Friends" group/collection for the new channel.
 *
 * @param array $arr assoziative array with:
 *  * \e string \b name full name of channel
 *  * \e string \b nickname "email/url-compliant" nickname
 *  * \e int \b account_id to attach with this channel
 *  * [other identity fields as desired]
 *
 * @returns array
 *     'success' => boolean true or false
 *     'message' => optional error text if success is false
 *     'channel' => if successful the created channel array
 */
function create_identity($arr)
{
    $a = get_app();
    $ret = array('success' => false);
    if (!$arr['account_id']) {
        $ret['message'] = t('No account identifier');
        return $ret;
    }
    $ret = identity_check_service_class($arr['account_id']);
    if (!$ret['success']) {
        return $ret;
    }
    // save this for auto_friending
    $total_identities = $ret['total_identities'];
    $nick = mb_strtolower(trim($arr['nickname']));
    if (!$nick) {
        $ret['message'] = t('Nickname is required.');
        return $ret;
    }
    $name = escape_tags($arr['name']);
    $pageflags = x($arr, 'pageflags') ? intval($arr['pageflags']) : PAGE_NORMAL;
    $system = x($arr, 'system') ? intval($arr['system']) : 0;
    $name_error = validate_channelname($arr['name']);
    if ($name_error) {
        $ret['message'] = $name_error;
        return $ret;
    }
    if ($nick === 'sys' && !$system) {
        $ret['message'] = t('Reserved nickname. Please choose another.');
        return $ret;
    }
    if (check_webbie(array($nick)) !== $nick) {
        $ret['message'] = t('Nickname has unsupported characters or is already being used on this site.');
        return $ret;
    }
    $guid = zot_new_uid($nick);
    $key = new_keypair(4096);
    $sig = base64url_encode(rsa_sign($guid, $key['prvkey']));
    $hash = make_xchan_hash($guid, $sig);
    // Force a few things on the short term until we can provide a theme or app with choice
    $publish = 1;
    if (array_key_exists('publish', $arr)) {
        $publish = intval($arr['publish']);
    }
    $primary = true;
    if (array_key_exists('primary', $arr)) {
        $primary = intval($arr['primary']);
    }
    $role_permissions = null;
    $global_perms = get_perms();
    if (array_key_exists('permissions_role', $arr) && $arr['permissions_role']) {
        $role_permissions = get_role_perms($arr['permissions_role']);
        if ($role_permissions) {
            foreach ($role_permissions as $p => $v) {
                if (strpos($p, 'channel_') !== false) {
                    $perms_keys .= ', ' . $p;
                    $perms_vals .= ', ' . intval($v);
                }
                if ($p === 'directory_publish') {
                    $publish = intval($v);
                }
            }
        }
    } else {
        $defperms = site_default_perms();
        foreach ($defperms as $p => $v) {
            $perms_keys .= ', ' . $global_perms[$p][0];
            $perms_vals .= ', ' . intval($v);
        }
    }
    $expire = 0;
    $r = q("insert into channel ( channel_account_id, channel_primary, \n\t\tchannel_name, channel_address, channel_guid, channel_guid_sig,\n\t\tchannel_hash, channel_prvkey, channel_pubkey, channel_pageflags, channel_system, channel_expire_days, channel_timezone {$perms_keys} )\n\t\tvalues ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s' {$perms_vals} ) ", intval($arr['account_id']), intval($primary), dbesc($name), dbesc($nick), dbesc($guid), dbesc($sig), dbesc($hash), dbesc($key['prvkey']), dbesc($key['pubkey']), intval($pageflags), intval($system), intval($expire), dbesc($a->timezone));
    $r = q("select * from channel where channel_account_id = %d \n\t\tand channel_guid = '%s' limit 1", intval($arr['account_id']), dbesc($guid));
    if (!$r) {
        $ret['message'] = t('Unable to retrieve created identity');
        return $ret;
    }
    $ret['channel'] = $r[0];
    if (intval($arr['account_id'])) {
        set_default_login_identity($arr['account_id'], $ret['channel']['channel_id'], false);
    }
    // Create a verified hub location pointing to this site.
    $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_primary, \n\t\thubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_network )\n\t\tvalues ( '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )", dbesc($guid), dbesc($sig), dbesc($hash), dbesc($ret['channel']['channel_address'] . '@' . get_app()->get_hostname()), intval($primary), dbesc(z_root()), dbesc(base64url_encode(rsa_sign(z_root(), $ret['channel']['channel_prvkey']))), dbesc(get_app()->get_hostname()), dbesc(z_root() . '/post'), dbesc(get_config('system', 'pubkey')), dbesc('zot'));
    if (!$r) {
        logger('create_identity: Unable to store hub location');
    }
    $newuid = $ret['channel']['channel_id'];
    $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_l, xchan_photo_m, xchan_photo_s, xchan_addr, xchan_url, xchan_follow, xchan_connurl, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_system ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)", dbesc($hash), dbesc($guid), dbesc($sig), dbesc($key['pubkey']), dbesc($a->get_baseurl() . "/photo/profile/l/{$newuid}"), dbesc($a->get_baseurl() . "/photo/profile/m/{$newuid}"), dbesc($a->get_baseurl() . "/photo/profile/s/{$newuid}"), dbesc($ret['channel']['channel_address'] . '@' . get_app()->get_hostname()), dbesc(z_root() . '/channel/' . $ret['channel']['channel_address']), dbesc(z_root() . '/follow?f=&url=%s'), dbesc(z_root() . '/poco/' . $ret['channel']['channel_address']), dbesc($ret['channel']['channel_name']), dbesc('zot'), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($system));
    // Not checking return value.
    // It's ok for this to fail if it's an imported channel, and therefore the hash is a duplicate
    $r = q("INSERT INTO profile ( aid, uid, profile_guid, profile_name, is_default, publish, name, photo, thumb)\n\t\tVALUES ( %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s') ", intval($ret['channel']['channel_account_id']), intval($newuid), dbesc(random_string()), t('Default Profile'), 1, $publish, dbesc($ret['channel']['channel_name']), dbesc($a->get_baseurl() . "/photo/profile/l/{$newuid}"), dbesc($a->get_baseurl() . "/photo/profile/m/{$newuid}"));
    if ($role_permissions) {
        $myperms = array_key_exists('perms_auto', $role_permissions) && $role_permissions['perms_auto'] ? intval($role_permissions['perms_accept']) : 0;
    } else {
        $myperms = PERMS_R_STREAM | PERMS_R_PROFILE | PERMS_R_PHOTOS | PERMS_R_ABOOK | PERMS_W_STREAM | PERMS_W_WALL | PERMS_W_COMMENT | PERMS_W_MAIL | PERMS_W_CHAT | PERMS_R_STORAGE | PERMS_R_PAGES | PERMS_W_LIKE;
    }
    $r = q("insert into abook ( abook_account, abook_channel, abook_xchan, abook_closeness, abook_created, abook_updated, abook_self, abook_my_perms )\n\t\tvalues ( %d, %d, '%s', %d, '%s', '%s', %d, %d ) ", intval($ret['channel']['channel_account_id']), intval($newuid), dbesc($hash), intval(0), dbesc(datetime_convert()), dbesc(datetime_convert()), intval(1), intval($myperms));
    if (intval($ret['channel']['channel_account_id'])) {
        // Save our permissions role so we can perhaps call it up and modify it later.
        if ($role_permissions) {
            set_pconfig($newuid, 'system', 'permissions_role', $arr['permissions_role']);
            if (array_key_exists('online', $role_permissions)) {
                set_pconfig($newuid, 'system', 'hide_presence', 1 - intval($role_permissions['online']));
            }
            if (array_key_exists('perms_auto', $role_permissions)) {
                set_pconfig($newuid, 'system', 'autoperms', $role_permissions['perms_auto'] ? $role_permissions['perms_accept'] : 0);
            }
        }
        // Create a group with yourself as a member. This allows somebody to use it
        // right away as a default group for new contacts.
        require_once 'include/group.php';
        group_add($newuid, t('Friends'));
        group_add_member($newuid, t('Friends'), $ret['channel']['channel_hash']);
        // if our role_permissions indicate that we're using a default collection ACL, add it.
        if (is_array($role_permissions) && $role_permissions['default_collection']) {
            $r = q("select hash from groups where uid = %d and name = '%s' limit 1", intval($newuid), dbesc(t('Friends')));
            if ($r) {
                q("update channel set channel_default_group = '%s', channel_allow_gid = '%s' where channel_id = %d", dbesc($r[0]['hash']), dbesc('<' . $r[0]['hash'] . '>'), intval($newuid));
            }
        }
        if (!$system) {
            set_pconfig($ret['channel']['channel_id'], 'system', 'photo_path', '%Y-%m');
            set_pconfig($ret['channel']['channel_id'], 'system', 'attach_path', '%Y-%m');
        }
        // auto-follow any of the hub's pre-configured channel choices.
        // Only do this if it's the first channel for this account;
        // otherwise it could get annoying. Don't make this list too big
        // or it will impact registration time.
        $accts = get_config('system', 'auto_follow');
        if ($accts && !$total_identities) {
            require_once 'include/follow.php';
            if (!is_array($accts)) {
                $accts = array($accts);
            }
            foreach ($accts as $acct) {
                if (trim($acct)) {
                    new_contact($newuid, trim($acct), $ret['channel'], false);
                }
            }
        }
        call_hooks('create_identity', $newuid);
        proc_run('php', 'include/directory.php', $ret['channel']['channel_id']);
    }
    $ret['success'] = true;
    return $ret;
}
Пример #7
0
 function post()
 {
     $channel = \App::get_channel();
     check_form_security_token_redirectOnErr('/settings', 'settings');
     call_hooks('settings_post', $_POST);
     $set_perms = '';
     $role = x($_POST, 'permissions_role') ? notags(trim($_POST['permissions_role'])) : '';
     $oldrole = get_pconfig(local_channel(), 'system', 'permissions_role');
     if ($role != $oldrole || $role === 'custom') {
         if ($role === 'custom') {
             $hide_presence = x($_POST, 'hide_presence') && intval($_POST['hide_presence']) == 1 ? 1 : 0;
             $publish = x($_POST, 'profile_in_directory') && intval($_POST['profile_in_directory']) == 1 ? 1 : 0;
             $def_group = x($_POST, 'group-selection') ? notags(trim($_POST['group-selection'])) : '';
             $r = q("update channel set channel_default_group = '%s' where channel_id = %d", dbesc($def_group), intval(local_channel()));
             $global_perms = \Zotlabs\Access\Permissions::Perms();
             foreach ($global_perms as $k => $v) {
                 \Zotlabs\Access\PermissionLimits::Set(local_channel(), $k, intval($_POST[$k]));
             }
             $acl = new \Zotlabs\Access\AccessList($channel);
             $acl->set_from_array($_POST);
             $x = $acl->get();
             $r = q("update channel set channel_allow_cid = '%s', channel_allow_gid = '%s', \n\t\t\t\t\tchannel_deny_cid = '%s', channel_deny_gid = '%s' where channel_id = %d", dbesc($x['allow_cid']), dbesc($x['allow_gid']), dbesc($x['deny_cid']), dbesc($x['deny_gid']), intval(local_channel()));
         } else {
             $role_permissions = \Zotlabs\Access\PermissionRoles::role_perms($_POST['permissions_role']);
             if (!$role_permissions) {
                 notice('Permissions category could not be found.');
                 return;
             }
             $hide_presence = 1 - intval($role_permissions['online']);
             if ($role_permissions['default_collection']) {
                 $r = q("select hash from groups where uid = %d and gname = '%s' limit 1", intval(local_channel()), dbesc(t('Friends')));
                 if (!$r) {
                     require_once 'include/group.php';
                     group_add(local_channel(), t('Friends'));
                     group_add_member(local_channel(), t('Friends'), $channel['channel_hash']);
                     $r = q("select hash from groups where uid = %d and gname = '%s' limit 1", intval(local_channel()), dbesc(t('Friends')));
                 }
                 if ($r) {
                     q("update channel set channel_default_group = '%s', channel_allow_gid = '%s', channel_allow_cid = '', channel_deny_gid = '', channel_deny_cid = '' where channel_id = %d", dbesc($r[0]['hash']), dbesc('<' . $r[0]['hash'] . '>'), intval(local_channel()));
                 } else {
                     notice(sprintf('Default privacy group \'%s\' not found. Please create and re-submit permission change.', t('Friends')) . EOL);
                     return;
                 }
             } else {
                 q("update channel set channel_default_group = '', channel_allow_gid = '', channel_allow_cid = '', channel_deny_gid = '', \n\t\t\t\t\t\tchannel_deny_cid = '' where channel_id = %d", intval(local_channel()));
             }
             $x = \Zotlabs\Access\Permissions::FilledPerms($role_permissions['perms_connect']);
             foreach ($x as $k => $v) {
                 set_abconfig(local_channel(), $channel['channel_hash'], 'my_perms', $k, $v);
                 if ($role_permissions['perms_auto']) {
                     set_pconfig(local_channel(), 'autoperms', $k, $v);
                 } else {
                     del_pconfig(local_channel(), 'autoperms', $k);
                 }
             }
             if ($role_permissions['limits']) {
                 foreach ($role_permissions['limits'] as $k => $v) {
                     \Zotlabs\Access\PermissionLimits::Set(local_channel(), $k, $v);
                 }
             }
             if (array_key_exists('directory_publish', $role_permissions)) {
                 $publish = intval($role_permissions['directory_publish']);
             }
         }
         set_pconfig(local_channel(), 'system', 'hide_online_status', $hide_presence);
         set_pconfig(local_channel(), 'system', 'permissions_role', $role);
     }
     $username = x($_POST, 'username') ? notags(trim($_POST['username'])) : '';
     $timezone = x($_POST, 'timezone_select') ? notags(trim($_POST['timezone_select'])) : '';
     $defloc = x($_POST, 'defloc') ? notags(trim($_POST['defloc'])) : '';
     $openid = x($_POST, 'openid_url') ? notags(trim($_POST['openid_url'])) : '';
     $maxreq = x($_POST, 'maxreq') ? intval($_POST['maxreq']) : 0;
     $expire = x($_POST, 'expire') ? intval($_POST['expire']) : 0;
     $evdays = x($_POST, 'evdays') ? intval($_POST['evdays']) : 3;
     $photo_path = x($_POST, 'photo_path') ? escape_tags(trim($_POST['photo_path'])) : '';
     $attach_path = x($_POST, 'attach_path') ? escape_tags(trim($_POST['attach_path'])) : '';
     $channel_menu = x($_POST['channel_menu']) ? htmlspecialchars_decode(trim($_POST['channel_menu']), ENT_QUOTES) : '';
     $expire_items = x($_POST, 'expire_items') ? intval($_POST['expire_items']) : 0;
     $expire_starred = x($_POST, 'expire_starred') ? intval($_POST['expire_starred']) : 0;
     $expire_photos = x($_POST, 'expire_photos') ? intval($_POST['expire_photos']) : 0;
     $expire_network_only = x($_POST, 'expire_network_only') ? intval($_POST['expire_network_only']) : 0;
     $allow_location = x($_POST, 'allow_location') && intval($_POST['allow_location']) == 1 ? 1 : 0;
     $blocktags = x($_POST, 'blocktags') && intval($_POST['blocktags']) == 1 ? 0 : 1;
     // this setting is inverted!
     $unkmail = x($_POST, 'unkmail') && intval($_POST['unkmail']) == 1 ? 1 : 0;
     $cntunkmail = x($_POST, 'cntunkmail') ? intval($_POST['cntunkmail']) : 0;
     $suggestme = x($_POST, 'suggestme') ? intval($_POST['suggestme']) : 0;
     $post_newfriend = $_POST['post_newfriend'] == 1 ? 1 : 0;
     $post_joingroup = $_POST['post_joingroup'] == 1 ? 1 : 0;
     $post_profilechange = $_POST['post_profilechange'] == 1 ? 1 : 0;
     $adult = $_POST['adult'] == 1 ? 1 : 0;
     $cal_first_day = x($_POST, 'first_day') && intval($_POST['first_day']) == 1 ? 1 : 0;
     $pageflags = $channel['channel_pageflags'];
     $existing_adult = $pageflags & PAGE_ADULT ? 1 : 0;
     if ($adult != $existing_adult) {
         $pageflags = $pageflags ^ PAGE_ADULT;
     }
     $notify = 0;
     if (x($_POST, 'notify1')) {
         $notify += intval($_POST['notify1']);
     }
     if (x($_POST, 'notify2')) {
         $notify += intval($_POST['notify2']);
     }
     if (x($_POST, 'notify3')) {
         $notify += intval($_POST['notify3']);
     }
     if (x($_POST, 'notify4')) {
         $notify += intval($_POST['notify4']);
     }
     if (x($_POST, 'notify5')) {
         $notify += intval($_POST['notify5']);
     }
     if (x($_POST, 'notify6')) {
         $notify += intval($_POST['notify6']);
     }
     if (x($_POST, 'notify7')) {
         $notify += intval($_POST['notify7']);
     }
     if (x($_POST, 'notify8')) {
         $notify += intval($_POST['notify8']);
     }
     $vnotify = 0;
     if (x($_POST, 'vnotify1')) {
         $vnotify += intval($_POST['vnotify1']);
     }
     if (x($_POST, 'vnotify2')) {
         $vnotify += intval($_POST['vnotify2']);
     }
     if (x($_POST, 'vnotify3')) {
         $vnotify += intval($_POST['vnotify3']);
     }
     if (x($_POST, 'vnotify4')) {
         $vnotify += intval($_POST['vnotify4']);
     }
     if (x($_POST, 'vnotify5')) {
         $vnotify += intval($_POST['vnotify5']);
     }
     if (x($_POST, 'vnotify6')) {
         $vnotify += intval($_POST['vnotify6']);
     }
     if (x($_POST, 'vnotify7')) {
         $vnotify += intval($_POST['vnotify7']);
     }
     if (x($_POST, 'vnotify8')) {
         $vnotify += intval($_POST['vnotify8']);
     }
     if (x($_POST, 'vnotify9')) {
         $vnotify += intval($_POST['vnotify9']);
     }
     if (x($_POST, 'vnotify10')) {
         $vnotify += intval($_POST['vnotify10']);
     }
     if (x($_POST, 'vnotify11')) {
         $vnotify += intval($_POST['vnotify11']);
     }
     $always_show_in_notices = x($_POST, 'always_show_in_notices') ? 1 : 0;
     $err = '';
     $name_change = false;
     if ($username != $channel['channel_name']) {
         $name_change = true;
         require_once 'include/channel.php';
         $err = validate_channelname($username);
         if ($err) {
             notice($err);
             return;
         }
     }
     if ($timezone != $channel['channel_timezone']) {
         if (strlen($timezone)) {
             date_default_timezone_set($timezone);
         }
     }
     set_pconfig(local_channel(), 'system', 'use_browser_location', $allow_location);
     set_pconfig(local_channel(), 'system', 'suggestme', $suggestme);
     set_pconfig(local_channel(), 'system', 'post_newfriend', $post_newfriend);
     set_pconfig(local_channel(), 'system', 'post_joingroup', $post_joingroup);
     set_pconfig(local_channel(), 'system', 'post_profilechange', $post_profilechange);
     set_pconfig(local_channel(), 'system', 'blocktags', $blocktags);
     set_pconfig(local_channel(), 'system', 'channel_menu', $channel_menu);
     set_pconfig(local_channel(), 'system', 'vnotify', $vnotify);
     set_pconfig(local_channel(), 'system', 'always_show_in_notices', $always_show_in_notices);
     set_pconfig(local_channel(), 'system', 'evdays', $evdays);
     set_pconfig(local_channel(), 'system', 'photo_path', $photo_path);
     set_pconfig(local_channel(), 'system', 'attach_path', $attach_path);
     set_pconfig(local_channel(), 'system', 'cal_first_day', $cal_first_day);
     $r = q("update channel set channel_name = '%s', channel_pageflags = %d, channel_timezone = '%s', channel_location = '%s', channel_notifyflags = %d, channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d {$set_perms} where channel_id = %d", dbesc($username), intval($pageflags), dbesc($timezone), dbesc($defloc), intval($notify), intval($unkmail), intval($maxreq), intval($expire), intval(local_channel()));
     if ($r) {
         info(t('Settings updated.') . EOL);
     }
     if (!is_null($publish)) {
         $r = q("UPDATE profile SET publish = %d WHERE is_default = 1 AND uid = %d", intval($publish), intval(local_channel()));
     }
     if ($name_change) {
         $r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s' where xchan_hash = '%s'", dbesc($username), dbesc(datetime_convert()), dbesc($channel['channel_hash']));
         $r = q("update profile set fullname = '%s' where uid = %d and is_default = 1", dbesc($username), intval($channel['channel_id']));
     }
     \Zotlabs\Daemon\Master::Summon(array('Directory', local_channel()));
     build_sync_packet();
     if ($email_changed && \App::$config['system']['register_policy'] == REGISTER_VERIFY) {
         // FIXME - set to un-verified, blocked and redirect to logout
         // Why? Are we verifying people or email addresses?
     }
     goaway(z_root() . '/settings');
     return;
     // NOTREACHED
 }
Пример #8
0
function settings_post(&$a)
{
    if (!local_channel()) {
        return;
    }
    if ($_SESSION['delegate']) {
        return;
    }
    $channel = $a->get_channel();
    logger('mod_settings: ' . print_r($_REQUEST, true));
    if (argc() > 1 && argv(1) === 'oauth' && x($_POST, 'remove')) {
        check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth');
        $key = $_POST['remove'];
        q("DELETE FROM tokens WHERE id='%s' AND uid=%d", dbesc($key), local_channel());
        goaway($a->get_baseurl(true) . "/settings/oauth/");
        return;
    }
    if (argc() > 2 && argv(1) === 'oauth' && (argv(2) === 'edit' || argv(2) === 'add') && x($_POST, 'submit')) {
        check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth');
        $name = x($_POST, 'name') ? $_POST['name'] : '';
        $key = x($_POST, 'key') ? $_POST['key'] : '';
        $secret = x($_POST, 'secret') ? $_POST['secret'] : '';
        $redirect = x($_POST, 'redirect') ? $_POST['redirect'] : '';
        $icon = x($_POST, 'icon') ? $_POST['icon'] : '';
        $ok = true;
        if ($name == '') {
            $ok = false;
            notice(t('Name is required') . EOL);
        }
        if ($key == '' || $secret == '') {
            $ok = false;
            notice(t('Key and Secret are required') . EOL);
        }
        if ($ok) {
            if ($_POST['submit'] == t("Update")) {
                $r = q("UPDATE clients SET\n\t\t\t\t\t\t\tclient_id='%s',\n\t\t\t\t\t\t\tpw='%s',\n\t\t\t\t\t\t\tname='%s',\n\t\t\t\t\t\t\tredirect_uri='%s',\n\t\t\t\t\t\t\ticon='%s',\n\t\t\t\t\t\t\tuid=%d\n\t\t\t\t\t\tWHERE client_id='%s'", dbesc($key), dbesc($secret), dbesc($name), dbesc($redirect), dbesc($icon), intval(local_channel()), dbesc($key));
            } else {
                $r = q("INSERT INTO clients (client_id, pw, name, redirect_uri, icon, uid)\n\t\t\t\t\tVALUES ('%s','%s','%s','%s','%s',%d)", dbesc($key), dbesc($secret), dbesc($name), dbesc($redirect), dbesc($icon), intval(local_channel()));
                $r = q("INSERT INTO xperm (xp_client, xp_channel, xp_perm) VALUES ('%s', %d, '%s') ", dbesc($key), intval(local_channel()), dbesc('all'));
            }
        }
        goaway($a->get_baseurl(true) . "/settings/oauth/");
        return;
    }
    if (argc() > 1 && argv(1) == 'featured') {
        check_form_security_token_redirectOnErr('/settings/featured', 'settings_featured');
        call_hooks('feature_settings_post', $_POST);
        build_sync_packet();
        return;
    }
    if (argc() > 1 && argv(1) === 'features') {
        check_form_security_token_redirectOnErr('/settings/features', 'settings_features');
        // Build list of features and check which are set
        $features = get_features();
        $all_features = array();
        foreach ($features as $k => $v) {
            foreach ($v as $f) {
                $all_features[] = $f[0];
            }
        }
        foreach ($all_features as $k) {
            if (x($_POST, "feature_{$k}")) {
                set_pconfig(local_channel(), 'feature', $k, 1);
            } else {
                set_pconfig(local_channel(), 'feature', $k, 0);
            }
        }
        build_sync_packet();
        return;
    }
    if (argc() > 1 && argv(1) == 'display') {
        check_form_security_token_redirectOnErr('/settings/display', 'settings_display');
        $theme = x($_POST, 'theme') ? notags(trim($_POST['theme'])) : $a->channel['channel_theme'];
        $mobile_theme = x($_POST, 'mobile_theme') ? notags(trim($_POST['mobile_theme'])) : '';
        $user_scalable = x($_POST, 'user_scalable') ? intval($_POST['user_scalable']) : 0;
        $nosmile = x($_POST, 'nosmile') ? intval($_POST['nosmile']) : 0;
        $title_tosource = x($_POST, 'title_tosource') ? intval($_POST['title_tosource']) : 0;
        $channel_list_mode = x($_POST, 'channel_list_mode') ? intval($_POST['channel_list_mode']) : 0;
        $network_list_mode = x($_POST, 'network_list_mode') ? intval($_POST['network_list_mode']) : 0;
        $channel_divmore_height = x($_POST, 'channel_divmore_height') ? intval($_POST['channel_divmore_height']) : 400;
        if ($channel_divmore_height < 50) {
            $channel_divmore_height = 50;
        }
        $network_divmore_height = x($_POST, 'network_divmore_height') ? intval($_POST['network_divmore_height']) : 400;
        if ($network_divmore_height < 50) {
            $network_divmore_height = 50;
        }
        $browser_update = x($_POST, 'browser_update') ? intval($_POST['browser_update']) : 0;
        $browser_update = $browser_update * 1000;
        if ($browser_update < 10000) {
            $browser_update = 10000;
        }
        $itemspage = x($_POST, 'itemspage') ? intval($_POST['itemspage']) : 20;
        if ($itemspage > 100) {
            $itemspage = 100;
        }
        if ($mobile_theme == "---") {
            del_pconfig(local_channel(), 'system', 'mobile_theme');
        } else {
            set_pconfig(local_channel(), 'system', 'mobile_theme', $mobile_theme);
        }
        set_pconfig(local_channel(), 'system', 'user_scalable', $user_scalable);
        set_pconfig(local_channel(), 'system', 'update_interval', $browser_update);
        set_pconfig(local_channel(), 'system', 'itemspage', $itemspage);
        set_pconfig(local_channel(), 'system', 'no_smilies', 1 - intval($nosmile));
        set_pconfig(local_channel(), 'system', 'title_tosource', $title_tosource);
        set_pconfig(local_channel(), 'system', 'channel_list_mode', $channel_list_mode);
        set_pconfig(local_channel(), 'system', 'network_list_mode', $network_list_mode);
        set_pconfig(local_channel(), 'system', 'channel_divmore_height', $channel_divmore_height);
        set_pconfig(local_channel(), 'system', 'network_divmore_height', $network_divmore_height);
        if ($theme == $a->channel['channel_theme']) {
            // call theme_post only if theme has not been changed
            if (($themeconfigfile = get_theme_config_file($theme)) != null) {
                require_once $themeconfigfile;
                theme_post($a);
            }
        }
        $r = q("UPDATE channel SET channel_theme = '%s' WHERE channel_id = %d", dbesc($theme), intval(local_channel()));
        call_hooks('display_settings_post', $_POST);
        build_sync_packet();
        goaway($a->get_baseurl(true) . '/settings/display');
        return;
        // NOTREACHED
    }
    if (argc() > 1 && argv(1) === 'account') {
        check_form_security_token_redirectOnErr('/settings/account', 'settings_account');
        call_hooks('account_settings_post', $_POST);
        //		call_hooks('settings_account', $_POST);
        $errs = array();
        if (x($_POST, 'npassword') || x($_POST, 'confirm')) {
            $newpass = $_POST['npassword'];
            $confirm = $_POST['confirm'];
            if ($newpass != $confirm) {
                $errs[] = t('Passwords do not match. Password unchanged.');
            }
            if (!x($newpass) || !x($confirm)) {
                $errs[] = t('Empty passwords are not allowed. Password unchanged.');
            }
            if (!$errs) {
                $salt = random_string(32);
                $password_encoded = hash('whirlpool', $salt . $newpass);
                $r = q("update account set account_salt = '%s', account_password = '******', account_password_changed = '%s' \n\t\t\t\t\twhere account_id = %d", dbesc($salt), dbesc($password_encoded), dbesc(datetime_convert()), intval(get_account_id()));
                if ($r) {
                    info(t('Password changed.') . EOL);
                } else {
                    $errs[] = t('Password update failed. Please try again.');
                }
            }
        }
        if ($errs) {
            foreach ($errs as $err) {
                notice($err . EOL);
            }
            $errs = array();
        }
        $email = x($_POST, 'email') ? trim(notags($_POST['email'])) : '';
        $account = $a->get_account();
        if ($email != $account['account_email']) {
            if (!valid_email($email)) {
                $errs[] = t('Not valid email.');
            }
            $adm = trim(get_config('system', 'admin_email'));
            if ($adm && strcasecmp($email, $adm) == 0) {
                $errs[] = t('Protected email address. Cannot change to that email.');
                $email = $a->user['email'];
            }
            if (!$errs) {
                $r = q("update account set account_email = '%s' where account_id = %d", dbesc($email), intval($account['account_id']));
                if (!$r) {
                    $errs[] = t('System failure storing new email. Please try again.');
                }
            }
        }
        if ($errs) {
            foreach ($errs as $err) {
                notice($err . EOL);
            }
        }
        goaway($a->get_baseurl(true) . '/settings/account');
    }
    check_form_security_token_redirectOnErr('/settings', 'settings');
    call_hooks('settings_post', $_POST);
    $set_perms = '';
    $role = x($_POST, 'permissions_role') ? notags(trim($_POST['permissions_role'])) : '';
    $oldrole = get_pconfig(local_channel(), 'system', 'permissions_role');
    if ($role != $oldrole || $role === 'custom') {
        if ($role === 'custom') {
            $hide_presence = x($_POST, 'hide_presence') && intval($_POST['hide_presence']) == 1 ? 1 : 0;
            $publish = x($_POST, 'profile_in_directory') && intval($_POST['profile_in_directory']) == 1 ? 1 : 0;
            $def_group = x($_POST, 'group-selection') ? notags(trim($_POST['group-selection'])) : '';
            $r = q("update channel set channel_default_group = '%s' where channel_id = %d", dbesc($def_group), intval(local_channel()));
            $global_perms = get_perms();
            foreach ($global_perms as $k => $v) {
                $set_perms .= ', ' . $v[0] . ' = ' . intval($_POST[$k]) . ' ';
            }
            $acl = new AccessList($channel);
            $acl->set_from_array($_POST);
            $x = $acl->get();
            $r = q("update channel set channel_allow_cid = '%s', channel_allow_gid = '%s', \n\t\t\t\tchannel_deny_cid = '%s', channel_deny_gid = '%s' where channel_id = %d", dbesc($x['allow_cid']), dbesc($x['allow_gid']), dbesc($x['deny_cid']), dbesc($x['deny_gid']), intval(local_channel()));
        } else {
            $role_permissions = get_role_perms($_POST['permissions_role']);
            if (!$role_permissions) {
                notice('Permissions category could not be found.');
                return;
            }
            $hide_presence = 1 - intval($role_permissions['online']);
            if ($role_permissions['default_collection']) {
                $r = q("select hash from groups where uid = %d and name = '%s' limit 1", intval(local_channel()), dbesc(t('Friends')));
                if (!$r) {
                    require_once 'include/group.php';
                    group_add(local_channel(), t('Friends'));
                    group_add_member(local_channel(), t('Friends'), $channel['channel_hash']);
                    $r = q("select hash from groups where uid = %d and name = '%s' limit 1", intval(local_channel()), dbesc(t('Friends')));
                }
                if ($r) {
                    q("update channel set channel_default_group = '%s', channel_allow_gid = '%s', channel_allow_cid = '', channel_deny_gid = '', channel_deny_cid = '' where channel_id = %d", dbesc($r[0]['hash']), dbesc('<' . $r[0]['hash'] . '>'), intval(local_channel()));
                } else {
                    notice(sprintf('Default privacy group \'%s\' not found. Please create and re-submit permission change.', t('Friends')) . EOL);
                    return;
                }
            } else {
                q("update channel set channel_default_group = '', channel_allow_gid = '', channel_allow_cid = '', channel_deny_gid = '', \n\t\t\t\t\tchannel_deny_cid = '' where channel_id = %d", intval(local_channel()));
            }
            $r = q("update abook set abook_my_perms  = %d where abook_channel = %d and abook_self = 1", intval(array_key_exists('perms_accept', $role_permissions) ? $role_permissions['perms_accept'] : 0), intval(local_channel()));
            set_pconfig(local_channel(), 'system', 'autoperms', $role_permissions['perms_auto'] ? intval($role_permissions['perms_accept']) : 0);
            foreach ($role_permissions as $p => $v) {
                if (strpos($p, 'channel_') !== false) {
                    $set_perms .= ', ' . $p . ' = ' . intval($v) . ' ';
                }
                if ($p === 'directory_publish') {
                    $publish = intval($v);
                }
            }
        }
        set_pconfig(local_channel(), 'system', 'hide_online_status', $hide_presence);
        set_pconfig(local_channel(), 'system', 'permissions_role', $role);
    }
    $username = x($_POST, 'username') ? notags(trim($_POST['username'])) : '';
    $timezone = x($_POST, 'timezone_select') ? notags(trim($_POST['timezone_select'])) : '';
    $defloc = x($_POST, 'defloc') ? notags(trim($_POST['defloc'])) : '';
    $openid = x($_POST, 'openid_url') ? notags(trim($_POST['openid_url'])) : '';
    $maxreq = x($_POST, 'maxreq') ? intval($_POST['maxreq']) : 0;
    $expire = x($_POST, 'expire') ? intval($_POST['expire']) : 0;
    $evdays = x($_POST, 'evdays') ? intval($_POST['evdays']) : 3;
    $photo_path = x($_POST, 'photo_path') ? escape_tags(trim($_POST['photo_path'])) : '';
    $attach_path = x($_POST, 'attach_path') ? escape_tags(trim($_POST['attach_path'])) : '';
    $channel_menu = x($_POST['channel_menu']) ? htmlspecialchars_decode(trim($_POST['channel_menu']), ENT_QUOTES) : '';
    $expire_items = x($_POST, 'expire_items') ? intval($_POST['expire_items']) : 0;
    $expire_starred = x($_POST, 'expire_starred') ? intval($_POST['expire_starred']) : 0;
    $expire_photos = x($_POST, 'expire_photos') ? intval($_POST['expire_photos']) : 0;
    $expire_network_only = x($_POST, 'expire_network_only') ? intval($_POST['expire_network_only']) : 0;
    $allow_location = x($_POST, 'allow_location') && intval($_POST['allow_location']) == 1 ? 1 : 0;
    $blocktags = x($_POST, 'blocktags') && intval($_POST['blocktags']) == 1 ? 0 : 1;
    // this setting is inverted!
    $unkmail = x($_POST, 'unkmail') && intval($_POST['unkmail']) == 1 ? 1 : 0;
    $cntunkmail = x($_POST, 'cntunkmail') ? intval($_POST['cntunkmail']) : 0;
    $suggestme = x($_POST, 'suggestme') ? intval($_POST['suggestme']) : 0;
    $post_newfriend = $_POST['post_newfriend'] == 1 ? 1 : 0;
    $post_joingroup = $_POST['post_joingroup'] == 1 ? 1 : 0;
    $post_profilechange = $_POST['post_profilechange'] == 1 ? 1 : 0;
    $adult = $_POST['adult'] == 1 ? 1 : 0;
    $cal_first_day = x($_POST, 'first_day') && intval($_POST['first_day']) == 1 ? 1 : 0;
    $channel = $a->get_channel();
    $pageflags = $channel['channel_pageflags'];
    $existing_adult = $pageflags & PAGE_ADULT ? 1 : 0;
    if ($adult != $existing_adult) {
        $pageflags = $pageflags ^ PAGE_ADULT;
    }
    $notify = 0;
    if (x($_POST, 'notify1')) {
        $notify += intval($_POST['notify1']);
    }
    if (x($_POST, 'notify2')) {
        $notify += intval($_POST['notify2']);
    }
    if (x($_POST, 'notify3')) {
        $notify += intval($_POST['notify3']);
    }
    if (x($_POST, 'notify4')) {
        $notify += intval($_POST['notify4']);
    }
    if (x($_POST, 'notify5')) {
        $notify += intval($_POST['notify5']);
    }
    if (x($_POST, 'notify6')) {
        $notify += intval($_POST['notify6']);
    }
    if (x($_POST, 'notify7')) {
        $notify += intval($_POST['notify7']);
    }
    if (x($_POST, 'notify8')) {
        $notify += intval($_POST['notify8']);
    }
    $vnotify = 0;
    if (x($_POST, 'vnotify1')) {
        $vnotify += intval($_POST['vnotify1']);
    }
    if (x($_POST, 'vnotify2')) {
        $vnotify += intval($_POST['vnotify2']);
    }
    if (x($_POST, 'vnotify3')) {
        $vnotify += intval($_POST['vnotify3']);
    }
    if (x($_POST, 'vnotify4')) {
        $vnotify += intval($_POST['vnotify4']);
    }
    if (x($_POST, 'vnotify5')) {
        $vnotify += intval($_POST['vnotify5']);
    }
    if (x($_POST, 'vnotify6')) {
        $vnotify += intval($_POST['vnotify6']);
    }
    if (x($_POST, 'vnotify7')) {
        $vnotify += intval($_POST['vnotify7']);
    }
    if (x($_POST, 'vnotify8')) {
        $vnotify += intval($_POST['vnotify8']);
    }
    if (x($_POST, 'vnotify9')) {
        $vnotify += intval($_POST['vnotify9']);
    }
    if (x($_POST, 'vnotify10')) {
        $vnotify += intval($_POST['vnotify10']);
    }
    if (x($_POST, 'vnotify11')) {
        $vnotify += intval($_POST['vnotify11']);
    }
    $always_show_in_notices = x($_POST, 'always_show_in_notices') ? 1 : 0;
    $channel = $a->get_channel();
    $err = '';
    $name_change = false;
    if ($username != $channel['channel_name']) {
        $name_change = true;
        require_once 'include/identity.php';
        $err = validate_channelname($username);
        if ($err) {
            notice($err);
            return;
        }
    }
    if ($timezone != $channel['channel_timezone']) {
        if (strlen($timezone)) {
            date_default_timezone_set($timezone);
        }
    }
    set_pconfig(local_channel(), 'system', 'use_browser_location', $allow_location);
    set_pconfig(local_channel(), 'system', 'suggestme', $suggestme);
    set_pconfig(local_channel(), 'system', 'post_newfriend', $post_newfriend);
    set_pconfig(local_channel(), 'system', 'post_joingroup', $post_joingroup);
    set_pconfig(local_channel(), 'system', 'post_profilechange', $post_profilechange);
    set_pconfig(local_channel(), 'system', 'blocktags', $blocktags);
    set_pconfig(local_channel(), 'system', 'channel_menu', $channel_menu);
    set_pconfig(local_channel(), 'system', 'vnotify', $vnotify);
    set_pconfig(local_channel(), 'system', 'always_show_in_notices', $always_show_in_notices);
    set_pconfig(local_channel(), 'system', 'evdays', $evdays);
    set_pconfig(local_channel(), 'system', 'photo_path', $photo_path);
    set_pconfig(local_channel(), 'system', 'attach_path', $attach_path);
    set_pconfig(local_channel(), 'system', 'cal_first_day', $cal_first_day);
    $r = q("update channel set channel_name = '%s', channel_pageflags = %d, channel_timezone = '%s', channel_location = '%s', channel_notifyflags = %d, channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d {$set_perms} where channel_id = %d", dbesc($username), intval($pageflags), dbesc($timezone), dbesc($defloc), intval($notify), intval($unkmail), intval($maxreq), intval($expire), intval(local_channel()));
    if ($r) {
        info(t('Settings updated.') . EOL);
    }
    if (!is_null($publish)) {
        $r = q("UPDATE profile SET publish = %d WHERE is_default = 1 AND uid = %d", intval($publish), intval(local_channel()));
    }
    if ($name_change) {
        $r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s' where xchan_hash = '%s'", dbesc($username), dbesc(datetime_convert()), dbesc($channel['channel_hash']));
        $r = q("update profile set name = '%s' where uid = %d and is_default = 1", dbesc($username), intval($channel['channel_id']));
    }
    proc_run('php', 'include/directory.php', local_channel());
    build_sync_packet();
    //$_SESSION['theme'] = $theme;
    if ($email_changed && $a->config['system']['register_policy'] == REGISTER_VERIFY) {
        // FIXME - set to un-verified, blocked and redirect to logout
        // Why? Are we verifying people or email addresses?
    }
    goaway($a->get_baseurl(true) . '/settings');
    return;
    // NOTREACHED
}
Пример #9
0
function new_follower($importer, $contact, $datarray, $item, $sharing = false)
{
    $url = notags(trim($datarray['author-link']));
    $name = notags(trim($datarray['author-name']));
    $photo = notags(trim($datarray['author-avatar']));
    if (is_object($item)) {
        $rawtag = $item->get_item_tags(NAMESPACE_ACTIVITY, 'actor');
        if ($rawtag && $rawtag[0]['child'][NAMESPACE_POCO]['preferredUsername'][0]['data']) {
            $nick = $rawtag[0]['child'][NAMESPACE_POCO]['preferredUsername'][0]['data'];
        }
    } else {
        $nick = $item;
    }
    if (is_array($contact)) {
        if ($contact['network'] == NETWORK_OSTATUS && $contact['rel'] == CONTACT_IS_SHARING || $sharing && $contact['rel'] == CONTACT_IS_FOLLOWER) {
            $r = q("UPDATE `contact` SET `rel` = %d, `writable` = 1 WHERE `id` = %d AND `uid` = %d", intval(CONTACT_IS_FRIEND), intval($contact['id']), intval($importer['uid']));
        }
        // send email notification to owner?
    } else {
        // create contact record
        $r = q("INSERT INTO `contact` (`uid`, `created`, `url`, `nurl`, `name`, `nick`, `photo`, `network`, `rel`,\n\t\t\t`blocked`, `readonly`, `pending`, `writable`)\n\t\t\tVALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, 0, 0, 1, 1)", intval($importer['uid']), dbesc(datetime_convert()), dbesc($url), dbesc(normalise_link($url)), dbesc($name), dbesc($nick), dbesc($photo), dbesc($sharing ? NETWORK_ZOT : NETWORK_OSTATUS), intval($sharing ? CONTACT_IS_SHARING : CONTACT_IS_FOLLOWER));
        $r = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND `url` = '%s' AND `pending` = 1 LIMIT 1", intval($importer['uid']), dbesc($url));
        if (count($r)) {
            $contact_record = $r[0];
            $photos = import_profile_photo($photo, $importer["uid"], $contact_record["id"]);
            q("UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `micro` = '%s' WHERE `id` = %d", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), intval($contact_record["id"]));
        }
        $r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($importer['uid']));
        $a = get_app();
        if (count($r) and !in_array($r[0]['page-flags'], array(PAGE_SOAPBOX, PAGE_FREELOVE))) {
            // create notification
            $hash = random_string();
            if (is_array($contact_record)) {
                $ret = q("INSERT INTO `intro` ( `uid`, `contact-id`, `blocked`, `knowyou`, `hash`, `datetime`)\n\t\t\t\t\tVALUES ( %d, %d, 0, 0, '%s', '%s' )", intval($importer['uid']), intval($contact_record['id']), dbesc($hash), dbesc(datetime_convert()));
            }
            if (intval($r[0]['def_gid'])) {
                require_once 'include/group.php';
                group_add_member($r[0]['uid'], '', $contact_record['id'], $r[0]['def_gid']);
            }
            if ($r[0]['notify-flags'] & NOTIFY_INTRO && in_array($r[0]['page-flags'], array(PAGE_NORMAL))) {
                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/intro', 'source_name' => strlen(stripslashes($contact_record['name'])) ? stripslashes($contact_record['name']) : t('[Name Withheld]'), 'source_link' => $contact_record['url'], 'source_photo' => $contact_record['photo'], 'verb' => $sharing ? ACTIVITY_FRIEND : ACTIVITY_FOLLOW, 'otype' => 'intro'));
            }
        } elseif (count($r) and in_array($r[0]['page-flags'], array(PAGE_SOAPBOX, PAGE_FREELOVE))) {
            $r = q("UPDATE `contact` SET `pending` = 0 WHERE `uid` = %d AND `url` = '%s' AND `pending` LIMIT 1", intval($importer['uid']), dbesc($url));
        }
    }
}
Пример #10
0
function new_contact($uid, $url, $channel, $interactive = false, $confirm = false)
{
    $result = array('success' => false, 'message' => '');
    $a = get_app();
    $is_red = false;
    $is_http = strpos($url, '://') !== false ? true : false;
    if ($is_http && substr($url, -1, 1) === '/') {
        $url = substr($url, 0, -1);
    }
    if (!allowed_url($url)) {
        $result['message'] = t('Channel is blocked on this site.');
        return $result;
    }
    if (!$url) {
        $result['message'] = t('Channel location missing.');
        return $result;
    }
    // check service class limits
    $r = q("select count(*) as total from abook where abook_channel = %d and abook_self = 0 ", intval($uid));
    if ($r) {
        $total_channels = $r[0]['total'];
    }
    if (!service_class_allows($uid, 'total_channels', $total_channels)) {
        $result['message'] = upgrade_message();
        return $result;
    }
    $arr = array('url' => $url, 'channel' => array());
    call_hooks('follow', $arr);
    if ($arr['channel']['success']) {
        $ret = $arr['channel'];
    } elseif (!$is_http) {
        $ret = zot_finger($url, $channel);
    }
    if ($ret && $ret['success']) {
        $is_red = true;
        $j = json_decode($ret['body'], true);
    }
    $my_perms = get_channel_default_perms($uid);
    $role = get_pconfig($uid, 'system', 'permissions_role');
    if ($role) {
        $x = get_role_perms($role);
        if ($x['perms_follow']) {
            $my_perms = $x['perms_follow'];
        }
    }
    if ($is_red && $j) {
        logger('follow: ' . $url . ' ' . print_r($j, true), LOGGER_DEBUG);
        if (!($j['success'] && $j['guid'])) {
            $result['message'] = t('Response from remote channel was incomplete.');
            logger('mod_follow: ' . $result['message']);
            return $result;
        }
        // Premium channel, set confirm before callback to avoid recursion
        if (array_key_exists('connect_url', $j) && $interactive && !$confirm) {
            goaway(zid($j['connect_url']));
        }
        // do we have an xchan and hubloc?
        // If not, create them.
        $x = import_xchan($j);
        if (array_key_exists('deleted', $j) && intval($j['deleted'])) {
            $result['message'] = t('Channel was deleted and no longer exists.');
            return $result;
        }
        if (!$x['success']) {
            return $x;
        }
        $xchan_hash = $x['hash'];
        $their_perms = 0;
        $global_perms = get_perms();
        if (array_key_exists('permissions', $j) && array_key_exists('data', $j['permissions'])) {
            $permissions = crypto_unencapsulate(array('data' => $j['permissions']['data'], 'key' => $j['permissions']['key'], 'iv' => $j['permissions']['iv']), $channel['channel_prvkey']);
            if ($permissions) {
                $permissions = json_decode($permissions, true);
            }
            logger('decrypted permissions: ' . print_r($permissions, true), LOGGER_DATA);
        } else {
            $permissions = $j['permissions'];
        }
        foreach ($permissions as $k => $v) {
            if ($v) {
                $their_perms = $their_perms | intval($global_perms[$k][1]);
            }
        }
    } else {
        $their_perms = 0;
        $xchan_hash = '';
        $r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' limit 1", dbesc($url), dbesc($url));
        if (!$r) {
            // attempt network auto-discovery
            if (strpos($url, '@') && !$is_http) {
                $r = discover_by_webbie($url);
            } elseif ($is_http) {
                $r = discover_by_url($url);
                $r['allowed'] = intval(get_config('system', 'feed_contacts'));
            }
            if ($r) {
                $r['channel_id'] = $uid;
                call_hooks('follow_allow', $r);
                if (!$r['allowed']) {
                    $result['message'] = t('Protocol disabled.');
                    return $result;
                }
                $r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' limit 1", dbesc($url), dbesc($url));
            }
        }
        if ($r) {
            $xchan_hash = $r[0]['xchan_hash'];
            $their_perms = 0;
        }
    }
    if (!$xchan_hash) {
        $result['message'] = t('Channel discovery failed.');
        logger('follow: ' . $result['message']);
        return $result;
    }
    if (local_channel() && $uid == local_channel()) {
        $aid = get_account_id();
        $hash = get_observer_hash();
        $ch = $a->get_channel();
        $default_group = $ch['channel_default_group'];
    } else {
        $r = q("select * from channel where channel_id = %d limit 1", intval($uid));
        if (!$r) {
            $result['message'] = t('local account not found.');
            return $result;
        }
        $aid = $r[0]['channel_account_id'];
        $hash = $r[0]['channel_hash'];
        $default_group = $r[0]['channel_default_group'];
    }
    if ($is_http) {
        $r = q("select count(*) as total from abook where abook_account = %d and abook_feed = 1 ", intval($aid));
        if ($r) {
            $total_feeds = $r[0]['total'];
        }
        if (!service_class_allows($uid, 'total_feeds', $total_feeds)) {
            $result['message'] = upgrade_message();
            return $result;
        }
    }
    if ($hash == $xchan_hash) {
        $result['message'] = t('Cannot connect to yourself.');
        return $result;
    }
    $r = q("select abook_xchan from abook where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($xchan_hash), intval($uid));
    if ($r) {
        $x = q("update abook set abook_their_perms = %d where abook_id = %d", intval($their_perms), intval($r[0]['abook_id']));
    } else {
        $closeness = get_pconfig($uid, 'system', 'new_abook_closeness');
        if ($closeness === false) {
            $closeness = 80;
        }
        $r = q("insert into abook ( abook_account, abook_channel, abook_closeness, abook_xchan, abook_feed, abook_their_perms, abook_my_perms, abook_created, abook_updated )\n\t\t\tvalues( %d, %d, %d, '%s', %d, %d, %d, '%s', '%s' ) ", intval($aid), intval($uid), intval($closeness), dbesc($xchan_hash), intval($is_http ? 1 : 0), intval($is_http ? $their_perms | PERMS_R_STREAM | PERMS_A_REPUBLISH : $their_perms), intval($my_perms), dbesc(datetime_convert()), dbesc(datetime_convert()));
    }
    if (!$r) {
        logger('mod_follow: abook creation failed');
    }
    $r = q("select abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash \n\t\twhere abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($xchan_hash), intval($uid));
    if ($r) {
        $result['abook'] = $r[0];
        proc_run('php', 'include/notifier.php', 'permission_update', $result['abook']['abook_id']);
    }
    $arr = array('channel_id' => $uid, 'abook' => $result['abook']);
    call_hooks('follow', $arr);
    /** If there is a default group for this channel, add this member to it */
    if ($default_group) {
        require_once 'include/group.php';
        $g = group_rec_byhash($uid, $default_group);
        if ($g) {
            group_add_member($uid, '', $xchan_hash, $g['id']);
        }
    }
    $result['success'] = true;
    return $result;
}
Пример #11
0
function twitter_fetch_contact($uid, $contact, $create_user)
{
    require_once "include/Photo.php";
    if ($contact->id_str == "") {
        return -1;
    }
    $avatar = str_replace("_normal.", ".", $contact->profile_image_url_https);
    $info = get_photo_info($avatar);
    if (!$info) {
        $avatar = $contact->profile_image_url_https;
    }
    // Check if the unique contact is existing
    // To-Do: only update once a while
    $r = q("SELECT id FROM unique_contacts WHERE url='%s' LIMIT 1", dbesc(normalise_link("https://twitter.com/" . $contact->screen_name)));
    if (count($r) == 0) {
        q("INSERT INTO unique_contacts (url, name, nick, avatar) VALUES ('%s', '%s', '%s', '%s')", dbesc(normalise_link("https://twitter.com/" . $contact->screen_name)), dbesc($contact->name), dbesc($contact->screen_name), dbesc($avatar));
    } else {
        q("UPDATE unique_contacts SET name = '%s', nick = '%s', avatar = '%s' WHERE url = '%s'", dbesc($contact->name), dbesc($contact->screen_name), dbesc($avatar), dbesc(normalise_link("https://twitter.com/" . $contact->screen_name)));
    }
    if (DB_UPDATE_VERSION >= "1177") {
        q("UPDATE `unique_contacts` SET `location` = '%s', `about` = '%s' WHERE url = '%s'", dbesc($contact->location), dbesc($contact->description), dbesc(normalise_link("https://twitter.com/" . $contact->screen_name)));
    }
    $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `alias` = '%s' LIMIT 1", intval($uid), dbesc("twitter::" . $contact->id_str));
    if (!count($r) and !$create_user) {
        return 0;
    }
    if (count($r) and ($r[0]["readonly"] or $r[0]["blocked"])) {
        logger("twitter_fetch_contact: Contact '" . $r[0]["nick"] . "' is blocked or readonly.", LOGGER_DEBUG);
        return -1;
    }
    if (!count($r)) {
        // create contact record
        q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `addr`, `alias`, `notify`, `poll`,\n\t\t\t\t\t`name`, `nick`, `photo`, `network`, `rel`, `priority`,\n\t\t\t\t\t`writable`, `blocked`, `readonly`, `pending` )\n\t\t\t\t\tVALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, 0, 0, 0) ", intval($uid), dbesc(datetime_convert()), dbesc("https://twitter.com/" . $contact->screen_name), dbesc(normalise_link("https://twitter.com/" . $contact->screen_name)), dbesc($contact->screen_name . "@twitter.com"), dbesc("twitter::" . $contact->id_str), dbesc(''), dbesc("twitter::" . $contact->id_str), dbesc($contact->name), dbesc($contact->screen_name), dbesc($avatar), dbesc(NETWORK_TWITTER), intval(CONTACT_IS_FRIEND), intval(1), intval(1));
        $r = q("SELECT * FROM `contact` WHERE `alias` = '%s' AND `uid` = %d LIMIT 1", dbesc("twitter::" . $contact->id_str), intval($uid));
        if (!count($r)) {
            return false;
        }
        $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']);
        }
        require_once "Photo.php";
        $photos = import_profile_photo($avatar, $uid, $contact_id);
        q("UPDATE `contact` SET `photo` = '%s',\n\t\t\t\t\t`thumb` = '%s',\n\t\t\t\t\t`micro` = '%s',\n\t\t\t\t\t`name-date` = '%s',\n\t\t\t\t\t`uri-date` = '%s',\n\t\t\t\t\t`avatar-date` = '%s'\n\t\t\t\tWHERE `id` = %d", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($contact_id));
        if (DB_UPDATE_VERSION >= "1177") {
            q("UPDATE `contact` SET `location` = '%s',\n\t\t\t\t\t\t`about` = '%s'\n\t\t\t\t\tWHERE `id` = %d", dbesc($contact->location), dbesc($contact->description), intval($contact_id));
        }
    } else {
        // update profile photos once every two weeks as we have no notification of when they change.
        //$update_photo = (($r[0]['avatar-date'] < datetime_convert('','','now -2 days')) ? true : false);
        $update_photo = $r[0]['avatar-date'] < datetime_convert('', '', 'now -12 hours');
        // check that we have all the photos, this has been known to fail on occasion
        if (!$r[0]['photo'] || !$r[0]['thumb'] || !$r[0]['micro'] || $update_photo) {
            logger("twitter_fetch_contact: Updating contact " . $contact->screen_name, LOGGER_DEBUG);
            require_once "Photo.php";
            $photos = import_profile_photo($avatar, $uid, $r[0]['id']);
            q("UPDATE `contact` SET `photo` = '%s',\n\t\t\t\t\t\t`thumb` = '%s',\n\t\t\t\t\t\t`micro` = '%s',\n\t\t\t\t\t\t`name-date` = '%s',\n\t\t\t\t\t\t`uri-date` = '%s',\n\t\t\t\t\t\t`avatar-date` = '%s',\n\t\t\t\t\t\t`url` = '%s',\n\t\t\t\t\t\t`nurl` = '%s',\n\t\t\t\t\t\t`addr` = '%s',\n\t\t\t\t\t\t`name` = '%s',\n\t\t\t\t\t\t`nick` = '%s'\n\t\t\t\t\tWHERE `id` = %d", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc("https://twitter.com/" . $contact->screen_name), dbesc(normalise_link("https://twitter.com/" . $contact->screen_name)), dbesc($contact->screen_name . "@twitter.com"), dbesc($contact->name), dbesc($contact->screen_name), intval($r[0]['id']));
            if (DB_UPDATE_VERSION >= "1177") {
                q("UPDATE `contact` SET `location` = '%s',\n\t\t\t\t\t\t\t`about` = '%s'\n\t\t\t\t\t\tWHERE `id` = %d", dbesc($contact->location), dbesc($contact->description), intval($r[0]['id']));
            }
        }
    }
    return $r[0]["id"];
}
Пример #12
0
function group_content(&$a)
{
    $change = false;
    if (!local_user()) {
        notice(t('Permission denied') . EOL);
        return;
    }
    // Switch to text mode interface if we have more than 'n' contacts or group members
    $switchtotext = get_pconfig(local_user(), 'system', 'groupedit_image_limit');
    if ($switchtotext === false) {
        $switchtotext = get_config('system', 'groupedit_image_limit');
    }
    if ($switchtotext === false) {
        $switchtotext = 400;
    }
    $tpl = get_markup_template('group_edit.tpl');
    $context = array('$submit' => t('Submit'));
    if ($a->argc == 2 && $a->argv[1] === 'new') {
        return replace_macros($tpl, $context + array('$title' => t('Create a group of contacts/friends.'), '$gname' => array('groupname', t('Group Name: '), '', ''), '$gid' => 'new', '$form_security_token' => get_form_security_token("group_edit")));
    }
    if ($a->argc == 3 && $a->argv[1] === 'drop') {
        check_form_security_token_redirectOnErr('/group', 'group_drop', 't');
        if (intval($a->argv[2])) {
            $r = q("SELECT `name` FROM `group` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($a->argv[2]), intval(local_user()));
            if (count($r)) {
                $result = group_rmv(local_user(), $r[0]['name']);
            }
            if ($result) {
                info(t('Group removed.') . EOL);
            } else {
                notice(t('Unable to remove group.') . EOL);
            }
        }
        goaway($a->get_baseurl() . '/group');
        // NOTREACHED
    }
    if ($a->argc > 2 && intval($a->argv[1]) && intval($a->argv[2])) {
        check_form_security_token_ForbiddenOnErr('group_member_change', 't');
        $r = q("SELECT `id` FROM `contact` WHERE `id` = %d AND `uid` = %d and `self` = 0 and `blocked` = 0 AND `pending` = 0 LIMIT 1", intval($a->argv[2]), intval(local_user()));
        if (count($r)) {
            $change = intval($a->argv[2]);
        }
    }
    if ($a->argc > 1 && intval($a->argv[1])) {
        require_once 'include/acl_selectors.php';
        $r = q("SELECT * FROM `group` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", intval($a->argv[1]), intval(local_user()));
        if (!count($r)) {
            notice(t('Group not found.') . EOL);
            goaway($a->get_baseurl() . '/contacts');
        }
        $group = $r[0];
        $members = group_get_members($group['id']);
        $preselected = array();
        if (count($members)) {
            foreach ($members as $member) {
                $preselected[] = $member['id'];
            }
        }
        if ($change) {
            if (in_array($change, $preselected)) {
                group_rmv_member(local_user(), $group['name'], $change);
            } else {
                group_add_member(local_user(), $group['name'], $change);
            }
            $members = group_get_members($group['id']);
            $preselected = array();
            if (count($members)) {
                foreach ($members as $member) {
                    $preselected[] = $member['id'];
                }
            }
        }
        $drop_tpl = get_markup_template('group_drop.tpl');
        $drop_txt = replace_macros($drop_tpl, array('$id' => $group['id'], '$delete' => t('Delete'), '$form_security_token' => get_form_security_token("group_drop")));
        $celeb = $a->user['page-flags'] == PAGE_SOAPBOX || $a->user['page-flags'] == PAGE_COMMUNITY ? true : false;
        $context = $context + array('$title' => t('Group Editor'), '$gname' => array('groupname', t('Group Name: '), $group['name'], ''), '$gid' => $group['id'], '$drop' => $drop_txt, '$form_security_token' => get_form_security_token('group_edit'));
    }
    if (!isset($group)) {
        return;
    }
    $groupeditor = array('label_members' => t('Members'), 'members' => array(), 'label_contacts' => t('All Contacts'), 'contacts' => array());
    $sec_token = addslashes(get_form_security_token('group_member_change'));
    $textmode = $switchtotext && count($members) > $switchtotext ? true : false;
    foreach ($members as $member) {
        if ($member['url']) {
            $member['click'] = 'groupChangeMember(' . $group['id'] . ',' . $member['id'] . ',\'' . $sec_token . '\'); return true;';
            $groupeditor['members'][] = micropro($member, true, 'mpgroup', $textmode);
        } else {
            group_rmv_member(local_user(), $group['name'], $member['id']);
        }
    }
    $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `blocked` = 0 and `pending` = 0 and `self` = 0 ORDER BY `name` ASC", intval(local_user()));
    if (count($r)) {
        $textmode = $switchtotext && count($r) > $switchtotext ? true : false;
        foreach ($r as $member) {
            if (!in_array($member['id'], $preselected)) {
                $member['click'] = 'groupChangeMember(' . $group['id'] . ',' . $member['id'] . ',\'' . $sec_token . '\'); return true;';
                $groupeditor['contacts'][] = micropro($member, true, 'mpall', $textmode);
            }
        }
    }
    $context['$groupeditor'] = $groupeditor;
    $context['$desc'] = t('Click on a contact to add or remove.');
    if ($change) {
        $tpl = get_markup_template('groupeditor.tpl');
        echo replace_macros($tpl, $context);
        killme();
    }
    return replace_macros($tpl, $context);
}
Пример #13
0
function connedit_post(&$a)
{
    if (!local_user()) {
        return;
    }
    $contact_id = intval(argv(1));
    if (!$contact_id) {
        return;
    }
    $orig_record = q("SELECT * FROM abook WHERE abook_id = %d AND abook_channel = %d LIMIT 1", intval($contact_id), intval(local_user()));
    if (!$orig_record) {
        notice(t('Could not access contact record.') . EOL);
        goaway($a->get_baseurl(true) . '/connections');
        return;
        // NOTREACHED
    }
    call_hooks('contact_edit_post', $_POST);
    $profile_id = $_POST['profile_assign'];
    if ($profile_id) {
        $r = q("SELECT profile_guid FROM profile WHERE profile_guid = '%s' AND `uid` = %d LIMIT 1", dbesc($profile_id), intval(local_user()));
        if (!count($r)) {
            notice(t('Could not locate selected profile.') . EOL);
            return;
        }
    }
    $hidden = intval($_POST['hidden']);
    $priority = intval($_POST['poll']);
    if ($priority > 5 || $priority < 0) {
        $priority = 0;
    }
    $closeness = intval($_POST['closeness']);
    if ($closeness < 0) {
        $closeness = 99;
    }
    $abook_my_perms = 0;
    foreach ($_POST as $k => $v) {
        if (strpos($k, 'perms_') === 0) {
            $abook_my_perms += $v;
        }
    }
    $abook_flags = $orig_record[0]['abook_flags'];
    $new_friend = false;
    if ($_REQUEST['pending'] && $abook_flags & ABOOK_FLAG_PENDING) {
        $abook_flags = $abook_flags ^ ABOOK_FLAG_PENDING;
        $new_friend = true;
    }
    $r = q("UPDATE abook SET abook_profile = '%s', abook_my_perms = %d , abook_closeness = %d, abook_flags = %d\n\t\twhere abook_id = %d AND abook_channel = %d LIMIT 1", dbesc($profile_id), intval($abook_my_perms), intval($closeness), intval($abook_flags), intval($contact_id), intval(local_user()));
    if ($orig_record[0]['abook_profile'] != $profile_id) {
        //Update profile photo permissions
        logger('As a new profile was assigned updating profile photos');
        require_once 'mod/profile_photo.php';
        profile_photo_set_profile_perms($profile_id);
    }
    if ($r) {
        info(t('Connection updated.') . EOL);
    } else {
        notice(t('Failed to update connection record.') . EOL);
    }
    if ($a->poi && $a->poi['abook_my_perms'] != $abook_my_perms && !($a->poi['abook_flags'] & ABOOK_FLAG_SELF)) {
        proc_run('php', 'include/notifier.php', 'permission_update', $contact_id);
    }
    if ($new_friend) {
        $channel = $a->get_channel();
        $default_group = $channel['channel_default_group'];
        if ($default_group) {
            require_once 'include/group.php';
            $g = group_rec_byhash(local_user(), $default_group);
            if ($g) {
                group_add_member(local_user(), '', $a->poi['abook_xchan'], $g['id']);
            }
        }
        // Check if settings permit ("post new friend activity" is allowed, and
        // friends in general or this friend in particular aren't hidden)
        // and send out a new friend activity
        $pr = q("select * from profile where uid = %d and is_default = 1 and hide_friends = 0", intval($channel['channel_id']));
        if ($pr && !($abook_flags & ABOOK_FLAG_HIDDEN) && intval(get_pconfig($channel['channel_id'], 'system', 'post_newfriend'))) {
            $xarr = array();
            $xarr['verb'] = ACTIVITY_FRIEND;
            $xarr['item_flags'] = ITEM_WALL | ITEM_ORIGIN | ITEM_THREAD_TOP;
            $xarr['owner_xchan'] = $xarr['author_xchan'] = $channel['channel_hash'];
            $xarr['allow_cid'] = $channel['channel_allow_cid'];
            $xarr['allow_gid'] = $channel['channel_allow_gid'];
            $xarr['deny_cid'] = $channel['channel_deny_cid'];
            $xarr['deny_gid'] = $channel['channel_deny_gid'];
            $xarr['item_private'] = $xarr['allow_cid'] || $xarr['allow_gid'] || $xarr['deny_cid'] || $xarr['deny_gid'] ? 1 : 0;
            $obj = array('type' => ACTIVITY_OBJ_PERSON, 'title' => $a->poi['xchan_name'], 'id' => $a->poi['xchan_hash'], 'link' => array(array('rel' => 'alternate', 'type' => 'text/html', 'href' => $a->poi['xchan_url']), array('rel' => 'photo', 'type' => $a->poi['xchan_photo_mimetype'], 'href' => $a->poi['xchan_photo_l'])));
            $xarr['object'] = json_encode($obj);
            $xarr['obj_type'] = ACTIVITY_OBJ_PERSON;
            $xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . $a->poi['xchan_url'] . ']' . $a->poi['xchan_name'] . '[/zrl]';
            $xarr['body'] .= "\n\n\n" . '[zrl=' . $a->poi['xchan_url'] . '][zmg=80x80]' . $a->poi['xchan_photo_m'] . '[/zmg][/zrl]';
            post_activity_item($xarr);
        }
        // pull in a bit of content if there is any to pull in
        proc_run('php', 'include/onepoll.php', $contact_id);
    }
    // Refresh the structure in memory with the new data
    $r = q("SELECT abook.*, xchan.* \n\t\tFROM abook left join xchan on abook_xchan = xchan_hash\n\t\tWHERE abook_channel = %d and abook_id = %d LIMIT 1", intval(local_user()), intval($contact_id));
    if ($r) {
        $a->poi = $r[0];
    }
    if ($new_friend) {
        $arr = array('channel_id' => local_user(), 'abook' => $a->poi);
        call_hooks('accept_follow', $arr);
    }
    connedit_clone($a);
    return;
}
Пример #14
0
 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 `ret-aes` = %d, hidden = %d WHERE `id` = %d", intval($aes_allow), 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 'include/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`,\n\t\t\t\t\t\t`request`, `confirm`, `notify`, `poll`, `poco`, `network`, `aes_allow`, `hidden`)\n\t\t\t\t\t\tVALUES ( %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']);
                 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']);
                     }
                     $forwardurl = $a->get_baseurl() . "/contacts/" . $r[0]['id'];
                 } else {
                     $forwardurl = $a->get_baseurl() . "/contacts";
                 }
                 /**
                  * 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)
                 // Old: goaway(zrl($dfrn_url));
                 goaway($forwardurl);
                 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`\n\t\t\tFROM `intro` LEFT JOIN `contact` on `intro`.`contact-id` = `contact`.`id`\n\t\t\tWHERE `intro`.`blocked` = 1 AND `contact`.`self` = 0\n\t\t\tAND `contact`.`network` != '%s'\n\t\t\tAND `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", intval($rr['cid']));
                 }
                 q("DELETE FROM `intro` WHERE `id` = %d", 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`\n\t\t\tFROM `intro` LEFT JOIN `contact` on `intro`.`contact-id` = `contact`.`id`\n\t\t\tWHERE `intro`.`blocked` = 1 AND `contact`.`self` = 0\n\t\t\tAND `contact`.`network` = '%s'\n\t\t\tAND `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", intval($rr['cid']));
                 }
                 q("DELETE FROM `intro` WHERE `id` = %d", 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 )\n\t\t\t\tvalues( %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\n\t\t\t\t\t`photo` = '%s',\n\t\t\t\t\t`thumb` = '%s',\n\t\t\t\t\t`micro` = '%s',\n\t\t\t\t\t`name-date` = '%s',\n\t\t\t\t\t`uri-date` = '%s',\n\t\t\t\t\t`avatar-date` = '%s',\n\t\t\t\t\t`hidden` = 0,\n\t\t\t\t\tWHERE `id` = %d\n\t\t\t\t", 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 )\n\t\t\t\tvalues( %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", 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 'include/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`,\n\t\t\t\t\t`request`, `confirm`, `notify`, `poll`, `poco`, `network` )\n\t\t\t\t\tVALUES ( %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`\n\t\t\t\t\t\tWHERE `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`)\n\t\t\t\t\tVALUES ( %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() . '/profile/' . $nickname, $url);
             goaway($url);
             // NOTREACHED
             // END $network === NETWORK_OSTATUS
         }
     }
     return;
 }
Пример #15
0
/**
 * @param int $uid
 * @param object $contact
 */
function fb_get_friends_sync_parsecontact($uid, $contact)
{
    $contact->link = 'http://facebook.com/profile.php?id=' . $contact->id;
    // If its a page then set the first name from the username
    if (!$contact->first_name and $contact->username) {
        $contact->first_name = $contact->username;
    }
    // check if we already have a contact
    $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' LIMIT 1", intval($uid), dbesc($contact->link));
    if (count($r)) {
        // check that we have all the photos, this has been known to fail on occasion
        if (!$r[0]['photo'] || !$r[0]['thumb'] || !$r[0]['micro']) {
            require_once "Photo.php";
            $photos = import_profile_photo('https://graph.facebook.com/' . $contact->id . '/picture', $uid, $r[0]['id']);
            q("UPDATE `contact` SET `photo` = '%s',\n                                        `thumb` = '%s',\n                                        `micro` = '%s',\n                                        `name-date` = '%s',\n                                        `uri-date` = '%s',\n                                        `avatar-date` = '%s'\n                                        WHERE `id` = %d LIMIT 1\n                                ", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($r[0]['id']));
        }
        return;
    } else {
        // create contact record
        q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `addr`, `alias`, `notify`, `poll`,\n                                `name`, `nick`, `photo`, `network`, `rel`, `priority`,\n                                `writable`, `blocked`, `readonly`, `pending` )\n                                VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, 0, 0, 0 ) ", intval($uid), dbesc(datetime_convert()), dbesc($contact->link), dbesc(normalise_link($contact->link)), dbesc(''), dbesc(''), dbesc($contact->id), dbesc('facebook ' . $contact->id), dbesc($contact->name), dbesc($contact->nickname ? $contact->nickname : strtolower($contact->first_name)), dbesc('https://graph.facebook.com/' . $contact->id . '/picture'), dbesc(NETWORK_FACEBOOK), intval(CONTACT_IS_FRIEND), intval(1), intval(1));
    }
    $r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1", dbesc($contact->link), intval($uid));
    if (!count($r)) {
        return;
    }
    $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']);
    }
    require_once "Photo.php";
    $photos = import_profile_photo($r[0]['photo'], $uid, $contact_id);
    q("UPDATE `contact` SET `photo` = '%s',\n                        `thumb` = '%s',\n                        `micro` = '%s',\n                        `name-date` = '%s',\n                        `uri-date` = '%s',\n                        `avatar-date` = '%s'\n                        WHERE `id` = %d LIMIT 1\n                ", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($contact_id));
}
Пример #16
0
/**
 * @brief Refreshes after permission changed or friending, etc.
 *
 * zot_refresh is typically invoked when somebody has changed permissions of a channel and they are notified
 * to fetch new permissions via a finger/discovery operation. This may result in a new connection
 * (abook entry) being added to a local channel and it may result in auto-permissions being granted.
 *
 * Friending in zot is accomplished by sending a refresh packet to a specific channel which indicates a
 * permission change has been made by the sender which affects the target channel. The hub controlling
 * the target channel does targetted discovery (a zot-finger request requesting permissions for the local
 * channel). These are decoded here, and if necessary and abook structure (addressbook) is created to store
 * the permissions assigned to this channel.
 *
 * Initially these abook structures are created with a 'pending' flag, so that no reverse permissions are
 * implied until this is approved by the owner channel. A channel can also auto-populate permissions in
 * return and send back a refresh packet of its own. This is used by forum and group communication channels
 * so that friending and membership in the channel's "club" is automatic.
 *
 * @param array $them => xchan structure of sender
 * @param array $channel => local channel structure of target recipient, required for "friending" operations
 * @param array $force default false
 *
 * @returns boolean true if successful, else false
 */
function zot_refresh($them, $channel = null, $force = false)
{
    if (array_key_exists('xchan_network', $them) && $them['xchan_network'] !== 'zot') {
        logger('zot_refresh: not got zot. ' . $them['xchan_name']);
        return true;
    }
    logger('zot_refresh: them: ' . print_r($them, true), LOGGER_DATA, LOG_DEBUG);
    if ($channel) {
        logger('zot_refresh: channel: ' . print_r($channel, true), LOGGER_DATA, LOG_DEBUG);
    }
    $url = null;
    if ($them['hubloc_url']) {
        $url = $them['hubloc_url'];
    } else {
        $r = null;
        // if they re-installed the server we could end up with the wrong record - pointing to the old install.
        // We'll order by reverse id to try and pick off the newest one first and hopefully end up with the
        // correct hubloc. If this doesn't work we may have to re-write this section to try them all.
        if (array_key_exists('xchan_addr', $them) && $them['xchan_addr']) {
            $r = q("select hubloc_url, hubloc_primary from hubloc where hubloc_addr = '%s' order by hubloc_id desc", dbesc($them['xchan_addr']));
        }
        if (!$r) {
            $r = q("select hubloc_url, hubloc_primary from hubloc where hubloc_hash = '%s' order by hubloc_id desc", dbesc($them['xchan_hash']));
        }
        if ($r) {
            foreach ($r as $rr) {
                if (intval($rr['hubloc_primary'])) {
                    $url = $rr['hubloc_url'];
                    break;
                }
            }
            if (!$url) {
                $url = $r[0]['hubloc_url'];
            }
        }
    }
    if (!$url) {
        logger('zot_refresh: no url');
        return false;
    }
    $token = random_string();
    $postvars = array();
    $postvars['token'] = $token;
    if ($channel) {
        $postvars['target'] = $channel['channel_guid'];
        $postvars['target_sig'] = $channel['channel_guid_sig'];
        $postvars['key'] = $channel['channel_pubkey'];
    }
    if (array_key_exists('xchan_addr', $them) && $them['xchan_addr']) {
        $postvars['address'] = $them['xchan_addr'];
    }
    if (array_key_exists('xchan_hash', $them) && $them['xchan_hash']) {
        $postvars['guid_hash'] = $them['xchan_hash'];
    }
    if (array_key_exists('xchan_guid', $them) && $them['xchan_guid'] && array_key_exists('xchan_guid_sig', $them) && $them['xchan_guid_sig']) {
        $postvars['guid'] = $them['xchan_guid'];
        $postvars['guid_sig'] = $them['xchan_guid_sig'];
    }
    $rhs = '/.well-known/zot-info';
    $result = z_post_url($url . $rhs, $postvars);
    logger('zot_refresh: zot-info: ' . print_r($result, true), LOGGER_DATA, LOG_DEBUG);
    if ($result['success']) {
        $j = json_decode($result['body'], true);
        if (!($j && $j['success'])) {
            logger('zot_refresh: result not decodable');
            return false;
        }
        $signed_token = is_array($j) && array_key_exists('signed_token', $j) ? $j['signed_token'] : null;
        if ($signed_token) {
            $valid = rsa_verify('token.' . $token, base64url_decode($signed_token), $j['key']);
            if (!$valid) {
                logger('invalid signed token: ' . $url . $rhs, LOGGER_NORMAL, LOG_ERR);
                return false;
            }
        } else {
            logger('No signed token from ' . $url . $rhs, LOGGER_NORMAL, LOG_WARNING);
            // after 2017-01-01 this will be a hard error unless you over-ride it.
            if (time() > 1483228800 && !get_config('system', 'allow_unsigned_zotfinger')) {
                return false;
            }
        }
        $x = import_xchan($j, $force ? UPDATE_FLAGS_FORCED : UPDATE_FLAGS_UPDATED);
        if (!$x['success']) {
            return false;
        }
        $their_perms = 0;
        if ($channel) {
            $global_perms = get_perms();
            if ($j['permissions']['data']) {
                $permissions = crypto_unencapsulate(array('data' => $j['permissions']['data'], 'key' => $j['permissions']['key'], 'iv' => $j['permissions']['iv']), $channel['channel_prvkey']);
                if ($permissions) {
                    $permissions = json_decode($permissions, true);
                }
                logger('decrypted permissions: ' . print_r($permissions, true), LOGGER_DATA, LOG_DEBUG);
            } else {
                $permissions = $j['permissions'];
            }
            $connected_set = false;
            if ($permissions && is_array($permissions)) {
                foreach ($permissions as $k => $v) {
                    // The connected permission means you are in their address book
                    if ($k === 'connected') {
                        $connected_set = intval($v);
                        continue;
                    }
                    if ($v && array_key_exists($k, $global_perms)) {
                        $their_perms = $their_perms | intval($global_perms[$k][1]);
                    }
                }
            }
            if (array_key_exists('profile', $j) && array_key_exists('next_birthday', $j['profile'])) {
                $next_birthday = datetime_convert('UTC', 'UTC', $j['profile']['next_birthday']);
            } else {
                $next_birthday = NULL_DATE;
            }
            $r = q("select * from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1", dbesc($x['hash']), intval($channel['channel_id']));
            if ($r) {
                // connection exists
                // if the dob is the same as what we have stored (disregarding the year), keep the one
                // we have as we may have updated the year after sending a notification; and resetting
                // to the one we just received would cause us to create duplicated events.
                if (substr($r[0]['abook_dob'], 5) == substr($next_birthday, 5)) {
                    $next_birthday = $r[0]['abook_dob'];
                }
                $current_abook_connected = intval($r[0]['abook_unconnected']) ? 0 : 1;
                $y = q("update abook set abook_their_perms = %d, abook_dob = '%s'\n\t\t\t\t\twhere abook_xchan = '%s' and abook_channel = %d\n\t\t\t\t\tand abook_self = 0 ", intval($their_perms), dbescdate($next_birthday), dbesc($x['hash']), intval($channel['channel_id']));
                //				if(($connected_set === 0 || $connected_set === 1) && ($connected_set !== $current_abook_unconnected)) {
                // if they are in your address book but you aren't in theirs, and/or this does not
                // match your current connected state setting, toggle it.
                /** @FIXME uncoverted to postgres */
                /** @FIXME when this was enabled, all contacts became unconnected. Currently disabled intentionally */
                //					$y1 = q("update abook set abook_unconnected = 1
                //						where abook_xchan = '%s' and abook_channel = %d
                //						and abook_self = 0 limit 1",
                //						dbesc($x['hash']),
                //						intval($channel['channel_id'])
                //					);
                //				}
                if (!$y) {
                    logger('abook update failed');
                } else {
                    // if we were just granted read stream permission and didn't have it before, try to pull in some posts
                    if (!($r[0]['abook_their_perms'] & PERMS_R_STREAM) && $their_perms & PERMS_R_STREAM) {
                        Zotlabs\Daemon\Master::Summon(array('Onepoll', $r[0]['abook_id']));
                    }
                }
            } else {
                // new connection
                $role = get_pconfig($channel['channel_id'], 'system', 'permissions_role');
                if ($role) {
                    $xx = get_role_perms($role);
                    if ($xx['perms_auto']) {
                        $default_perms = $xx['perms_accept'];
                    }
                }
                if (!$default_perms) {
                    $default_perms = intval(get_pconfig($channel['channel_id'], 'system', 'autoperms'));
                }
                // Keep original perms to check if we need to notify them
                $previous_perms = get_all_perms($channel['channel_id'], $x['hash']);
                $closeness = get_pconfig($channel['channel_id'], 'system', 'new_abook_closeness');
                if ($closeness === false) {
                    $closeness = 80;
                }
                $y = q("insert into abook ( abook_account, abook_channel, abook_closeness, abook_xchan, abook_their_perms, abook_my_perms, abook_created, abook_updated, abook_dob, abook_pending ) values ( %d, %d, %d, '%s', %d, %d, '%s', '%s', '%s', %d )", intval($channel['channel_account_id']), intval($channel['channel_id']), intval($closeness), dbesc($x['hash']), intval($their_perms), intval($default_perms), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($next_birthday), intval($default_perms ? 0 : 1));
                if ($y) {
                    logger("New introduction received for {$channel['channel_name']}");
                    $new_perms = get_all_perms($channel['channel_id'], $x['hash']);
                    // Send a clone sync packet and a permissions update if permissions have changed
                    $new_connection = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 order by abook_created desc limit 1", dbesc($x['hash']), intval($channel['channel_id']));
                    if ($new_connection) {
                        if ($new_perms != $previous_perms) {
                            Zotlabs\Daemon\Master::Summon(array('Notifier', 'permission_create', $new_connection[0]['abook_id']));
                        }
                        Zotlabs\Lib\Enotify::submit(array('type' => NOTIFY_INTRO, 'from_xchan' => $x['hash'], 'to_xchan' => $channel['channel_hash'], 'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id']));
                        if ($their_perms & PERMS_R_STREAM) {
                            if ($channel['channel_w_stream'] & PERMS_PENDING || !intval($new_connection[0]['abook_pending'])) {
                                Zotlabs\Daemon\Master::Summon(array('Onepoll', $new_connection[0]['abook_id']));
                            }
                        }
                        /** If there is a default group for this channel, add this connection to it */
                        $default_group = $channel['channel_default_group'];
                        if ($default_group) {
                            require_once 'include/group.php';
                            $g = group_rec_byhash($channel['channel_id'], $default_group);
                            if ($g) {
                                group_add_member($channel['channel_id'], '', $x['hash'], $g['id']);
                            }
                        }
                        unset($new_connection[0]['abook_id']);
                        unset($new_connection[0]['abook_account']);
                        unset($new_connection[0]['abook_channel']);
                        $abconfig = load_abconfig($channel['channel_id'], $new_connection['abook_xchan']);
                        if ($abconfig) {
                            $new_connection['abconfig'] = $abconfig;
                        }
                        build_sync_packet($channel['channel_id'], array('abook' => $new_connection));
                    }
                }
            }
        }
        return true;
    }
    return false;
}
Пример #17
0
function diaspora_request($importer, $xml)
{
    $a = get_app();
    $sender_handle = unxmlify($xml->sender_handle);
    $recipient_handle = unxmlify($xml->recipient_handle);
    if (!$sender_handle || !$recipient_handle) {
        return;
    }
    // Do we already have an abook record?
    $contact = diaspora_get_contact_by_handle($importer['channel_id'], $sender_handle);
    if ($contact && $contact['abook_id']) {
        // perhaps we were already sharing with this person. Now they're sharing with us.
        // That makes us friends. Maybe.
        // Please note some of these permissions such as PERMS_R_PAGES are impossible for Disapora.
        // They cannot authenticate to our system.
        $newperms = PERMS_R_STREAM | PERMS_R_PROFILE | PERMS_R_PHOTOS | PERMS_R_ABOOK | PERMS_W_STREAM | PERMS_W_COMMENT | PERMS_W_MAIL | PERMS_W_CHAT | PERMS_R_STORAGE | PERMS_R_PAGES;
        $r = q("update abook set abook_their_perms = %d where abook_id = %d and abook_channel = %d", intval($newperms), intval($contact['abook_id']), intval($importer['channel_id']));
        return;
    }
    $ret = find_diaspora_person_by_handle($sender_handle);
    if (!$ret || !strstr($ret['xchan_network'], 'diaspora')) {
        logger('diaspora_request: Cannot resolve diaspora handle ' . $sender_handle . ' for ' . $recipient_handle);
        return;
    }
    //FIXME
    /*
    	if(feature_enabled($channel['channel_id'],'premium_channel')) {
    		$myaddr = $importer['channel_address'] . '@' .  get_app()->get_hostname();
    		$cnv = random_string();
    		$mid = random_string();
    		$msg = t('You have started sharing with a Redmatrix premium channel.');
    		$msg .= t('Redmatrix premium channels are not available for sharing with Diaspora members. This sharing request has been blocked.') . "\r";
    		$msg .= t('Please do not reply to this message, as this channel is not sharing with you and any reply will not be seen by the recipient.') . "\r";
    		$created = datetime_convert('UTC','UTC',$item['created'],'Y-m-d H:i:s \U\T\C');
    		$signed_text =  $mid . ';' . $cnv . ';' . $msg .  ';'
            . $created . ';' . $myaddr . ';' . $cnv;
    		$sig = base64_encode(rsa_sign($signed_text,$importer['channel_prvkey'],'sha256'));
    		$conv = array(
    			'guid' => xmlify($cnv),
    			'subject' => xmlify(t('Sharing request failed.')),
    			'created_at' => xmlify($created),
    			'diaspora_handle' => xmlify($myaddr),
    			'participant_handles' => xmlify($myaddr . ';' . $sender_handle)
    		);
    		$msg = array(
    			'guid' => xmlify($mid),
    			'parent_guid' => xmlify($cnv),
    			'parent_author_signature' => xmlify($sig),
    			'author_signature' => xmlify($sig),
    			'text' => xmlify($msg),
    			'created_at' => xmlify($created),
    			'diaspora_handle' => xmlify($myaddr),
    			'conversation_guid' => xmlify($cnv)
    		);
    		$conv['messages'] = array($msg);
    		$tpl = get_markup_template('diaspora_conversation.tpl');
    		$xmsg = replace_macros($tpl, array('$conv' => $conv));
    		$slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($xmsg,$importer,$ret,$importer['channel_prvkey'],$ret['xchan_pubkey'],false)));
    		diaspora_transmit($importer,$ret,$slap,false);
    		return;
    	}
    */
    // End FIXME
    $role = get_pconfig($channel['channel_id'], 'system', 'permissions_role');
    if ($role) {
        $x = get_role_perms($role);
        if ($x['perms_auto']) {
            $default_perms = $x['perms_accept'];
        }
    }
    if (!$default_perms) {
        $default_perms = intval(get_pconfig($importer['channel_id'], 'system', 'autoperms'));
    }
    $their_perms = PERMS_R_STREAM | PERMS_R_PROFILE | PERMS_R_PHOTOS | PERMS_R_ABOOK | PERMS_W_STREAM | PERMS_W_COMMENT | PERMS_W_MAIL | PERMS_W_CHAT | PERMS_R_STORAGE | PERMS_R_PAGES;
    $closeness = get_pconfig($importer['channel_id'], 'system', 'new_abook_closeness');
    if ($closeness === false) {
        $closeness = 80;
    }
    $r = q("insert into abook ( abook_account, abook_channel, abook_xchan, abook_my_perms, abook_their_perms, abook_closeness, abook_rating, abook_created, abook_updated, abook_connected, abook_dob, abook_flags) values ( %d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', %d )", intval($importer['channel_account_id']), intval($importer['channel_id']), dbesc($ret['xchan_hash']), intval($default_perms), intval($their_perms), intval($closeness), intval(0), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(NULL_DATE), intval($default_perms ? 0 : ABOOK_FLAG_PENDING));
    if ($r) {
        logger("New Diaspora introduction received for {$importer['channel_name']}");
        $new_connection = q("select * from abook left join xchan on abook_xchan = xchan_hash left join hubloc on hubloc_hash = xchan_hash where abook_channel = %d and abook_xchan = '%s' order by abook_created desc limit 1", intval($importer['channel_id']), dbesc($ret['xchan_hash']));
        if ($new_connection) {
            require_once 'include/enotify.php';
            notification(array('type' => NOTIFY_INTRO, 'from_xchan' => $ret['xchan_hash'], 'to_xchan' => $importer['channel_hash'], 'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id']));
            if ($default_perms) {
                // Send back a sharing notification to them
                diaspora_share($importer, $new_connection[0]);
            }
        }
    }
    // find the abook record we just created
    $contact_record = diaspora_get_contact_by_handle($importer['channel_id'], $sender_handle);
    if (!$contact_record) {
        logger('diaspora_request: unable to locate newly created contact record.');
        return;
    }
    /** If there is a default group for this channel, add this member to it */
    if ($importer['channel_default_group']) {
        require_once 'include/group.php';
        $g = group_rec_byhash($importer['channel_id'], $importer['channel_default_group']);
        if ($g) {
            group_add_member($importer['channel_id'], '', $contact_record['xchan_hash'], $g['id']);
        }
    }
    return;
}
Пример #18
0
function diaspora_request($importer, $xml)
{
    $a = get_app();
    $sender_handle = unxmlify(diaspora_get_author($xml));
    $recipient_handle = unxmlify(diaspora_get_recipient($xml));
    // @TODO - map these perms to $newperms below
    if (array_key_exists('following', $xml) && array_key_exists('sharing', $xml)) {
        $following = unxmlify($xml['following']) === 'true' ? true : false;
        $sharing = unxmlify($xml['sharing']) === 'true' ? true : false;
    } else {
        $following = true;
        $sharing = true;
    }
    if (!$sender_handle || !$recipient_handle) {
        return;
    }
    // Do we already have an abook record?
    $contact = diaspora_get_contact_by_handle($importer['channel_id'], $sender_handle);
    // Please note some permissions such as PERMS_R_PAGES are impossible for Disapora.
    // They cannot currently authenticate to our system.
    $x = \Zotlabs\Access\PermissionRoles::role_perms('social');
    $their_perms = \Zotlabs\Access\Permissions::FilledPerms($x['perms_connect']);
    if ($contact && $contact['abook_id']) {
        // perhaps we were already sharing with this person. Now they're sharing with us.
        // That makes us friends. Maybe.
        foreach ($their_perms as $k => $v) {
            set_abconfig($importer['channel_id'], $contact['abook_xchan'], 'their_perms', $k, $v);
        }
        $abook_instance = $contact['abook_instance'];
        if ($abook_instance) {
            $abook_instance .= ',';
        }
        $abook_instance .= z_root();
        $r = q("update abook set abook_instance = '%s' where abook_id = %d and abook_channel = %d", dbesc($abook_instance), intval($contact['abook_id']), intval($importer['channel_id']));
        return;
    }
    $ret = find_diaspora_person_by_handle($sender_handle);
    if (!$ret || !strstr($ret['xchan_network'], 'diaspora')) {
        logger('diaspora_request: Cannot resolve diaspora handle ' . $sender_handle . ' for ' . $recipient_handle);
        return;
    }
    $my_perms = false;
    $role = get_pconfig($importer['channel_id'], 'system', 'permissions_role');
    if ($role) {
        $x = \Zotlabs\Access\PermissionRoles::role_perms($role);
        if ($x['perms_auto']) {
            $my_perms = \Zotlabs\Access\Permissions::FilledPerms($x['perms_connect']);
        }
    }
    if (!$my_perms) {
        $my_perms = \Zotlabs\Access\Permissions::FilledAutoperms($importer['channel_id']);
    }
    $closeness = get_pconfig($importer['channel_id'], 'system', 'new_abook_closeness');
    if ($closeness === false) {
        $closeness = 80;
    }
    $r = q("insert into abook ( abook_account, abook_channel, abook_xchan, abook_my_perms, abook_their_perms, abook_closeness, abook_created, abook_updated, abook_connected, abook_dob, abook_pending, abook_instance ) values ( %d, %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s', %d, '%s' )", intval($importer['channel_account_id']), intval($importer['channel_id']), dbesc($ret['xchan_hash']), intval($default_perms), intval($their_perms), intval($closeness), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(NULL_DATE), intval($my_perms ? 0 : 1), dbesc(z_root()));
    if ($my_perms) {
        foreach ($my_perms as $k => $v) {
            set_abconfig($importer['channel_id'], $ret['xchan_hash'], 'my_perms', $k, $v);
        }
    }
    if ($their_perms) {
        foreach ($their_perms as $k => $v) {
            set_abconfig($importer['channel_id'], $ret['xchan_hash'], 'their_perms', $k, $v);
        }
    }
    if ($r) {
        logger("New Diaspora introduction received for {$importer['channel_name']}");
        $new_connection = q("select * from abook left join xchan on abook_xchan = xchan_hash left join hubloc on hubloc_hash = xchan_hash where abook_channel = %d and abook_xchan = '%s' order by abook_created desc limit 1", intval($importer['channel_id']), dbesc($ret['xchan_hash']));
        if ($new_connection) {
            \Zotlabs\Lib\Enotify::submit(['type' => NOTIFY_INTRO, 'from_xchan' => $ret['xchan_hash'], 'to_xchan' => $importer['channel_hash'], 'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id']]);
            if ($my_perms) {
                // Send back a sharing notification to them
                $x = diaspora_share($importer, $new_connection[0]);
                if ($x) {
                    Zotlabs\Daemon\Master::Summon(array('Deliver', $x));
                }
            }
            $clone = array();
            foreach ($new_connection[0] as $k => $v) {
                if (strpos($k, 'abook_') === 0) {
                    $clone[$k] = $v;
                }
            }
            unset($clone['abook_id']);
            unset($clone['abook_account']);
            unset($clone['abook_channel']);
            $abconfig = load_abconfig($importer['channel_id'], $clone['abook_xchan']);
            if ($abconfig) {
                $clone['abconfig'] = $abconfig;
            }
            build_sync_packet($importer['channel_id'], ['abook' => array($clone)]);
        }
    }
    // find the abook record we just created
    $contact_record = diaspora_get_contact_by_handle($importer['channel_id'], $sender_handle);
    if (!$contact_record) {
        logger('diaspora_request: unable to locate newly created contact record.');
        return;
    }
    /** If there is a default group for this channel, add this member to it */
    if ($importer['channel_default_group']) {
        require_once 'include/group.php';
        $g = group_rec_byhash($importer['channel_id'], $importer['channel_default_group']);
        if ($g) {
            group_add_member($importer['channel_id'], '', $contact_record['xchan_hash'], $g['id']);
        }
    }
    return;
}
Пример #19
0
function pumpio_get_contact($uid, $contact)
{
    $r = q("SELECT id FROM unique_contacts WHERE url='%s' LIMIT 1", dbesc(normalise_link($contact->url)));
    if (count($r) == 0) {
        q("INSERT INTO unique_contacts (url, name, nick, avatar) VALUES ('%s', '%s', '%s', '%s')", dbesc(normalise_link($contact->url)), dbesc($contact->displayName), dbesc($contact->preferredUsername), dbesc($contact->image->url));
    } else {
        q("UPDATE unique_contacts SET name = '%s', nick = '%s', avatar = '%s' WHERE url = '%s'", dbesc($contact->displayName), dbesc($contact->preferredUsername), dbesc($contact->image->url), dbesc(normalise_link($contact->url)));
    }
    if (DB_UPDATE_VERSION >= "1177") {
        q("UPDATE `unique_contacts` SET `location` = '%s', `about` = '%s' WHERE url = '%s'", dbesc($contact->location->displayName), dbesc($contact->summary), dbesc(normalise_link($contact->url)));
    }
    $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' LIMIT 1", intval($uid), dbesc($contact->url));
    if (!count($r)) {
        // create contact record
        q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `addr`, `alias`, `notify`, `poll`,\n\t\t\t\t\t`name`, `nick`, `photo`, `network`, `rel`, `priority`,\n\t\t\t\t\t`writable`, `blocked`, `readonly`, `pending` )\n\t\t\t\tVALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, 0, 0, 0 ) ", intval($uid), dbesc(datetime_convert()), dbesc($contact->url), dbesc(normalise_link($contact->url)), dbesc(str_replace("acct:", "", $contact->id)), dbesc(''), dbesc($contact->id), dbesc('pump.io ' . $contact->id), dbesc($contact->displayName), dbesc($contact->preferredUsername), dbesc($contact->image->url), dbesc(NETWORK_PUMPIO), intval(CONTACT_IS_FRIEND), intval(1), intval(1));
        $r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1", dbesc($contact->url), intval($uid));
        if (!count($r)) {
            return false;
        }
        $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']);
        }
        require_once "Photo.php";
        $photos = import_profile_photo($contact->image->url, $uid, $contact_id);
        q("UPDATE `contact` SET `photo` = '%s',\n\t\t\t\t\t`thumb` = '%s',\n\t\t\t\t\t`micro` = '%s',\n\t\t\t\t\t`name-date` = '%s',\n\t\t\t\t\t`uri-date` = '%s',\n\t\t\t\t\t`avatar-date` = '%s'\n\t\t\t\tWHERE `id` = %d\n\t\t\t", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($contact_id));
        if (DB_UPDATE_VERSION >= "1177") {
            q("UPDATE `contact` SET `location` = '%s',\n\t\t\t\t\t\t`about` = '%s'\n\t\t\t\t\tWHERE `id` = %d", dbesc($contact->location->displayName), dbesc($contact->summary), intval($contact_id));
        }
    } else {
        // update profile photos once every two weeks as we have no notification of when they change.
        //$update_photo = (($r[0]['avatar-date'] < datetime_convert('','','now -14 days')) ? true : false);
        $update_photo = $r[0]['avatar-date'] < datetime_convert('', '', 'now -12 hours');
        // check that we have all the photos, this has been known to fail on occasion
        if (!$r[0]['photo'] || !$r[0]['thumb'] || !$r[0]['micro'] || $update_photo) {
            require_once "Photo.php";
            $photos = import_profile_photo($contact->image->url, $uid, $r[0]['id']);
            q("UPDATE `contact` SET `photo` = '%s',\n\t\t\t\t\t`thumb` = '%s',\n\t\t\t\t\t`micro` = '%s',\n\t\t\t\t\t`name-date` = '%s',\n\t\t\t\t\t`uri-date` = '%s',\n\t\t\t\t\t`avatar-date` = '%s',\n\t\t\t\t\t`name` = '%s',\n\t\t\t\t\t`nick` = '%s'\n\t\t\t\t\tWHERE `id` = %d\n\t\t\t\t", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($contact->displayName), dbesc($contact->preferredUsername), intval($r[0]['id']));
            if (DB_UPDATE_VERSION >= "1177") {
                q("UPDATE `contact` SET `location` = '%s',\n\t\t\t\t\t\t\t`about` = '%s'\n\t\t\t\t\t\tWHERE `id` = %d", dbesc($contact->location->displayName), dbesc($contact->summary), intval($r[0]['id']));
            }
        }
    }
    return $r[0]["id"];
}
Пример #20
0
 function post()
 {
     if (!local_channel()) {
         return;
     }
     $contact_id = intval(argv(1));
     if (!$contact_id) {
         return;
     }
     $channel = \App::get_channel();
     // TODO if configured for hassle-free permissions, we'll post the form with ajax as soon as the
     // connection enable is toggled to a special autopost url and set permissions immediately, leaving
     // the other form elements alone pending a manual submit of the form. The downside is that there
     // will be a window of opportunity when the permissions have been set but before you've had a chance
     // to review and possibly restrict them. The upside is we won't have to warn you that your connection
     // can't do anything until you save the bloody form.
     $autopost = argc() > 2 && argv(2) === 'auto' ? true : false;
     $orig_record = q("SELECT * FROM abook WHERE abook_id = %d AND abook_channel = %d LIMIT 1", intval($contact_id), intval(local_channel()));
     if (!$orig_record) {
         notice(t('Could not access contact record.') . EOL);
         goaway(z_root() . '/connections');
         return;
         // NOTREACHED
     }
     call_hooks('contact_edit_post', $_POST);
     if (intval($orig_record[0]['abook_self'])) {
         $autoperms = intval($_POST['autoperms']);
         $is_self = true;
     } else {
         $autoperms = null;
         $is_self = false;
     }
     $profile_id = $_POST['profile_assign'];
     if ($profile_id) {
         $r = q("SELECT profile_guid FROM profile WHERE profile_guid = '%s' AND `uid` = %d LIMIT 1", dbesc($profile_id), intval(local_channel()));
         if (!count($r)) {
             notice(t('Could not locate selected profile.') . EOL);
             return;
         }
     }
     $abook_incl = escape_tags($_POST['abook_incl']);
     $abook_excl = escape_tags($_POST['abook_excl']);
     $hidden = intval($_POST['hidden']);
     $priority = intval($_POST['poll']);
     if ($priority > 5 || $priority < 0) {
         $priority = 0;
     }
     $closeness = intval($_POST['closeness']);
     if ($closeness < 0) {
         $closeness = 99;
     }
     $rating = intval($_POST['rating']);
     if ($rating < -10) {
         $rating = -10;
     }
     if ($rating > 10) {
         $rating = 10;
     }
     $rating_text = trim(escape_tags($_REQUEST['rating_text']));
     $abook_my_perms = 0;
     foreach ($_POST as $k => $v) {
         if (strpos($k, 'perms_') === 0) {
             $abook_my_perms += $v;
         }
     }
     $new_friend = false;
     if (!$is_self) {
         $signed = $orig_record[0]['abook_xchan'] . '.' . $rating . '.' . $rating_text;
         $sig = base64url_encode(rsa_sign($signed, $channel['channel_prvkey']));
         $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", dbesc($channel['channel_hash']), dbesc($orig_record[0]['abook_xchan']));
         if ($z) {
             $record = $z[0]['xlink_id'];
             $w = q("update xlink set xlink_rating = '%d', xlink_rating_text = '%s', xlink_sig = '%s', xlink_updated = '%s'\n\t\t\t\t\twhere xlink_id = %d", intval($rating), dbesc($rating_text), dbesc($sig), dbesc(datetime_convert()), intval($record));
         } else {
             $w = q("insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_sig, xlink_updated, xlink_static ) values ( '%s', '%s', %d, '%s', '%s', '%s', 1 ) ", dbesc($channel['channel_hash']), dbesc($orig_record[0]['abook_xchan']), intval($rating), dbesc($rating_text), dbesc($sig), dbesc(datetime_convert()));
             $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", dbesc($channel['channel_hash']), dbesc($orig_record[0]['abook_xchan']));
             if ($z) {
                 $record = $z[0]['xlink_id'];
             }
         }
         if ($record) {
             proc_run('php', 'include/ratenotif.php', 'rating', $record);
         }
     }
     if ($_REQUEST['pending'] && intval($orig_record[0]['abook_pending'])) {
         $new_friend = true;
         // @fixme it won't be common, but when you accept a new connection request
         // the permissions will now be that of your permissions role and ignore
         // any you may have set manually on the form. We'll probably see a bug if somebody
         // tries to set the permissions *and* approve the connection in the same
         // request. The workaround is to approve the connection, then go back and
         // adjust permissions as desired.
         $abook_my_perms = get_channel_default_perms(local_channel());
         $role = get_pconfig(local_channel(), 'system', 'permissions_role');
         if ($role) {
             $x = get_role_perms($role);
             if ($x['perms_accept']) {
                 $abook_my_perms = $x['perms_accept'];
             }
         }
     }
     $abook_pending = $new_friend ? 0 : $orig_record[0]['abook_pending'];
     $r = q("UPDATE abook SET abook_profile = '%s', abook_my_perms = %d , abook_closeness = %d, abook_pending = %d,\n\t\t\tabook_incl = '%s', abook_excl = '%s'\n\t\t\twhere abook_id = %d AND abook_channel = %d", dbesc($profile_id), intval($abook_my_perms), intval($closeness), intval($abook_pending), dbesc($abook_incl), dbesc($abook_excl), intval($contact_id), intval(local_channel()));
     if ($orig_record[0]['abook_profile'] != $profile_id) {
         //Update profile photo permissions
         logger('A new profile was assigned - updating profile photos');
         profile_photo_set_profile_perms($profile_id);
     }
     if ($r) {
         info(t('Connection updated.') . EOL);
     } else {
         notice(t('Failed to update connection record.') . EOL);
     }
     if (\App::$poi && \App::$poi['abook_my_perms'] != $abook_my_perms && !intval(\App::$poi['abook_self'])) {
         proc_run('php', 'include/notifier.php', $new_friend ? 'permission_create' : 'permission_update', $contact_id);
     }
     if ($new_friend) {
         $default_group = $channel['channel_default_group'];
         if ($default_group) {
             require_once 'include/group.php';
             $g = group_rec_byhash(local_channel(), $default_group);
             if ($g) {
                 group_add_member(local_channel(), '', \App::$poi['abook_xchan'], $g['id']);
             }
         }
         // Check if settings permit ("post new friend activity" is allowed, and
         // friends in general or this friend in particular aren't hidden)
         // and send out a new friend activity
         $pr = q("select * from profile where uid = %d and is_default = 1 and hide_friends = 0", intval($channel['channel_id']));
         if ($pr && !intval($orig_record[0]['abook_hidden']) && intval(get_pconfig($channel['channel_id'], 'system', 'post_newfriend'))) {
             $xarr = array();
             $xarr['verb'] = ACTIVITY_FRIEND;
             $xarr['item_wall'] = 1;
             $xarr['item_origin'] = 1;
             $xarr['item_thread_top'] = 1;
             $xarr['owner_xchan'] = $xarr['author_xchan'] = $channel['channel_hash'];
             $xarr['allow_cid'] = $channel['channel_allow_cid'];
             $xarr['allow_gid'] = $channel['channel_allow_gid'];
             $xarr['deny_cid'] = $channel['channel_deny_cid'];
             $xarr['deny_gid'] = $channel['channel_deny_gid'];
             $xarr['item_private'] = $xarr['allow_cid'] || $xarr['allow_gid'] || $xarr['deny_cid'] || $xarr['deny_gid'] ? 1 : 0;
             $obj = array('type' => ACTIVITY_OBJ_PERSON, 'title' => \App::$poi['xchan_name'], 'id' => \App::$poi['xchan_hash'], 'link' => array(array('rel' => 'alternate', 'type' => 'text/html', 'href' => \App::$poi['xchan_url']), array('rel' => 'photo', 'type' => \App::$poi['xchan_photo_mimetype'], 'href' => \App::$poi['xchan_photo_l'])));
             $xarr['object'] = json_encode($obj);
             $xarr['obj_type'] = ACTIVITY_OBJ_PERSON;
             $xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . \App::$poi['xchan_url'] . ']' . \App::$poi['xchan_name'] . '[/zrl]';
             $xarr['body'] .= "\n\n\n" . '[zrl=' . \App::$poi['xchan_url'] . '][zmg=80x80]' . \App::$poi['xchan_photo_m'] . '[/zmg][/zrl]';
             post_activity_item($xarr);
         }
         // pull in a bit of content if there is any to pull in
         proc_run('php', 'include/onepoll.php', $contact_id);
     }
     // Refresh the structure in memory with the new data
     $r = q("SELECT abook.*, xchan.*\n\t\t\tFROM abook left join xchan on abook_xchan = xchan_hash\n\t\t\tWHERE abook_channel = %d and abook_id = %d LIMIT 1", intval(local_channel()), intval($contact_id));
     if ($r) {
         \App::$poi = $r[0];
     }
     if ($new_friend) {
         $arr = array('channel_id' => local_channel(), 'abook' => \App::$poi);
         call_hooks('accept_follow', $arr);
     }
     if (!is_null($autoperms)) {
         set_pconfig(local_channel(), 'system', 'autoperms', $autoperms ? $abook_my_perms : 0);
     }
     $this->connedit_clone($a);
     if ($_REQUEST['pending'] && !$_REQUEST['done']) {
         goaway(z_root() . '/connections/ifpending');
     }
     return;
 }
Пример #21
0
function new_contact($uid, $url, $interactive = false)
{
    $result = array('cid' => -1, 'success' => false, 'message' => '');
    $a = get_app();
    // remove ajax junk, e.g. Twitter
    $url = str_replace('/#!/', '/', $url);
    if (!allowed_url($url)) {
        $result['message'] = t('Disallowed profile URL.');
        return $result;
    }
    if (!$url) {
        $result['message'] = t('Connect URL missing.');
        return $result;
    }
    $arr = array('url' => $url, 'contact' => array());
    call_hooks('follow', $arr);
    if (x($arr['contact'], 'name')) {
        $ret = $arr['contact'];
    } else {
        $ret = probe_url($url);
    }
    if ($ret['network'] === NETWORK_DFRN) {
        if ($interactive) {
            if (strlen($a->path)) {
                $myaddr = bin2hex($a->get_baseurl() . '/profile/' . $a->user['nickname']);
            } else {
                $myaddr = bin2hex($a->user['nickname'] . '@' . $a->get_hostname());
            }
            goaway($ret['request'] . "&addr={$myaddr}");
            // NOTREACHED
        }
    } else {
        if (get_config('system', 'dfrn_only')) {
            $result['message'] = t('This site is not configured to allow communications with other networks.') . EOL;
            $result['message'] != t('No compatible communication protocols or feeds were discovered.') . EOL;
            return $result;
        }
    }
    // This extra param just confuses things, remove it
    if ($ret['network'] === NETWORK_DIASPORA) {
        $ret['url'] = str_replace('?absolute=true', '', $ret['url']);
    }
    // do we have enough information?
    if (!(x($ret, 'name') && x($ret, 'poll') && (x($ret, 'url') || x($ret, 'addr')))) {
        $result['message'] .= t('The profile address specified does not provide adequate information.') . EOL;
        if (!x($ret, 'poll')) {
            $result['message'] .= t('No compatible communication protocols or feeds were discovered.') . EOL;
        }
        if (!x($ret, 'name')) {
            $result['message'] .= t('An author or name was not found.') . EOL;
        }
        if (!x($ret, 'url')) {
            $result['message'] .= t('No browser URL could be matched to this address.') . EOL;
        }
        if (strpos($url, '@') !== false) {
            $result['message'] .= t('Unable to match @-style Identity Address with a known protocol or email contact.') . EOL;
            $result['message'] .= t('Use mailto: in front of address to force email check.') . EOL;
        }
        return $result;
    }
    if ($ret['network'] === NETWORK_OSTATUS && get_config('system', 'ostatus_disabled')) {
        $result['message'] .= t('The profile address specified belongs to a network which has been disabled on this site.') . EOL;
        $ret['notify'] = '';
    }
    if (!$ret['notify']) {
        $result['message'] .= t('Limited profile. This person will be unable to receive direct/personal notifications from you.') . EOL;
    }
    $writeable = $ret['network'] === NETWORK_OSTATUS && $ret['notify'] ? 1 : 0;
    $subhub = $ret['network'] === NETWORK_OSTATUS ? true : false;
    $hidden = $ret['network'] === NETWORK_MAIL ? 1 : 0;
    if ($ret['network'] === NETWORK_MAIL) {
        $writeable = 1;
    }
    if ($ret['network'] === NETWORK_DIASPORA) {
        $writeable = 1;
    }
    // check if we already have a contact
    // the poll url is more reliable than the profile url, as we may have
    // indirect links or webfinger links
    $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `poll` IN ('%s', '%s') AND `network` = '%s' LIMIT 1", intval($uid), dbesc($ret['poll']), dbesc(normalise_link($ret['poll'])), dbesc($ret['network']));
    if (!count($r)) {
        $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' AND `network` = '%s' LIMIT 1", intval($uid), dbesc(normalise_link($url)), dbesc($ret['network']));
    }
    if (count($r)) {
        // update contact
        if ($r[0]['rel'] == CONTACT_IS_FOLLOWER || $network === NETWORK_DIASPORA && $r[0]['rel'] == CONTACT_IS_SHARING) {
            q("UPDATE `contact` SET `rel` = %d , `subhub` = %d, `readonly` = 0 WHERE `id` = %d AND `uid` = %d", intval(CONTACT_IS_FRIEND), intval($subhub), intval($r[0]['id']), intval($uid));
        }
    } else {
        // check service class limits
        $r = q("select count(*) as total from contact where uid = %d and pending = 0 and self = 0", intval($uid));
        if (count($r)) {
            $total_contacts = $r[0]['total'];
        }
        if (!service_class_allows($uid, 'total_contacts', $total_contacts)) {
            $result['message'] .= upgrade_message();
            return $result;
        }
        $r = q("select count(network) as total from contact where uid = %d and network = '%s' and pending = 0 and self = 0", intval($uid), dbesc($network));
        if (count($r)) {
            $total_network = $r[0]['total'];
        }
        if (!service_class_allows($uid, 'total_contacts_' . $network, $total_network)) {
            $result['message'] .= upgrade_message();
            return $result;
        }
        $new_relation = $ret['network'] === NETWORK_MAIL ? CONTACT_IS_FRIEND : CONTACT_IS_SHARING;
        if ($ret['network'] === NETWORK_DIASPORA) {
            $new_relation = CONTACT_IS_FOLLOWER;
        }
        // create contact record
        $r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `addr`, `alias`, `batch`, `notify`, `poll`, `poco`, `name`, `nick`, `network`, `pubkey`, `rel`, `priority`,\n\t\t\t`writable`, `hidden`, `blocked`, `readonly`, `pending`, `subhub` )\n\t\t\tVALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, 0, 0, 0, %d ) ", intval($uid), dbesc(datetime_convert()), dbesc($ret['url']), dbesc(normalise_link($ret['url'])), dbesc($ret['addr']), dbesc($ret['alias']), dbesc($ret['batch']), dbesc($ret['notify']), dbesc($ret['poll']), dbesc($ret['poco']), dbesc($ret['name']), dbesc($ret['nick']), dbesc($ret['network']), dbesc($ret['pubkey']), intval($new_relation), intval($ret['priority']), intval($writeable), intval($hidden), intval($subhub));
    }
    $r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `network` = '%s' AND `uid` = %d LIMIT 1", dbesc($ret['url']), dbesc($ret['network']), intval($uid));
    if (!count($r)) {
        $result['message'] .= t('Unable to retrieve contact information.') . EOL;
        return $result;
    }
    $contact = $r[0];
    $contact_id = $r[0]['id'];
    $result['cid'] = $contact_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']);
    }
    require_once "include/Photo.php";
    $photos = import_profile_photo($ret['photo'], $uid, $contact_id);
    $r = q("UPDATE `contact` SET `photo` = '%s',\n\t\t\t`thumb` = '%s',\n\t\t\t`micro` = '%s',\n\t\t\t`name-date` = '%s',\n\t\t\t`uri-date` = '%s',\n\t\t\t`avatar-date` = '%s'\n\t\t\tWHERE `id` = %d", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($contact_id));
    // pull feed and consume it, which should subscribe to the hub.
    proc_run('php', "include/onepoll.php", "{$contact_id}", "force");
    // create a follow slap
    $tpl = get_markup_template('follow_slap.tpl');
    $slap = replace_macros($tpl, array('$name' => $a->user['username'], '$profile_page' => $a->get_baseurl() . '/profile/' . $a->user['nickname'], '$photo' => $a->contact['photo'], '$thumb' => $a->contact['thumb'], '$published' => datetime_convert('UTC', 'UTC', 'now', ATOM_TIME), '$item_id' => 'urn:X-dfrn:' . $a->get_hostname() . ':follow:' . get_guid(32), '$title' => '', '$type' => 'text', '$content' => t('following'), '$nick' => $a->user['nickname'], '$verb' => ACTIVITY_FOLLOW, '$ostat_follow' => ''));
    $r = q("SELECT `contact`.*, `user`.* FROM `contact` INNER JOIN `user` ON `contact`.`uid` = `user`.`uid`\n\t\t\tWHERE `user`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1", intval($uid));
    if (count($r)) {
        if ($contact['network'] == NETWORK_OSTATUS && strlen($contact['notify'])) {
            require_once 'include/salmon.php';
            slapper($r[0], $contact['notify'], $slap);
        }
        if ($contact['network'] == NETWORK_DIASPORA) {
            require_once 'include/diaspora.php';
            $ret = diaspora_share($a->user, $contact);
            logger('mod_follow: diaspora_share returns: ' . $ret);
        }
    }
    $result['success'] = true;
    return $result;
}
Пример #22
0
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('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('Confirming request for dfrn_id (issued) ' . $dfrn_id);
        if ($cid) {
            logger('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('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", 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('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(' 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);
            }
            if (stristr($res, "<status") === false) {
                // wrong xml! stop here!
                notice(t('Unexpected response from remote site: ') . EOL . htmlspecialchars($res) . EOL);
                return;
            }
            $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", 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", 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\n\t\t\t\t`photo` = '%s',\n\t\t\t\t`thumb` = '%s',\n\t\t\t\t`micro` = '%s',\n\t\t\t\t`rel` = %d,\n\t\t\t\t`name-date` = '%s',\n\t\t\t\t`uri-date` = '%s',\n\t\t\t\t`avatar-date` = '%s',\n\t\t\t\t`blocked` = 0,\n\t\t\t\t`pending` = 0,\n\t\t\t\t`duplex` = %d,\n\t\t\t\t`hidden` = %d,\n\t\t\t\t`network` = '%s' WHERE `id` = %d\n\t\t\t", 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), dbesc(NETWORK_DFRN), 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'];
            if ($network === NETWORK_DIASPORA) {
                if ($duplex) {
                    $new_relation = CONTACT_IS_FRIEND;
                } else {
                    $new_relation = CONTACT_IS_FOLLOWER;
                }
                if ($new_relation != CONTACT_IS_FOLLOWER) {
                    $writable = 1;
                }
            }
            $r = q("DELETE FROM `intro` WHERE `id` = %d AND `uid` = %d", intval($intro_id), intval($uid));
            $r = q("UPDATE `contact` SET `photo` = '%s',\n\t\t\t\t`thumb` = '%s',\n\t\t\t\t`micro` = '%s',\n\t\t\t\t`name-date` = '%s',\n\t\t\t\t`uri-date` = '%s',\n\t\t\t\t`avatar-date` = '%s',\n\t\t\t\t`notify` = '%s',\n\t\t\t\t`poll` = '%s',\n\t\t\t\t`blocked` = 0,\n\t\t\t\t`pending` = 0,\n\t\t\t\t`network` = '%s',\n\t\t\t\t`writable` = %d,\n\t\t\t\t`hidden` = %d,\n\t\t\t\t`rel` = %d\n\t\t\t\tWHERE `id` = %d\n\t\t\t", 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) {
            if ($contact && $contact['network'] === NETWORK_DIASPORA) {
                require_once 'include/diaspora.php';
                $ret = diaspora_share($user[0], $r[0]);
                logger('mod_follow: diaspora_share returns: ' . $ret);
            }
            // 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_new_uri($a->get_hostname(), $uid);
                    $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['object-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['last-child'] = 1;
                    $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') ? (double) $_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", 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", 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 "include/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\n\t\t\t`photo` = '%s',\n\t\t\t`thumb` = '%s',\n\t\t\t`micro` = '%s',\n\t\t\t`rel` = %d,\n\t\t\t`name-date` = '%s',\n\t\t\t`uri-date` = '%s',\n\t\t\t`avatar-date` = '%s',\n\t\t\t`blocked` = 0,\n\t\t\t`pending` = 0,\n\t\t\t`duplex` = %d,\n\t\t\t`forum` = %d,\n\t\t\t`prv` = %d,\n\t\t\t`network` = '%s' WHERE `id` = %d\n\t\t", 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`\n\t\t\tWHERE `contact`.`id` = %d LIMIT 1", intval($dfrn_record));
        if (count($r)) {
            $combined = $r[0];
        }
        if (count($r) && $r[0]['notify-flags'] & NOTIFY_CONFIRM) {
            $mutual = $new_relation == CONTACT_IS_FRIEND;
            notification(array('type' => NOTIFY_CONFIRM, '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() . '/contacts/' . $dfrn_record, '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' => $mutual ? ACTIVITY_FRIEND : ACTIVITY_FOLLOW, 'otype' => 'intro'));
        }
        // 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_new_uri($a->get_hostname(), $local_uid);
                    $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['object-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['last-child'] = 1;
                    $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
}
Пример #23
0
function diaspora_request($importer, $xml)
{
    $a = get_app();
    $sender_handle = unxmlify($xml->sender_handle);
    $recipient_handle = unxmlify($xml->recipient_handle);
    if (!$sender_handle || !$recipient_handle) {
        return;
    }
    // Do we already have an abook record?
    $contact = diaspora_get_contact_by_handle($importer['channel_id'], $sender_handle);
    if ($contact && $contact['abook_id']) {
        // perhaps we were already sharing with this person. Now they're sharing with us.
        // That makes us friends. Maybe.
        // Please note some of these permissions such as PERMS_R_PAGES are impossible for Disapora.
        // They cannot authenticate to our system.
        $newperms = PERMS_R_STREAM | PERMS_R_PROFILE | PERMS_R_PHOTOS | PERMS_R_ABOOK | PERMS_W_STREAM | PERMS_W_COMMENT | PERMS_W_MAIL | PERMS_W_CHAT | PERMS_R_STORAGE | PERMS_R_PAGES;
        $r = q("update abook set abook_their_perms = %d where abook_id = %d and abook_channel = %d limit 1", intval($newperms), intval($contact['abook_id']), intval($importer['channel_id']));
        return;
    }
    $ret = find_diaspora_person_by_handle($sender_handle);
    if (!$ret || !strstr($ret['xchan_network'], 'diaspora')) {
        logger('diaspora_request: Cannot resolve diaspora handle ' . $sender_handle . ' for ' . $recipient_handle);
        return;
    }
    $default_perms = 0;
    // look for default permissions to apply in return - e.g. auto-friend
    $z = q("select * from abook where abook_channel = %d and (abook_flags & %d) limit 1", intval($importer['channel_id']), intval(ABOOK_FLAG_SELF));
    if ($z) {
        $default_perms = intval($z[0]['abook_my_perms']);
    }
    $their_perms = PERMS_R_STREAM | PERMS_R_PROFILE | PERMS_R_PHOTOS | PERMS_R_ABOOK | PERMS_W_STREAM | PERMS_W_COMMENT | PERMS_W_MAIL | PERMS_W_CHAT | PERMS_R_STORAGE | PERMS_R_PAGES;
    $r = q("insert into abook ( abook_account, abook_channel, abook_xchan, abook_my_perms, abook_their_perms, abook_closeness, abook_rating, abook_created, abook_updated, abook_connected, abook_dob, abook_flags) values ( %d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', %d )", intval($importer['channel_account_id']), intval($importer['channel_id']), dbesc($ret['xchan_hash']), intval($default_perms), intval($their_perms), intval(99), intval(0), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(NULL_DATE), intval($default_perms ? 0 : ABOOK_FLAG_PENDING));
    if ($r) {
        logger("New Diaspora introduction received for {$importer['channel_name']}");
        $new_connection = q("select * from abook left join xchan on abook_xchan = xchan_hash left join hubloc on hubloc_hash = xchan_hash where abook_channel = %d and abook_xchan = '%s' order by abook_created desc limit 1", intval($importer['channel_id']), dbesc($ret['xchan_hash']));
        if ($new_connection) {
            require_once 'include/enotify.php';
            notification(array('type' => NOTIFY_INTRO, 'from_xchan' => $ret['xchan_hash'], 'to_xchan' => $importer['channel_hash'], 'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id']));
            if ($default_perms) {
                // Send back a sharing notification to them
                diaspora_share($importer, $new_connection[0]);
            }
        }
    }
    // find the abook record we just created
    $contact_record = diaspora_get_contact_by_handle($importer['channel_id'], $sender_handle);
    if (!$contact_record) {
        logger('diaspora_request: unable to locate newly created contact record.');
        return;
    }
    /** If there is a default group for this channel, add this member to it */
    if ($importer['channel_default_group']) {
        require_once 'include/group.php';
        $g = group_rec_byhash($importer['channel_id'], $importer['channel_default_group']);
        if ($g) {
            group_add_member($importer['channel_id'], '', $contact_record['xchan_hash'], $g['id']);
        }
    }
    return;
}
Пример #24
0
function new_follower($importer, $contact, $datarray, $item, $sharing = false)
{
    $url = notags(trim($datarray['author-link']));
    $name = notags(trim($datarray['author-name']));
    $photo = notags(trim($datarray['author-avatar']));
    $rawtag = $item->get_item_tags(NAMESPACE_ACTIVITY, 'actor');
    if ($rawtag && $rawtag[0]['child'][NAMESPACE_POCO]['preferredUsername'][0]['data']) {
        $nick = $rawtag[0]['child'][NAMESPACE_POCO]['preferredUsername'][0]['data'];
    }
    if (is_array($contact)) {
        if ($contact['network'] == NETWORK_OSTATUS && $contact['rel'] == CONTACT_IS_SHARING || $sharing && $contact['rel'] == CONTACT_IS_FOLLOWER) {
            $r = q("UPDATE `contact` SET `rel` = %d WHERE `id` = %d AND `uid` = %d LIMIT 1", intval(CONTACT_IS_FRIEND), intval($contact['id']), intval($importer['uid']));
        }
        // send email notification to owner?
    } else {
        // create contact record
        $r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `name`, `nick`, `photo`, `network`, `rel`, \n\t\t\t`blocked`, `readonly`, `pending`, `writable` )\n\t\t\tVALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, 0, 0, 1, 1 ) ", intval($importer['uid']), dbesc(datetime_convert()), dbesc($url), dbesc(normalise_link($url)), dbesc($name), dbesc($nick), dbesc($photo), dbesc($sharing ? NETWORK_ZOT : NETWORK_OSTATUS), intval($sharing ? CONTACT_IS_SHARING : CONTACT_IS_FOLLOWER));
        $r = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND `url` = '%s' AND `pending` = 1 LIMIT 1", intval($importer['uid']), dbesc($url));
        if (count($r)) {
            $contact_record = $r[0];
        }
        // create notification
        $hash = random_string();
        if (is_array($contact_record)) {
            $ret = q("INSERT INTO `intro` ( `uid`, `contact-id`, `blocked`, `knowyou`, `hash`, `datetime`)\n\t\t\t\tVALUES ( %d, %d, 0, 0, '%s', '%s' )", intval($importer['uid']), intval($contact_record['id']), dbesc($hash), dbesc(datetime_convert()));
        }
        $r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($importer['uid']));
        $a = get_app();
        if (count($r)) {
            if (intval($r[0]['def_gid'])) {
                require_once 'include/group.php';
                group_add_member($r[0]['uid'], '', $contact_record['id'], $r[0]['def_gid']);
            }
            if ($r[0]['notify-flags'] & NOTIFY_INTRO && $r[0]['page-flags'] == PAGE_NORMAL) {
                $email_tpl = get_intltext_template('follow_notify_eml.tpl');
                $email = replace_macros($email_tpl, array('$requestor' => strlen($name) ? $name : t('[Name Withheld]'), '$url' => $url, '$myname' => $r[0]['username'], '$siteurl' => $a->get_baseurl(), '$sitename' => $a->config['sitename']));
                $res = mail($r[0]['email'], ($sharing ? t('A new person is sharing with you at ') : t("You have a new follower at ")) . $a->config['sitename'], $email, 'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n" . 'Content-type: text/plain; charset=UTF-8' . "\n" . 'Content-transfer-encoding: 8bit');
            }
        }
    }
}
Пример #25
0
function connections_post(&$a)
{
    if (!local_channel()) {
        return;
    }
    $contact_id = intval(argv(1));
    if (!$contact_id) {
        return;
    }
    $orig_record = q("SELECT * FROM abook WHERE abook_id = %d AND abook_channel = %d LIMIT 1", intval($contact_id), intval(local_channel()));
    if (!$orig_record) {
        notice(t('Could not access contact record.') . EOL);
        goaway(z_root() . '/connections');
        return;
        // NOTREACHED
    }
    call_hooks('contact_edit_post', $_POST);
    $profile_id = $_POST['profile_assign'];
    if ($profile_id) {
        $r = q("SELECT profile_guid FROM profile WHERE profile_guid = '%s' AND `uid` = %d LIMIT 1", dbesc($profile_id), intval(local_channel()));
        if (!count($r)) {
            notice(t('Could not locate selected profile.') . EOL);
            return;
        }
    }
    $hidden = intval($_POST['hidden']);
    $priority = intval($_POST['poll']);
    if ($priority > 5 || $priority < 0) {
        $priority = 0;
    }
    $closeness = intval($_POST['closeness']);
    if ($closeness < 0) {
        $closeness = 99;
    }
    $abook_my_perms = 0;
    foreach ($_POST as $k => $v) {
        if (strpos($k, 'perms_') === 0) {
            $abook_my_perms += $v;
        }
    }
    $abook_flags = $orig_record[0]['abook_flags'];
    $new_friend = false;
    if ($_REQUEST['pending'] && $abook_flags & ABOOK_FLAG_PENDING) {
        $abook_flags = $abook_flags ^ ABOOK_FLAG_PENDING;
        $new_friend = true;
    }
    $r = q("UPDATE abook SET abook_profile = '%s', abook_my_perms = %d , abook_closeness = %d, abook_flags = %d\n\t\twhere abook_id = %d AND abook_channel = %d", dbesc($profile_id), intval($abook_my_perms), intval($closeness), intval($abook_flags), intval($contact_id), intval(local_channel()));
    if ($r) {
        info(t('Connection updated.') . EOL);
    } else {
        notice(t('Failed to update connection record.') . EOL);
    }
    if (x($a->data, 'abook') && $a->data['abook']['abook_my_perms'] != $abook_my_perms && !($a->data['abook']['abook_flags'] & ABOOK_FLAG_SELF)) {
        proc_run('php', 'include/notifier.php', 'permission_update', $contact_id);
    }
    if ($new_friend) {
        $channel = $a->get_channel();
        $default_group = $channel['channel_default_group'];
        if ($default_group) {
            require_once 'include/group.php';
            $g = group_rec_byhash(local_channel(), $default_group);
            if ($g) {
                group_add_member(local_channel(), '', $a->data['abook_xchan'], $g['id']);
            }
        }
        // Check if settings permit ("post new friend activity" is allowed, and
        // friends in general or this friend in particular aren't hidden)
        // and send out a new friend activity
        // TODO
        // pull in a bit of content if there is any to pull in
        proc_run('php', 'include/onepoll.php', $contact_id);
    }
    // Refresh the structure in memory with the new data
    $r = q("SELECT abook.*, xchan.* \n\t\tFROM abook left join xchan on abook_xchan = xchan_hash\n\t\tWHERE abook_channel = %d and abook_id = %d LIMIT 1", intval(local_channel()), intval($contact_id));
    if ($r) {
        $a->data['abook'] = $r[0];
    }
    if ($new_friend) {
        $arr = array('channel_id' => local_channel(), 'abook' => $a->data['abook']);
        call_hooks('accept_follow', $arr);
    }
    connections_clone($a);
    return;
}
Пример #26
0
function import_diaspora($data)
{
    $a = get_app();
    $account = $a->get_account();
    if (!$account) {
        return false;
    }
    $address = escape_tags($data['user']['username']);
    if (!$address) {
        notice(t('No username found in import file.') . EOL);
        return false;
    }
    $r = q("select * from channel where channel_address = '%s' limit 1", dbesc($address));
    if ($r) {
        // try at most ten times to generate a unique address.
        $x = 0;
        $found_unique = false;
        do {
            $tmp = $address . mt_rand(1000, 9999);
            $r = q("select * from channel where channel_address = '%s' limit 1", dbesc($tmp));
            if (!$r) {
                $address = $tmp;
                $found_unique = true;
                break;
            }
            $x++;
        } while ($x < 10);
        if (!$found_unique) {
            logger('import_diaspora: duplicate channel address. randomisation failed.');
            notice(t('Unable to create a unique channel address. Import failed.') . EOL);
            return;
        }
    }
    $c = create_identity(array('name' => escape_tags($data['user']['name']), 'nickname' => $address, 'account_id' => $account['account_id'], 'permissions_role' => 'social'));
    if (!$c['success']) {
        return;
    }
    $channel_id = $c['channel']['channel_id'];
    // todo - add auto follow settings, (and strip exif in hubzilla)
    $location = escape_tags($data['user']['profile']['location']);
    if (!$location) {
        $location = '';
    }
    q("update channel set channel_location = '%s' where channel_id = %d", dbesc($location), intval($channel_id));
    if ($data['user']['profile']['nsfw']) {
        // fixme for hubzilla which doesn't use pageflags any more
        q("update channel set channel_pageflags = (channel_pageflags | %d) where channel_id = %d", intval(PAGE_ADULT), intval($channel_id));
    }
    if ($data['user']['profile']['image_url']) {
        $p = z_fetch_url($data['user']['profile']['image_url'], true);
        if ($p['success']) {
            $rawbytes = $p['body'];
            $type = guess_image_type('dummyfile', $p['header']);
            import_channel_photo($rawbytes, $type, $c['channel']['channel_account_id'], $channel_id);
        }
    }
    $gender = escape_tags($data['user']['profile']['gender']);
    $about = diaspora2bb($data['user']['profile']['bio']);
    $publish = intval($data['user']['profile']['searchable']);
    if ($data['user']['profile']['birthday']) {
        $dob = datetime_convert('UTC', 'UTC', $data['user']['profile']['birthday'], 'Y-m-d');
    } else {
        $dob = '0000-00-00';
    }
    // we're relying on the fact that this channel was just created and will only
    // have the default profile currently
    $r = q("update profile set gender = '%s', about = '%s', dob = '%s', publish = %d where uid = %d", dbesc($gender), dbesc($about), dbesc($dob), dbesc($publish), intval($channel_id));
    if ($data['user']['aspects']) {
        foreach ($data['user']['aspects'] as $aspect) {
            group_add($channel_id, escape_tags($aspect['name']), intval($aspect['contacts_visible']));
        }
    }
    // now add connections and send friend requests
    if ($data['user']['contacts']) {
        foreach ($data['user']['contacts'] as $contact) {
            $result = new_contact($channel_id, $contact['person_diaspora_handle'], $c['channel']);
            if ($result['success']) {
                if ($contact['aspects']) {
                    foreach ($contact['aspects'] as $aspect) {
                        group_add_member($channel_id, $aspect['name'], $result['abook']['xchan_hash']);
                    }
                }
            }
        }
    }
    // Then add items - note this can't be done until Diaspora adds guids to exported
    // items and comments
    // This will indirectly perform a refresh_all *and* update the directory
    proc_run('php', 'include/directory.php', $channel_id);
    notice(t('Import completed.') . EOL);
    change_channel($channel_id);
    goaway(z_root() . '/network');
}
Пример #27
0
function new_contact($uid, $url, $channel, $interactive = false, $confirm = false)
{
    $result = array('success' => false, 'message' => '');
    $is_red = false;
    $is_http = strpos($url, '://') !== false ? true : false;
    if ($is_http && substr($url, -1, 1) === '/') {
        $url = substr($url, 0, -1);
    }
    if (!allowed_url($url)) {
        $result['message'] = t('Channel is blocked on this site.');
        return $result;
    }
    if (!$url) {
        $result['message'] = t('Channel location missing.');
        return $result;
    }
    // check service class limits
    $r = q("select count(*) as total from abook where abook_channel = %d and abook_self = 0 ", intval($uid));
    if ($r) {
        $total_channels = $r[0]['total'];
    }
    if (!service_class_allows($uid, 'total_channels', $total_channels)) {
        $result['message'] = upgrade_message();
        return $result;
    }
    $arr = array('url' => $url, 'channel' => array());
    call_hooks('follow', $arr);
    if ($arr['channel']['success']) {
        $ret = $arr['channel'];
    } elseif (!$is_http) {
        $ret = Zotlabs\Zot\Finger::run($url, $channel);
    }
    if ($ret && is_array($ret) && $ret['success']) {
        $is_red = true;
        $j = $ret;
    }
    $my_perms = get_channel_default_perms($uid);
    $role = get_pconfig($uid, 'system', 'permissions_role');
    if ($role) {
        $x = \Zotlabs\Access\PermissionRoles::role_perms($role);
        if ($x['perms_connect']) {
            $my_perms = $x['perms_connect'];
        }
    }
    if ($is_red && $j) {
        logger('follow: ' . $url . ' ' . print_r($j, true), LOGGER_DEBUG);
        if (!($j['success'] && $j['guid'])) {
            $result['message'] = t('Response from remote channel was incomplete.');
            logger('mod_follow: ' . $result['message']);
            return $result;
        }
        // Premium channel, set confirm before callback to avoid recursion
        if (array_key_exists('connect_url', $j) && $interactive && !$confirm) {
            goaway(zid($j['connect_url']));
        }
        // do we have an xchan and hubloc?
        // If not, create them.
        $x = import_xchan($j);
        if (array_key_exists('deleted', $j) && intval($j['deleted'])) {
            $result['message'] = t('Channel was deleted and no longer exists.');
            return $result;
        }
        if (!$x['success']) {
            return $x;
        }
        $xchan_hash = $x['hash'];
        if (array_key_exists('permissions', $j) && array_key_exists('data', $j['permissions'])) {
            $permissions = crypto_unencapsulate(array('data' => $j['permissions']['data'], 'key' => $j['permissions']['key'], 'iv' => $j['permissions']['iv']), $channel['channel_prvkey']);
            if ($permissions) {
                $permissions = json_decode($permissions, true);
            }
            logger('decrypted permissions: ' . print_r($permissions, true), LOGGER_DATA);
        } else {
            $permissions = $j['permissions'];
        }
        if (is_array($permissions) && $permissions) {
            foreach ($permissions as $k => $v) {
                set_abconfig($channel['channel_uid'], $xchan_hash, 'their_perms', $k, intval($v));
            }
        }
    } else {
        $xchan_hash = '';
        $r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' limit 1", dbesc($url), dbesc($url));
        if (!$r) {
            // attempt network auto-discovery
            $d = discover_by_webbie($url);
            if (!$d && $is_http) {
                // try RSS discovery
                if (get_config('system', 'feed_contacts')) {
                    $d = discover_by_url($url);
                } else {
                    $result['message'] = t('Protocol disabled.');
                    return $result;
                }
            }
            if ($d) {
                $r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' limit 1", dbesc($url), dbesc($url));
            }
        }
        // if discovery was a success we should have an xchan record in $r
        if ($r) {
            $xchan = $r[0];
            $xchan_hash = $r[0]['xchan_hash'];
            $their_perms = 0;
        }
    }
    if (!$xchan_hash) {
        $result['message'] = t('Channel discovery failed.');
        logger('follow: ' . $result['message']);
        return $result;
    }
    $allowed = $is_red || $r[0]['xchan_network'] === 'rss' ? 1 : 0;
    $x = array('channel_id' => $uid, 'follow_address' => $url, 'xchan' => $r[0], 'allowed' => $allowed, 'singleton' => 0);
    call_hooks('follow_allow', $x);
    if (!$x['allowed']) {
        $result['message'] = t('Protocol disabled.');
        return $result;
    }
    $singleton = intval($x['singleton']);
    $aid = $channel['channel_account_id'];
    $hash = get_observer_hash();
    $default_group = $channel['channel_default_group'];
    if ($xchan['xchan_network'] === 'rss') {
        // check service class feed limits
        $r = q("select count(*) as total from abook where abook_account = %d and abook_feed = 1 ", intval($aid));
        if ($r) {
            $total_feeds = $r[0]['total'];
        }
        if (!service_class_allows($uid, 'total_feeds', $total_feeds)) {
            $result['message'] = upgrade_message();
            return $result;
        }
    }
    if ($hash == $xchan_hash) {
        $result['message'] = t('Cannot connect to yourself.');
        return $result;
    }
    $r = q("select abook_xchan, abook_instance from abook where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($xchan_hash), intval($uid));
    if ($is_http) {
        // Always set these "remote" permissions for feeds since we cannot interact with them
        // to negotiate a suitable permission response
        set_abconfig($uid, $xchan_hash, 'their_perms', 'view_stream', 1);
        set_abconfig($uid, $xchan_hash, 'their_perms', 'republish', 1);
    }
    if ($r) {
        $abook_instance = $r[0]['abook_instance'];
        if ($singleton && strpos($abook_instance, z_root()) === false) {
            if ($abook_instance) {
                $abook_instance .= ',';
            }
            $abook_instance .= z_root();
        }
        $x = q("update abook set abook_instance = '%s' where abook_id = %d", dbesc($abook_instance), intval($r[0]['abook_id']));
    } else {
        $closeness = get_pconfig($uid, 'system', 'new_abook_closeness');
        if ($closeness === false) {
            $closeness = 80;
        }
        $r = q("insert into abook ( abook_account, abook_channel, abook_closeness, abook_xchan, abook_feed, abook_created, abook_updated, abook_instance )\n\t\t\tvalues( %d, %d, %d, '%s', %d, '%s', '%s', '%s' ) ", intval($aid), intval($uid), intval($closeness), dbesc($xchan_hash), intval($is_http ? 1 : 0), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($singleton ? z_root() : ''));
    }
    if (!$r) {
        logger('mod_follow: abook creation failed');
    }
    $all_perms = \Zotlabs\Access\Permissions::Perms();
    if ($all_perms) {
        foreach ($all_perms as $k => $v) {
            if (in_array($k, $my_perms)) {
                set_abconfig($uid, $xchan_hash, 'my_perms', $k, 1);
            } else {
                set_abconfig($uid, $xchan_hash, 'my_perms', $k, 0);
            }
        }
    }
    $r = q("select abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash \n\t\twhere abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($xchan_hash), intval($uid));
    if ($r) {
        $result['abook'] = $r[0];
        Zotlabs\Daemon\Master::Summon(array('Notifier', 'permission_create', $result['abook']['abook_id']));
    }
    $arr = array('channel_id' => $uid, 'channel' => $channel, 'abook' => $result['abook']);
    call_hooks('follow', $arr);
    /** If there is a default group for this channel, add this connection to it */
    if ($default_group) {
        require_once 'include/group.php';
        $g = group_rec_byhash($uid, $default_group);
        if ($g) {
            group_add_member($uid, '', $xchan_hash, $g['id']);
        }
    }
    $result['success'] = true;
    return $result;
}
Пример #28
0
function appnet_fetchcontact($a, $uid, $contact, $me, $create_user)
{
    if (function_exists("update_gcontact")) {
        update_gcontact(array("url" => $contact["canonical_url"], "generation" => 2, "network" => NETWORK_APPNET, "photo" => $contact["avatar_image"]["url"], "name" => $contact["name"], "nick" => $contact["username"], "about" => $contact["description"]["text"], "hide" => true, "addr" => $contact["username"] . "@app.net"));
    } else {
        // Old Code
        $r = q("SELECT id FROM unique_contacts WHERE url='%s' LIMIT 1", dbesc(normalise_link($contact["canonical_url"])));
        if (count($r) == 0) {
            q("INSERT INTO unique_contacts (url, name, nick, avatar) VALUES ('%s', '%s', '%s', '%s')", dbesc(normalise_link($contact["canonical_url"])), dbesc($contact["name"]), dbesc($contact["username"]), dbesc($contact["avatar_image"]["url"]));
        } else {
            q("UPDATE unique_contacts SET name = '%s', nick = '%s', avatar = '%s' WHERE url = '%s'", dbesc($contact["name"]), dbesc($contact["username"]), dbesc($contact["avatar_image"]["url"]), dbesc(normalise_link($contact["canonical_url"])));
        }
        if (DB_UPDATE_VERSION >= "1177") {
            q("UPDATE `unique_contacts` SET `location` = '%s', `about` = '%s' WHERE url = '%s'", dbesc(""), dbesc($contact["description"]["text"]), dbesc(normalise_link($contact["canonical_url"])));
        }
    }
    $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `alias` = '%s' LIMIT 1", intval($uid), dbesc("adn::" . $contact["id"]));
    if (!count($r) and !$create_user) {
        return $me["id"];
    }
    if ($contact["canonical_url"] == "") {
        return $me["id"];
    }
    if (count($r) and ($r[0]["readonly"] or $r[0]["blocked"])) {
        logger("appnet_fetchcontact: Contact '" . $r[0]["nick"] . "' is blocked or readonly.", LOGGER_DEBUG);
        return -1;
    }
    if (!count($r)) {
        if ($contact["name"] == "") {
            $contact["name"] = $contact["username"];
        }
        if ($contact["username"] == "") {
            $contact["username"] = $contact["name"];
        }
        // create contact record
        q("INSERT INTO `contact` (`uid`, `created`, `url`, `nurl`, `addr`, `alias`, `notify`, `poll`,\n\t\t\t\t\t`name`, `nick`, `photo`, `network`, `rel`, `priority`,\n\t\t\t\t\t`writable`, `blocked`, `readonly`, `pending` )\n\t\t\t\t\tVALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, 0, 0, 0 ) ", intval($uid), dbesc(datetime_convert()), dbesc($contact["canonical_url"]), dbesc(normalise_link($contact["canonical_url"])), dbesc($contact["username"] . "@app.net"), dbesc("adn::" . $contact["id"]), dbesc(''), dbesc("adn::" . $contact["id"]), dbesc($contact["name"]), dbesc($contact["username"]), dbesc($contact["avatar_image"]["url"]), dbesc(NETWORK_APPNET), intval(CONTACT_IS_FRIEND), intval(1), intval(1));
        $r = q("SELECT * FROM `contact` WHERE `alias` = '%s' AND `uid` = %d LIMIT 1", dbesc("adn::" . $contact["id"]), intval($uid));
        if (!count($r)) {
            return false;
        }
        $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']);
        }
        require_once "Photo.php";
        $photos = import_profile_photo($contact["avatar_image"]["url"], $uid, $contact_id);
        q("UPDATE `contact` SET `photo` = '%s',\n\t\t\t\t\t`thumb` = '%s',\n\t\t\t\t\t`micro` = '%s',\n\t\t\t\t\t`name-date` = '%s',\n\t\t\t\t\t`uri-date` = '%s',\n\t\t\t\t\t`avatar-date` = '%s'\n\t\t\t\tWHERE `id` = %d", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($contact_id));
        if (DB_UPDATE_VERSION >= "1177") {
            q("UPDATE `contact` SET `location` = '%s',\n\t\t\t\t\t\t`about` = '%s'\n\t\t\t\t\tWHERE `id` = %d", dbesc(""), dbesc($contact["description"]["text"]), intval($contact_id));
        }
    } else {
        // update profile photos once every two weeks as we have no notification of when they change.
        //$update_photo = (($r[0]['avatar-date'] < datetime_convert('','','now -2 days')) ? true : false);
        $update_photo = $r[0]['avatar-date'] < datetime_convert('', '', 'now -12 hours');
        // check that we have all the photos, this has been known to fail on occasion
        if (!$r[0]['photo'] || !$r[0]['thumb'] || !$r[0]['micro'] || $update_photo) {
            logger("appnet_fetchcontact: Updating contact " . $contact["username"], LOGGER_DEBUG);
            require_once "Photo.php";
            $photos = import_profile_photo($contact["avatar_image"]["url"], $uid, $r[0]['id']);
            q("UPDATE `contact` SET `photo` = '%s',\n\t\t\t\t\t\t`thumb` = '%s',\n\t\t\t\t\t\t`micro` = '%s',\n\t\t\t\t\t\t`name-date` = '%s',\n\t\t\t\t\t\t`uri-date` = '%s',\n\t\t\t\t\t\t`avatar-date` = '%s',\n\t\t\t\t\t\t`url` = '%s',\n\t\t\t\t\t\t`nurl` = '%s',\n\t\t\t\t\t\t`addr` = '%s',\n\t\t\t\t\t\t`name` = '%s',\n\t\t\t\t\t\t`nick` = '%s'\n\t\t\t\t\tWHERE `id` = %d", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($contact["canonical_url"]), dbesc(normalise_link($contact["canonical_url"])), dbesc($contact["username"] . "@app.net"), dbesc($contact["name"]), dbesc($contact["username"]), intval($r[0]['id']));
            if (DB_UPDATE_VERSION >= "1177") {
                q("UPDATE `contact` SET `location` = '%s',\n\t\t\t\t\t\t\t`about` = '%s'\n\t\t\t\t\t\tWHERE `id` = %d", dbesc(""), dbesc($contact["description"]["text"]), intval($r[0]['id']));
            }
        }
    }
    return $r[0]["id"];
}
Пример #29
0
function diaspora_request($importer, $xml)
{
    $a = get_app();
    $sender_handle = unxmlify($xml->sender_handle);
    $recipient_handle = unxmlify($xml->recipient_handle);
    if (!$sender_handle || !$recipient_handle) {
        return;
    }
    $contact = diaspora_get_contact_by_handle($importer['uid'], $sender_handle);
    if ($contact) {
        // perhaps we were already sharing with this person. Now they're sharing with us.
        // That makes us friends.
        if ($contact['rel'] == CONTACT_IS_FOLLOWER && !in_array($importer['page-flags'], array(PAGE_COMMUNITY, PAGE_SOAPBOX))) {
            q("UPDATE `contact` SET `rel` = %d, `writable` = 1 WHERE `id` = %d AND `uid` = %d", intval(CONTACT_IS_FRIEND), intval($contact['id']), intval($importer['uid']));
        }
        // send notification
        $r = q("SELECT `hide-friends` FROM `profile` WHERE `uid` = %d AND `is-default` = 1 LIMIT 1", intval($importer['uid']));
        if (count($r) && !$r[0]['hide-friends'] && !$contact['hidden'] && intval(get_pconfig($importer['uid'], 'system', 'post_newfriend'))) {
            require_once 'include/items.php';
            $self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1", intval($importer['uid']));
            // they are not CONTACT_IS_FOLLOWER anymore but that's what we have in the array
            if (count($self) && $contact['rel'] == CONTACT_IS_FOLLOWER) {
                $arr = array();
                $arr['uri'] = $arr['parent-uri'] = item_new_uri($a->get_hostname(), $importer['uid']);
                $arr['uid'] = $importer['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'];
                $arr['verb'] = ACTIVITY_FRIEND;
                $arr['object-type'] = ACTIVITY_OBJ_PERSON;
                $A = '[url=' . $self[0]['url'] . ']' . $self[0]['name'] . '[/url]';
                $B = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]';
                $BPhoto = '[url=' . $contact['url'] . ']' . '[img]' . $contact['thumb'] . '[/img][/url]';
                $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['last-child'] = 1;
                $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}");
                }
            }
        }
        return;
    }
    $ret = find_diaspora_person_by_handle($sender_handle);
    if (!count($ret) || $ret['network'] != NETWORK_DIASPORA) {
        logger('diaspora_request: Cannot resolve diaspora handle ' . $sender_handle . ' for ' . $recipient_handle);
        return;
    }
    $batch = $ret['batch'] ? $ret['batch'] : implode('/', array_slice(explode('/', $ret['url']), 0, 3)) . '/receive/public';
    $r = q("INSERT INTO `contact` (`uid`, `network`,`addr`,`created`,`url`,`nurl`,`batch`,`name`,`nick`,`photo`,`pubkey`,`notify`,`poll`,`blocked`,`priority`)\n\t\tVALUES ( %d, '%s', '%s', '%s', '%s','%s','%s','%s','%s','%s','%s','%s','%s',%d,%d) ", intval($importer['uid']), dbesc($ret['network']), dbesc($ret['addr']), datetime_convert(), dbesc($ret['url']), dbesc(normalise_link($ret['url'])), dbesc($batch), dbesc($ret['name']), dbesc($ret['nick']), dbesc($ret['photo']), dbesc($ret['pubkey']), dbesc($ret['notify']), dbesc($ret['poll']), 1, 2);
    // find the contact record we just created
    $contact_record = diaspora_get_contact_by_handle($importer['uid'], $sender_handle);
    if (!$contact_record) {
        logger('diaspora_request: unable to locate newly created contact record.');
        return;
    }
    $g = q("select def_gid from user where uid = %d limit 1", intval($importer['uid']));
    if ($g && intval($g[0]['def_gid'])) {
        require_once 'include/group.php';
        group_add_member($importer['uid'], '', $contact_record['id'], $g[0]['def_gid']);
    }
    if ($importer['page-flags'] == PAGE_NORMAL) {
        $hash = random_string() . (string) time();
        // Generate a confirm_key
        $ret = q("INSERT INTO `intro` ( `uid`, `contact-id`, `blocked`, `knowyou`, `note`, `hash`, `datetime` )\n\t\t\tVALUES ( %d, %d, %d, %d, '%s', '%s', '%s' )", intval($importer['uid']), intval($contact_record['id']), 0, 0, dbesc(t('Sharing notification from Diaspora network')), dbesc($hash), dbesc(datetime_convert()));
    } else {
        // automatic friend approval
        require_once 'include/Photo.php';
        $photos = import_profile_photo($contact_record['photo'], $importer['uid'], $contact_record['id']);
        // technically they are sharing with us (CONTACT_IS_SHARING),
        // but if our page-type is PAGE_COMMUNITY or PAGE_SOAPBOX
        // we are going to change the relationship and make them a follower.
        if ($importer['page-flags'] == PAGE_FREELOVE) {
            $new_relation = CONTACT_IS_FRIEND;
        } else {
            $new_relation = CONTACT_IS_FOLLOWER;
        }
        $r = q("UPDATE `contact` SET\n\t\t\t`photo` = '%s',\n\t\t\t`thumb` = '%s',\n\t\t\t`micro` = '%s',\n\t\t\t`rel` = %d,\n\t\t\t`name-date` = '%s',\n\t\t\t`uri-date` = '%s',\n\t\t\t`avatar-date` = '%s',\n\t\t\t`blocked` = 0,\n\t\t\t`pending` = 0,\n\t\t\t`writable` = 1\n\t\t\tWHERE `id` = %d\n\t\t\t", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), intval($new_relation), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($contact_record['id']));
        $u = q("select * from user where uid = %d limit 1", intval($importer['uid']));
        if ($u) {
            $ret = diaspora_share($u[0], $contact_record);
        }
    }
    return;
}
Пример #30
0
function pumpio_get_contact($uid, $contact, $no_insert = false)
{
    if (function_exists("update_gcontact")) {
        update_gcontact(array("url" => $contact->url, "network" => NETWORK_PUMPIO, "generation" => 2, "photo" => $contact->image->url, "name" => $contact->displayName, "hide" => true, "nick" => $contact->preferredUsername, "location" => $contact->location->displayName, "about" => $contact->summary, "addr" => str_replace("acct:", "", $contact->id)));
        $cid = get_contact($contact->url, $uid);
    } else {
        // Old Code
        $r = q("SELECT id FROM unique_contacts WHERE url='%s' LIMIT 1", dbesc(normalise_link($contact->url)));
        if (count($r) == 0) {
            q("INSERT INTO unique_contacts (url, name, nick, avatar) VALUES ('%s', '%s', '%s', '%s')", dbesc(normalise_link($contact->url)), dbesc($contact->displayName), dbesc($contact->preferredUsername), dbesc($contact->image->url));
        } else {
            q("UPDATE unique_contacts SET name = '%s', nick = '%s', avatar = '%s' WHERE url = '%s'", dbesc($contact->displayName), dbesc($contact->preferredUsername), dbesc($contact->image->url), dbesc(normalise_link($contact->url)));
        }
        if (DB_UPDATE_VERSION >= "1177") {
            q("UPDATE `unique_contacts` SET `location` = '%s', `about` = '%s' WHERE url = '%s'", dbesc($contact->location->displayName), dbesc($contact->summary), dbesc(normalise_link($contact->url)));
        }
        $cid = 0;
    }
    if ($no_insert) {
        return $cid;
    }
    $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' LIMIT 1", intval($uid), dbesc($contact->url));
    if (!count($r)) {
        // create contact record
        q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `addr`, `alias`, `notify`, `poll`,\n\t\t\t\t\t`name`, `nick`, `photo`, `network`, `rel`, `priority`,\n\t\t\t\t\t`writable`, `blocked`, `readonly`, `pending` )\n\t\t\t\tVALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, 0, 0, 0 ) ", intval($uid), dbesc(datetime_convert()), dbesc($contact->url), dbesc(normalise_link($contact->url)), dbesc(str_replace("acct:", "", $contact->id)), dbesc(''), dbesc($contact->id), dbesc('pump.io ' . $contact->id), dbesc($contact->displayName), dbesc($contact->preferredUsername), dbesc($contact->image->url), dbesc(NETWORK_PUMPIO), intval(CONTACT_IS_FRIEND), intval(1), intval(1));
        $r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1", dbesc($contact->url), intval($uid));
        if (!count($r)) {
            return false;
        }
        $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']);
        }
        if (DB_UPDATE_VERSION >= "1177") {
            q("UPDATE `contact` SET `location` = '%s',\n\t\t\t\t\t\t`about` = '%s'\n\t\t\t\t\tWHERE `id` = %d", dbesc($contact->location->displayName), dbesc($contact->summary), intval($contact_id));
        }
    } else {
        $contact_id = $r[0]["id"];
        /*	if (DB_UPDATE_VERSION >= "1177")
        				q("UPDATE `contact` SET `location` = '%s',
        							`about` = '%s'
        						WHERE `id` = %d",
        					dbesc($contact->location->displayName),
        					dbesc($contact->summary),
        					intval($r[0]['id'])
        				);
        		*/
    }
    if (function_exists("update_contact_avatar")) {
        update_contact_avatar($contact->image->url, $uid, $contact_id);
    }
    return $contact_id;
}