Example #1
0
function permissions_sql($owner_id, $remote_verified = false, $groups = null)
{
    $local_user = local_user();
    $remote_user = remote_user();
    /**
     * Construct permissions
     *
     * default permissions - anonymous user
     */
    $sql = " AND allow_cid = '' \n\t\t\t AND allow_gid = '' \n\t\t\t AND deny_cid  = '' \n\t\t\t AND deny_gid  = '' \n\t";
    /**
     * Profile owner - everything is visible
     */
    if ($local_user && $local_user == $owner_id) {
        $sql = '';
    } elseif ($remote_user) {
        if (!$remote_verified) {
            $r = q("SELECT id FROM contact WHERE id = %d AND uid = %d AND blocked = 0 LIMIT 1", intval($remote_user), intval($owner_id));
            if (count($r)) {
                $remote_verified = true;
                $groups = init_groups_visitor($remote_user);
            }
        }
        if ($remote_verified) {
            $gs = '<<>>';
            // should be impossible to match
            if (is_array($groups) && count($groups)) {
                foreach ($groups as $g) {
                    $gs .= '|<' . intval($g) . '>';
                }
            }
            $sql = sprintf(" AND ( allow_cid = '' OR allow_cid REGEXP '<%d>' ) \n\t\t\t\t  AND ( deny_cid  = '' OR  NOT deny_cid REGEXP '<%d>' ) \n\t\t\t\t  AND ( allow_gid = '' OR allow_gid REGEXP '%s' )\n\t\t\t\t  AND ( deny_gid  = '' OR NOT deny_gid REGEXP '%s') \n\t\t\t\t", intval($remote_user), intval($remote_user), dbesc($gs), dbesc($gs));
        }
    }
    return $sql;
}
Example #2
0
function photos_content(&$a)
{
    // URLs:
    // photos/name
    // photos/name/upload
    // photos/name/upload/xxxxx (xxxxx is album name)
    // photos/name/album/xxxxx
    // photos/name/album/xxxxx/edit
    // photos/name/image/xxxxx
    // photos/name/image/xxxxx/edit
    if (get_config('system', 'block_public') && !local_user() && !remote_user()) {
        notice(t('Public access denied.') . EOL);
        return;
    }
    require_once 'include/bbcode.php';
    require_once 'include/security.php';
    require_once 'include/conversation.php';
    if (!x($a->data, 'user')) {
        notice(t('No photos selected') . EOL);
        return;
    }
    $_SESSION['photo_return'] = $a->cmd;
    //
    // Parse arguments
    //
    if ($a->argc > 3) {
        $datatype = $a->argv[2];
        $datum = $a->argv[3];
    } elseif ($a->argc > 2 && $a->argv[2] === 'upload') {
        $datatype = 'upload';
    } else {
        $datatype = 'summary';
    }
    if ($a->argc > 4) {
        $cmd = $a->argv[4];
    } else {
        $cmd = 'view';
    }
    //
    // Setup permissions structures
    //
    $can_post = false;
    $visitor = 0;
    $contact = null;
    $remote_contact = false;
    $owner_uid = $a->data['user']['uid'];
    $community_page = $a->data['user']['page-flags'] == PAGE_COMMUNITY ? true : false;
    if (local_user() && local_user() == $owner_uid) {
        $can_post = true;
    } else {
        if ($community_page && remote_user()) {
            $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval(remote_user()), intval($owner_uid));
            if (count($r)) {
                $can_post = true;
                $contact = $r[0];
                $remote_contact = true;
                $visitor = remote_user();
            }
        }
    }
    // perhaps they're visiting - but not a community page, so they wouldn't have write access
    if (remote_user() && !$visitor) {
        $contact_id = $_SESSION['visitor_id'];
        $groups = init_groups_visitor($contact_id);
        $r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval(remote_user()), intval($owner_uid));
        if (count($r)) {
            $contact = $r[0];
            $remote_contact = true;
        }
    }
    if (!$remote_contact) {
        if (local_user()) {
            $contact_id = $_SESSION['cid'];
            $contact = $a->contact;
        }
    }
    if ($a->data['user']['hidewall'] && local_user() != $owner_uid && !$remote_contact) {
        notice(t('Access to this item is restricted.') . EOL);
        return;
    }
    $sql_extra = permissions_sql($owner_uid, $remote_contact, $groups);
    $o = "";
    // tabs
    $_is_owner = local_user() && local_user() == $owner_uid;
    $o .= profile_tabs($a, $_is_owner, $a->data['user']['nickname']);
    //
    // dispatch request
    //
    if ($datatype === 'upload') {
        if (!$can_post) {
            notice(t('Permission denied.'));
            return;
        }
        $selname = $datum ? hex2bin($datum) : '';
        $albumselect = '<select id="photos-upload-album-select" name="album" size="4">';
        $albumselect .= '<option value="" ' . (!$selname ? ' selected="selected" ' : '') . '>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option>';
        if (count($a->data['albums'])) {
            foreach ($a->data['albums'] as $album) {
                if ($album['album'] === '' || $album['album'] === 'Contact Photos' || $album['album'] === t('Contact Photos')) {
                    continue;
                }
                $selected = $selname === $album['album'] ? ' selected="selected" ' : '';
                $albumselect .= '<option value="' . $album['album'] . '"' . $selected . '>' . $album['album'] . '</option>';
            }
        }
        $celeb = $a->user['page-flags'] == PAGE_SOAPBOX || $a->user['page-flags'] == PAGE_COMMUNITY ? true : false;
        $albumselect .= '</select>';
        $uploader = '';
        $ret = array('post_url' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'], 'addon_text' => $uploader, 'default_upload' => true);
        call_hooks('photo_upload_form', $ret);
        $default_upload = '<input type="file" name="userfile" /> 	<div class="photos-upload-submit-wrapper" >
		<input type="submit" name="submit" value="' . t('Submit') . '" id="photos-upload-submit" /> </div>';
        $tpl = get_markup_template('photos_upload.tpl');
        $o .= replace_macros($tpl, array('$pagename' => t('Upload Photos'), '$sessid' => session_id(), '$nickname' => $a->data['user']['nickname'], '$newalbum' => t('New album name: '), '$existalbumtext' => t('or existing album name: '), '$nosharetext' => t('Do not show a status post for this upload'), '$albumselect' => template_escape($albumselect), '$permissions' => t('Permissions'), '$aclselect' => $visitor ? '' : template_escape(populate_acl($a->user, $celeb)), '$uploader' => $ret['addon_text'], '$default' => $ret['default_upload'] ? $default_upload : '', '$uploadurl' => $ret['post_url']));
        return $o;
    }
    if ($datatype === 'album') {
        $album = hex2bin($datum);
        $r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` = '%s' \n\t\t\tAND `scale` <= 4 {$sql_extra} GROUP BY `resource-id`", intval($owner_uid), dbesc($album));
        if (count($r)) {
            $a->set_pager_total(count($r));
            $a->set_pager_itemspage(20);
        }
        $r = q("SELECT `resource-id`, `id`, `filename`, max(`scale`) AS `scale`, `desc` FROM `photo` WHERE `uid` = %d AND `album` = '%s' \n\t\t\tAND `scale` <= 4 {$sql_extra} GROUP BY `resource-id` ORDER BY `created` DESC LIMIT %d , %d", intval($owner_uid), dbesc($album), intval($a->pager['start']), intval($a->pager['itemspage']));
        $o .= '<h3>' . $album . '</h3>';
        if ($cmd === 'edit') {
            if ($album !== t('Profile Photos') && $album !== 'Contact Photos' && $album !== t('Contact Photos')) {
                if ($can_post) {
                    $edit_tpl = get_markup_template('album_edit.tpl');
                    $o .= replace_macros($edit_tpl, array('$nametext' => t('New album name: '), '$nickname' => $a->data['user']['nickname'], '$album' => template_escape($album), '$hexalbum' => bin2hex($album), '$submit' => t('Submit'), '$dropsubmit' => t('Delete Album')));
                }
            }
        } else {
            if ($album !== t('Profile Photos') && $album !== 'Contact Photos' && $album !== t('Contact Photos')) {
                if ($can_post) {
                    $o .= '<div id="album-edit-link"><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album) . '/edit' . '">' . t('Edit Album') . '</a></div>';
                }
            }
        }
        if ($can_post) {
            $o .= '<div class="photos-upload-link" ><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/upload/' . bin2hex($album) . '" >' . t('Upload New Photos') . '</a></div>';
        }
        $tpl = get_markup_template('photo_album.tpl');
        if (count($r)) {
            $twist = 'rotright';
        }
        foreach ($r as $rr) {
            if ($twist == 'rotright') {
                $twist = 'rotleft';
            } else {
                $twist = 'rotright';
            }
            $o .= replace_macros($tpl, array('$id' => $rr['id'], '$twist' => ' ' . $twist . rand(2, 4), '$photolink' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id'], '$phototitle' => t('View Photo'), '$imgsrc' => $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . $rr['scale'] . '.jpg', '$imgalt' => template_escape($rr['filename']), '$desc' => template_escape($rr['desc'])));
        }
        $o .= '<div id="photo-album-end"></div>';
        $o .= paginate($a);
        return $o;
    }
    if ($datatype === 'image') {
        //$o = '';
        // fetch image, item containing image, then comments
        $ph = q("SELECT * FROM `photo` WHERE `uid` = %d AND `resource-id` = '%s' \n\t\t\t{$sql_extra} ORDER BY `scale` ASC ", intval($owner_uid), dbesc($datum));
        if (!count($ph)) {
            $ph = q("SELECT `id` FROM `photo` WHERE `uid` = %d AND `resource-id` = '%s' \n\t\t\t\tLIMIT 1", intval($owner_uid), dbesc($datum));
            if (count($ph)) {
                notice(t('Permission denied. Access to this item may be restricted.'));
            } else {
                notice(t('Photo not available') . EOL);
            }
            return;
        }
        $prevlink = '';
        $nextlink = '';
        $prvnxt = q("SELECT `resource-id` FROM `photo` WHERE `album` = '%s' AND `uid` = %d AND `scale` = 0 \n\t\t\t{$sql_extra} ORDER BY `created` DESC ", dbesc($ph[0]['album']), intval($owner_uid));
        if (count($prvnxt)) {
            for ($z = 0; $z < count($prvnxt); $z++) {
                if ($prvnxt[$z]['resource-id'] == $ph[0]['resource-id']) {
                    $prv = $z - 1;
                    $nxt = $z + 1;
                    if ($prv < 0) {
                        $prv = count($prvnxt) - 1;
                    }
                    if ($nxt >= count($prvnxt)) {
                        $nxt = 0;
                    }
                    break;
                }
            }
            $edit_suffix = $cmd === 'edit' && $can_post ? '/edit' : '';
            $prevlink = $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $prvnxt[$prv]['resource-id'] . $edit_suffix;
            $nextlink = $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $prvnxt[$nxt]['resource-id'] . $edit_suffix;
        }
        if (count($ph) == 1) {
            $hires = $lores = $ph[0];
        }
        if (count($ph) > 1) {
            if ($ph[1]['scale'] == 2) {
                // original is 640 or less, we can display it directly
                $hires = $lores = $ph[0];
            } else {
                $hires = $ph[0];
                $lores = $ph[1];
            }
        }
        $album_link = $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($ph[0]['album']);
        $tools = Null;
        $lock = Null;
        if ($can_post && $ph[0]['uid'] == $owner_uid) {
            $tools = array('edit' => array($a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $datum . ($cmd === 'edit' ? '' : '/edit'), $cmd === 'edit' ? t('View photo') : t('Edit photo')), 'profile' => array($a->get_baseurl() . '/profile_photo/use/' . $ph[0]['resource-id'], t('Use as profile photo')));
            // lock
            $lock = $ph[0]['uid'] == local_user() && (strlen($ph[0]['allow_cid']) || strlen($ph[0]['allow_gid']) || strlen($ph[0]['deny_cid']) || strlen($ph[0]['deny_gid'])) ? t('Private Message') : Null;
        }
        if (!$cmd !== 'edit') {
            $a->page['htmlhead'] .= '<script>
				$(document).keydown(function(event) {' . "\n";
            if ($prevlink) {
                $a->page['htmlhead'] .= 'if(event.ctrlKey && event.keyCode == 37) { event.preventDefault(); window.location.href = \'' . $prevlink . '\'; }' . "\n";
            }
            if ($nextlink) {
                $a->page['htmlhead'] .= 'if(event.ctrlKey && event.keyCode == 39) { event.preventDefault(); window.location.href = \'' . $nextlink . '\'; }' . "\n";
            }
            $a->page['htmlhead'] .= '});</script>';
        }
        if ($prevlink) {
            $prevlink = array($prevlink, '<div class="icon prev"></div>');
        }
        $photo = array('href' => $a->get_baseurl() . '/photo/' . $hires['resource-id'] . '-' . $hires['scale'] . '.jpg', 'title' => t('View Full Size'), 'src' => $a->get_baseurl() . '/photo/' . $lores['resource-id'] . '-' . $lores['scale'] . '.jpg' . '?f=&_u=' . datetime_convert('', '', '', 'ymdhis'));
        if ($nextlink) {
            $nextlink = array($nextlink, '<div class="icon next"></div>');
        }
        // Do we have an item for this photo?
        $linked_items = q("SELECT * FROM `item` WHERE `resource-id` = '%s' {$sql_extra} LIMIT 1", dbesc($datum));
        if (count($linked_items)) {
            $link_item = $linked_items[0];
            $r = q("SELECT COUNT(*) AS `total`\n\t\t\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\t\tWHERE `parent-uri` = '%s' AND `uri` != '%s' AND `item`.`deleted` = 0 and `item`.`moderated` = 0\n\t\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\t\tAND `item`.`uid` = %d \n\t\t\t\t{$sql_extra} ", dbesc($link_item['uri']), dbesc($link_item['uri']), intval($link_item['uid']));
            if (count($r)) {
                $a->set_pager_total($r[0]['total']);
            }
            $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, \n\t\t\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`network`, \n\t\t\t\t`contact`.`rel`, `contact`.`thumb`, `contact`.`self`, \n\t\t\t\t`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`\n\t\t\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\t\tWHERE `parent-uri` = '%s' AND `uri` != '%s' AND `item`.`deleted` = 0 and `item`.`moderated` = 0\n\t\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\t\tAND `item`.`uid` = %d\n\t\t\t\t{$sql_extra}\n\t\t\t\tORDER BY `parent` DESC, `id` ASC LIMIT %d ,%d ", dbesc($link_item['uri']), dbesc($link_item['uri']), intval($link_item['uid']), intval($a->pager['start']), intval($a->pager['itemspage']));
            if (local_user() && local_user() == $link_item['uid']) {
                q("UPDATE `item` SET `unseen` = 0 WHERE `parent` = %d and `uid` = %d", intval($link_item['parent']), intval(local_user()));
            }
        }
        $tags = Null;
        if (count($linked_items) && strlen($link_item['tag'])) {
            $arr = explode(',', $link_item['tag']);
            // parse tags and add links
            $tag_str = '';
            foreach ($arr as $t) {
                if (strlen($tag_str)) {
                    $tag_str .= ', ';
                }
                $tag_str .= bbcode($t);
            }
            $tags = array(t('Tags: '), $tag_str);
            if ($cmd === 'edit') {
                $tags[] = $a->get_baseurl() . '/tagrm/' . $link_item['id'];
                $tags[] = t('[Remove any tag]');
            }
        }
        $edit = Null;
        if ($cmd === 'edit' && $can_post) {
            $edit_tpl = get_markup_template('photo_edit.tpl');
            $edit = replace_macros($edit_tpl, array('$id' => $ph[0]['id'], '$rotate' => t('Rotate CW'), '$album' => template_escape($ph[0]['album']), '$newalbum' => t('New album name'), '$nickname' => $a->data['user']['nickname'], '$resource_id' => $ph[0]['resource-id'], '$capt_label' => t('Caption'), '$caption' => template_escape($ph[0]['desc']), '$tag_label' => t('Add a Tag'), '$tags' => $link_item['tag'], '$permissions' => t('Permissions'), '$aclselect' => template_escape(populate_acl($ph[0])), '$help_tags' => t('Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping'), '$item_id' => count($linked_items) ? $link_item['id'] : 0, '$submit' => t('Submit'), '$delete' => t('Delete Photo')));
        }
        if (count($linked_items)) {
            $cmnt_tpl = get_markup_template('comment_item.tpl');
            $tpl = get_markup_template('photo_item.tpl');
            $return_url = $a->cmd;
            $like_tpl = get_markup_template('like_noshare.tpl');
            $likebuttons = '';
            if ($can_post || can_write_wall($a, $owner_uid)) {
                $likebuttons = replace_macros($like_tpl, array('$id' => $link_item['id'], '$likethis' => t("I like this (toggle)"), '$nolike' => t("I don't like this (toggle)"), '$share' => t('Share'), '$wait' => t('Please wait')));
            }
            $comments = '';
            if (!count($r)) {
                if ($can_post || can_write_wall($a, $owner_uid)) {
                    if ($link_item['last-child']) {
                        $comments .= replace_macros($cmnt_tpl, array('$return_path' => '', '$jsreload' => $return_url, '$type' => 'wall-comment', '$id' => $link_item['id'], '$parent' => $link_item['id'], '$profile_uid' => $owner_uid, '$mylink' => $contact['url'], '$mytitle' => t('This is you'), '$myphoto' => $contact['thumb'], '$comment' => t('Comment'), '$submit' => t('Submit'), '$preview' => t('Preview'), '$ww' => ''));
                    }
                }
            }
            $alike = array();
            $dlike = array();
            $like = '';
            $dislike = '';
            // display comments
            if (count($r)) {
                foreach ($r as $item) {
                    like_puller($a, $item, $alike, 'like');
                    like_puller($a, $item, $dlike, 'dislike');
                }
                $like = isset($alike[$link_item['id']]) ? format_like($alike[$link_item['id']], $alike[$link_item['id'] . '-l'], 'like', $link_item['id']) : '';
                $dislike = isset($dlike[$link_item['id']]) ? format_like($dlike[$link_item['id']], $dlike[$link_item['id'] . '-l'], 'dislike', $link_item['id']) : '';
                if ($can_post || can_write_wall($a, $owner_uid)) {
                    if ($link_item['last-child']) {
                        $comments .= replace_macros($cmnt_tpl, array('$return_path' => '', '$jsreload' => $return_url, '$type' => 'wall-comment', '$id' => $link_item['id'], '$parent' => $link_item['id'], '$profile_uid' => $owner_uid, '$mylink' => $contact['url'], '$mytitle' => t('This is you'), '$myphoto' => $contact['thumb'], '$comment' => t('Comment'), '$submit' => t('Submit'), '$ww' => ''));
                    }
                }
                foreach ($r as $item) {
                    $comment = '';
                    $template = $tpl;
                    $sparkle = '';
                    if ((activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE)) && $item['id'] != $item['parent']) {
                        continue;
                    }
                    $redirect_url = $a->get_baseurl() . '/redir/' . $item['cid'];
                    if ($can_post || can_write_wall($a, $owner_uid)) {
                        if ($item['last-child']) {
                            $comments .= replace_macros($cmnt_tpl, array('$return_path' => '', '$jsreload' => $return_url, '$type' => 'wall-comment', '$id' => $item['item_id'], '$parent' => $item['parent'], '$profile_uid' => $owner_uid, '$mylink' => $contact['url'], '$mytitle' => t('This is you'), '$myphoto' => $contact['thumb'], '$comment' => t('Comment'), '$submit' => t('Submit'), '$ww' => ''));
                        }
                    }
                    if (local_user() && $item['contact-uid'] == local_user() && $item['network'] == 'dfrn' && !$item['self']) {
                        $profile_url = $redirect_url;
                        $sparkle = ' sparkle';
                    } else {
                        $profile_url = $item['url'];
                        $sparkle = '';
                    }
                    $diff_author = $item['url'] !== $item['author-link'] ? true : false;
                    $profile_name = strlen($item['author-name']) && $diff_author ? $item['author-name'] : $item['name'];
                    $profile_avatar = strlen($item['author-avatar']) && $diff_author ? $item['author-avatar'] : $item['thumb'];
                    $profile_link = $profile_url;
                    $drop = '';
                    if ($item['contact-id'] == remote_user() || $item['uid'] == local_user()) {
                        $drop = replace_macros(get_markup_template('photo_drop.tpl'), array('$id' => $item['id'], '$delete' => t('Delete')));
                    }
                    $comments .= replace_macros($template, array('$id' => $item['item_id'], '$profile_url' => $profile_link, '$name' => template_escape($profile_name), '$thumb' => $profile_avatar, '$sparkle' => $sparkle, '$title' => template_escape($item['title']), '$body' => template_escape(bbcode($item['body'])), '$ago' => relative_date($item['created']), '$indent' => $item['parent'] != $item['item_id'] ? ' comment' : '', '$drop' => $drop, '$comment' => $comment));
                }
            }
            $paginate = paginate($a);
        }
        $photo_tpl = get_markup_template('photo_view.tpl');
        $o .= replace_macros($photo_tpl, array('$id' => $ph[0]['id'], '$album' => array($album_link, template_escape($ph[0]['album'])), '$tools' => $tools, '$lock' => $lock, '$photo' => $photo, '$prevlink' => $prevlink, '$nextlink' => $nextlink, '$desc' => $ph[0]['desc'], '$tags' => template_escape($tags), '$edit' => $edit, '$likebuttons' => $likebuttons, '$like' => template_escape($like), '$dislike' => template_escape($dislike), '$comments' => $comments, '$paginate' => $paginate));
        return $o;
    }
    // Default - show recent photos with upload link (if applicable)
    //$o = '';
    $r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' \n\t\t{$sql_extra} GROUP BY `resource-id`", intval($a->data['user']['uid']), dbesc('Contact Photos'), dbesc(t('Contact Photos')));
    if (count($r)) {
        $a->set_pager_total(count($r));
        $a->set_pager_itemspage(20);
    }
    $r = q("SELECT `resource-id`, `id`, `filename`, `album`, max(`scale`) AS `scale` FROM `photo`\n\t\tWHERE `uid` = %d AND `album` != '%s' AND `album` != '%s'  \n\t\t{$sql_extra} GROUP BY `resource-id` ORDER BY `created` DESC LIMIT %d , %d", intval($a->data['user']['uid']), dbesc('Contact Photos'), dbesc(t('Contact Photos')), intval($a->pager['start']), intval($a->pager['itemspage']));
    $photos = array();
    if (count($r)) {
        $twist = 'rotright';
        foreach ($r as $rr) {
            if ($twist == 'rotright') {
                $twist = 'rotleft';
            } else {
                $twist = 'rotright';
            }
            $photos[] = array('id' => $rr['id'], 'twist' => ' ' . $twist . rand(2, 4), 'link' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id'], 'title' => t('View Photo'), 'src' => $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . ($rr['scale'] == 6 ? 4 : $rr['scale']) . '.jpg', 'alt' => template_escape($rr['filename']), 'album' => array('link' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($rr['album']), 'name' => template_escape($rr['album']), 'alt' => t('View Album')));
        }
    }
    $tpl = get_markup_template('photos_recent.tpl');
    $o .= replace_macros($tpl, array('$title' => t('Recent Photos'), '$can_post' => $can_post, '$upload' => array(t('Upload New Photos'), $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/upload'), '$photos' => $photos));
    $o .= paginate($a);
    return $o;
}
Example #3
0
function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0, $forpubsub = false)
{
    $sitefeed = strlen($owner_nick) ? false : true;
    // not yet implemented, need to rewrite huge chunks of following logic
    $public_feed = $dfrn_id ? false : true;
    $starred = false;
    // not yet implemented, possible security issues
    $converse = false;
    if ($public_feed && $a->argc > 2) {
        for ($x = 2; $x < $a->argc; $x++) {
            if ($a->argv[$x] == 'converse') {
                $converse = true;
            }
            if ($a->argv[$x] == 'starred') {
                $starred = true;
            }
            if ($a->argv[$x] === 'category' && $a->argc > $x + 1 && strlen($a->argv[$x + 1])) {
                $category = $a->argv[$x + 1];
            }
        }
    }
    // default permissions - anonymous user
    $sql_extra = " AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid`  = '' AND `item`.`deny_gid`  = '' ";
    $r = q("SELECT `contact`.*, `user`.`uid` AS `user_uid`, `user`.`nickname`, `user`.`timezone`, `user`.`page-flags`\n\t\tFROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`\n\t\tWHERE `contact`.`self` = 1 AND `user`.`nickname` = '%s' LIMIT 1", dbesc($owner_nick));
    if (!count($r)) {
        killme();
    }
    $owner = $r[0];
    $owner_id = $owner['user_uid'];
    $owner_nick = $owner['nickname'];
    $birthday = feed_birthday($owner_id, $owner['timezone']);
    $sql_post_table = "";
    $visibility = "";
    if (!$public_feed) {
        $sql_extra = '';
        switch ($direction) {
            case -1:
                $sql_extra = sprintf(" AND `issued-id` = '%s' ", dbesc($dfrn_id));
                $my_id = $dfrn_id;
                break;
            case 0:
                $sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
                $my_id = '1:' . $dfrn_id;
                break;
            case 1:
                $sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
                $my_id = '0:' . $dfrn_id;
                break;
            default:
                return false;
                break;
                // NOTREACHED
        }
        $r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `contact`.`uid` = %d {$sql_extra} LIMIT 1", intval($owner_id));
        if (!count($r)) {
            killme();
        }
        $contact = $r[0];
        require_once 'include/security.php';
        $groups = init_groups_visitor($contact['id']);
        if (count($groups)) {
            for ($x = 0; $x < count($groups); $x++) {
                $groups[$x] = '<' . intval($groups[$x]) . '>';
            }
            $gs = implode('|', $groups);
        } else {
            $gs = '<<>>';
        }
        // Impossible to match
        $sql_extra = sprintf("\n\t\t\tAND ( `allow_cid` = '' OR     `allow_cid` REGEXP '<%d>' )\n\t\t\tAND ( `deny_cid`  = '' OR NOT `deny_cid`  REGEXP '<%d>' )\n\t\t\tAND ( `allow_gid` = '' OR     `allow_gid` REGEXP '%s' )\n\t\t\tAND ( `deny_gid`  = '' OR NOT `deny_gid`  REGEXP '%s')\n\t\t", intval($contact['id']), intval($contact['id']), dbesc($gs), dbesc($gs));
    }
    if ($public_feed) {
        $sort = 'DESC';
    } else {
        $sort = 'ASC';
    }
    // Include answers to status.net posts in pubsub feeds
    if ($forpubsub) {
        $sql_post_table = "INNER JOIN `thread` ON `thread`.`iid` = `item`.`parent`\n\t\t\t\tLEFT JOIN `item` AS `thritem` ON `thritem`.`uri`=`item`.`thr-parent` AND `thritem`.`uid`=`item`.`uid`";
        $visibility = sprintf("AND (`item`.`parent` = `item`.`id`) OR (`item`.`network` = '%s' AND ((`thread`.`network`='%s') OR (`thritem`.`network` = '%s')))", dbesc(NETWORK_DFRN), dbesc(NETWORK_OSTATUS), dbesc(NETWORK_OSTATUS));
        $date_field = "`received`";
        $sql_order = "`item`.`received` DESC";
    } else {
        $date_field = "`changed`";
        $sql_order = "`item`.`parent` " . $sort . ", `item`.`created` ASC";
    }
    if (!strlen($last_update)) {
        $last_update = 'now -30 days';
    }
    if (isset($category)) {
        $sql_post_table = sprintf("INNER JOIN (SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d ORDER BY `tid` DESC) AS `term` ON `item`.`id` = `term`.`oid` ", dbesc(protect_sprintf($category)), intval(TERM_OBJ_POST), intval(TERM_CATEGORY), intval($owner_id));
        //$sql_extra .= file_tag_file_query('item',$category,'category');
    }
    if ($public_feed) {
        if (!$converse) {
            $sql_extra .= " AND `contact`.`self` = 1 ";
        }
    }
    $check_date = datetime_convert('UTC', 'UTC', $last_update, 'Y-m-d H:i:s');
    //	AND ( `item`.`edited` > '%s' OR `item`.`changed` > '%s' )
    //	dbesc($check_date),
    $r = q("SELECT STRAIGHT_JOIN `item`.*, `item`.`id` AS `item_id`,\n\t\t`contact`.`name`, `contact`.`network`, `contact`.`photo`, `contact`.`url`,\n\t\t`contact`.`name-date`, `contact`.`uri-date`, `contact`.`avatar-date`,\n\t\t`contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,\n\t\t`contact`.`id` AS `contact-id`, `contact`.`uid` AS `contact-uid`,\n\t\t`sign`.`signed_text`, `sign`.`signature`, `sign`.`signer`\n\t\tFROM `item` {$sql_post_table}\n\t\tINNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\tLEFT JOIN `sign` ON `sign`.`iid` = `item`.`id`\n\t\tWHERE `item`.`uid` = %d AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`parent` != 0\n\t\tAND ((`item`.`wall` = 1) {$visibility}) AND `item`.{$date_field} > '%s'\n\t\t{$sql_extra}\n\t\tORDER BY {$sql_order} LIMIT 0, 300", intval($owner_id), dbesc($check_date), dbesc($sort));
    // Will check further below if this actually returned results.
    // We will provide an empty feed if that is the case.
    $items = $r;
    $feed_template = get_markup_template($dfrn_id ? 'atom_feed_dfrn.tpl' : 'atom_feed.tpl');
    $atom = '';
    $hubxml = feed_hublinks();
    $salmon = feed_salmonlinks($owner_nick);
    $alternatelink = $owner['url'];
    if (isset($category)) {
        $alternatelink .= "/category/" . $category;
    }
    $atom .= replace_macros($feed_template, array('$version' => xmlify(FRIENDICA_VERSION), '$feed_id' => xmlify($a->get_baseurl() . '/profile/' . $owner_nick), '$feed_title' => xmlify($owner['name']), '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)), '$hub' => $hubxml, '$salmon' => $salmon, '$alternatelink' => xmlify($alternatelink), '$name' => xmlify($owner['name']), '$profile_page' => xmlify($owner['url']), '$photo' => xmlify($owner['photo']), '$thumb' => xmlify($owner['thumb']), '$picdate' => xmlify(datetime_convert('UTC', 'UTC', $owner['avatar-date'] . '+00:00', ATOM_TIME)), '$uridate' => xmlify(datetime_convert('UTC', 'UTC', $owner['uri-date'] . '+00:00', ATOM_TIME)), '$namdate' => xmlify(datetime_convert('UTC', 'UTC', $owner['name-date'] . '+00:00', ATOM_TIME)), '$birthday' => strlen($birthday) ? '<dfrn:birthday>' . xmlify($birthday) . '</dfrn:birthday>' : '', '$community' => $owner['page-flags'] == PAGE_COMMUNITY ? '<dfrn:community>1</dfrn:community>' : ''));
    call_hooks('atom_feed', $atom);
    if (!count($items)) {
        call_hooks('atom_feed_end', $atom);
        $atom .= '</feed>' . "\r\n";
        return $atom;
    }
    foreach ($items as $item) {
        // prevent private email from leaking.
        if ($item['network'] === NETWORK_MAIL) {
            continue;
        }
        // public feeds get html, our own nodes use bbcode
        if ($public_feed) {
            $type = 'html';
            // catch any email that's in a public conversation and make sure it doesn't leak
            if ($item['private']) {
                continue;
            }
        } else {
            $type = 'text';
        }
        $atom .= atom_entry($item, $type, null, $owner, true);
    }
    call_hooks('atom_feed_end', $atom);
    $atom .= '</feed>' . "\r\n";
    return $atom;
}
Example #4
0
function display_content(&$a, $update = 0)
{
    if (get_config('system', 'block_public') && !local_user() && !remote_user()) {
        notice(t('Public access denied.') . EOL);
        return;
    }
    require_once "include/bbcode.php";
    require_once 'include/security.php';
    require_once 'include/conversation.php';
    require_once 'include/acl_selectors.php';
    $o = '';
    $a->page['htmlhead'] .= replace_macros(get_markup_template('display-head.tpl'), array());
    if ($update) {
        $nick = $_REQUEST['nick'];
    } else {
        $nick = $a->argc > 1 ? $a->argv[1] : '';
    }
    if ($update) {
        $item_id = $_REQUEST['item_id'];
        $a->profile = array('uid' => intval($update), 'profile_uid' => intval($update));
    } else {
        $item_id = $a->argc > 2 ? $a->argv[2] : 0;
        if ($a->argc == 2) {
            $nick = "";
            if (local_user()) {
                $r = q("SELECT `id` FROM `item`\n\t\t\t\t\tWHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0\n\t\t\t\t\t\tAND `guid` = '%s' AND `uid` = %d", $a->argv[1], local_user());
                if (count($r)) {
                    $item_id = $r[0]["id"];
                    $nick = $a->user["nickname"];
                }
            }
            if ($nick == "") {
                $r = q("SELECT `user`.`nickname`, `item`.`id` FROM `item` INNER JOIN `user` ON `user`.`uid` = `item`.`uid`\n\t\t\t\t\tWHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0\n\t\t\t\t\t\tAND `item`.`allow_cid` = ''  AND `item`.`allow_gid` = ''\n\t\t\t\t\t\tAND `item`.`deny_cid`  = '' AND `item`.`deny_gid`  = ''\n\t\t\t\t\t\tAND `item`.`private` = 0  AND NOT `user`.`hidewall`\n\t\t\t\t\t\tAND `item`.`guid` = '%s'", $a->argv[1]);
                //	AND `item`.`private` = 0 AND `item`.`wall` = 1
                if (count($r)) {
                    $item_id = $r[0]["id"];
                    $nick = $r[0]["nickname"];
                }
            }
            if ($nick == "") {
                $r = q("SELECT `item`.`id` FROM `item`\n\t\t\t\t\tWHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0\n\t\t\t\t\t\tAND `item`.`allow_cid` = ''  AND `item`.`allow_gid` = ''\n\t\t\t\t\t\tAND `item`.`deny_cid`  = '' AND `item`.`deny_gid`  = ''\n\t\t\t\t\t\tAND `item`.`private` = 0  AND `item`.`uid` = 0\n\t\t\t\t\t\tAND `item`.`guid` = '%s'", $a->argv[1]);
                //	AND `item`.`private` = 0 AND `item`.`wall` = 1
                if (count($r)) {
                    $item_id = $r[0]["id"];
                }
            }
        }
    }
    if (!$item_id) {
        $a->error = 404;
        notice(t('Item not found.') . EOL);
        return;
    }
    $groups = array();
    $contact = null;
    $remote_contact = false;
    $contact_id = 0;
    if (is_array($_SESSION['remote'])) {
        foreach ($_SESSION['remote'] as $v) {
            if ($v['uid'] == $a->profile['uid']) {
                $contact_id = $v['cid'];
                break;
            }
        }
    }
    if ($contact_id) {
        $groups = init_groups_visitor($contact_id);
        $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($contact_id), intval($a->profile['uid']));
        if (count($r)) {
            $contact = $r[0];
            $remote_contact = true;
        }
    }
    if (!$remote_contact) {
        if (local_user()) {
            $contact_id = $_SESSION['cid'];
            $contact = $a->contact;
        }
    }
    $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1", intval($a->profile['uid']));
    if (count($r)) {
        $a->page_contact = $r[0];
    }
    $is_owner = local_user() && local_user() == $a->profile['profile_uid'] ? true : false;
    if ($a->profile['hidewall'] && !$is_owner && !$remote_contact) {
        notice(t('Access to this profile has been restricted.') . EOL);
        return;
    }
    if ($is_owner) {
        $celeb = $a->user['page-flags'] == PAGE_SOAPBOX || $a->user['page-flags'] == PAGE_COMMUNITY ? true : false;
        $x = array('is_owner' => true, 'allow_location' => $a->user['allow_location'], 'default_location' => $a->user['default-location'], 'nickname' => $a->user['nickname'], 'lockstate' => is_array($a->user) && (strlen($a->user['allow_cid']) || strlen($a->user['allow_gid']) || strlen($a->user['deny_cid']) || strlen($a->user['deny_gid'])) ? 'lock' : 'unlock', 'acl' => populate_acl($a->user, $celeb), 'bang' => '', 'visitor' => 'block', 'profile_uid' => local_user(), 'acl_data' => construct_acl_data($a, $a->user));
        $o .= status_editor($a, $x, 0, true);
    }
    $sql_extra = item_permissions_sql($a->profile['uid'], $remote_contact, $groups);
    //	        AND `item`.`parent` = ( SELECT `parent` FROM `item` FORCE INDEX (PRIMARY, `uri`) WHERE ( `id` = '%s' OR `uri` = '%s' ))
    if ($update) {
        $r = q("SELECT id FROM item WHERE item.uid = %d\n\t\t        AND `item`.`parent` = (SELECT `parent` FROM `item` WHERE (`id` = '%s' OR `uri` = '%s'))\n\t\t        {$sql_extra} AND unseen = 1", intval($a->profile['uid']), dbesc($item_id), dbesc($item_id));
        if (!$r) {
            return '';
        }
    }
    //	AND `item`.`parent` = ( SELECT `parent` FROM `item` FORCE INDEX (PRIMARY, `uri`) WHERE ( `id` = '%s' OR `uri` = '%s' )
    $r = q("SELECT `item`.*, `item`.`id` AS `item_id`,  `item`.`network` AS `item_network`,\n\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,\n\t\t`contact`.`network`, `contact`.`thumb`, `contact`.`self`, `contact`.`writable`,\n\t\t`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`\n\t\tFROM `item` INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\tWHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0\n\t\tand `item`.`moderated` = 0\n\t\tAND `item`.`parent` = (SELECT `parent` FROM `item` WHERE (`id` = '%s' OR `uri` = '%s')\n\t\tAND uid = %d)\n\t\t{$sql_extra}\n\t\tORDER BY `parent` DESC, `gravity` ASC, `id` ASC", intval($a->profile['uid']), dbesc($item_id), dbesc($item_id), intval($a->profile['uid']));
    if (!$r && local_user()) {
        // Check if this is another person's link to a post that we have
        $r = q("SELECT `item`.uri FROM `item`\n\t\t\tWHERE (`item`.`id` = '%s' OR `item`.`uri` = '%s' )\n\t\t\tLIMIT 1", dbesc($item_id), dbesc($item_id));
        if ($r) {
            $item_uri = $r[0]['uri'];
            //	AND `item`.`parent` = ( SELECT `parent` FROM `item` FORCE INDEX (PRIMARY, `uri`) WHERE `uri` = '%s' AND uid = %d )
            $r = q("SELECT `item`.*, `item`.`id` AS `item_id`,  `item`.`network` AS `item_network`,\n\t\t\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,\n\t\t\t\t`contact`.`network`, `contact`.`thumb`, `contact`.`self`, `contact`.`writable`, \n\t\t\t\t`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`\n\t\t\t\tFROM `item` INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\t\tWHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0\n\t\t\t\tand `item`.`moderated` = 0\n\t\t\t\tAND `item`.`parent` = (SELECT `parent` FROM `item` WHERE `uri` = '%s' AND uid = %d)\n\t\t\t\tORDER BY `parent` DESC, `gravity` ASC, `id` ASC ", intval(local_user()), dbesc($item_uri), intval(local_user()));
        }
    }
    if ($r) {
        if (local_user() && local_user() == $a->profile['uid']) {
            q("UPDATE `item` SET `unseen` = 0\n\t\t\t\tWHERE `parent` = %d AND `unseen` = 1", intval($r[0]['parent']));
        }
        $items = conv_sort($r, "`commented`");
        if (!$update) {
            $o .= "<script> var netargs = '?f=&nick=" . $nick . "&item_id=" . $item_id . "'; </script>";
        }
        $o .= conversation($a, $items, 'display', $update);
        // Preparing the meta header
        require_once 'include/bbcode.php';
        require_once "include/html2plain.php";
        $description = trim(html2plain(bbcode($r[0]["body"], false, false), 0, true));
        $title = trim(html2plain(bbcode($r[0]["title"], false, false), 0, true));
        $author_name = $r[0]["author-name"];
        $image = "";
        if ($image == "") {
            $image = $r[0]["thumb"];
        }
        if ($title == "") {
            $title = $author_name;
        }
        $description = htmlspecialchars($description, ENT_COMPAT, 'UTF-8', true);
        // allow double encoding here
        $title = htmlspecialchars($title, ENT_COMPAT, 'UTF-8', true);
        // allow double encoding here
        $author_name = htmlspecialchars($author_name, ENT_COMPAT, 'UTF-8', true);
        // allow double encoding here
        //<meta name="keywords" content="">
        $a->page['htmlhead'] .= '<meta name="author" content="' . $author_name . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta name="title" content="' . $title . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta name="fulltitle" content="' . $title . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta name="description" content="' . $description . '" />' . "\n";
        // Schema.org microdata
        $a->page['htmlhead'] .= '<meta itemprop="name" content="' . $title . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta itemprop="description" content="' . $description . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta itemprop="image" content="' . $image . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta itemprop="author" content="' . $author_name . '" />' . "\n";
        // Twitter cards
        $a->page['htmlhead'] .= '<meta name="twitter:card" content="summary" />' . "\n";
        $a->page['htmlhead'] .= '<meta name="twitter:title" content="' . $title . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta name="twitter:description" content="' . $description . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta name="twitter:image" content="' . $image . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta name="twitter:url" content="' . $r[0]["plink"] . '" />' . "\n";
        // Dublin Core
        $a->page['htmlhead'] .= '<meta name="DC.title" content="' . $title . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta name="DC.description" content="' . $description . '" />' . "\n";
        // Open Graph
        $a->page['htmlhead'] .= '<meta property="og:type" content="website" />' . "\n";
        $a->page['htmlhead'] .= '<meta property="og:title" content="' . $title . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta property="og:image" content="' . $image . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta property="og:url" content="' . $r[0]["plink"] . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta property="og:description" content="' . $description . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta name="og:article:author" content="' . $author_name . '" />' . "\n";
        // article:tag
        return $o;
    }
    $r = q("SELECT `id`,`deleted` FROM `item` WHERE `id` = '%s' OR `uri` = '%s' LIMIT 1", dbesc($item_id), dbesc($item_id));
    if ($r) {
        if ($r[0]['deleted']) {
            notice(t('Item has been removed.') . EOL);
        } else {
            notice(t('Permission denied.') . EOL);
        }
    } else {
        notice(t('Item not found.') . EOL);
    }
    return $o;
}
Example #5
0
 function Verify($channel, $hubloc)
 {
     logger('auth request received from ' . $hubloc['hubloc_addr']);
     $this->remote = remote_channel();
     $this->remote_service_class = '';
     $this->remote_level = 0;
     $this->remote_hub = $hubloc['hubloc_url'];
     $this->dnt = 0;
     // check credentials and access
     // If they are already authenticated and haven't changed credentials,
     // we can save an expensive network round trip and improve performance.
     // Also check that they are coming from the same site as they authenticated with originally.
     $already_authed = remote_channel() && $hubloc['hubloc_hash'] == remote_channel() && $hubloc['hubloc_url'] === $_SESSION['remote_hub'] ? true : false;
     if ($this->delegate && $this->delegate !== $_SESSION['delegate_channel']) {
         $already_authed = false;
     }
     if ($already_authed) {
         return true;
     }
     if (local_channel()) {
         // tell them to logout if they're logged in locally as anything but the target remote account
         // in which case just shut up because they don't need to be doing this at all.
         if (\App::$channel['channel_hash'] == $hubloc['xchan_hash']) {
             return true;
         } else {
             logger('already authenticated locally as somebody else.');
             notice(t('Remote authentication blocked. You are logged into this site locally. Please logout and retry.') . EOL);
             if ($this->test) {
                 $this->Debug('already logged in locally with a conflicting identity.');
                 return false;
             }
         }
         return false;
     }
     // Auth packets MUST use ultra top-secret hush-hush mode - e.g. the entire packet is encrypted using the
     // site private key
     // The actual channel sending the packet ($c[0]) is not important, but this provides a
     // generic zot packet with a sender which can be verified
     $p = zot_build_packet($channel, $type = 'auth_check', array(array('guid' => $hubloc['hubloc_guid'], 'guid_sig' => $hubloc['hubloc_guid_sig'])), $hubloc['hubloc_sitekey'], $this->sec);
     $this->Debug('auth check packet created using sitekey ' . $hubloc['hubloc_sitekey']);
     $this->Debug('packet contents: ' . $p);
     $result = zot_zot($hubloc['hubloc_callback'], $p);
     if (!$result['success']) {
         logger('auth_check callback failed.');
         if ($this->test) {
             $this->Debug('auth check request to your site returned .' . print_r($result, true));
         }
         return false;
     }
     $j = json_decode($result['body'], true);
     if (!$j) {
         logger('auth_check json data malformed.');
         if ($this->test) {
             $this->Debug('json malformed: ' . $result['body']);
         }
         return false;
     }
     $this->Debug('auth check request returned .' . print_r($j, true));
     if (!$j['success']) {
         return false;
     }
     // legit response, but we do need to check that this wasn't answered by a man-in-middle
     if (!rsa_verify($this->sec . $hubloc['xchan_hash'], base64url_decode($j['confirm']), $hubloc['xchan_pubkey'])) {
         logger('final confirmation failed.');
         if ($this->test) {
             $this->Debug('final confirmation failed. ' . $sec . print_r($j, true) . print_r($hubloc, true));
         }
         return false;
     }
     if (array_key_exists('service_class', $j)) {
         $this->remote_service_class = $j['service_class'];
     }
     if (array_key_exists('level', $j)) {
         $this->remote_level = $j['level'];
     }
     if (array_key_exists('DNT', $j)) {
         $this->dnt = $j['DNT'];
     }
     // log them in
     if ($this->test) {
         // testing only - return the success result
         $this->test_results['success'] = true;
         $this->Debug('Authentication Success!');
         $this->Finalise();
     }
     $_SESSION['authenticated'] = 1;
     // check for delegation and if all is well, log them in locally with delegation restrictions
     $this->delegate_success = false;
     if ($this->delegate) {
         $r = q("select * from channel left join xchan on channel_hash = xchan_hash where xchan_addr = '%s' limit 1", dbesc($this->delegate));
         if ($r && intval($r[0]['channel_id'])) {
             $allowed = perm_is_allowed($r[0]['channel_id'], $hubloc['xchan_hash'], 'delegate');
             if ($allowed) {
                 $_SESSION['delegate_channel'] = $r[0]['channel_id'];
                 $_SESSION['delegate'] = $hubloc['xchan_hash'];
                 $_SESSION['account_id'] = intval($r[0]['channel_account_id']);
                 require_once 'include/security.php';
                 // this will set the local_channel authentication in the session
                 change_channel($r[0]['channel_id']);
                 $this->delegate_success = true;
             }
         }
     }
     if (!$this->delegate_success) {
         // normal visitor (remote_channel) login session credentials
         $_SESSION['visitor_id'] = $hubloc['xchan_hash'];
         $_SESSION['my_url'] = $hubloc['xchan_url'];
         $_SESSION['my_address'] = $this->address;
         $_SESSION['remote_service_class'] = $this->remote_service_class;
         $_SESSION['remote_level'] = $this->remote_level;
         $_SESSION['remote_hub'] = $this->remote_hub;
         $_SESSION['DNT'] = $this->dnt;
     }
     $arr = array('xchan' => $hubloc, 'url' => $this->desturl, 'session' => $_SESSION);
     call_hooks('magic_auth_success', $arr);
     \App::set_observer($hubloc);
     require_once 'include/security.php';
     \App::set_groups(init_groups_visitor($_SESSION['visitor_id']));
     info(sprintf(t('Welcome %s. Remote authentication successful.'), $hubloc['xchan_name']));
     logger('mod_zot: auth success from ' . $hubloc['xchan_addr']);
     $this->success = true;
     return true;
 }
Example #6
0
/**
 * @brief HTTP POST entry point for Zot.
 *
 * Most access to this endpoint is via the post method.
 * Here we will pick out the magic auth params which arrive as a get request,
 * and the only communications to arrive this way.
 *
 * Magic Auth
 * ==========
 *
 * So-called "magic auth" takes place by a special exchange. On the site where the "channel to be authenticated" lives (e.g. $mysite), 
 * a redirection is made via $mysite/magic to the zot endpoint of the remote site ($remotesite) with special GET parameters.
 *
 * The endpoint is typically  https://$remotesite/post - or whatever was specified as the callback url in prior communications
 * (we will bootstrap an address and fetch a zot info packet if possible where no prior communications exist)
 *
 * Five GET parameters are supplied:
 * * auth => the urlencoded webbie (channel@host.domain) of the channel requesting access
 * * dest => the desired destination URL (urlencoded)
 * * sec  => a random string which is also stored on $mysite for use during the verification phase. 
 * * version => the zot revision
 * * delegate => optional urlencoded webbie of a local channel to invoke delegation rights for
 *
 * When this packet is received, an "auth-check" zot message is sent to $mysite.
 * (e.g. if $_GET['auth'] is foobar@podunk.edu, a zot packet is sent to the podunk.edu zot endpoint, which is typically /post)
 * If no information has been recorded about the requesting identity a zot information packet will be retrieved before
 * continuing.
 *
 * The sender of this packet is an arbitrary/random site channel. The recipients will be a single recipient corresponding
 * to the guid and guid_sig we have associated with the requesting auth identity
 *
 * \code{.json}
 * {
 *   "type":"auth_check",
 *   "sender":{
 *     "guid":"kgVFf_...",
 *     "guid_sig":"PT9-TApz...",
 *     "url":"http:\/\/podunk.edu",
 *     "url_sig":"T8Bp7j..."
 *   },
 *   "recipients":{
 *     {
 *       "guid":"ZHSqb...",
 *       "guid_sig":"JsAAXi..."
 *     }
 *   }
 *   "callback":"\/post",
 *   "version":1,
 *   "secret":"1eaa661",
 *   "secret_sig":"eKV968b1..."
 * }
 * \endcode
 *
 * auth_check messages MUST use encapsulated encryption. This message is sent to the origination site, which checks the 'secret' to see 
 * if it is the same as the 'sec' which it passed originally. It also checks the secret_sig which is the secret signed by the 
 * destination channel's private key and base64url encoded. If everything checks out, a json packet is returned:
 *
 * \code{.json}
 * {
 *   "success":1,
 *   "confirm":"q0Ysovd1u...",
 *   "service_class":(optional)
 *   "level":(optional)
 * }
 * \endcode
 *
 * 'confirm' in this case is the base64url encoded RSA signature of the concatenation of 'secret' with the
 * base64url encoded whirlpool hash of the requestor's guid and guid_sig; signed with the source channel private key. 
 * This prevents a man-in-the-middle from inserting a rogue success packet. Upon receipt and successful 
 * verification of this packet, the destination site will redirect to the original destination URL and indicate a successful remote login. 
 * Service_class can be used by cooperating sites to provide different access rights based on account rights and subscription plans. It is 
 * a string whose contents are not defined by protocol. Example: "basic" or "gold".
 *
 * @param[in,out] App &$a
 */
function post_init(&$a)
{
    if (array_key_exists('auth', $_REQUEST)) {
        $ret = array('success' => false, 'message' => '');
        logger('mod_zot: auth request received.');
        $address = $_REQUEST['auth'];
        $desturl = $_REQUEST['dest'];
        $sec = $_REQUEST['sec'];
        $version = $_REQUEST['version'];
        $delegate = $_REQUEST['delegate'];
        $test = x($_REQUEST, 'test') ? intval($_REQUEST['test']) : 0;
        // They are authenticating ultimately to the site and not to a particular channel.
        // Any channel will do, providing it's currently active. We just need to have an
        // identity to attach to the packet we send back. So find one.
        $c = q("select * from channel where channel_removed = 0 limit 1");
        if (!$c) {
            // nobody here
            logger('mod_zot: auth: unable to find a response channel');
            if ($test) {
                $ret['message'] .= 'no local channels found.' . EOL;
                json_return_and_die($ret);
            }
            goaway($desturl);
        }
        // Try and find a hubloc for the person attempting to auth
        $x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' order by hubloc_id desc", dbesc($address));
        if (!$x) {
            // finger them if they can't be found.
            $ret = zot_finger($address, null);
            if ($ret['success']) {
                $j = json_decode($ret['body'], true);
                if ($j) {
                    import_xchan($j);
                }
                $x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' order by hubloc_id desc", dbesc($address));
            }
        }
        if (!$x) {
            logger('mod_zot: auth: unable to finger ' . $address);
            if ($test) {
                $ret['message'] .= 'no hubloc found for ' . $address . ' and probing failed.' . EOL;
                json_return_and_die($ret);
            }
            goaway($desturl);
        }
        foreach ($x as $xx) {
            logger('mod_zot: auth request received from ' . $xx['hubloc_addr']);
            // check credentials and access
            // If they are already authenticated and haven't changed credentials,
            // we can save an expensive network round trip and improve performance.
            $remote = remote_channel();
            $result = null;
            $remote_service_class = '';
            $remote_level = 0;
            $remote_hub = $xx['hubloc_url'];
            $DNT = 0;
            // Also check that they are coming from the same site as they authenticated with originally.
            $already_authed = $remote && $xx['hubloc_hash'] == $remote && $xx['hubloc_url'] === $_SESSION['remote_hub'] ? true : false;
            if ($delegate && $delegate !== $_SESSION['delegate_channel']) {
                $already_authed = false;
            }
            $j = array();
            if (!$already_authed) {
                // Auth packets MUST use ultra top-secret hush-hush mode - e.g. the entire packet is encrypted using the site private key
                // The actual channel sending the packet ($c[0]) is not important, but this provides a generic zot packet with a sender
                // which can be verified
                $p = zot_build_packet($c[0], $type = 'auth_check', array(array('guid' => $xx['hubloc_guid'], 'guid_sig' => $xx['hubloc_guid_sig'])), $xx['hubloc_sitekey'], $sec);
                if ($test) {
                    $ret['message'] .= 'auth check packet created using sitekey ' . $xx['hubloc_sitekey'] . EOL;
                    $ret['message'] .= 'packet contents: ' . $p . EOL;
                }
                $result = zot_zot($xx['hubloc_callback'], $p);
                if (!$result['success']) {
                    logger('mod_zot: auth_check callback failed.');
                    if ($test) {
                        $ret['message'] .= 'auth check request to your site returned .' . print_r($result, true) . EOL;
                        continue;
                    }
                    continue;
                }
                $j = json_decode($result['body'], true);
                if (!$j) {
                    logger('mod_zot: auth_check json data malformed.');
                    if ($test) {
                        $ret['message'] .= 'json malformed: ' . $result['body'] . EOL;
                        continue;
                    }
                }
            }
            if ($test) {
                $ret['message'] .= 'auth check request returned .' . print_r($j, true) . EOL;
            }
            if ($already_authed || $j['success']) {
                if ($j['success']) {
                    // legit response, but we do need to check that this wasn't answered by a man-in-middle
                    if (!rsa_verify($sec . $xx['xchan_hash'], base64url_decode($j['confirm']), $xx['xchan_pubkey'])) {
                        logger('mod_zot: auth: final confirmation failed.');
                        if ($test) {
                            $ret['message'] .= 'final confirmation failed. ' . $sec . print_r($j, true) . print_r($xx, true);
                            continue;
                        }
                        continue;
                    }
                    if (array_key_exists('service_class', $j)) {
                        $remote_service_class = $j['service_class'];
                    }
                    if (array_key_exists('level', $j)) {
                        $remote_level = $j['level'];
                    }
                    if (array_key_exists('DNT', $j)) {
                        $DNT = $j['DNT'];
                    }
                }
                // everything is good... maybe
                if (local_channel()) {
                    // tell them to logout if they're logged in locally as anything but the target remote account
                    // in which case just shut up because they don't need to be doing this at all.
                    if ($a->channel['channel_hash'] != $xx['xchan_hash']) {
                        logger('mod_zot: auth: already authenticated locally as somebody else.');
                        notice(t('Remote authentication blocked. You are logged into this site locally. Please logout and retry.') . EOL);
                        if ($test) {
                            $ret['message'] .= 'already logged in locally with a conflicting identity.' . EOL;
                            continue;
                        }
                    }
                    continue;
                }
                // log them in
                if ($test) {
                    $ret['success'] = true;
                    $ret['message'] .= 'Authentication Success!' . EOL;
                    json_return_and_die($ret);
                }
                $delegation_success = false;
                if ($delegate) {
                    $r = q("select * from channel left join xchan on channel_hash = xchan_hash where xchan_addr = '%s' limit 1", dbesc($delegate));
                    if ($r && intval($r[0]['channel_id'])) {
                        $allowed = perm_is_allowed($r[0]['channel_id'], $xx['xchan_hash'], 'delegate');
                        if ($allowed) {
                            $_SESSION['delegate_channel'] = $r[0]['channel_id'];
                            $_SESSION['delegate'] = $xx['xchan_hash'];
                            $_SESSION['account_id'] = intval($r[0]['channel_account_id']);
                            require_once 'include/security.php';
                            change_channel($r[0]['channel_id']);
                            $delegation_success = true;
                        }
                    }
                }
                $_SESSION['authenticated'] = 1;
                if (!$delegation_success) {
                    $_SESSION['visitor_id'] = $xx['xchan_hash'];
                    $_SESSION['my_url'] = $xx['xchan_url'];
                    $_SESSION['my_address'] = $address;
                    $_SESSION['remote_service_class'] = $remote_service_class;
                    $_SESSION['remote_level'] = $remote_level;
                    $_SESSION['remote_hub'] = $remote_hub;
                    $_SESSION['DNT'] = $DNT;
                }
                $arr = array('xchan' => $xx, 'url' => $desturl, 'session' => $_SESSION);
                call_hooks('magic_auth_success', $arr);
                $a->set_observer($xx);
                require_once 'include/security.php';
                $a->set_groups(init_groups_visitor($_SESSION['visitor_id']));
                info(sprintf(t('Welcome %s. Remote authentication successful.'), $xx['xchan_name']));
                logger('mod_zot: auth success from ' . $xx['xchan_addr']);
            } else {
                if ($test) {
                    $ret['message'] .= 'auth failure. ' . print_r($_REQUEST, true) . print_r($j, true) . EOL;
                    continue;
                }
                logger('mod_zot: magic-auth failure - not authenticated: ' . $xx['xchan_addr']);
            }
            if ($test) {
                $ret['message'] .= 'auth failure fallthrough ' . print_r($_REQUEST, true) . print_r($j, true) . EOL;
                continue;
            }
        }
        /**
         * @FIXME we really want to save the return_url in the session before we
         * visit rmagic. This does however prevent a recursion if you visit
         * rmagic directly, as it would otherwise send you back here again.
         * But z_root() probably isn't where you really want to go.
         */
        if (strstr($desturl, z_root() . '/rmagic')) {
            goaway(z_root());
        }
        if ($test) {
            json_return_and_die($ret);
        }
        goaway($desturl);
    }
}
Example #7
0
function public_permissions_sql($observer_hash)
{
    $observer = get_app()->get_observer();
    $groups = init_groups_visitor($observer_hash);
    $gs = '<<>>';
    // should be impossible to match
    if (is_array($groups) && count($groups)) {
        foreach ($groups as $g) {
            $gs .= '|<' . $g . '>';
        }
    }
    $sql = '';
    if ($observer_hash) {
        $sql = sprintf(" OR (( NOT (deny_cid like '%s' OR deny_gid REGEXP '%s')\n\t\t\t  AND ( allow_cid like '%s' OR allow_gid REGEXP '%s' OR ( allow_cid = '' AND allow_gid = '') )\n\t\t\t  ))\n\t\t\t", dbesc(protect_sprintf('%<' . $observer_hash . '>%')), dbesc($gs), dbesc(protect_sprintf('%<' . $observer_hash . '>%')), dbesc($gs));
    }
    return $sql;
}
Example #8
0
function get_feed_for(&$a, $dfrn_id, $owner_id, $last_update)
{
    require_once 'bbcode.php';
    // default permissions - anonymous user
    $sql_extra = " \n\t\tAND `allow_cid` = '' \n\t\tAND `allow_gid` = '' \n\t\tAND `deny_cid`  = '' \n\t\tAND `deny_gid`  = '' \n\t";
    if (strlen($owner_id) && !intval($owner_id)) {
        $r = q("SELECT `uid` FROM `user` WHERE `nickname` = '%s' LIMIT 1", dbesc($owner_id));
        if (count($r)) {
            $owner_id = $r[0]['uid'];
            $owner_nick = $r[0]['nickname'];
        }
    }
    $r = q("SELECT * FROM `contact` WHERE `self` = 1 LIMIT 1");
    if (count($r)) {
        $owner = $r[0];
    } else {
        killme();
    }
    if ($dfrn_id != '*') {
        $r = q("SELECT * FROM `contact` WHERE ( `issued-id` = '%s' OR ( `duplex` = 1 AND `dfrn-id` = '%s' )) LIMIT 1", dbesc($dfrn_id), dbesc($dfrn_id));
        if (!count($r)) {
            return false;
        }
        $contact = $r[0];
        $groups = init_groups_visitor($contact['id']);
        if (count($groups)) {
            for ($x = 0; $x < count($groups); $x++) {
                $groups[$x] = '<' . intval($groups[$x]) . '>';
            }
            $gs = implode('|', $groups);
        } else {
            $gs = '<<>>';
        }
        // Impossible to match
        $sql_extra = sprintf(" \n\t\t\tAND ( `allow_cid` = '' OR     `allow_cid` REGEXP '<%d>' ) \n\t\t\tAND ( `deny_cid`  = '' OR NOT `deny_cid`  REGEXP '<%d>' ) \n\t\t\tAND ( `allow_gid` = '' OR     `allow_gid` REGEXP '%s' )\n\t\t\tAND ( `deny_gid`  = '' OR NOT `deny_gid`  REGEXP '%s') \n\t\t", intval($contact['id']), intval($contact['id']), dbesc($gs), dbesc($gs));
    }
    if ($dfrn_id == '' || $dfrn_id == '*') {
        $sort = 'DESC';
    } else {
        $sort = 'ASC';
    }
    if (!strlen($last_update)) {
        $last_update = 'now - 30 days';
    }
    $check_date = datetime_convert('UTC', 'UTC', $last_update, 'Y-m-d H:i:s');
    $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, \n\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, \n\t\t`contact`.`name-date`, `contact`.`uri-date`, `contact`.`avatar-date`,\n\t\t`contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`, \n\t\t`contact`.`id` AS `contact-id`\n\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\tWHERE `item`.`visible` = 1 \n\t\tAND NOT `item`.`type` IN ( 'remote', 'net-comment' ) AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\tAND ( `item`.`edited` > '%s' OR `item`.`changed` > '%s' )\n\t\t{$sql_extra}\n\t\tORDER BY `parent` %s, `created` ASC LIMIT 0, 300", dbesc($check_date), dbesc($check_date), dbesc($sort));
    if (!count($r)) {
        killme();
    }
    $items = $r;
    $feed_template = file_get_contents('view/atom_feed.tpl');
    $tomb_template = file_get_contents('view/atom_tomb.tpl');
    $item_template = file_get_contents('view/atom_item.tpl');
    $cmnt_template = file_get_contents('view/atom_cmnt.tpl');
    $atom = '';
    $atom .= replace_macros($feed_template, array('$feed_id' => xmlify($a->get_baseurl() . '/profile/' . $owner_nick), '$feed_title' => xmlify($owner['name']), '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', $updated . '+00:00', 'Y-m-d\\TH:i:s\\Z')), '$name' => xmlify($owner['name']), '$profile_page' => xmlify($owner['url']), '$photo' => xmlify($owner['photo']), '$thumb' => xmlify($owner['thumb']), '$picdate' => xmlify(datetime_convert('UTC', 'UTC', $owner['avatar-date'] . '+00:00', 'Y-m-d\\TH:i:s\\Z')), '$uridate' => xmlify(datetime_convert('UTC', 'UTC', $owner['uri-date'] . '+00:00', 'Y-m-d\\TH:i:s\\Z')), '$namdate' => xmlify(datetime_convert('UTC', 'UTC', $owner['name-date'] . '+00:00', 'Y-m-d\\TH:i:s\\Z'))));
    foreach ($items as $item) {
        // public feeds get html, our own nodes use bbcode
        if ($dfrn_id == '*') {
            $item['body'] = bbcode($item['body']);
            $type = 'html';
        } else {
            $type = 'text';
        }
        if ($item['deleted']) {
            $atom .= replace_macros($tomb_template, array('$id' => xmlify($item['uri']), '$updated' => xmlify(datetime_convert('UTC', 'UTC', $item['edited'] . '+00:00', 'Y-m-d\\TH:i:s\\Z'))));
        } else {
            $verb = construct_verb($item);
            $actobj = construct_activity($item);
            if ($item['parent'] == $item['id']) {
                $atom .= replace_macros($item_template, array('$name' => xmlify($item['name']), '$profile_page' => xmlify($item['url']), '$thumb' => xmlify($item['thumb']), '$owner_name' => xmlify($item['owner-name']), '$owner_profile_page' => xmlify($item['owner-link']), '$owner_thumb' => xmlify($item['owner-avatar']), '$item_id' => xmlify($item['uri']), '$title' => xmlify($item['title']), '$published' => xmlify(datetime_convert('UTC', 'UTC', $item['created'] . '+00:00', 'Y-m-d\\TH:i:s\\Z')), '$updated' => xmlify(datetime_convert('UTC', 'UTC', $item['edited'] . '+00:00', 'Y-m-d\\TH:i:s\\Z')), '$location' => xmlify($item['location']), '$type' => $type, '$content' => xmlify($item['body']), '$verb' => xmlify($verb), '$actobj' => $actobj, '$comment_allow' => $item['last-child'] && strlen($contact['dfrn-id']) ? 1 : 0));
            } else {
                $atom .= replace_macros($cmnt_template, array('$name' => xmlify($item['name']), '$profile_page' => xmlify($item['url']), '$thumb' => xmlify($item['thumb']), '$item_id' => xmlify($item['uri']), '$title' => xmlify($item['title']), '$published' => xmlify(datetime_convert('UTC', 'UTC', $item['created'] . '+00:00', 'Y-m-d\\TH:i:s\\Z')), '$updated' => xmlify(datetime_convert('UTC', 'UTC', $item['edited'] . '+00:00', 'Y-m-d\\TH:i:s\\Z')), '$type' => $type, '$content' => xmlify($item['body']), '$verb' => xmlify($verb), '$actobj' => $actobj, '$parent_id' => xmlify($item['parent-uri']), '$comment_allow' => $item['last-child'] ? 1 : 0));
            }
        }
    }
    $atom .= '</feed>' . "\r\n";
    return $atom;
}
Example #9
0
File: post.php Project: Mauru/red
function post_init(&$a)
{
    // Most access to this endpoint is via the post method.
    // Here we will pick out the magic auth params which arrive
    // as a get request, and the only communications to arrive this way.
    /**
     * Magic Auth
     * ==========
     *
     * So-called "magic auth" takes place by a special exchange. On the site where the "channel to be authenticated" lives (e.g. $mysite), 
     * a redirection is made via $mysite/magic to the zot endpoint of the remote site ($remotesite) with special GET parameters.
     *
     * The endpoint is typically  https://$remotesite/post - or whatever was specified as the callback url in prior communications
     * (we will bootstrap an address and fetch a zot info packet if possible where no prior communications exist)
     *
     * Four GET parameters are supplied:
     *
     ** auth => the urlencoded webbie (channel@host.domain) of the channel requesting access
     ** dest => the desired destination URL (urlencoded)
     ** sec  => a random string which is also stored on $mysite for use during the verification phase. 
     ** version => the zot revision
     *
     * When this packet is received, an "auth-check" zot message is sent to $mysite.
     * (e.g. if $_GET['auth'] is foobar@podunk.edu, a zot packet is sent to the podunk.edu zot endpoint, which is typically /post)
     * If no information has been recorded about the requesting identity a zot information packet will be retrieved before
     * continuing.
     * 
     * The sender of this packet is an arbitrary/random site channel. The recipients will be a single recipient corresponding
     * to the guid and guid_sig we have associated with the requesting auth identity
     *
     *
     *    {
     *      "type":"auth_check",
     *      "sender":{
     *        "guid":"kgVFf_...",
     *        "guid_sig":"PT9-TApz...",
     *        "url":"http:\/\/podunk.edu",
     *        "url_sig":"T8Bp7j..."
     *      },
     *      "recipients":{
     *        {
     *        "guid":"ZHSqb...",
     *        "guid_sig":"JsAAXi..."
     *        }
     *      }
     *      "callback":"\/post",
     *      "version":1,
     *      "secret":"1eaa661",
     *      "secret_sig":"eKV968b1..."
     *    }
     *
     *
     * auth_check messages MUST use encapsulated encryption. This message is sent to the origination site, which checks the 'secret' to see 
     * if it is the same as the 'sec' which it passed originally. It also checks the secret_sig which is the secret signed by the 
     * destination channel's private key and base64url encoded. If everything checks out, a json packet is returned:
     *
     *    { 
     *      "success":1, 
     *      "confirm":"q0Ysovd1u..."
     *      "service_class":(optional)
     *      "level":(optional)
     *    }
     *
     * 'confirm' in this case is the base64url encoded RSA signature of the concatenation of 'secret' with the
     * base64url encoded whirlpool hash of the requestor's guid and guid_sig; signed with the source channel private key. 
     * This prevents a man-in-the-middle from inserting a rogue success packet. Upon receipt and successful 
     * verification of this packet, the destination site will redirect to the original destination URL and indicate a successful remote login. 
     * Service_class can be used by cooperating sites to provide different access rights based on account rights and subscription plans. It is 
     * a string whose contents are not defined by protocol. Example: "basic" or "gold". 
     *
     *
     *
     */
    if (array_key_exists('auth', $_REQUEST)) {
        $ret = array('success' => false, 'message' => '');
        logger('mod_zot: auth request received.');
        $address = $_REQUEST['auth'];
        $desturl = $_REQUEST['dest'];
        $sec = $_REQUEST['sec'];
        $version = $_REQUEST['version'];
        $test = x($_REQUEST, 'test') ? intval($_REQUEST['test']) : 0;
        // They are authenticating ultimately to the site and not to a particular channel.
        // Any channel will do, providing it's currently active. We just need to have an
        // identity to attach to the packet we send back. So find one.
        $c = q("select * from channel where not ( channel_pageflags & %d ) limit 1", intval(PAGE_REMOVED));
        if (!$c) {
            // nobody here
            logger('mod_zot: auth: unable to find a response channel');
            if ($test) {
                $ret['message'] .= 'no local channels found.' . EOL;
                json_return_and_die($ret);
            }
            goaway($desturl);
        }
        // Try and find a hubloc for the person attempting to auth
        $x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' order by hubloc_id desc limit 1", dbesc($address));
        if (!$x) {
            // finger them if they can't be found.
            $ret = zot_finger($address, null);
            if ($ret['success']) {
                $j = json_decode($ret['body'], true);
                if ($j) {
                    import_xchan($j);
                }
                $x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' order by hubloc_id desc limit 1", dbesc($address));
            }
        }
        if (!$x) {
            logger('mod_zot: auth: unable to finger ' . $address);
            if ($test) {
                $ret['message'] .= 'no hubloc found for ' . $address . ' and probing failed.' . EOL;
                json_return_and_die($ret);
            }
            goaway($desturl);
        }
        logger('mod_zot: auth request received from ' . $x[0]['hubloc_addr']);
        // check credentials and access
        // If they are already authenticated and haven't changed credentials,
        // we can save an expensive network round trip and improve performance.
        $remote = remote_user();
        $result = null;
        $remote_service_class = '';
        $remote_level = 0;
        $remote_hub = $x[0]['hubloc_url'];
        $DNT = 0;
        // Also check that they are coming from the same site as they authenticated with originally.
        $already_authed = $remote && $x[0]['hubloc_hash'] == $remote && $x[0]['hubloc_url'] === $_SESSION['remote_hub'] ? true : false;
        $j = array();
        if (!$already_authed) {
            // Auth packets MUST use ultra top-secret hush-hush mode - e.g. the entire packet is encrypted using the site private key
            // The actual channel sending the packet ($c[0]) is not important, but this provides a generic zot packet with a sender
            // which can be verified
            $p = zot_build_packet($c[0], $type = 'auth_check', array(array('guid' => $x[0]['hubloc_guid'], 'guid_sig' => $x[0]['hubloc_guid_sig'])), $x[0]['hubloc_sitekey'], $sec);
            if ($test) {
                $ret['message'] .= 'auth check packet created using sitekey ' . $x[0]['hubloc_sitekey'] . EOL;
                $ret['message'] .= 'packet contents: ' . $p . EOL;
            }
            $result = zot_zot($x[0]['hubloc_callback'], $p);
            if (!$result['success']) {
                logger('mod_zot: auth_check callback failed.');
                if ($test) {
                    $ret['message'] .= 'auth check request to your site returned .' . print_r($result, true) . EOL;
                    json_return_and_die($ret);
                }
                goaway($desturl);
            }
            $j = json_decode($result['body'], true);
            if (!$j) {
                logger('mod_zot: auth_check json data malformed.');
                if ($test) {
                    $ret['message'] .= 'json malformed: ' . $result['body'] . EOL;
                    json_return_and_die($ret);
                }
            }
        }
        if ($test) {
            $ret['message'] .= 'auth check request returned .' . print_r($j, true) . EOL;
        }
        if ($already_authed || $j['success']) {
            if ($j['success']) {
                // legit response, but we do need to check that this wasn't answered by a man-in-middle
                if (!rsa_verify($sec . $x[0]['xchan_hash'], base64url_decode($j['confirm']), $x[0]['xchan_pubkey'])) {
                    logger('mod_zot: auth: final confirmation failed.');
                    if ($test) {
                        $ret['message'] .= 'final confirmation failed. ' . $sec . print_r($j, true) . print_r($x[0], true);
                        json_return_and_die($ret);
                    }
                    goaway($desturl);
                }
                if (array_key_exists('service_class', $j)) {
                    $remote_service_class = $j['service_class'];
                }
                if (array_key_exists('level', $j)) {
                    $remote_level = $j['level'];
                }
                if (array_key_exists('DNT', $j)) {
                    $DNT = $j['DNT'];
                }
            }
            // everything is good... maybe
            if (local_user()) {
                // tell them to logout if they're logged in locally as anything but the target remote account
                // in which case just shut up because they don't need to be doing this at all.
                if ($a->channel['channel_hash'] != $x[0]['xchan_hash']) {
                    logger('mod_zot: auth: already authenticated locally as somebody else.');
                    notice(t('Remote authentication blocked. You are logged into this site locally. Please logout and retry.') . EOL);
                    if ($test) {
                        $ret['message'] .= 'already logged in locally with a conflicting identity.' . EOL;
                        json_return_and_die($ret);
                    }
                }
                goaway($desturl);
            }
            // log them in
            if ($test) {
                $ret['success'] = true;
                $ret['message'] .= 'Authentication Success!' . EOL;
                json_return_and_die($ret);
            }
            $_SESSION['authenticated'] = 1;
            $_SESSION['visitor_id'] = $x[0]['xchan_hash'];
            $_SESSION['my_url'] = $x[0]['xchan_url'];
            $_SESSION['my_address'] = $address;
            $_SESSION['remote_service_class'] = $remote_service_class;
            $_SESSION['remote_level'] = $remote_level;
            $_SESSION['remote_hub'] = $remote_hub;
            $_SESSION['DNT'] = $DNT;
            $arr = array('xchan' => $x[0], 'url' => $desturl, 'session' => $_SESSION);
            call_hooks('magic_auth_success', $arr);
            $a->set_observer($x[0]);
            require_once 'include/security.php';
            $a->set_groups(init_groups_visitor($_SESSION['visitor_id']));
            info(sprintf(t('Welcome %s. Remote authentication successful.'), $x[0]['xchan_name']));
            logger('mod_zot: auth success from ' . $x[0]['xchan_addr']);
            q("update hubloc set hubloc_status =  (hubloc_status | %d ) where hubloc_id = %d ", intval(HUBLOC_WORKS), intval($x[0]['hubloc_id']));
        } else {
            if ($test) {
                $ret['message'] .= 'auth failure. ' . print_r($_REQUEST, true) . print_r($j, true) . EOL;
                json_return_and_die($ret);
            }
            logger('mod_zot: magic-auth failure - not authenticated: ' . $x[0]['xchan_addr']);
            q("update hubloc set hubloc_status =  (hubloc_status | %d ) where hubloc_id = %d ", intval(HUBLOC_RECEIVE_ERROR), intval($x[0]['hubloc_id']));
        }
        // FIXME - we really want to save the return_url in the session before we visit rmagic.
        // This does however prevent a recursion if you visit rmagic directly, as it would otherwise send you back here again.
        // But z_root() probably isn't where you really want to go.
        if ($test) {
            $ret['message'] .= 'auth failure fallthrough ' . print_r($_REQUEST, true) . print_r($j, true) . EOL;
            json_return_and_die($ret);
        }
        if (strstr($desturl, z_root() . '/rmagic')) {
            goaway(z_root());
        }
        goaway($desturl);
    }
    return;
}
Example #10
0
function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0)
{
    // default permissions - anonymous user
    if (!strlen($owner_nick)) {
        killme();
    }
    $public_feed = $dfrn_id ? false : true;
    $starred = false;
    $converse = false;
    if ($public_feed && $a->argc > 2) {
        for ($x = 2; $x < $a->argc; $x++) {
            if ($a->argv[$x] == 'converse') {
                $converse = true;
            }
            if ($a->argv[$x] == 'starred') {
                $starred = true;
            }
        }
    }
    $sql_extra = " AND `allow_cid` = '' AND `allow_gid` = '' AND `deny_cid`  = '' AND `deny_gid`  = '' ";
    $r = q("SELECT `contact`.*, `user`.`uid` AS `user_uid`, `user`.`nickname`, `user`.`timezone`\n\t\tFROM `contact` LEFT JOIN `user` ON `user`.`uid` = `contact`.`uid`\n\t\tWHERE `contact`.`self` = 1 AND `user`.`nickname` = '%s' LIMIT 1", dbesc($owner_nick));
    if (!count($r)) {
        killme();
    }
    $owner = $r[0];
    $owner_id = $owner['user_uid'];
    $owner_nick = $owner['nickname'];
    $birthday = feed_birthday($owner_id, $owner['timezone']);
    if (!$public_feed) {
        $sql_extra = '';
        switch ($direction) {
            case -1:
                $sql_extra = sprintf(" AND `issued-id` = '%s' ", dbesc($dfrn_id));
                $my_id = $dfrn_id;
                break;
            case 0:
                $sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
                $my_id = '1:' . $dfrn_id;
                break;
            case 1:
                $sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
                $my_id = '0:' . $dfrn_id;
                break;
            default:
                return false;
                break;
                // NOTREACHED
        }
        $r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `contact`.`uid` = %d {$sql_extra} LIMIT 1", intval($owner_id));
        if (!count($r)) {
            killme();
        }
        $contact = $r[0];
        $groups = init_groups_visitor($contact['id']);
        if (count($groups)) {
            for ($x = 0; $x < count($groups); $x++) {
                $groups[$x] = '<' . intval($groups[$x]) . '>';
            }
            $gs = implode('|', $groups);
        } else {
            $gs = '<<>>';
        }
        // Impossible to match
        $sql_extra = sprintf(" \n\t\t\tAND ( `allow_cid` = '' OR     `allow_cid` REGEXP '<%d>' ) \n\t\t\tAND ( `deny_cid`  = '' OR NOT `deny_cid`  REGEXP '<%d>' ) \n\t\t\tAND ( `allow_gid` = '' OR     `allow_gid` REGEXP '%s' )\n\t\t\tAND ( `deny_gid`  = '' OR NOT `deny_gid`  REGEXP '%s') \n\t\t", intval($contact['id']), intval($contact['id']), dbesc($gs), dbesc($gs));
    }
    if ($public_feed) {
        $sort = 'DESC';
    } else {
        $sort = 'ASC';
    }
    if (!strlen($last_update)) {
        $last_update = 'now -30 days';
    }
    if ($public_feed) {
        if (!$converse) {
            $sql_extra .= " AND `contact`.`self` = 1 ";
        }
    }
    $check_date = datetime_convert('UTC', 'UTC', $last_update, 'Y-m-d H:i:s');
    $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, \n\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, \n\t\t`contact`.`name-date`, `contact`.`uri-date`, `contact`.`avatar-date`,\n\t\t`contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`, \n\t\t`contact`.`id` AS `contact-id`, `contact`.`uid` AS `contact-uid`,\n\t\t`sign`.`signed_text`, `sign`.`signature`, `sign`.`signer`\n\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\tLEFT JOIN `sign` ON `sign`.`iid` = `item`.`id`\n\t\tWHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`parent` != 0 \n\t\tAND `item`.`wall` = 1 AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\tAND ( `item`.`edited` > '%s' OR `item`.`changed` > '%s' )\n\t\t{$sql_extra}\n\t\tORDER BY `parent` %s, `created` ASC LIMIT 0, 300", intval($owner_id), dbesc($check_date), dbesc($check_date), dbesc($sort));
    // Will check further below if this actually returned results.
    // We will provide an empty feed if that is the case.
    $items = $r;
    $feed_template = get_markup_template($dfrn_id ? 'atom_feed_dfrn.tpl' : 'atom_feed.tpl');
    $atom = '';
    $hubxml = feed_hublinks();
    $salmon = feed_salmonlinks($owner_nick);
    $atom .= replace_macros($feed_template, array('$version' => xmlify(FRIENDICA_VERSION), '$feed_id' => xmlify($a->get_baseurl() . '/profile/' . $owner_nick), '$feed_title' => xmlify($owner['name']), '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)), '$hub' => $hubxml, '$salmon' => $salmon, '$name' => xmlify($owner['name']), '$profile_page' => xmlify($owner['url']), '$photo' => xmlify($owner['photo']), '$thumb' => xmlify($owner['thumb']), '$picdate' => xmlify(datetime_convert('UTC', 'UTC', $owner['avatar-date'] . '+00:00', ATOM_TIME)), '$uridate' => xmlify(datetime_convert('UTC', 'UTC', $owner['uri-date'] . '+00:00', ATOM_TIME)), '$namdate' => xmlify(datetime_convert('UTC', 'UTC', $owner['name-date'] . '+00:00', ATOM_TIME)), '$birthday' => strlen($birthday) ? '<dfrn:birthday>' . xmlify($birthday) . '</dfrn:birthday>' : ''));
    call_hooks('atom_feed', $atom);
    if (!count($items)) {
        call_hooks('atom_feed_end', $atom);
        $atom .= '</feed>' . "\r\n";
        return $atom;
    }
    foreach ($items as $item) {
        // public feeds get html, our own nodes use bbcode
        if ($public_feed) {
            $type = 'html';
            // catch any email that's in a public conversation and make sure it doesn't leak
            if ($item['private']) {
                continue;
            }
        } else {
            $type = 'text';
        }
        $atom .= atom_entry($item, $type, null, $owner, true);
    }
    call_hooks('atom_feed_end', $atom);
    $atom .= '</feed>' . "\r\n";
    return $atom;
}
Example #11
0
function profile_content(&$a, $update = false)
{
    require_once "include/bbcode.php";
    require_once 'include/security.php';
    $groups = array();
    $tab = 'posts';
    if (remote_user()) {
        $contact_id = $_SESSION['visitor_id'];
        $groups = init_groups_visitor($contact_id);
        $r = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", intval($contact_id));
        if (count($r)) {
            $contact = $r[0];
        }
    } else {
        if (local_user()) {
            $contact_id = $_SESSION['cid'];
            $contact = $a->contact;
        }
    }
    $a->profile['profile_uid'] = 1;
    if (!$update) {
        if (x($_GET, 'tab')) {
            $tab = notags(trim($_GET['tab']));
        }
        $tpl = file_get_contents('view/profile_tabs.tpl');
        $o .= replace_macros($tpl, array('$url' => $a->get_baseurl() . '/' . $a->cmd, '$phototab' => $a->get_baseurl() . '/photos/' . $a->profile['nickname']));
        if ($tab == 'profile') {
            require_once 'view/profile_advanced.php';
            return $o;
        }
        if (can_write_wall($a, 1)) {
            $tpl = file_get_contents('view/jot-header.tpl');
            $a->page['htmlhead'] .= replace_macros($tpl, array('$baseurl' => $a->get_baseurl()));
            require_once 'view/acl_selectors.php';
            $tpl = file_get_contents("view/jot.tpl");
            if (is_array($a->user) && (strlen($a->user['allow_cid']) || strlen($a->user['allow_gid']) || strlen($a->user['deny_cid']) || strlen($a->user['deny_gid']))) {
                $lockstate = 'lock';
            } else {
                $lockstate = 'unlock';
            }
            $o .= replace_macros($tpl, array('$baseurl' => $a->get_baseurl(), '$defloc' => $_SESSION['uid'] == 1 ? $a->user['default-location'] : '', '$return_path' => $a->cmd, '$visitor' => $_SESSION['uid'] == 1 ? 'block' : 'none', '$lockstate' => $lockstate, '$acl' => $_SESSION['uid'] == 1 ? populate_acl($a->user) : '', '$profile_uid' => 1));
        }
        if ($tab == 'posts' && !$a->pager['start']) {
            $o .= '<div id="live-profile"></div>' . "\r\n";
        }
    }
    // default permissions - anonymous user
    $sql_extra = " AND `allow_cid` = '' AND `allow_gid` = '' AND `deny_cid` = '' AND `deny_gid` = '' ";
    // Profile owner - everything is visible
    if (local_user()) {
        $sql_extra = '';
        // Oh - while we're here... reset the Unseen messages
        $r = q("UPDATE `item` SET `unseen` = 0 WHERE `type` != 'remote' AND `unseen` = 1 ");
    } elseif (remote_user()) {
        $gs = '<<>>';
        // should be impossible to match
        if (count($groups)) {
            foreach ($groups as $g) {
                $gs .= '|<' . intval($g) . '>';
            }
        }
        $sql_extra = sprintf(" AND ( `allow_cid` = '' OR `allow_cid` REGEXP '<%d>' ) \n\t\t\t  AND ( `deny_cid`  = '' OR  NOT `deny_cid` REGEXP '<%d>' ) \n\t\t\t  AND ( `allow_gid` = '' OR `allow_gid` REGEXP '%s' )\n\t\t\t  AND ( `deny_gid`  = '' OR NOT `deny_gid` REGEXP '%s') ", intval($_SESSION['visitor_id']), intval($_SESSION['visitor_id']), dbesc($gs), dbesc($gs));
    }
    $r = q("SELECT COUNT(*) AS `total`\n\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\tWHERE `item`.`visible` = 1 AND `item`.`deleted` = 0\n\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\tAND `item`.`parent` IN ( SELECT `parent` FROM `item` WHERE `id` = `parent` AND `type` != 'remote') \n\t\t{$sql_extra} ");
    if (count($r)) {
        $a->set_pager_total($r[0]['total']);
    }
    $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, \n\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, \n\t\t`contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`, \n\t\t`contact`.`id` AS `cid`\n\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\tWHERE `item`.`visible` = 1 AND `item`.`deleted` = 0\n\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\tAND `item`.`parent` IN ( SELECT `parent` FROM `item` WHERE `id` = `parent` AND `type` != 'remote') \n\t\t{$sql_extra}\n\t\tORDER BY `parent` DESC, `id` ASC LIMIT %d ,%d ", intval($a->pager['start']), intval($a->pager['itemspage']));
    $cmnt_tpl = file_get_contents('view/comment_item.tpl');
    $tpl = file_get_contents('view/wall_item.tpl');
    if ($update) {
        $return_url = $_SESSION['return_url'];
    } else {
        $return_url = $_SESSION['return_url'] = $a->cmd;
    }
    if (count($r)) {
        foreach ($r as $item) {
            $comment = '';
            $template = $tpl;
            $redirect_url = $a->get_baseurl() . '/redir/' . $item['cid'];
            if (can_write_wall($a, 1)) {
                if ($item['last-child']) {
                    $comment = replace_macros($cmnt_tpl, array('$return_path' => $_SESSION['return_url'], '$type' => 'wall-comment', '$id' => $item['item_id'], '$parent' => $item['parent'], '$profile_uid' => 1, '$mylink' => $contact['url'], '$mytitle' => t('Me'), '$myphoto' => $contact['thumb'], '$ww' => ''));
                }
            }
            $profile_url = $item['url'];
            // This is my profile but I'm not the author of this post/comment. If it's somebody that's a fan or mutual friend,
            // I can go directly to their profile as an authenticated guest.
            if (local_user() && ($item['rel'] == DIRECTION_IN || $item['rel'] == DIRECTION_BOTH) && !$item['self']) {
                $profile_url = $redirect_url;
            }
            // We received this post via a remote feed. It's either a wall-to-wall or a remote comment. The author is
            // known to us and is reflected in the contact-id for this item. We can use the contact url or redirect rather than
            // use the link in the feed. This is different than on the network page where we may not know the author.
            $profile_name = strlen($item['author-name']) ? $item['author-name'] : $item['name'];
            $profile_avatar = strlen($item['author-avatar']) ? $item['author-avatar'] : $item['thumb'];
            $profile_link = $profile_url;
            $drop = '';
            if ($item['contact-id'] == $_SESSION['visitor_id'] || $_SESSION['uid']) {
                $drop = replace_macros(file_get_contents('view/wall_item_drop.tpl'), array('$id' => $item['id']));
            }
            $o .= replace_macros($template, array('$id' => $item['item_id'], '$profile_url' => $profile_link, '$name' => $profile_name, '$thumb' => $profile_avatar, '$title' => $item['title'], '$body' => bbcode($item['body']), '$ago' => relative_date($item['created']), '$location' => $item['location'] ? '<a target="map" href="http://maps.google.com/?q=' . urlencode($item['location']) . '">' . $item['location'] . '</a>' : '', '$indent' => $item['parent'] != $item['item_id'] ? ' comment' : '', '$drop' => $drop, '$comment' => $comment));
        }
    }
    if ($update) {
        return $o;
    }
    $o .= paginate($a);
    return $o;
}
Example #12
0
function photo_init(&$a)
{
    switch ($a->argc) {
        case 3:
            $person = $a->argv[2];
            $type = $a->argv[1];
            break;
        case 2:
            $photo = $a->argv[1];
            break;
        case 1:
        default:
            killme();
            return;
            // NOTREACHED
    }
    if (x($type)) {
        switch ($type) {
            case 'profile':
                $resolution = 4;
                break;
            case 'avatar':
            default:
                $resolution = 5;
                break;
        }
        $uid = str_replace('.jpg', '', $person);
        $r = q("SELECT * FROM `photo` WHERE `scale` = %d AND `profile` = 1 LIMIT 1", intval($resolution));
        if (count($r)) {
            $data = $r[0]['data'];
        }
        if (x($data) === false) {
            $data = file_get_contents($resolution == 5 ? 'images/default-profile-sm.jpg' : 'images/default-profile.jpg');
        }
    } else {
        $resolution = 0;
        $photo = str_replace('.jpg', '', $photo);
        if (substr($photo, -2, 1) == '-') {
            $resolution = intval(substr($photo, -1, 1));
            $photo = substr($photo, 0, -2);
        }
        $sql_extra = " AND `allow_cid` = '' AND `allow_gid` = '' AND `deny_cid` = '' AND `deny_gid` = '' ";
        if (local_user()) {
            // Owner can always see his/her photos
            $sql_extra = '';
        } elseif (remote_user()) {
            // authenticated visitor - here lie dragons
            $groups = init_groups_visitor($_SESSION['visitor_id']);
            $gs = '<<>>';
            // should be impossible to match
            if (count($groups)) {
                foreach ($groups as $g) {
                    $gs .= '|<' . intval($g) . '>';
                }
            }
            $sql_extra = sprintf(" AND ( `allow_cid` = '' OR `allow_cid` REGEXP '<%d>' ) \n\t\t\t\t\t  AND ( `deny_cid`  = '' OR  NOT `deny_cid` REGEXP '<%d>' ) \n\t\t\t\t\t  AND ( `allow_gid` = '' OR `allow_gid` REGEXP '%s' )\n\t\t\t\t\t  AND ( `deny_gid`  = '' OR NOT `deny_gid` REGEXP '%s') ", intval($_SESSION['visitor_id']), intval($_SESSION['visitor_id']), dbesc($gs), dbesc($gs));
        }
        // Now we'll see if we can access the photo
        $r = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' AND `scale` = %d {$sql_extra} LIMIT 1", dbesc($photo), intval($resolution));
        if (count($r)) {
            $data = $r[0]['data'];
        }
    }
    if (x($data) === false) {
        killme();
        return;
        // NOTREACHED
    }
    header("Content-type: image/jpeg");
    header('Expires: ' . datetime_convert('UTC', 'UTC', 'now + 3 months', 'D, d M Y H:i:s' . ' GMT'));
    //	header("Cache-Control: max-age=36000, only-if-cached");
    echo $data;
    killme();
    return;
    //NOTREACHED
}
Example #13
0
function display_content(&$a)
{
    if (get_config('system', 'block_public') && !local_user() && !remote_user()) {
        notice(t('Public access denied.') . EOL);
        return;
    }
    require_once "include/bbcode.php";
    require_once 'include/security.php';
    require_once 'include/conversation.php';
    require_once 'include/acl_selectors.php';
    $o = '<div id="live-display"></div>' . "\r\n";
    $a->page['htmlhead'] .= <<<EOT
<script>
\$(document).ready(function() {
\t\$(".comment-edit-wrapper textarea").contact_autocomplete(baseurl+"/acl");
\t// make auto-complete work in more places
\t\$(".wall-item-comment-wrapper textarea").contact_autocomplete(baseurl+"/acl");
});
</script>
EOT;
    $nick = $a->argc > 1 ? $a->argv[1] : '';
    profile_load($a, $nick);
    $item_id = $a->argc > 2 ? intval($a->argv[2]) : 0;
    if (!$item_id) {
        $a->error = 404;
        notice(t('Item not found.') . EOL);
        return;
    }
    $groups = array();
    $contact = null;
    $remote_contact = false;
    if (remote_user()) {
        $contact_id = $_SESSION['visitor_id'];
        $groups = init_groups_visitor($contact_id);
        $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($contact_id), intval($a->profile['uid']));
        if (count($r)) {
            $contact = $r[0];
            $remote_contact = true;
        }
    }
    if (!$remote_contact) {
        if (local_user()) {
            $contact_id = $_SESSION['cid'];
            $contact = $a->contact;
        }
    }
    $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1", intval($a->profile['uid']));
    if (count($r)) {
        $a->page_contact = $r[0];
    }
    $is_owner = local_user() && local_user() == $a->profile['profile_uid'] ? true : false;
    if ($a->profile['hidewall'] && !$is_owner && !$remote_contact) {
        notice(t('Access to this profile has been restricted.') . EOL);
        return;
    }
    if ($is_owner) {
        $celeb = $a->user['page-flags'] == PAGE_SOAPBOX || $a->user['page-flags'] == PAGE_COMMUNITY ? true : false;
    }
    $x = array('is_owner' => true, 'allow_location' => $a->user['allow_location'], 'default_location' => $a->user['default-location'], 'nickname' => $a->user['nickname'], 'lockstate' => is_array($a->user) && (strlen($a->user['allow_cid']) || strlen($a->user['allow_gid']) || strlen($a->user['deny_cid']) || strlen($a->user['deny_gid'])) ? 'lock' : 'unlock', 'acl' => populate_acl($a->user, $celeb), 'bang' => '', 'visitor' => 'block', 'profile_uid' => local_user());
    $o .= status_editor($a, $x, 0, true);
    $sql_extra = item_permissions_sql($a->profile['uid'], $remote_contact, $groups);
    $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, \n\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,\n\t\t`contact`.`network`, `contact`.`thumb`, `contact`.`self`, `contact`.`writable`, \n\t\t`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`\n\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\tWHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0\n\t\tand `item`.`moderated` = 0\n\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\tAND `item`.`parent` = ( SELECT `parent` FROM `item` WHERE ( `id` = '%s' OR `uri` = '%s' ))\n\t\t{$sql_extra}\n\t\tORDER BY `parent` DESC, `gravity` ASC, `id` ASC ", intval($a->profile['uid']), dbesc($item_id), dbesc($item_id));
    if (count($r)) {
        if (local_user() && local_user() == $a->profile['uid']) {
            q("UPDATE `item` SET `unseen` = 0 \n\t\t\t\tWHERE `parent` = %d AND `unseen` = 1", intval($r[0]['parent']));
        }
        $o .= conversation($a, $r, 'display', false);
    } else {
        $r = q("SELECT `id` FROM `item` WHERE `id` = '%s' OR `uri` = '%s' LIMIT 1", dbesc($item_id), dbesc($item_id));
        if (count($r)) {
            if ($r[0]['deleted']) {
                notice(t('Item has been removed.') . EOL);
            } else {
                notice(t('Permission denied.') . EOL);
            }
        } else {
            notice(t('Item not found.') . EOL);
        }
    }
    return $o;
}
Example #14
0
function photos_content(&$a)
{
    // URLs:
    // photos/name
    // photos/name/upload
    // photos/name/album/xxxxx
    // photos/name/album/xxxxx/edit
    // photos/name/image/xxxxx
    // photos/name/image/xxxxx/edit
    if (!x($a->data, 'user')) {
        notice(t('No photos selected') . EOL);
        return;
    }
    $_SESSION['photo_return'] = $a->cmd;
    //
    // Parse arguments
    //
    if ($a->argc > 3) {
        $datatype = $a->argv[2];
        $datum = $a->argv[3];
    } elseif ($a->argc > 2 && $a->argv[2] == 'upload') {
        $datatype = 'upload';
    } else {
        $datatype = 'summary';
    }
    if ($a->argc > 4) {
        $cmd = $a->argv[4];
    } else {
        $cmd = 'view';
    }
    //
    // Setup permissions structures
    //
    $owner_uid = $a->data['user']['uid'];
    if (remote_user()) {
        $contact_id = $_SESSION['visitor_id'];
        $groups = init_groups_visitor($contact_id);
    }
    // default permissions - anonymous user
    $sql_extra = " AND `allow_cid` = '' AND `allow_gid` = '' AND `deny_cid` = '' AND `deny_gid` = '' ";
    // Profile owner - everything is visible
    if (local_user() && $_SESSION['uid'] == $owner_uid) {
        $sql_extra = '';
    } elseif (remote_user()) {
        // authenticated visitor - here lie dragons
        $gs = '<<>>';
        // should be impossible to match
        if (count($groups)) {
            foreach ($groups as $g) {
                $gs .= '|<' . intval($g) . '>';
            }
        }
        $sql_extra = sprintf(" AND ( `allow_cid` = '' OR `allow_cid` REGEXP '<%d>' ) \n\t\t\t  AND ( `deny_cid`  = '' OR  NOT `deny_cid` REGEXP '<%d>' ) \n\t\t\t  AND ( `allow_gid` = '' OR `allow_gid` REGEXP '%s' )\n\t\t\t  AND ( `deny_gid`  = '' OR NOT `deny_gid` REGEXP '%s') ", intval($_SESSION['visitor_id']), intval($_SESSION['visitor_id']), dbesc($gs), dbesc($gs));
    }
    //
    // dispatch request
    //
    if ($datatype == 'upload') {
        if (!(local_user() && $_SESSION['uid'] == $a->data['user']['uid'])) {
            notice(t('Permission denied.'));
            return;
        }
        $albumselect = '<select id="photos-upload-album-select" name="album" size="4">';
        $albumselect .= '<option value="" selected="selected" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option>';
        if (count($a->data['albums'])) {
            foreach ($a->data['albums'] as $album) {
                if ($album['album'] == '' || $album['album'] == t('Contact Photos')) {
                    continue;
                }
                $albumselect .= '<option value="' . $album['album'] . '">' . $album['album'] . '</option>';
            }
        }
        $albumselect .= '</select>';
        $tpl = file_get_contents('view/photos_upload.tpl');
        $o .= replace_macros($tpl, array('$pagename' => t('Upload Photos'), '$sessid' => session_id(), '$newalbum' => t('New album name: '), '$existalbumtext' => t('or existing album name: '), '$filestext' => t('Select files to upload: '), '$albumselect' => $albumselect, '$permissions' => t('Permissions'), '$aclselect' => populate_acl($a->user), '$archive' => $a->get_baseurl() . '/jumploader_z.jar', '$nojava' => t('Use the following controls only if the Java uploader (above) fails to launch.'), '$uploadurl' => $a->get_baseurl() . '/photos', '$submit' => t('Submit')));
        return $o;
    }
    if ($datatype == 'album') {
        $album = hex2bin($datum);
        $r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `album` = '%s' \n\t\t\t{$sql_extra} GROUP BY `resource-id`", dbesc($album));
        if (count($r)) {
            $a->set_pager_total(count($r));
        }
        $r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `album` = '%s' \n\t\t\t{$sql_extra} GROUP BY `resource-id` ORDER BY `created` DESC LIMIT %d , %d", dbesc($album), intval($a->pager['start']), intval($a->pager['itemspage']));
        $o .= '<h3>' . $album . '</h3>';
        if ($cmd == 'edit') {
            if ($album != t('Profile Photos') && $album != t('Contact Photos')) {
                if (local_user() && $_SESSION['uid'] == $a->data['user']['uid']) {
                    $edit_tpl = file_get_contents('view/album_edit.tpl');
                    $o .= replace_macros($edit_tpl, array('$nametext' => t('New album name: '), '$album' => $album, '$hexalbum' => bin2hex($album), '$submit' => t('Submit'), '$dropsubmit' => t('Delete Album')));
                }
            }
        } else {
            if ($album != t('Profile Photos') && $album != t('Contact Photos')) {
                if (local_user() && $_SESSION['uid'] == $a->data['user']['uid']) {
                    $o .= '<div id="album-edit-link"><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album) . '/edit' . '">' . t('Edit Album') . '</a></div>';
                }
            }
        }
        $tpl = file_get_contents('view/photo_album.tpl');
        if (count($r)) {
            foreach ($r as $rr) {
                $o .= replace_macros($tpl, array('$id' => $rr['id'], '$photolink' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id'], '$phototitle' => t('View Photo'), '$imgsrc' => $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . $rr['scale'] . '.jpg', '$imgalt' => $rr['filename']));
            }
        }
        $o .= '<div id="photo-album-end"></div>';
        return $o;
    }
    if ($datatype == 'image') {
        require_once 'security.php';
        require_once 'bbcode.php';
        // fetch image, item containing image, then comments
        $ph = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' \n\t\t\t{$sql_extra} ORDER BY `scale` ASC ", dbesc($datum));
        if (!count($ph)) {
            notice(t('Photo not available') . EOL);
            return;
        }
        if (count($ph) == 1) {
            $hires = $lores = $ph[0];
        }
        if (count($ph) > 1) {
            if ($ph[1]['scale'] == 2) {
                // original is 640 or less, we can display it directly
                $hires = $lores = $ph[0];
            } else {
                $hires = $ph[0];
                $lores = $ph[1];
            }
        }
        $o .= '<h3>' . '<a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($ph[0]['album']) . '">' . $ph[0]['album'] . '</a></h3>';
        if (local_user()) {
            $o .= '<div id="photo-edit-link-wrap" ><a id="photo-edit-link" href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $datum . '/edit' . '">' . t('Edit photo') . '</a></div>';
        }
        $o .= '<a href="' . $a->get_baseurl() . '/photo/' . $hires['resource-id'] . '-' . $hires['scale'] . '.jpg" title="' . t('View Full Size') . '" ><img src="' . $a->get_baseurl() . '/photo/' . $lores['resource-id'] . '-' . $lores['scale'] . '.jpg' . '" /></a>';
        // Do we have an item for this photo?
        $i1 = q("SELECT * FROM `item` WHERE `resource-id` = '%s' {$sql_extra} LIMIT 1", dbesc($datum));
        if (count($i1)) {
            $r = q("SELECT COUNT(*) AS `total`\n\t\t\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\t\tWHERE `parent-uri` = '%s' AND `uri` != '%s' AND `item`.`deleted` = 0\n\t\t\t\tAND NOT `item`.`type` IN ( 'remote', 'net-comment') \n\t\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 \n\t\t\t\t{$sql_extra} ", dbesc($i1[0]['uri']), dbesc($i1[0]['uri']));
            if (count($r)) {
                $a->set_pager_total($r[0]['total']);
            }
            $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, \n\t\t\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, \n\t\t\t\t`contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`, \n\t\t\t\t`contact`.`id` AS `cid`\n\t\t\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\t\tWHERE `parent-uri` = '%s' AND `uri` != '%s' AND `item`.`deleted` = 0\n\t\t\t\tAND NOT `item`.`type` IN ( 'remote', 'net-comment') \n\t\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\t\t{$sql_extra}\n\t\t\t\tORDER BY `parent` DESC, `id` ASC LIMIT %d ,%d ", dbesc($i1[0]['uri']), dbesc($i1[0]['uri']), intval($a->pager['start']), intval($a->pager['itemspage']));
        }
        $o .= '<div id="photo-caption" >' . $ph[0]['desc'] . '</div>';
        if (count($i1) && strlen($i1[0]['tag'])) {
            // parse tags and add links
            $o .= '<div id="in-this-photo-text">' . t('In this photo: ') . '</div>';
            $o .= '<div id="in-this-photo">' . $i1[0]['tag'] . '</div>';
        }
        if ($cmd == 'edit') {
            $edit_tpl = file_get_contents('view/photo_edit.tpl');
            $o .= replace_macros($edit_tpl, array('$id' => $ph[0]['id'], '$resource_id' => $ph[0]['resource-id'], '$capt_label' => t('Caption'), '$caption' => $ph[0]['desc'], '$tag_label' => t('Tags'), '$tags' => $i1[0]['tag'], '$item_id' => count($i1) ? $i1[0]['id'] : 0, '$submit' => t('Submit'), '$delete' => t('Delete Photo')));
        }
        if (count($i1)) {
            // pull out how many people like the photo
            $cmnt_tpl = file_get_contents('view/comment_item.tpl');
            $tpl = file_get_contents('view/photo_item.tpl');
            $return_url = $a->cmd;
            if (can_write_wall($a, $a->data['user']['uid'])) {
                if ($i1[0]['last-child']) {
                    $o .= replace_macros($cmnt_tpl, array('$return_path' => $return_url, '$type' => 'wall-comment', '$id' => $i1[0]['id'], '$parent' => $i1[0]['id'], '$profile_uid' => $a->data['user']['uid'], '$ww' => ''));
                }
            }
            // display comments
            if (count($r)) {
                foreach ($r as $item) {
                    $comment = '';
                    $template = $tpl;
                    $redirect_url = $a->get_baseurl() . '/redir/' . $item['cid'];
                    if (can_write_wall($a, $a->data['user']['uid'])) {
                        if ($item['last-child']) {
                            $comment = replace_macros($cmnt_tpl, array('$return_path' => $return_url, '$type' => 'wall-comment', '$id' => $item['item_id'], '$parent' => $item['parent'], '$profile_uid' => $a->data['user']['uid'], '$ww' => ''));
                        }
                    }
                    $profile_url = $item['url'];
                    if (local_user() && ($item['rel'] == DIRECTION_IN || $item['rel'] == DIRECTION_BOTH) && !$item['self']) {
                        $profile_url = $redirect_url;
                    }
                    $profile_name = strlen($item['author-name']) ? $item['author-name'] : $item['name'];
                    $profile_avatar = strlen($item['author-avatar']) ? $item['author-avatar'] : $item['thumb'];
                    $profile_link = $profile_url;
                    $drop = '';
                    if ($item['contact-id'] == $_SESSION['visitor_id'] || local_user()) {
                        $drop = replace_macros(file_get_contents('view/wall_item_drop.tpl'), array('$id' => $item['id']));
                    }
                    $o .= replace_macros($template, array('$id' => $item['item_id'], '$profile_url' => $profile_link, '$name' => $profile_name, '$thumb' => $profile_avatar, '$title' => $item['title'], '$body' => bbcode($item['body']), '$ago' => relative_date($item['created']), '$indent' => $item['parent'] != $item['item_id'] ? ' comment' : '', '$drop' => $drop, '$comment' => $comment));
                }
            }
            $o .= paginate($a);
        }
        return $o;
    }
    // Default - show recent photos with upload link (if applicable)
    $r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `album` != '%s' \n\t\t{$sql_extra} GROUP BY `resource-id`", dbesc(t('Contact Photos')));
    if (count($r)) {
        $a->set_pager_total(count($r));
    }
    $r = q("SELECT `resource-id`, `album`, max(`scale`) AS `scale` FROM `photo` WHERE `album` != '%s' \n\t\t{$sql_extra} GROUP BY `resource-id` ORDER BY `created` DESC LIMIT %d , %d", dbesc(t('Contact Photos')), intval($a->pager['start']), intval($a->pager['itemspage']));
    $o .= '<h3>' . t('Recent Photos') . '</h3>';
    if (local_user()) {
        $o .= '<div id="photo-top-links"><a id="photo-top-upload-link" href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/upload' . '">' . t('Upload New Photos') . '</a></div>';
    }
    $tpl = file_get_contents('view/photo_top.tpl');
    if (count($r)) {
        foreach ($r as $rr) {
            $o .= replace_macros($tpl, array('$id' => $rr['id'], '$photolink' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id'], '$phototitle' => t('View Photo'), '$imgsrc' => $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . $rr['scale'] . '.jpg', '$albumlink' => $a->get_baseurl . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($rr['album']), '$albumname' => $rr['album'], '$albumalt' => t('View Album'), '$imgalt' => $rr['filename']));
        }
        $o .= '<div id="photo-top-end"></div>';
    }
    return $o;
}
Example #15
0
 function get()
 {
     $noid = get_config('system', 'disable_openid');
     if ($noid) {
         goaway(z_root());
     }
     logger('mod_openid ' . print_r($_REQUEST, true), LOGGER_DATA);
     if (x($_REQUEST, 'openid_mode')) {
         $openid = new LightOpenID(z_root());
         if ($openid->validate()) {
             logger('openid: validate');
             $authid = normalise_openid($_REQUEST['openid_identity']);
             if (!strlen($authid)) {
                 logger(t('OpenID protocol error. No ID returned.') . EOL);
                 goaway(z_root());
             }
             $x = match_openid($authid);
             if ($x) {
                 $r = q("select * from channel where channel_id = %d limit 1", intval($x));
                 if ($r) {
                     $y = q("select * from account where account_id = %d limit 1", intval($r[0]['channel_account_id']));
                     if ($y) {
                         foreach ($y as $record) {
                             if ($record['account_flags'] == ACCOUNT_OK || $record['account_flags'] == ACCOUNT_UNVERIFIED) {
                                 logger('mod_openid: openid success for ' . $x[0]['channel_name']);
                                 $_SESSION['uid'] = $r[0]['channel_id'];
                                 $_SESSION['account_id'] = $r[0]['channel_account_id'];
                                 $_SESSION['authenticated'] = true;
                                 authenticate_success($record, $r[0], true, true, true, true);
                                 goaway(z_root());
                             }
                         }
                     }
                 }
             }
             // Successful OpenID login - but we can't match it to an existing account.
             // See if they've got an xchan
             $r = q("select * from xconfig left join xchan on xchan_hash = xconfig.xchan where cat = 'system' and k = 'openid' and v = '%s' limit 1", dbesc($authid));
             if ($r) {
                 $_SESSION['authenticated'] = 1;
                 $_SESSION['visitor_id'] = $r[0]['xchan_hash'];
                 $_SESSION['my_url'] = $r[0]['xchan_url'];
                 $_SESSION['my_address'] = $r[0]['xchan_addr'];
                 $arr = array('xchan' => $r[0], 'session' => $_SESSION);
                 call_hooks('magic_auth_openid_success', $arr);
                 \App::set_observer($r[0]);
                 require_once 'include/security.php';
                 \App::set_groups(init_groups_visitor($_SESSION['visitor_id']));
                 info(sprintf(t('Welcome %s. Remote authentication successful.'), $r[0]['xchan_name']));
                 logger('mod_openid: remote auth success from ' . $r[0]['xchan_addr']);
                 if ($_SESSION['return_url']) {
                     goaway($_SESSION['return_url']);
                 }
                 goaway(z_root());
             }
             // no xchan...
             // create one.
             // We should probably probe the openid url and figure out if they have any kind of
             // social presence we might be able to scrape some identifying info from.
             $name = $authid;
             $url = trim($_REQUEST['openid_identity'], '/');
             if (strpos($url, 'http') === false) {
                 $url = 'https://' . $url;
             }
             $pphoto = z_root() . '/' . get_default_profile_photo();
             $parsed = @parse_url($url);
             if ($parsed) {
                 $host = $parsed['host'];
             }
             $attr = $openid->getAttributes();
             if (is_array($attr) && count($attr)) {
                 foreach ($attr as $k => $v) {
                     if ($k === 'namePerson/friendly') {
                         $nick = notags(trim($v));
                     }
                     if ($k === 'namePerson/first') {
                         $first = notags(trim($v));
                     }
                     if ($k === 'namePerson') {
                         $name = notags(trim($v));
                     }
                     if ($k === 'contact/email') {
                         $addr = notags(trim($v));
                     }
                     if ($k === 'media/image/aspect11') {
                         $photosq = trim($v);
                     }
                     if ($k === 'media/image/default') {
                         $photo_other = trim($v);
                     }
                 }
             }
             if (!$nick) {
                 if ($first) {
                     $nick = $first;
                 } else {
                     $nick = $name;
                 }
             }
             require_once 'library/urlify/URLify.php';
             $x = strtolower(\URLify::transliterate($nick));
             if ($nick & $host) {
                 $addr = $nick . '@' . $host;
             }
             $network = 'unknown';
             if ($photosq) {
                 $pphoto = $photosq;
             } elseif ($photo_other) {
                 $pphoto = $photo_other;
             }
             $mimetype = guess_image_type($pphoto);
             $x = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_mimetype,\n\t                xchan_photo_l, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_photo_date, \n\t\t\t\t\txchan_name_date, xchan_hidden)\n\t                values ( '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 1) ", dbesc($url), dbesc(''), dbesc(''), dbesc(''), dbesc($mimetype), dbesc($pphoto), dbesc($addr), dbesc($url), dbesc(''), dbesc(''), dbesc(''), dbesc($name), dbesc($network), dbesc(datetime_convert()), dbesc(datetime_convert()));
             if ($x) {
                 $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($url));
                 if ($r) {
                     $photos = import_xchan_photo($pphoto, $url);
                     if ($photos) {
                         $z = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', \n\t\t\t\t\t\t\t\txchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", dbesc(datetime_convert()), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($url));
                     }
                     set_xconfig($url, 'system', 'openid', $authid);
                     $_SESSION['authenticated'] = 1;
                     $_SESSION['visitor_id'] = $r[0]['xchan_hash'];
                     $_SESSION['my_url'] = $r[0]['xchan_url'];
                     $_SESSION['my_address'] = $r[0]['xchan_addr'];
                     $arr = array('xchan' => $r[0], 'session' => $_SESSION);
                     call_hooks('magic_auth_openid_success', $arr);
                     \App::set_observer($r[0]);
                     info(sprintf(t('Welcome %s. Remote authentication successful.'), $r[0]['xchan_name']));
                     logger('mod_openid: remote auth success from ' . $r[0]['xchan_addr']);
                     if ($_SESSION['return_url']) {
                         goaway($_SESSION['return_url']);
                     }
                     goaway(z_root());
                 }
             }
         }
     }
     notice(t('Login failed.') . EOL);
     goaway(z_root());
     // NOTREACHED
 }
Example #16
0
File: auth.php Project: Mauru/red
             new_cookie(60 * 60 * 24);
             // one day
             $_SESSION['last_login_date'] = datetime_convert();
             unset($_SESSION['visitor_id']);
             // no longer a visitor
             authenticate_success($x[0], true, true);
         }
     }
     $r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where xchan_hash = '%s' limit 1", dbesc($_SESSION['visitor_id']));
     if ($r) {
         get_app()->set_observer($r[0]);
     } else {
         unset($_SESSION['visitor_id']);
         unset($_SESSION['authenticated']);
     }
     $a->set_groups(init_groups_visitor($_SESSION['visitor_id']));
 }
 // already logged in user returning
 if (x($_SESSION, 'uid') || x($_SESSION, 'account_id')) {
     // first check if we're enforcing that sessions can't change IP address
     if ($_SESSION['addr'] && $_SESSION['addr'] != $_SERVER['REMOTE_ADDR']) {
         logger('SECURITY: Session IP address changed: ' . $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']);
         $partial1 = substr($_SESSION['addr'], 0, strrpos($_SESSION['addr'], '.'));
         $partial2 = substr($_SERVER['REMOTE_ADDR'], 0, strrpos($_SERVER['REMOTE_ADDR'], '.'));
         $paranoia = intval(get_pconfig($_SESSION['uid'], 'system', 'paranoia'));
         if (!$paranoia) {
             $paranoia = intval(get_config('system', 'paranoia'));
         }
         switch ($paranoia) {
             case 0:
                 // no IP checking
Example #17
0
function profile_content(&$a, $update = 0)
{
    if (get_config('system', 'block_public') && !local_user() && !remote_user()) {
        return login();
    }
    require_once "include/bbcode.php";
    require_once 'include/security.php';
    require_once 'include/conversation.php';
    require_once 'include/acl_selectors.php';
    $groups = array();
    $tab = 'posts';
    $o = '';
    if ($update) {
        // Ensure we've got a profile owner if updating.
        $a->profile['profile_uid'] = $update;
    } else {
        if ($a->profile['profile_uid'] == local_user()) {
            nav_set_selected('home');
        }
    }
    $contact = null;
    $remote_contact = false;
    if (remote_user()) {
        $contact_id = $_SESSION['visitor_id'];
        $groups = init_groups_visitor($contact_id);
        $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($contact_id), intval($a->profile['profile_uid']));
        if (count($r)) {
            $contact = $r[0];
            $remote_contact = true;
        }
    }
    if (!$remote_contact) {
        if (local_user()) {
            $contact_id = $_SESSION['cid'];
            $contact = $a->contact;
        }
    }
    $is_owner = local_user() && local_user() == $a->profile['profile_uid'] ? true : false;
    if ($a->profile['hidewall'] && !$is_owner && !$remote_contact) {
        notice(t('Access to this profile has been restricted.') . EOL);
        return;
    }
    if (!$update) {
        if (x($_GET, 'tab')) {
            $tab = notags(trim($_GET['tab']));
        }
        $o .= profile_tabs($a, $is_owner, $a->profile['nickname']);
        if ($tab === 'profile') {
            require_once 'include/profile_advanced.php';
            $o .= advanced_profile($a);
            call_hooks('profile_advanced', $o);
            return $o;
        }
        if (x($_SESSION, 'new_member') && $_SESSION['new_member'] && $is_owner) {
            $o .= '<a href="newmember">' . t('Tips for New Members') . '</a>' . EOL;
        }
        $commpage = $a->profile['page-flags'] == PAGE_COMMUNITY ? true : false;
        $commvisitor = $commpage && $remote_contact == true ? true : false;
        $celeb = $a->profile['page-flags'] == PAGE_SOAPBOX || $a->profile['page-flags'] == PAGE_COMMUNITY ? true : false;
        if (can_write_wall($a, $a->profile['profile_uid'])) {
            $x = array('is_owner' => $is_owner, 'allow_location' => ($is_owner || $commvisitor) && $a->profile['allow_location'] ? true : false, 'default_location' => $is_owner ? $a->user['default-location'] : '', 'nickname' => $a->profile['nickname'], 'lockstate' => is_array($a->user) && (strlen($a->user['allow_cid']) || strlen($a->user['allow_gid']) || strlen($a->user['deny_cid']) || strlen($a->user['deny_gid'])) ? 'lock' : 'unlock', 'acl' => $is_owner ? populate_acl($a->user, $celeb) : '', 'bang' => '', 'visitor' => $is_owner || $commvisitor ? 'block' : 'none', 'profile_uid' => $a->profile['profile_uid']);
            $o .= status_editor($a, $x);
        }
    }
    if ($is_owner) {
        $r = q("UPDATE `item` SET `unseen` = 0 \n\t\t\tWHERE `wall` = 1 AND `unseen` = 1 AND `uid` = %d", intval(local_user()));
    }
    /**
     * Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
     */
    $sql_extra = permissions_sql($a->profile['profile_uid'], $remote_contact, $groups);
    $r = q("SELECT COUNT(*) AS `total`\n\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\tWHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0\n\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 \n\t\tAND `item`.`id` = `item`.`parent` AND `item`.`wall` = 1\n\t\t{$sql_extra} ", intval($a->profile['profile_uid']));
    if (count($r)) {
        $a->set_pager_total($r[0]['total']);
        $a->set_pager_itemspage(40);
    }
    $r = q("SELECT `item`.`id` AS `item_id`, `contact`.`uid` AS `contact-uid`\n\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\tWHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0\n\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\tAND `item`.`id` = `item`.`parent` AND `item`.`wall` = 1\n\t\t{$sql_extra}\n\t\tORDER BY `item`.`created` DESC LIMIT %d ,%d ", intval($a->profile['profile_uid']), intval($a->pager['start']), intval($a->pager['itemspage']));
    $parents_arr = array();
    $parents_str = '';
    if (count($r)) {
        foreach ($r as $rr) {
            $parents_arr[] = $rr['item_id'];
        }
        $parents_str = implode(', ', $parents_arr);
        $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, \n\t\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`network`, `contact`.`rel`, \n\t\t\t`contact`.`thumb`, `contact`.`self`, `contact`.`writable`, \n\t\t\t`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`\n\t\t\tFROM `item`, (SELECT `p`.`id`,`p`.`created` FROM `item` AS `p` WHERE `p`.`parent` = `p`.`id`) AS `parentitem`, `contact`\n\t\t\tWHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0\n\t\t\tAND `contact`.`id` = `item`.`contact-id`\n\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\tAND `item`.`parent` = `parentitem`.`id` AND `item`.`parent` IN ( %s )\n\t\t\t{$sql_extra}\n\t\t\tORDER BY `parentitem`.`created` DESC, `gravity` ASC, `item`.`created` ASC ", intval($a->profile['profile_uid']), dbesc($parents_str));
    }
    if ($is_owner && !$update) {
        $o .= get_birthdays();
        $o .= get_events();
    }
    if (!$update && $tab === 'posts') {
        // This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
        // because browser prefetching might change it on us. We have to deliver it with the page.
        $o .= '<div id="live-profile"></div>' . "\r\n";
        $o .= "<script> var profile_uid = " . $a->profile['profile_uid'] . "; var netargs = '/?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n";
    }
    $o .= conversation($a, $r, 'profile', $update);
    if (!$update) {
        $o .= paginate($a);
    }
    return $o;
}
Example #18
0
function photos_content(&$a)
{
    // URLs:
    // photos/name
    // photos/name/upload
    // photos/name/upload/xxxxx (xxxxx is album name)
    // photos/name/album/xxxxx
    // photos/name/album/xxxxx/edit
    // photos/name/image/xxxxx
    // photos/name/image/xxxxx/edit
    if (get_config('system', 'block_public') && !local_user() && !remote_user()) {
        notice(t('Public access denied.') . EOL);
        return;
    }
    require_once 'include/bbcode.php';
    require_once 'include/security.php';
    require_once 'include/conversation.php';
    if (!x($a->data, 'user')) {
        notice(t('No photos selected') . EOL);
        return;
    }
    $phototypes = Photo::supportedTypes();
    $_SESSION['photo_return'] = $a->cmd;
    //
    // Parse arguments
    //
    if ($a->argc > 3) {
        $datatype = $a->argv[2];
        $datum = $a->argv[3];
    } elseif ($a->argc > 2 && $a->argv[2] === 'upload') {
        $datatype = 'upload';
    } else {
        $datatype = 'summary';
    }
    if ($a->argc > 4) {
        $cmd = $a->argv[4];
    } else {
        $cmd = 'view';
    }
    //
    // Setup permissions structures
    //
    $can_post = false;
    $visitor = 0;
    $contact = null;
    $remote_contact = false;
    $contact_id = 0;
    $owner_uid = $a->data['user']['uid'];
    $community_page = $a->data['user']['page-flags'] == PAGE_COMMUNITY ? true : false;
    if (local_user() && local_user() == $owner_uid) {
        $can_post = true;
    } else {
        if ($community_page && remote_user()) {
            if (is_array($_SESSION['remote'])) {
                foreach ($_SESSION['remote'] as $v) {
                    if ($v['uid'] == $owner_uid) {
                        $contact_id = $v['cid'];
                        break;
                    }
                }
            }
            if ($contact_id) {
                $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval($contact_id), intval($owner_uid));
                if (count($r)) {
                    $can_post = true;
                    $contact = $r[0];
                    $remote_contact = true;
                    $visitor = $cid;
                }
            }
        }
    }
    // perhaps they're visiting - but not a community page, so they wouldn't have write access
    if (remote_user() && !$visitor) {
        $contact_id = 0;
        if (is_array($_SESSION['remote'])) {
            foreach ($_SESSION['remote'] as $v) {
                if ($v['uid'] == $owner_uid) {
                    $contact_id = $v['cid'];
                    break;
                }
            }
        }
        if ($contact_id) {
            $groups = init_groups_visitor($contact_id);
            $r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval($contact_id), intval($owner_uid));
            if (count($r)) {
                $contact = $r[0];
                $remote_contact = true;
            }
        }
    }
    if (!$remote_contact) {
        if (local_user()) {
            $contact_id = $_SESSION['cid'];
            $contact = $a->contact;
        }
    }
    if ($a->data['user']['hidewall'] && local_user() != $owner_uid && !$remote_contact) {
        notice(t('Access to this item is restricted.') . EOL);
        return;
    }
    $sql_extra = permissions_sql($owner_uid, $remote_contact, $groups);
    $o = "";
    // tabs
    $_is_owner = local_user() && local_user() == $owner_uid;
    $o .= profile_tabs($a, $_is_owner, $a->data['user']['nickname']);
    //
    // dispatch request
    //
    if ($datatype === 'upload') {
        if (!$can_post) {
            notice(t('Permission denied.'));
            return;
        }
        $selname = $datum ? hex2bin($datum) : '';
        $albumselect = '';
        $albumselect .= '<option value="" ' . (!$selname ? ' selected="selected" ' : '') . '>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option>';
        if (count($a->data['albums'])) {
            foreach ($a->data['albums'] as $album) {
                if ($album['album'] === '' || $album['album'] === 'Contact Photos' || $album['album'] === t('Contact Photos')) {
                    continue;
                }
                $selected = $selname === $album['album'] ? ' selected="selected" ' : '';
                $albumselect .= '<option value="' . $album['album'] . '"' . $selected . '>' . $album['album'] . '</option>';
            }
        }
        $celeb = $a->user['page-flags'] == PAGE_SOAPBOX || $a->user['page-flags'] == PAGE_COMMUNITY ? true : false;
        $uploader = '';
        $ret = array('post_url' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'], 'addon_text' => $uploader, 'default_upload' => true);
        call_hooks('photo_upload_form', $ret);
        $default_upload_box = replace_macros(get_markup_template('photos_default_uploader_box.tpl'), array());
        $default_upload_submit = replace_macros(get_markup_template('photos_default_uploader_submit.tpl'), array('$submit' => t('Submit')));
        $usage_message = '';
        $limit = service_class_fetch($a->data['user']['uid'], 'photo_upload_limit');
        if ($limit !== false) {
            $r = q("select sum(datasize) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", intval($a->data['user']['uid']));
            $usage_message = sprintf(t("You have used %1\$.2f Mbytes of %2\$.2f Mbytes photo storage."), $r[0]['total'] / 1024000, $limit / 1024000);
        }
        // Private/public post links for the non-JS ACL form
        $private_post = 1;
        if ($_REQUEST['public']) {
            $private_post = 0;
        }
        $query_str = $a->query_string;
        if (strpos($query_str, 'public=1') !== false) {
            $query_str = str_replace(array('?public=1', '&public=1'), array('', ''), $query_str);
        }
        // I think $a->query_string may never have ? in it, but I could be wrong
        // It looks like it's from the index.php?q=[etc] rewrite that the web
        // server does, which converts any ? to &, e.g. suggest&ignore=61 for suggest?ignore=61
        if (strpos($query_str, '?') === false) {
            $public_post_link = '?public=1';
        } else {
            $public_post_link = '&public=1';
        }
        $tpl = get_markup_template('photos_upload.tpl');
        if ($a->theme['template_engine'] === 'internal') {
            $albumselect_e = template_escape($albumselect);
            $aclselect_e = $visitor ? '' : template_escape(populate_acl($a->user, $celeb));
        } else {
            $albumselect_e = $albumselect;
            $aclselect_e = $visitor ? '' : populate_acl($a->user, $celeb);
        }
        $o .= replace_macros($tpl, array('$pagename' => t('Upload Photos'), '$sessid' => session_id(), '$usage' => $usage_message, '$nickname' => $a->data['user']['nickname'], '$newalbum' => t('New album name: '), '$existalbumtext' => t('or existing album name: '), '$nosharetext' => t('Do not show a status post for this upload'), '$albumselect' => $albumselect_e, '$permissions' => t('Permissions'), '$aclselect' => $aclselect_e, '$alt_uploader' => $ret['addon_text'], '$default_upload_box' => $ret['default_upload'] ? $default_upload_box : '', '$default_upload_submit' => $ret['default_upload'] ? $default_upload_submit : '', '$uploadurl' => $ret['post_url'], '$acl_data' => construct_acl_data($a, $a->user), '$group_perms' => t('Show to Groups'), '$contact_perms' => t('Show to Contacts'), '$private' => t('Private Photo'), '$public' => t('Public Photo'), '$is_private' => $private_post, '$return_path' => $query_str, '$public_link' => $public_post_link));
        return $o;
    }
    if ($datatype === 'album') {
        $album = hex2bin($datum);
        $r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` = '%s' \n\t\t\tAND `scale` <= 4 {$sql_extra} GROUP BY `resource-id`", intval($owner_uid), dbesc($album));
        if (count($r)) {
            $a->set_pager_total(count($r));
            $a->set_pager_itemspage(20);
        }
        if ($_GET['order'] === 'posted') {
            $order = 'ASC';
        } else {
            $order = 'DESC';
        }
        $r = q("SELECT `resource-id`, `id`, `filename`, type, max(`scale`) AS `scale`, `desc` FROM `photo` WHERE `uid` = %d AND `album` = '%s' \n\t\t\tAND `scale` <= 4 {$sql_extra} GROUP BY `resource-id` ORDER BY `created` {$order} LIMIT %d , %d", intval($owner_uid), dbesc($album), intval($a->pager['start']), intval($a->pager['itemspage']));
        $o .= '<h3 id="photo-album-title">' . $album . '</h3>';
        if ($cmd === 'edit') {
            if ($album !== t('Profile Photos') && $album !== 'Contact Photos' && $album !== t('Contact Photos')) {
                if ($can_post) {
                    $edit_tpl = get_markup_template('album_edit.tpl');
                    if ($a->theme['template_engine'] === 'internal') {
                        $album_e = template_escape($album);
                    } else {
                        $album_e = $album;
                    }
                    $o .= replace_macros($edit_tpl, array('$nametext' => t('New album name: '), '$nickname' => $a->data['user']['nickname'], '$album' => $album_e, '$hexalbum' => bin2hex($album), '$submit' => t('Submit'), '$dropsubmit' => t('Delete Album')));
                }
            }
        } else {
            if ($album !== t('Profile Photos') && $album !== 'Contact Photos' && $album !== t('Contact Photos')) {
                if ($can_post) {
                    $o .= '<div id="album-edit-link"><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album) . '/edit' . '">' . t('Edit Album') . '</a></div>';
                }
            }
        }
        if ($_GET['order'] === 'posted') {
            $o .= '<div class="photos-upload-link" ><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album) . '" >' . t('Show Newest First') . '</a></div>';
        } else {
            $o .= '<div class="photos-upload-link" ><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album) . '?f=&order=posted" >' . t('Show Oldest First') . '</a></div>';
        }
        if ($can_post) {
            $o .= '<div class="photos-upload-link" ><a href="' . $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/upload/' . bin2hex($album) . '" >' . t('Upload New Photos') . '</a></div>';
        }
        $tpl = get_markup_template('photo_album.tpl');
        if (count($r)) {
            $twist = 'rotright';
        }
        foreach ($r as $rr) {
            if ($twist == 'rotright') {
                $twist = 'rotleft';
            } else {
                $twist = 'rotright';
            }
            $ext = $phototypes[$rr['type']];
            if ($a->theme['template_engine'] === 'internal') {
                $imgalt_e = template_escape($rr['filename']);
                $desc_e = template_escape($rr['desc']);
            } else {
                $imgalt_e = $rr['filename'];
                $desc_e = $rr['desc'];
            }
            $o .= replace_macros($tpl, array('$id' => $rr['id'], '$twist' => ' ' . $twist . rand(2, 4), '$photolink' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id'] . ($_GET['order'] === 'posted' ? '?f=&order=posted' : ''), '$phototitle' => t('View Photo'), '$imgsrc' => $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . $rr['scale'] . '.' . $ext, '$imgalt' => $imgalt_e, '$desc' => $desc_e));
        }
        $o .= '<div id="photo-album-end"></div>';
        $o .= paginate($a);
        return $o;
    }
    if ($datatype === 'image') {
        //$o = '';
        // fetch image, item containing image, then comments
        $ph = q("SELECT * FROM `photo` WHERE `uid` = %d AND `resource-id` = '%s' \n\t\t\t{$sql_extra} ORDER BY `scale` ASC ", intval($owner_uid), dbesc($datum));
        if (!count($ph)) {
            $ph = q("SELECT `id` FROM `photo` WHERE `uid` = %d AND `resource-id` = '%s'\n\t\t\t\tLIMIT 1", intval($owner_uid), dbesc($datum));
            if (count($ph)) {
                notice(t('Permission denied. Access to this item may be restricted.'));
            } else {
                notice(t('Photo not available') . EOL);
            }
            return;
        }
        $prevlink = '';
        $nextlink = '';
        if ($_GET['order'] === 'posted') {
            $order = 'ASC';
        } else {
            $order = 'DESC';
        }
        $prvnxt = q("SELECT `resource-id` FROM `photo` WHERE `album` = '%s' AND `uid` = %d AND `scale` = 0\n\t\t\t{$sql_extra} ORDER BY `created` {$order} ", dbesc($ph[0]['album']), intval($owner_uid));
        if (count($prvnxt)) {
            for ($z = 0; $z < count($prvnxt); $z++) {
                if ($prvnxt[$z]['resource-id'] == $ph[0]['resource-id']) {
                    $prv = $z - 1;
                    $nxt = $z + 1;
                    if ($prv < 0) {
                        $prv = count($prvnxt) - 1;
                    }
                    if ($nxt >= count($prvnxt)) {
                        $nxt = 0;
                    }
                    break;
                }
            }
            $edit_suffix = $cmd === 'edit' && $can_post ? '/edit' : '';
            $prevlink = $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $prvnxt[$prv]['resource-id'] . $edit_suffix . ($_GET['order'] === 'posted' ? '?f=&order=posted' : '');
            $nextlink = $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $prvnxt[$nxt]['resource-id'] . $edit_suffix . ($_GET['order'] === 'posted' ? '?f=&order=posted' : '');
        }
        if (count($ph) == 1) {
            $hires = $lores = $ph[0];
        }
        if (count($ph) > 1) {
            if ($ph[1]['scale'] == 2) {
                // original is 640 or less, we can display it directly
                $hires = $lores = $ph[0];
            } else {
                $hires = $ph[0];
                $lores = $ph[1];
            }
        }
        $album_link = $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($ph[0]['album']);
        $tools = Null;
        $lock = Null;
        if ($can_post && $ph[0]['uid'] == $owner_uid) {
            $tools = array('edit' => array($a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $datum . ($cmd === 'edit' ? '' : '/edit'), $cmd === 'edit' ? t('View photo') : t('Edit photo')), 'profile' => array($a->get_baseurl() . '/profile_photo/use/' . $ph[0]['resource-id'], t('Use as profile photo')));
            // lock
            $lock = $ph[0]['uid'] == local_user() && (strlen($ph[0]['allow_cid']) || strlen($ph[0]['allow_gid']) || strlen($ph[0]['deny_cid']) || strlen($ph[0]['deny_gid'])) ? t('Private Message') : Null;
        }
        if ($cmd === 'edit') {
            $tpl = get_markup_template('photo_edit_head.tpl');
            $a->page['htmlhead'] .= replace_macros($tpl, array('$prevlink' => $prevlink, '$nextlink' => $nextlink));
        }
        if ($prevlink) {
            $prevlink = array($prevlink, '<div class="icon prev"></div>');
        }
        $photo = array('href' => $a->get_baseurl() . '/photo/' . $hires['resource-id'] . '-' . $hires['scale'] . '.' . $phototypes[$hires['type']], 'title' => t('View Full Size'), 'src' => $a->get_baseurl() . '/photo/' . $lores['resource-id'] . '-' . $lores['scale'] . '.' . $phototypes[$lores['type']] . '?f=&_u=' . datetime_convert('', '', '', 'ymdhis'), 'height' => $hires['height'], 'width' => $hires['width'], 'album' => $hires['album'], 'filename' => $hires['filename']);
        if ($nextlink) {
            $nextlink = array($nextlink, '<div class="icon next"></div>');
        }
        // Do we have an item for this photo?
        // FIXME! - replace following code to display the conversation with our normal
        // conversation functions so that it works correctly and tracks changes
        // in the evolving conversation code.
        // The difference is that we won't be displaying the conversation head item
        // as a "post" but displaying instead the photo it is linked to
        $linked_items = q("SELECT * FROM `item` WHERE `resource-id` = '%s' {$sql_extra} LIMIT 1", dbesc($datum));
        if (count($linked_items)) {
            $link_item = $linked_items[0];
            $r = q("SELECT COUNT(*) AS `total`\n\t\t\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\t\tWHERE `parent-uri` = '%s' AND `uri` != '%s' AND `item`.`deleted` = 0 and `item`.`moderated` = 0\n\t\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\t\tAND `item`.`uid` = %d\n\t\t\t\t{$sql_extra} ", dbesc($link_item['uri']), dbesc($link_item['uri']), intval($link_item['uid']));
            if (count($r)) {
                $a->set_pager_total($r[0]['total']);
            }
            $r = q("SELECT `item`.*, `item`.`id` AS `item_id`,\n\t\t\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`network`,\n\t\t\t\t`contact`.`rel`, `contact`.`thumb`, `contact`.`self`,\n\t\t\t\t`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`\n\t\t\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\t\tWHERE `parent-uri` = '%s' AND `uri` != '%s' AND `item`.`deleted` = 0 and `item`.`moderated` = 0\n\t\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\t\tAND `item`.`uid` = %d\n\t\t\t\t{$sql_extra}\n\t\t\t\tORDER BY `parent` DESC, `id` ASC LIMIT %d ,%d ", dbesc($link_item['uri']), dbesc($link_item['uri']), intval($link_item['uid']), intval($a->pager['start']), intval($a->pager['itemspage']));
            if (local_user() && local_user() == $link_item['uid']) {
                q("UPDATE `item` SET `unseen` = 0 WHERE `parent` = %d and `uid` = %d", intval($link_item['parent']), intval(local_user()));
                update_thread($link_item['parent']);
            }
        }
        $tags = Null;
        if (count($linked_items) && strlen($link_item['tag'])) {
            $arr = explode(',', $link_item['tag']);
            // parse tags and add links
            $tag_str = '';
            foreach ($arr as $t) {
                if (strlen($tag_str)) {
                    $tag_str .= ', ';
                }
                $tag_str .= bbcode($t);
            }
            $tags = array(t('Tags: '), $tag_str);
            if ($cmd === 'edit') {
                $tags[] = $a->get_baseurl() . '/tagrm/' . $link_item['id'];
                $tags[] = t('[Remove any tag]');
            }
        }
        $edit = Null;
        if ($cmd === 'edit' && $can_post) {
            $edit_tpl = get_markup_template('photo_edit.tpl');
            // Private/public post links for the non-JS ACL form
            $private_post = 1;
            if ($_REQUEST['public']) {
                $private_post = 0;
            }
            $query_str = $a->query_string;
            if (strpos($query_str, 'public=1') !== false) {
                $query_str = str_replace(array('?public=1', '&public=1'), array('', ''), $query_str);
            }
            // I think $a->query_string may never have ? in it, but I could be wrong
            // It looks like it's from the index.php?q=[etc] rewrite that the web
            // server does, which converts any ? to &, e.g. suggest&ignore=61 for suggest?ignore=61
            if (strpos($query_str, '?') === false) {
                $public_post_link = '?public=1';
            } else {
                $public_post_link = '&public=1';
            }
            if ($a->theme['template_engine'] === 'internal') {
                $album_e = template_escape($ph[0]['album']);
                $caption_e = template_escape($ph[0]['desc']);
                $aclselect_e = template_escape(populate_acl($ph[0]));
            } else {
                $album_e = $ph[0]['album'];
                $caption_e = $ph[0]['desc'];
                $aclselect_e = populate_acl($ph[0]);
            }
            $edit = replace_macros($edit_tpl, array('$id' => $ph[0]['id'], '$rotatecw' => t('Rotate CW (right)'), '$rotateccw' => t('Rotate CCW (left)'), '$album' => $album_e, '$newalbum' => t('New album name'), '$nickname' => $a->data['user']['nickname'], '$resource_id' => $ph[0]['resource-id'], '$capt_label' => t('Caption'), '$caption' => $caption_e, '$tag_label' => t('Add a Tag'), '$tags' => $link_item['tag'], '$permissions' => t('Permissions'), '$aclselect' => $aclselect_e, '$help_tags' => t('Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping'), '$item_id' => count($linked_items) ? $link_item['id'] : 0, '$submit' => t('Submit'), '$delete' => t('Delete Photo'), '$acl_data' => construct_acl_data($a, $ph[0]), '$group_perms' => t('Show to Groups'), '$contact_perms' => t('Show to Contacts'), '$private' => t('Private photo'), '$public' => t('Public photo'), '$is_private' => $private_post, '$return_path' => $query_str, '$public_link' => $public_post_link));
        }
        if (count($linked_items)) {
            $cmnt_tpl = get_markup_template('comment_item.tpl');
            $tpl = get_markup_template('photo_item.tpl');
            $return_url = $a->cmd;
            $like_tpl = get_markup_template('like_noshare.tpl');
            $likebuttons = '';
            if ($can_post || can_write_wall($a, $owner_uid)) {
                $likebuttons = replace_macros($like_tpl, array('$id' => $link_item['id'], '$likethis' => t("I like this (toggle)"), '$nolike' => feature_enabled(local_user(), 'dislike') ? t("I don't like this (toggle)") : '', '$share' => t('Share'), '$wait' => t('Please wait'), '$return_path' => $a->query_string));
            }
            $comments = '';
            if (!count($r)) {
                if ($can_post || can_write_wall($a, $owner_uid)) {
                    if ($link_item['last-child']) {
                        $comments .= replace_macros($cmnt_tpl, array('$return_path' => '', '$jsreload' => $return_url, '$type' => 'wall-comment', '$id' => $link_item['id'], '$parent' => $link_item['id'], '$profile_uid' => $owner_uid, '$mylink' => $contact['url'], '$mytitle' => t('This is you'), '$myphoto' => $contact['thumb'], '$comment' => t('Comment'), '$submit' => t('Submit'), '$preview' => t('Preview'), '$sourceapp' => t($a->sourcename), '$ww' => '', '$rand_num' => random_digits(12)));
                    }
                }
            }
            $alike = array();
            $dlike = array();
            $like = '';
            $dislike = '';
            // display comments
            if (count($r)) {
                foreach ($r as $item) {
                    like_puller($a, $item, $alike, 'like');
                    like_puller($a, $item, $dlike, 'dislike');
                }
                $like = isset($alike[$link_item['id']]) ? format_like($alike[$link_item['id']], $alike[$link_item['id'] . '-l'], 'like', $link_item['id']) : '';
                $dislike = isset($dlike[$link_item['id']]) ? format_like($dlike[$link_item['id']], $dlike[$link_item['id'] . '-l'], 'dislike', $link_item['id']) : '';
                if ($can_post || can_write_wall($a, $owner_uid)) {
                    if ($link_item['last-child']) {
                        $comments .= replace_macros($cmnt_tpl, array('$return_path' => '', '$jsreload' => $return_url, '$type' => 'wall-comment', '$id' => $link_item['id'], '$parent' => $link_item['id'], '$profile_uid' => $owner_uid, '$mylink' => $contact['url'], '$mytitle' => t('This is you'), '$myphoto' => $contact['thumb'], '$comment' => t('Comment'), '$submit' => t('Submit'), '$preview' => t('Preview'), '$sourceapp' => t($a->sourcename), '$ww' => '', '$rand_num' => random_digits(12)));
                    }
                }
                foreach ($r as $item) {
                    $comment = '';
                    $template = $tpl;
                    $sparkle = '';
                    if ((activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE)) && $item['id'] != $item['parent']) {
                        continue;
                    }
                    $redirect_url = $a->get_baseurl() . '/redir/' . $item['cid'];
                    if (local_user() && $item['contact-uid'] == local_user() && $item['network'] == 'dfrn' && !$item['self']) {
                        $profile_url = $redirect_url;
                        $sparkle = ' sparkle';
                    } else {
                        $profile_url = $item['url'];
                        $sparkle = '';
                    }
                    $diff_author = $item['url'] !== $item['author-link'] ? true : false;
                    $profile_name = strlen($item['author-name']) && $diff_author ? $item['author-name'] : $item['name'];
                    $profile_avatar = strlen($item['author-avatar']) && $diff_author ? $item['author-avatar'] : $item['thumb'];
                    $profile_link = $profile_url;
                    $dropping = $item['contact-id'] == $contact_id || $item['uid'] == local_user();
                    $drop = array('dropping' => $dropping, 'pagedrop' => false, 'select' => t('Select'), 'delete' => t('Delete'));
                    if ($a->theme['template_engine'] === 'internal') {
                        $name_e = template_escape($profile_name);
                        $title_e = template_escape($item['title']);
                        $body_e = template_escape(bbcode($item['body']));
                    } else {
                        $name_e = $profile_name;
                        $title_e = $item['title'];
                        $body_e = bbcode($item['body']);
                    }
                    $comments .= replace_macros($template, array('$id' => $item['item_id'], '$profile_url' => $profile_link, '$name' => $name_e, '$thumb' => $profile_avatar, '$sparkle' => $sparkle, '$title' => $title_e, '$body' => $body_e, '$ago' => relative_date($item['created']), '$indent' => $item['parent'] != $item['item_id'] ? ' comment' : '', '$drop' => $drop, '$comment' => $comment));
                    if ($can_post || can_write_wall($a, $owner_uid)) {
                        if ($item['last-child']) {
                            $comments .= replace_macros($cmnt_tpl, array('$return_path' => '', '$jsreload' => $return_url, '$type' => 'wall-comment', '$id' => $item['item_id'], '$parent' => $item['parent'], '$profile_uid' => $owner_uid, '$mylink' => $contact['url'], '$mytitle' => t('This is you'), '$myphoto' => $contact['thumb'], '$comment' => t('Comment'), '$submit' => t('Submit'), '$preview' => t('Preview'), '$sourceapp' => t($a->sourcename), '$ww' => '', '$rand_num' => random_digits(12)));
                        }
                    }
                }
            }
            $paginate = paginate($a);
        }
        $photo_tpl = get_markup_template('photo_view.tpl');
        if ($a->theme['template_engine'] === 'internal') {
            $album_e = array($album_link, template_escape($ph[0]['album']));
            $tags_e = template_escape($tags);
            $like_e = template_escape($like);
            $dislike_e = template_escape($dislike);
        } else {
            $album_e = array($album_link, $ph[0]['album']);
            $tags_e = $tags;
            $like_e = $like;
            $dislike_e = $dislike;
        }
        $o .= replace_macros($photo_tpl, array('$id' => $ph[0]['id'], '$album' => $album_e, '$tools' => $tools, '$lock' => $lock, '$photo' => $photo, '$prevlink' => $prevlink, '$nextlink' => $nextlink, '$desc' => $ph[0]['desc'], '$tags' => $tags_e, '$edit' => $edit, '$likebuttons' => $likebuttons, '$like' => $like_e, '$dislike' => $dikslike_e, '$comments' => $comments, '$paginate' => $paginate));
        $a->page['htmlhead'] .= "\n" . '<meta name="twitter:card" content="photo" />' . "\n";
        $a->page['htmlhead'] .= '<meta name="twitter:title" content="' . $photo["album"] . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta name="twitter:image" content="' . $photo["href"] . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta name="twitter:image:width" content="' . $photo["width"] . '" />' . "\n";
        $a->page['htmlhead'] .= '<meta name="twitter:image:height" content="' . $photo["height"] . '" />' . "\n";
        return $o;
    }
    // Default - show recent photos with upload link (if applicable)
    //$o = '';
    $r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' \n\t\t{$sql_extra} GROUP BY `resource-id`", intval($a->data['user']['uid']), dbesc('Contact Photos'), dbesc(t('Contact Photos')));
    if (count($r)) {
        $a->set_pager_total(count($r));
        $a->set_pager_itemspage(20);
    }
    $r = q("SELECT `resource-id`, `id`, `filename`, type, `album`, max(`scale`) AS `scale` FROM `photo`\n\t\tWHERE `uid` = %d AND `album` != '%s' AND `album` != '%s'  \n\t\t{$sql_extra} GROUP BY `resource-id` ORDER BY `created` DESC LIMIT %d , %d", intval($a->data['user']['uid']), dbesc('Contact Photos'), dbesc(t('Contact Photos')), intval($a->pager['start']), intval($a->pager['itemspage']));
    $photos = array();
    if (count($r)) {
        $twist = 'rotright';
        foreach ($r as $rr) {
            if ($twist == 'rotright') {
                $twist = 'rotleft';
            } else {
                $twist = 'rotright';
            }
            $ext = $phototypes[$rr['type']];
            if ($a->theme['template_engine'] === 'internal') {
                $alt_e = template_escape($rr['filename']);
                $name_e = template_escape($rr['album']);
            } else {
                $alt_e = $rr['filename'];
                $name_e = $rr['album'];
            }
            $photos[] = array('id' => $rr['id'], 'twist' => ' ' . $twist . rand(2, 4), 'link' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id'], 'title' => t('View Photo'), 'src' => $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . ($rr['scale'] == 6 ? 4 : $rr['scale']) . '.' . $ext, 'alt' => $alt_e, 'album' => array('link' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($rr['album']), 'name' => $name_e, 'alt' => t('View Album')));
        }
    }
    $tpl = get_markup_template('photos_recent.tpl');
    $o .= replace_macros($tpl, array('$title' => t('Recent Photos'), '$can_post' => $can_post, '$upload' => array(t('Upload New Photos'), $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/upload'), '$photos' => $photos));
    $o .= paginate($a);
    return $o;
}
Example #19
0
function videos_content(&$a)
{
    // URLs (most aren't currently implemented):
    // videos/name
    // videos/name/upload
    // videos/name/upload/xxxxx (xxxxx is album name)
    // videos/name/album/xxxxx
    // videos/name/album/xxxxx/edit
    // videos/name/video/xxxxx
    // videos/name/video/xxxxx/edit
    if (get_config('system', 'block_public') && !local_user() && !remote_user()) {
        notice(t('Public access denied.') . EOL);
        return;
    }
    require_once 'include/bbcode.php';
    require_once 'include/security.php';
    require_once 'include/conversation.php';
    if (!x($a->data, 'user')) {
        notice(t('No videos selected') . EOL);
        return;
    }
    //$phototypes = Photo::supportedTypes();
    $_SESSION['video_return'] = $a->cmd;
    //
    // Parse arguments
    //
    if ($a->argc > 3) {
        $datatype = $a->argv[2];
        $datum = $a->argv[3];
    } elseif ($a->argc > 2 && $a->argv[2] === 'upload') {
        $datatype = 'upload';
    } else {
        $datatype = 'summary';
    }
    if ($a->argc > 4) {
        $cmd = $a->argv[4];
    } else {
        $cmd = 'view';
    }
    //
    // Setup permissions structures
    //
    $can_post = false;
    $visitor = 0;
    $contact = null;
    $remote_contact = false;
    $contact_id = 0;
    $owner_uid = $a->data['user']['uid'];
    $community_page = $a->data['user']['page-flags'] == PAGE_COMMUNITY ? true : false;
    if (local_user() && local_user() == $owner_uid) {
        $can_post = true;
    } else {
        if ($community_page && remote_user()) {
            if (is_array($_SESSION['remote'])) {
                foreach ($_SESSION['remote'] as $v) {
                    if ($v['uid'] == $owner_uid) {
                        $contact_id = $v['cid'];
                        break;
                    }
                }
            }
            if ($contact_id) {
                $r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval($contact_id), intval($owner_uid));
                if (count($r)) {
                    $can_post = true;
                    $contact = $r[0];
                    $remote_contact = true;
                    $visitor = $cid;
                }
            }
        }
    }
    // perhaps they're visiting - but not a community page, so they wouldn't have write access
    if (remote_user() && !$visitor) {
        $contact_id = 0;
        if (is_array($_SESSION['remote'])) {
            foreach ($_SESSION['remote'] as $v) {
                if ($v['uid'] == $owner_uid) {
                    $contact_id = $v['cid'];
                    break;
                }
            }
        }
        if ($contact_id) {
            $groups = init_groups_visitor($contact_id);
            $r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1", intval($contact_id), intval($owner_uid));
            if (count($r)) {
                $contact = $r[0];
                $remote_contact = true;
            }
        }
    }
    if (!$remote_contact) {
        if (local_user()) {
            $contact_id = $_SESSION['cid'];
            $contact = $a->contact;
        }
    }
    if ($a->data['user']['hidewall'] && local_user() != $owner_uid && !$remote_contact) {
        notice(t('Access to this item is restricted.') . EOL);
        return;
    }
    $sql_extra = permissions_sql($owner_uid, $remote_contact, $groups);
    $o = "";
    // tabs
    $_is_owner = local_user() && local_user() == $owner_uid;
    $o .= profile_tabs($a, $_is_owner, $a->data['user']['nickname']);
    //
    // dispatch request
    //
    if ($datatype === 'upload') {
        return;
        // no uploading for now
        // DELETED -- look at mod/photos.php if you want to implement
    }
    if ($datatype === 'album') {
        return;
        // no albums for now
        // DELETED -- look at mod/photos.php if you want to implement
    }
    if ($datatype === 'video') {
        return;
        // no single video view for now
        // DELETED -- look at mod/photos.php if you want to implement
    }
    // Default - show recent videos (no upload link for now)
    //$o = '';
    $r = q("SELECT hash FROM `attach` WHERE `uid` = %d AND filetype LIKE '%%video%%'\n\t\t{$sql_extra} GROUP BY hash", intval($a->data['user']['uid']));
    if (count($r)) {
        $a->set_pager_total(count($r));
        $a->set_pager_itemspage(20);
    }
    $r = q("SELECT hash, `id`, `filename`, filetype FROM `attach`\n\t\tWHERE `uid` = %d AND filetype LIKE '%%video%%'\n\t\t{$sql_extra} GROUP BY hash ORDER BY `created` DESC LIMIT %d , %d", intval($a->data['user']['uid']), intval($a->pager['start']), intval($a->pager['itemspage']));
    $videos = array();
    if (count($r)) {
        foreach ($r as $rr) {
            if ($a->theme['template_engine'] === 'internal') {
                $alt_e = template_escape($rr['filename']);
                $name_e = template_escape($rr['album']);
            } else {
                $alt_e = $rr['filename'];
                $name_e = $rr['album'];
            }
            $videos[] = array('id' => $rr['id'], 'link' => $a->get_baseurl() . '/videos/' . $a->data['user']['nickname'] . '/video/' . $rr['resource-id'], 'title' => t('View Video'), 'src' => $a->get_baseurl() . '/attach/' . $rr['id'] . '?attachment=0', 'alt' => $alt_e, 'mime' => $rr['filetype'], 'album' => array('link' => $a->get_baseurl() . '/videos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($rr['album']), 'name' => $name_e, 'alt' => t('View Album')));
        }
    }
    $tpl = get_markup_template('videos_recent.tpl');
    $o .= replace_macros($tpl, array('$title' => t('Recent Videos'), '$can_post' => $can_post, '$upload' => array(t('Upload New Videos'), $a->get_baseurl() . '/videos/' . $a->data['user']['nickname'] . '/upload'), '$videos' => $videos, '$delete_url' => $can_post ? $a->get_baseurl() . '/videos/' . $a->data['user']['nickname'] : False));
    $o .= paginate($a);
    return $o;
}
Example #20
0
function profile_content(&$a, $update = 0)
{
    $category = $datequery = $datequery2 = '';
    if ($a->argc > 2) {
        for ($x = 2; $x < $a->argc; $x++) {
            if (is_a_date_arg($a->argv[$x])) {
                if ($datequery) {
                    $datequery2 = escape_tags($a->argv[$x]);
                } else {
                    $datequery = escape_tags($a->argv[$x]);
                }
            } else {
                $category = $a->argv[$x];
            }
        }
    }
    if (!x($category)) {
        $category = x($_GET, 'category') ? $_GET['category'] : '';
    }
    if (get_config('system', 'block_public') && !local_user() && !remote_user()) {
        return login();
    }
    require_once "include/bbcode.php";
    require_once 'include/security.php';
    require_once 'include/conversation.php';
    require_once 'include/acl_selectors.php';
    require_once 'include/items.php';
    $groups = array();
    $tab = 'posts';
    $o = '';
    if ($update) {
        // Ensure we've got a profile owner if updating.
        $a->profile['profile_uid'] = $update;
    } else {
        if ($a->profile['profile_uid'] == local_user()) {
            nav_set_selected('home');
        }
    }
    $contact = null;
    $remote_contact = false;
    $contact_id = 0;
    if (is_array($_SESSION['remote'])) {
        foreach ($_SESSION['remote'] as $v) {
            if ($v['uid'] == $a->profile['profile_uid']) {
                $contact_id = $v['cid'];
                break;
            }
        }
    }
    if ($contact_id) {
        $groups = init_groups_visitor($contact_id);
        $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($contact_id), intval($a->profile['profile_uid']));
        if (count($r)) {
            $contact = $r[0];
            $remote_contact = true;
        }
    }
    if (!$remote_contact) {
        if (local_user()) {
            $contact_id = $_SESSION['cid'];
            $contact = $a->contact;
        }
    }
    $is_owner = local_user() && local_user() == $a->profile['profile_uid'] ? true : false;
    if ($a->profile['hidewall'] && !$is_owner && !$remote_contact) {
        notice(t('Access to this profile has been restricted.') . EOL);
        return;
    }
    if (!$update) {
        if (x($_GET, 'tab')) {
            $tab = notags(trim($_GET['tab']));
        }
        $o .= profile_tabs($a, $is_owner, $a->profile['nickname']);
        if ($tab === 'profile') {
            $o .= advanced_profile($a);
            call_hooks('profile_advanced', $o);
            return $o;
        }
        $o .= common_friends_visitor_widget($a->profile['profile_uid']);
        if (x($_SESSION, 'new_member') && $_SESSION['new_member'] && $is_owner) {
            $o .= '<a href="newmember" id="newmember-tips" style="font-size: 1.2em;"><b>' . t('Tips for New Members') . '</b></a>' . EOL;
        }
        $commpage = $a->profile['page-flags'] == PAGE_COMMUNITY ? true : false;
        $commvisitor = $commpage && $remote_contact == true ? true : false;
        $a->page['aside'] .= posted_date_widget($a->get_baseurl(true) . '/profile/' . $a->profile['nickname'], $a->profile['profile_uid'], true);
        $a->page['aside'] .= categories_widget($a->get_baseurl(true) . '/profile/' . $a->profile['nickname'], x($category) ? xmlify($category) : '');
        if (can_write_wall($a, $a->profile['profile_uid'])) {
            $x = array('is_owner' => $is_owner, 'allow_location' => ($is_owner || $commvisitor) && $a->profile['allow_location'] ? true : false, 'default_location' => $is_owner ? $a->user['default-location'] : '', 'nickname' => $a->profile['nickname'], 'lockstate' => is_array($a->user) && (strlen($a->user['allow_cid']) || strlen($a->user['allow_gid']) || strlen($a->user['deny_cid']) || strlen($a->user['deny_gid'])) ? 'lock' : 'unlock', 'acl' => $is_owner ? populate_acl($a->user, true) : '', 'bang' => '', 'visitor' => $is_owner || $commvisitor ? 'block' : 'none', 'profile_uid' => $a->profile['profile_uid'], 'acl_data' => $is_owner ? construct_acl_data($a, $a->user) : '');
            $o .= status_editor($a, $x);
        }
    }
    /**
     * Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
     */
    $sql_extra = item_permissions_sql($a->profile['profile_uid'], $remote_contact, $groups);
    if ($update) {
        $r = q("SELECT distinct(parent) AS `item_id`, `item`.`network` AS `item_network`,\n\t\t\t`contact`.`uid` AS `contact-uid`\n\t\t\tFROM `item` INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\tWHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND\n\t\t\t(`item`.`deleted` = 0 OR item.verb = '" . ACTIVITY_LIKE . "' OR item.verb = '" . ACTIVITY_DISLIKE . "')\n\t\t\tand `item`.`moderated` = 0 and `item`.`unseen` = 1\n\t\t\tAND `item`.`wall` = 1\n\t\t\t{$sql_extra}\n\t\t\tORDER BY `item`.`created` DESC", intval($a->profile['profile_uid']));
    } else {
        $sql_post_table = "";
        if (x($category)) {
            $sql_post_table = sprintf("INNER JOIN (SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d ORDER BY `tid` DESC) AS `term` ON `item`.`id` = `term`.`oid` ", dbesc(protect_sprintf($category)), intval(TERM_OBJ_POST), intval(TERM_CATEGORY), intval($a->profile['profile_uid']));
            //$sql_extra .= protect_sprintf(file_tag_file_query('item',$category,'category'));
        }
        if ($datequery) {
            $sql_extra2 .= protect_sprintf(sprintf(" AND `thread`.`created` <= '%s' ", dbesc(datetime_convert(date_default_timezone_get(), '', $datequery))));
        }
        if ($datequery2) {
            $sql_extra2 .= protect_sprintf(sprintf(" AND `thread`.`created` >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(), '', $datequery2))));
        }
        if (get_config('system', 'old_pager')) {
            $r = q("SELECT COUNT(*) AS `total`\n\t\t\t    FROM `thread` INNER JOIN `item` ON `item`.`id` = `thread`.`iid`\n\t\t\t    {$sql_post_table} INNER JOIN `contact` ON `contact`.`id` = `thread`.`contact-id`\n\t\t\t    AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\t    WHERE `thread`.`uid` = %d AND `thread`.`visible` = 1 AND `thread`.`deleted` = 0\n\t\t\t    and `thread`.`moderated` = 0\n\t\t\t    AND `thread`.`wall` = 1\n\t\t\t    {$sql_extra} {$sql_extra2} ", intval($a->profile['profile_uid']));
            if (count($r)) {
                $a->set_pager_total($r[0]['total']);
            }
        }
        //  check if we serve a mobile device and get the user settings
        //  accordingly
        if ($a->is_mobile) {
            $itemspage_network = get_pconfig(local_user(), 'system', 'itemspage_mobile_network');
            $itemspage_network = intval($itemspage_network) ? $itemspage_network : 20;
        } else {
            $itemspage_network = get_pconfig(local_user(), 'system', 'itemspage_network');
            $itemspage_network = intval($itemspage_network) ? $itemspage_network : 40;
        }
        //  now that we have the user settings, see if the theme forces
        //  a maximum item number which is lower then the user choice
        if ($a->force_max_items > 0 && $a->force_max_items < $itemspage_network) {
            $itemspage_network = $a->force_max_items;
        }
        $a->set_pager_itemspage($itemspage_network);
        $pager_sql = sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage']));
        $r = q("SELECT `thread`.`iid` AS `item_id`, `thread`.`network` AS `item_network`,\n\t\t\t`thread`.`uid` AS `contact-uid`\n\t\t\tFROM `thread` INNER JOIN `item` ON `item`.`id` = `thread`.`iid`\n\t\t\t{$sql_post_table} INNER JOIN `contact` ON `contact`.`id` = `thread`.`contact-id`\n\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\tWHERE `thread`.`uid` = %d AND `thread`.`visible` = 1 AND `thread`.`deleted` = 0\n\t\t\tand `thread`.`moderated` = 0\n\t\t\tAND `thread`.`wall` = 1\n\t\t\t{$sql_extra} {$sql_extra2}\n\t\t\tORDER BY `thread`.`created` DESC {$pager_sql} ", intval($a->profile['profile_uid']));
    }
    $parents_arr = array();
    $parents_str = '';
    if (count($r)) {
        foreach ($r as $rr) {
            $parents_arr[] = $rr['item_id'];
        }
        $parents_str = implode(', ', $parents_arr);
        $items = q("SELECT `item`.*, `item`.`id` AS `item_id`, `item`.`network` AS `item_network`,\n\t\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`alias`, `contact`.`network`, `contact`.`rel`,\n\t\t\t`contact`.`thumb`, `contact`.`self`, `contact`.`writable`,\n\t\t\t`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`\n\t\t\tFROM `item`, `contact`\n\t\t\tWHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0\n\t\t\tand `item`.`moderated` = 0\n\t\t\tAND `contact`.`id` = `item`.`contact-id`\n\t\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\t\tAND `item`.`parent` IN ( %s )\n\t\t\t{$sql_extra} ", intval($a->profile['profile_uid']), dbesc($parents_str));
        $items = conv_sort($items, 'created');
    } else {
        $items = array();
    }
    if ($is_owner && !$update && !get_config('theme', 'hide_eventlist')) {
        $o .= get_birthdays();
        $o .= get_events();
    }
    if ($is_owner) {
        $r = q("UPDATE `item` SET `unseen` = 0\n\t\t\tWHERE `wall` = 1 AND `unseen` = 1 AND `uid` = %d", intval(local_user()));
    }
    $o .= conversation($a, $items, 'profile', $update);
    if (!$update) {
        if (!get_config('system', 'old_pager')) {
            $o .= alt_pager($a, count($items));
        } else {
            $o .= paginate($a);
        }
    }
    return $o;
}
Example #21
0
function display_content(&$a)
{
    if (get_config('system', 'block_public') && !local_user() && !remote_user()) {
        notice(t('Public access denied.') . EOL);
        return;
    }
    require_once "include/bbcode.php";
    require_once 'include/security.php';
    require_once 'include/conversation.php';
    $o = '<div id="live-display"></div>' . "\r\n";
    $a->page['htmlhead'] .= '<script>$(document).ready(function() {	$(".comment-edit-wrapper  textarea").contact_autocomplete(baseurl+"/acl"); });</script>';
    $nick = $a->argc > 1 ? $a->argv[1] : '';
    profile_load($a, $nick);
    $item_id = $a->argc > 2 ? intval($a->argv[2]) : 0;
    if (!$item_id) {
        $a->error = 404;
        notice(t('Item not found.') . EOL);
        return;
    }
    $groups = array();
    $contact = null;
    $remote_contact = false;
    if (remote_user()) {
        $contact_id = $_SESSION['visitor_id'];
        $groups = init_groups_visitor($contact_id);
        $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($contact_id), intval($a->profile['uid']));
        if (count($r)) {
            $contact = $r[0];
            $remote_contact = true;
        }
    }
    if (!$remote_contact) {
        if (local_user()) {
            $contact_id = $_SESSION['cid'];
            $contact = $a->contact;
        }
    }
    $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1", intval($a->profile['uid']));
    if (count($r)) {
        $a->page_contact = $r[0];
    }
    $is_owner = local_user() && local_user() == $a->profile['profile_uid'] ? true : false;
    if ($a->profile['hidewall'] && !$is_owner && !$remote_contact) {
        notice(t('Access to this profile has been restricted.') . EOL);
        return;
    }
    $sql_extra = permissions_sql($a->profile['uid'], $remote_contact, $groups);
    $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, \n\t\t`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,\n\t\t`contact`.`network`, `contact`.`thumb`, `contact`.`self`, `contact`.`writable`, \n\t\t`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`\n\t\tFROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`\n\t\tWHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0\n\t\tAND `contact`.`blocked` = 0 AND `contact`.`pending` = 0\n\t\tAND `item`.`parent` = ( SELECT `parent` FROM `item` WHERE ( `id` = '%s' OR `uri` = '%s' ))\n\t\t{$sql_extra}\n\t\tORDER BY `parent` DESC, `gravity` ASC, `id` ASC ", intval($a->profile['uid']), dbesc($item_id), dbesc($item_id));
    if (count($r)) {
        if (local_user() && local_user() == $a->profile['uid']) {
            q("UPDATE `item` SET `unseen` = 0 \n\t\t\t\tWHERE `parent` = %d AND `unseen` = 1", intval($r[0]['parent']));
        }
        $o .= conversation($a, $r, 'display', false);
    } else {
        $r = q("SELECT `id` FROM `item` WHERE `id` = '%s' OR `uri` = '%s' LIMIT 1", dbesc($item_id), dbesc($item_id));
        if (count($r)) {
            if ($r[0]['deleted']) {
                notice(t('Item has been removed.') . EOL);
            } else {
                notice(t('Permission denied.') . EOL);
            }
        } else {
            notice(t('Item not found.') . EOL);
        }
    }
    return $o;
}