From 32881234d002f017feacc67f21644ccd1803d3e2 Mon Sep 17 00:00:00 2001 From: Friendika Date: Tue, 7 Dec 2010 14:11:26 -0800 Subject: [PATCH 1/7] bring back full name check but without utf-8 regex's --- mod/register.php | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/mod/register.php b/mod/register.php index 973c54470..7ad7ef211 100644 --- a/mod/register.php +++ b/mod/register.php @@ -30,17 +30,12 @@ function register_post(&$a) { break; } - if(x($_POST,'username')) - $username = notags(trim($_POST['username'])); - if(x($_POST['nickname'])) - $nickname = notags(trim($_POST['nickname'])); - if(x($_POST,'email')) - $email = notags(trim($_POST['email'])); - if(x($_POST,'openid_url')) - $openid_url = notags(trim($_POST['openid_url'])); - - $photo = ((x($_POST,'photo')) ? notags(trim($_POST['photo'])) : ''); + $username = ((x($_POST,'username')) ? notags(trim($_POST['username'])) : ''); + $nickname = ((x($_POST,'nickname')) ? notags(trim($_POST['nickname'])) : ''); + $email = ((x($_POST,'email')) ? notags(trim($_POST['email'])) : ''); + $openid_url = ((x($_POST,'openid_url')) ? notags(trim($_POST['openid_url'])) : ''); + $photo = ((x($_POST,'photo')) ? notags(trim($_POST['photo'])) : ''); if((! x($username)) || (! x($email)) || (! x($nickname))) { if($openid_url) { @@ -71,14 +66,15 @@ function register_post(&$a) { // I don't really like having this rule, but it cuts down // on the number of auto-registrations by Russian spammers -// $no_utf = get_config('system','no_utf'); + // Using preg_match was completely unreliable, due to mixed UTF-8 regex support + // $no_utf = get_config('system','no_utf'); + // $pat = (($no_utf) ? '/^[a-zA-Z]* [a-zA-Z]*$/' : '/^\p{L}* \p{L}*$/u' ); -// $pat = (($no_utf) ? '/^[a-zA-Z]* [a-zA-Z]*$/' : '/^\p{L}* \p{L}*$/u' ); - -// $loose_reg = get_config('system','no_regfullname'); - -// if((! $loose_reg) && (! preg_match($pat,$username))) -// $err .= t('That doesn\'t appear to be your full name.') . EOL; + // So now we are just looking for a space in the full name. + + $loose_reg = get_config('system','no_regfullname'); + if((! $loose_reg) && (! strpos($username,' '))) + $err .= t("That doesn\'t appear to be your full \x28First Last\x29 name.") . EOL; if(! allowed_email($email)) $err .= t('Your email domain is not among those allowed on this site.') . EOL; From f3e8b55a7a72ee35fb62211bc9b545b382f962fb Mon Sep 17 00:00:00 2001 From: Friendika Date: Tue, 7 Dec 2010 14:37:56 -0800 Subject: [PATCH 2/7] removed high-bit angle-char stripping from input filter - interfering with utf-8 chars --- boot.php | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/boot.php b/boot.php index 49679c3b7..a80832b89 100644 --- a/boot.php +++ b/boot.php @@ -518,16 +518,29 @@ function random_string() { return(hash('sha256',uniqid(rand(),true))); }} -// This is our primary input filter. The high bit hack only involved some old -// IE browser, forget which. -// Use this on any text input where angle chars are not valid or permitted -// They will be replaced with safer brackets. This may be filtered further -// if these are not allowed either. +/** + * This is our primary input filter. + * + * The high bit hack only involved some old IE browser, forget which (IE5/Mac?) + * that had an XSS attack vector due to stripping the high-bit on an 8-bit character + * after cleansing, and angle chars with the high bit set could get through as markup. + * + * This is now disabled because it was interfering with some legitimate unicode sequences + * and hopefully there aren't a lot of those browsers left. + * + * Use this on any text input where angle chars are not valid or permitted + * They will be replaced with safer brackets. This may be filtered further + * if these are not allowed either. + * + */ if(! function_exists('notags')) { function notags($string) { - // protect against :<> with high-bit set - return(str_replace(array("<",">","\xBA","\xBC","\xBE"), array('[',']','','',''), $string)); + + return(str_replace(array("<",">"), array('[',']'), $string)); + +// High-bit filter no longer used +// return(str_replace(array("<",">","\xBA","\xBC","\xBE"), array('[',']','','',''), $string)); }} // use this on "body" or "content" input where angle chars shouldn't be removed, From e59377d96b09c8d7bc0090ce2cea0e99517c7d9b Mon Sep 17 00:00:00 2001 From: Friendika Date: Tue, 7 Dec 2010 16:27:30 -0800 Subject: [PATCH 3/7] highlight any messages on page newer than 12 hours --- mod/display.php | 8 +++++++- mod/network.php | 8 +++++++- mod/profile.php | 7 ++++++- view/theme/default/style.css | 5 +++++ 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/mod/display.php b/mod/display.php index aa9455361..92034d9ae 100644 --- a/mod/display.php +++ b/mod/display.php @@ -235,6 +235,12 @@ function display_content(&$a) { $location = '' . $coord . ''; } + $indent = (($item['parent'] != $item['item_id']) ? ' comment' : ''); + + if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0) + $indent .= ' shiny'; + + $o .= replace_macros($template,array( '$id' => $item['item_id'], '$profile_url' => $profile_link, @@ -247,7 +253,7 @@ function display_content(&$a) { '$ago' => relative_date($item['created']), '$lock' => $lock, '$location' => $location, - '$indent' => (($item['parent'] != $item['item_id']) ? ' comment' : ''), + '$indent' => $indent, '$owner_url' => $owner_url, '$owner_photo' => $owner_photo, '$owner_name' => $owner_name, diff --git a/mod/network.php b/mod/network.php index dd4ec63a3..7a81fd1a2 100644 --- a/mod/network.php +++ b/mod/network.php @@ -274,6 +274,12 @@ function network_content(&$a, $update = 0) { $location = '' . $coord . ''; } + $indent = (($item['parent'] != $item['item_id']) ? ' comment' : ''); + + if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0) + $indent .= ' shiny'; + + // Build the HTML $o .= replace_macros($template,array( @@ -288,7 +294,7 @@ function network_content(&$a, $update = 0) { '$ago' => relative_date($item['created']), '$lock' => $lock, '$location' => $location, - '$indent' => (($item['parent'] != $item['item_id']) ? ' comment' : ''), + '$indent' => $indent, '$owner_url' => $owner_url, '$owner_photo' => $owner_photo, '$owner_name' => $owner_name, diff --git a/mod/profile.php b/mod/profile.php index c18c7d196..9bd56044e 100644 --- a/mod/profile.php +++ b/mod/profile.php @@ -376,6 +376,11 @@ function profile_content(&$a, $update = 0) { $location = '' . $coord . ''; } + $indent = (($item['parent'] != $item['item_id']) ? ' comment' : ''); + + if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0) + $indent .= ' shiny'; + $o .= replace_macros($template,array( '$id' => $item['item_id'], '$profile_url' => $profile_link, @@ -387,7 +392,7 @@ function profile_content(&$a, $update = 0) { '$ago' => relative_date($item['created']), '$lock' => $lock, '$location' => $location, - '$indent' => (($item['parent'] != $item['item_id']) ? ' comment' : ''), + '$indent' => $indent, '$drop' => $drop, '$like' => $like, '$vote' => $likebuttons, diff --git a/view/theme/default/style.css b/view/theme/default/style.css index ad3e1c7c1..c5f535527 100644 --- a/view/theme/default/style.css +++ b/view/theme/default/style.css @@ -71,6 +71,11 @@ code { blockquote:before { content: '>> '; } + +.shiny { + border-color: orange !important; +} + .nav-login-link { float: right; margin-left: 0px; From 8b086a76e5607c3db96ca17ce66d2a68139d2584 Mon Sep 17 00:00:00 2001 From: Friendika Date: Tue, 7 Dec 2010 17:16:05 -0800 Subject: [PATCH 4/7] stray debugging statement --- mod/photos.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/photos.php b/mod/photos.php index 581c104a5..f29c39386 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -644,7 +644,7 @@ function photos_content(&$a) { $owner_uid = $a->data['user']['uid']; $community_page = (($a->data['user']['page-flags'] == PAGE_COMMUNITY) ? true : false); -dbg(1); + if((local_user()) && (local_user() == $owner_uid)) $can_post = true; else { From 5763d31b4f213fbb2eea4d366a9c7ad534a7f1ec Mon Sep 17 00:00:00 2001 From: Friendika Date: Tue, 7 Dec 2010 18:13:51 -0800 Subject: [PATCH 5/7] db prepare for enhanced magic profiles and remote privacy indicators, fixed $lang setting to use system config var, some other syntax issues --- boot.php | 2 +- database.sql | 3 +++ index.php | 13 +++++++------ update.php | 7 +++++++ view/en/profile.php | 2 +- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/boot.php b/boot.php index a80832b89..451a622c0 100644 --- a/boot.php +++ b/boot.php @@ -2,7 +2,7 @@ set_time_limit(0); -define ( 'BUILD_ID', 1021 ); +define ( 'BUILD_ID', 1022 ); define ( 'DFRN_PROTOCOL_VERSION', '2.0' ); define ( 'EOL', "
\r\n" ); diff --git a/database.sql b/database.sql index be0671bb1..0b322e9e0 100644 --- a/database.sql +++ b/database.sql @@ -187,6 +187,7 @@ CREATE TABLE IF NOT EXISTS `item` ( `allow_gid` mediumtext NOT NULL, `deny_cid` mediumtext NOT NULL, `deny_gid` mediumtext NOT NULL, + `private` tinyint(1) NOT NULL DEFAULT '0', `visible` tinyint(1) NOT NULL DEFAULT '0', `unseen` tinyint(1) NOT NULL DEFAULT '1', `deleted` tinyint(1) NOT NULL DEFAULT '0', @@ -319,7 +320,9 @@ CREATE TABLE IF NOT EXISTS `profile` ( CREATE TABLE IF NOT EXISTS `profile_check` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `uid` int(10) unsigned NOT NULL, + `cid` int(10) unsigned NOT NULL, `dfrn_id` char(255) NOT NULL, + `sec` char(255) NOT NULL, `expire` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/index.php b/index.php index cf20d35a2..4ad5f17e2 100644 --- a/index.php +++ b/index.php @@ -12,8 +12,12 @@ $install = ((file_exists('.htconfig.php')) ? false : true); @include(".htconfig.php"); -if(isset($lang) && strlen($lang)) - load_translation_table($lang); +// get language setting directly from system variables, bypassing get_config() +// as database may not yet be configured. + +$lang = ((isset($a->config['system']['language'])) ? $a->config['system']['language'] : 'en'); + +load_translation_table($lang); require_once("dba.php"); $db = new dba($db_host, $db_user, $db_pass, $db_data, $install); @@ -111,7 +115,7 @@ if($a->module != 'install') // make sure the desired theme exists, though if the default theme doesn't exist we're stuffed. -if((x($_SESSION,'theme')) && (! file_exists('/view/theme/' . $_SESSION['theme'] . '/style.css'))) +if((x($_SESSION,'theme')) && (! file_exists('view/theme/' . $_SESSION['theme'] . '/style.css'))) unset($_SESSION['theme']); $a->page['htmlhead'] = replace_macros($a->page['htmlhead'], array( @@ -122,9 +126,6 @@ $a->page['htmlhead'] = replace_macros($a->page['htmlhead'], array( $page = $a->page; $profile = $a->profile; -$lang = get_config('system','language'); -if($lang === false) - $lang = 'en'; header("Content-type: text/html; charset=utf-8"); diff --git a/update.php b/update.php index b1950e588..ff57c12f3 100644 --- a/update.php +++ b/update.php @@ -186,3 +186,10 @@ function update_1020() { q("ALTER TABLE `profile` DROP `showwith`"); q("ALTER TABLE `item` ADD `thr-parent` CHAR( 255 ) NOT NULL AFTER `parent-uri` "); } + +function update_1021() { + q("ALTER TABLE `profile_check` ADD `sec` CHAR( 255 ) NOT NULL AFTER `dfrn_id` "); + q("ALTER TABLE `profile_check` ADD `cid` INT(10) unsigned NOT NULL DEFAULT '0' AFTER `uid`"); + q("ALTER TABLE `item` ADD `private` TINYINT( 1 ) NOT NULL DEFAULT '0' AFTER `deny_gid` "); +} + diff --git a/view/en/profile.php b/view/en/profile.php index 190a3e297..fa7372668 100644 --- a/view/en/profile.php +++ b/view/en/profile.php @@ -48,7 +48,7 @@ - + From e241c401cf21108f39f67e54f64f50ad139af221 Mon Sep 17 00:00:00 2001 From: Friendika Date: Tue, 7 Dec 2010 19:40:12 -0800 Subject: [PATCH 6/7] significantly enhanced profile security --- include/dba.php | 24 ++++-- mod/dfrn_poll.php | 214 +++++++++++++++++++++++++++++++++++----------- mod/redir.php | 23 +++-- 3 files changed, 198 insertions(+), 63 deletions(-) diff --git a/include/dba.php b/include/dba.php index 4e3f11f7b..fd403b560 100644 --- a/include/dba.php +++ b/include/dba.php @@ -1,12 +1,15 @@ 0$decoded_challenge$sec"; + killme(); + // NOTREACHED } - q("DELETE FROM `profile_check` WHERE `expire` < " . intval(time())); - $r = q("SELECT * FROM `profile_check` WHERE `dfrn_id` = '%s' ORDER BY `expire` DESC", - dbesc($dfrn_id)); - if(count($r)) { - xml_status(1); + else { + // old protocol + + switch($direction) { + case 1: + $dfrn_id = '0:' . $dfrn_id; + break; + case 0: + $dfrn_id = '1:' . $dfrn_id; + break; + default: + break; + } + + + q("DELETE FROM `profile_check` WHERE `expire` < " . intval(time())); + $r = q("SELECT * FROM `profile_check` WHERE `dfrn_id` = '%s' ORDER BY `expire` DESC", + dbesc($dfrn_id)); + if(count($r)) { + xml_status(1); + return; // NOTREACHED + } + xml_status(0); return; // NOTREACHED } - xml_status(0); - return; // NOTREACHED } - } @@ -118,7 +177,7 @@ function dfrn_poll_post(&$a) { $dfrn_id = ((x($_POST,'dfrn_id')) ? $_POST['dfrn_id'] : ''); $challenge = ((x($_POST,'challenge')) ? $_POST['challenge'] : ''); $url = ((x($_POST,'url')) ? $_POST['url'] : ''); - $dfrn_version = ((x($_POST,'dfrn_version')) ? (float) $_POST['dfrn_version'] : 0); + $dfrn_version = ((x($_POST,'dfrn_version')) ? (float) $_POST['dfrn_version'] : 2.0); $direction = (-1); if(strpos($dfrn_id,':') == 1) { @@ -213,11 +272,12 @@ function dfrn_poll_post(&$a) { function dfrn_poll_content(&$a) { - $dfrn_id = ((x($_GET,'dfrn_id')) ? $_GET['dfrn_id'] : ''); - $type = ((x($_GET,'type')) ? $_GET['type'] : 'data'); - $last_update = ((x($_GET,'last_update')) ? $_GET['last_update'] : ''); - $dfrn_version = ((x($_GET,'dfrn_version')) ? (float) $_GET['dfrn_version'] : 2.0); - $sec = ((x($_GET,'sec')) ? intval($_GET['sec']) : 0); + $dfrn_id = ((x($_GET,'dfrn_id')) ? $_GET['dfrn_id'] : ''); + $type = ((x($_GET,'type')) ? $_GET['type'] : 'data'); + $last_update = ((x($_GET,'last_update')) ? $_GET['last_update'] : ''); + $destination_url = ((x($_GET,'destination_url')) ? $_GET['destination_url'] : ''); + $sec = ((x($_GET,'sec')) ? $_GET['sec'] : ''); + $dfrn_version = ((x($_GET,'dfrn_version')) ? (float) $_GET['dfrn_version'] : 2.0); $direction = (-1); if(strpos($dfrn_id,':') == 1) { @@ -234,19 +294,23 @@ function dfrn_poll_content(&$a) { $r = q("DELETE FROM `challenge` WHERE `expire` < " . intval(time())); - $r = q("INSERT INTO `challenge` ( `challenge`, `dfrn-id`, `expire` , `type`, `last_update` ) - VALUES( '%s', '%s', '%s', '%s', '%s' ) ", - dbesc($hash), - dbesc($dfrn_id), - intval(time() + 60 ), - dbesc($type), - dbesc($last_update) - ); - + if($type !== 'profile') { + $r = q("INSERT INTO `challenge` ( `challenge`, `dfrn-id`, `expire` , `type`, `last_update` ) + VALUES( '%s', '%s', '%s', '%s', '%s' ) ", + dbesc($hash), + dbesc($dfrn_id), + intval(time() + 60 ), + dbesc($type), + dbesc($last_update) + ); + } $sql_extra = ''; switch($direction) { case (-1): - $sql_extra = sprintf(" AND `issued-id` = '%s' ", dbesc($dfrn_id)); + if($type === 'profile') + $sql_extra = sprintf(" AND ( `dfrn-id` = '%s' OR `issued-id` = '%s' ) ", dbesc($dfrn_id),dbesc($dfrn_id)); + else + $sql_extra = sprintf(" AND `issued-id` = '%s' ", dbesc($dfrn_id)); $my_id = $dfrn_id; break; case 0: @@ -262,7 +326,12 @@ function dfrn_poll_content(&$a) { break; // NOTREACHED } - $r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 $sql_extra LIMIT 1"); + $r = q("SELECT `contact`.*, `user`.`username`, `user`.`nickname` + FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid` + WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0 + AND `user`.`nickname` = '%s' $sql_extra LIMIT 1", + dbesc($a->argv[1]) + ); if(count($r)) { @@ -270,7 +339,6 @@ function dfrn_poll_content(&$a) { $encrypted_id = ''; $id_str = $my_id . '.' . mt_rand(1000,9999); - if($r[0]['duplex'] && strlen($r[0]['pubkey'])) { openssl_public_encrypt($hash,$challenge,$r[0]['pubkey']); openssl_public_encrypt($id_str,$encrypted_id,$r[0]['pubkey']); @@ -287,15 +355,61 @@ function dfrn_poll_content(&$a) { $status = 1; } - header("Content-type: text/xml"); - echo '' . "\r\n" - . '' . "\r\n" - . "\t" . '' . $status . '' . "\r\n" - . "\t" . '' . DFRN_PROTOCOL_VERSION . '' . "\r\n" - . "\t" . '' . $encrypted_id . '' . "\r\n" - . "\t" . '' . $challenge . '' . "\r\n" - . '' . "\r\n" ; - killme(); + if(($type === 'profile') && (strlen($sec))) { + // URL reply + + $s = fetch_url($r[0]['poll'] + . '?dfrn_id=' . $encrypted_id + . '&type=profile-check' + . '&dfrn_version=' . DFRN_PROTOCOL_VERSION + . '&challenge=' . $challenge + . '&sec=' . $sec + ); + + logger("dfrn_poll: sec profile: " . $s, LOGGER_DATA); + + if(strlen($s) && strstr($s,'challenge . ' expecting ' . $hash); + logger('dfrn_poll: secure profile: sec: ' . $xml->sec . ' expecting ' . $sec); + + + if(((int) $xml->status == 0) && ($xml->challenge == $hash) && ($xml->sec == $sec)) { + $_SESSION['authenticated'] = 1; + $_SESSION['visitor_id'] = $r[0]['id']; + notice( $r[0]['username'] . t(' welcomes ') . $r[0]['name'] . EOL); + // Visitors get 1 day session. + $session_id = session_id(); + $expire = time() + 86400; + q("UPDATE `session` SET `expire` = '%s' WHERE `sid` = '%s' LIMIT 1", + dbesc($expire), + dbesc($session_id) + ); + } + $profile = $r[0]['nickname']; + goaway((strlen($destination_url)) ? $destination_url : $a->get_baseurl() . '/profile/' . $profile); + } + goaway($a->get_baseurl()); + // NOTREACHED + + } + else { + // XML reply + header("Content-type: text/xml"); + echo '' . "\r\n" + . '' . "\r\n" + . "\t" . '' . $status . '' . "\r\n" + . "\t" . '' . DFRN_PROTOCOL_VERSION . '' . "\r\n" + . "\t" . '' . $encrypted_id . '' . "\r\n" + . "\t" . '' . $challenge . '' . "\r\n" + . '' . "\r\n" ; + killme(); + // NOTREACHED + } } } diff --git a/mod/redir.php b/mod/redir.php index f95c52c96..cc58b9cd1 100644 --- a/mod/redir.php +++ b/mod/redir.php @@ -4,10 +4,13 @@ function redir_init(&$a) { if((! local_user()) || (! ($a->argc == 2)) || (! intval($a->argv[1]))) goaway($a->get_baseurl()); + $cid = $a->argv[1]; + $r = q("SELECT `network`, `issued-id`, `dfrn-id`, `duplex`, `poll` FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($a->argv[1]), + intval($cid), intval(local_user()) ); + if((! count($r)) || ($r[0]['network'] !== 'dfrn')) goaway($a->get_baseurl()); @@ -21,12 +24,20 @@ function redir_init(&$a) { $orig_id = $r[0]['dfrn-id']; $dfrn_id = '0:' . $orig_id; } - q("INSERT INTO `profile_check` ( `uid`, `dfrn_id`, `expire`) - VALUES( %d, '%s', %d )", - intval($_SESSION['uid']), + + $sec = random_string(); + + q("INSERT INTO `profile_check` ( `uid`, `cid`, `dfrn_id`, `sec`, `expire`) + VALUES( %d, %s, '%s', '%s', %d )", + intval(local_user()), + intval($cid), dbesc($dfrn_id), - intval(time() + 45)); + dbesc($sec), + intval(time() + 45) + ); + goaway ($r[0]['poll'] . '?dfrn_id=' . $dfrn_id - . '&dfrn_version=' . DFRN_PROTOCOL_VERSION . '&type=profile&sec=1'); +// . '&dfrn_version=' . DFRN_PROTOCOL_VERSION . '&type=profile'); + . '&dfrn_version=' . DFRN_PROTOCOL_VERSION . '&type=profile&sec=' . $sec); } From a42b9ea3dea5e1490dd4aa4852760354d569ea51 Mon Sep 17 00:00:00 2001 From: Friendika Date: Tue, 7 Dec 2010 20:47:53 -0800 Subject: [PATCH 7/7] display the fact that a conversation is private without disclosing the details of who can/cannot see it. --- include/items.php | 18 +++++++++++++++++- mod/display.php | 4 ++-- mod/item.php | 12 ++++++++---- mod/lockview.php | 7 +++++++ mod/network.php | 6 ++++-- mod/profile.php | 4 ++-- 6 files changed, 40 insertions(+), 11 deletions(-) diff --git a/include/items.php b/include/items.php index a4d3953f9..bb1b4f16b 100644 --- a/include/items.php +++ b/include/items.php @@ -367,6 +367,12 @@ function get_atom_elements($feed,$item) { else $res['last-child'] = 0; + $private = $item->get_item_tags(NAMESPACE_DFRN,'private'); + if($private && $private[0]['data'] == 1) + $res['private'] = 1; + else + $res['private'] = 0; + $rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'published'); if($rawcreated) $res['created'] = unxmlify($rawcreated[0]['data']); @@ -549,6 +555,7 @@ function item_store($arr) { $arr['allow_gid'] = ((x($arr,'allow_gid')) ? trim($arr['allow_gid']) : ''); $arr['deny_cid'] = ((x($arr,'deny_cid')) ? trim($arr['deny_cid']) : ''); $arr['deny_gid'] = ((x($arr,'deny_gid')) ? trim($arr['deny_gid']) : ''); + $arr['private'] = ((x($arr,'private')) ? intval($arr['private']) : 0 ); $arr['body'] = ((x($arr,'body')) ? escape_tags(trim($arr['body'])) : ''); // The content body has been through a lot of filtering and transport escaping by now. @@ -631,15 +638,21 @@ function item_store($arr) { if($arr['parent-uri'] === $arr['uri']) $parent_id = $current_post; + if(strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid)) + $private = 1; + else + $private = $arr['private']; + // Set parent id - and also make sure to inherit the parent's ACL's. $r = q("UPDATE `item` SET `parent` = %d, `allow_cid` = '%s', `allow_gid` = '%s', - `deny_cid` = '%s', `deny_gid` = '%s' WHERE `id` = %d LIMIT 1", + `deny_cid` = '%s', `deny_gid` = '%s', `private` = %d WHERE `id` = %d LIMIT 1", intval($parent_id), dbesc($allow_cid), dbesc($allow_gid), dbesc($deny_cid), dbesc($deny_gid), + intval($private), intval($current_post) ); @@ -1256,6 +1269,9 @@ function atom_entry($item,$type,$author,$owner,$comment = false) { if($item['coord']) $o .= '' . xmlify($item['coord']) . '' . "\r\n"; + if(($item['private']) || strlen($item['allow_cid']) || strlen($item['allow_gid']) || strlen($item['deny_cid']) || strlen($item['deny_gid'])) + $o .= '1' . "\r\n"; + $verb = construct_verb($item); $o .= '' . xmlify($verb) . '' . "\r\n"; $actobj = construct_activity_object($item); diff --git a/mod/display.php b/mod/display.php index 92034d9ae..ec036de62 100644 --- a/mod/display.php +++ b/mod/display.php @@ -142,8 +142,8 @@ function display_content(&$a) { && ($item['id'] != $item['parent'])) continue; - $lock = (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid']) - || strlen($item['deny_cid']) || strlen($item['deny_gid'])) + $lock = ((($item['private']) || (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid']) + || strlen($item['deny_cid']) || strlen($item['deny_gid'])))) ? '
' . t('Private Message') . '
' : '
'); diff --git a/mod/item.php b/mod/item.php index 504856d7d..ea88e6c31 100644 --- a/mod/item.php +++ b/mod/item.php @@ -53,6 +53,8 @@ function item_post(&$a) { $str_group_deny = perms2str($_POST['group_deny']); $str_contact_deny = perms2str($_POST['contact_deny']); + $private = ((strlen($str_group_allow) || strlen($str_contact_allow) || strlen($str_group_deny) || strlen($str_contact_deny)) ? 1 : 0); + $title = notags(trim($_POST['title'])); $body = escape_tags(trim($_POST['body'])); $location = notags(trim($_POST['location'])); @@ -195,8 +197,8 @@ function item_post(&$a) { $r = q("INSERT INTO `item` (`uid`,`type`,`wall`,`gravity`,`contact-id`,`owner-name`,`owner-link`,`owner-avatar`, `author-name`, `author-link`, `author-avatar`, `created`, `edited`, `changed`, `uri`, `title`, `body`, `location`, `coord`, - `tag`, `inform`, `verb`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`) - VALUES( %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )", + `tag`, `inform`, `verb`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`, `private` ) + VALUES( %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d )", intval($profile_uid), dbesc($post_type), intval($wall), @@ -222,7 +224,8 @@ function item_post(&$a) { dbesc($str_contact_allow), dbesc($str_group_allow), dbesc($str_contact_deny), - dbesc($str_group_deny) + dbesc($str_group_deny), + intval($private) ); $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' LIMIT 1", dbesc($uri)); @@ -241,12 +244,13 @@ function item_post(&$a) { // Inherit ACL's from the parent item. // TODO merge with subsequent UPDATE operation and save a db write - $r = q("UPDATE `item` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s' + $r = q("UPDATE `item` SET `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s', `private` = %d WHERE `id` = %d LIMIT 1", dbesc($parent_item['allow_cid']), dbesc($parent_item['allow_gid']), dbesc($parent_item['deny_cid']), dbesc($parent_item['deny_gid']), + intval($parent_item['private']), intval($post_id) ); diff --git a/mod/lockview.php b/mod/lockview.php index b8f4318df..a886effeb 100644 --- a/mod/lockview.php +++ b/mod/lockview.php @@ -22,6 +22,13 @@ function lockview_content(&$a) { $deny_users = expand_acl($item['deny_cid']); $deny_groups = expand_acl($item['deny_gid']); + if(($item['private']) && (! strlen($item['allow_cid'])) && (! strlen($item['allow_gid'])) + && (! strlen($item['deny_cid'])) && (! strlen($item['deny_gid']))) { + + echo t('Remote privacy information not available.') . '
'; + killme(); + } + $o = t('Visible to:') . '
'; $l = array(); diff --git a/mod/network.php b/mod/network.php index 7a81fd1a2..c52bb74fc 100644 --- a/mod/network.php +++ b/mod/network.php @@ -165,11 +165,13 @@ function network_content(&$a, $update = 0) { if(((activity_match($item['verb'],ACTIVITY_LIKE)) || (activity_match($item['verb'],ACTIVITY_DISLIKE))) && ($item['id'] != $item['parent'])) continue; - $lock = (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid']) - || strlen($item['deny_cid']) || strlen($item['deny_gid'])) + + $lock = ((($item['private']) || (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid']) + || strlen($item['deny_cid']) || strlen($item['deny_gid'])))) ? '
' . t('Private Message') . '
' : '
'); + // Top-level wall post not written by the wall owner (wall-to-wall) // First figure out who owns it. diff --git a/mod/profile.php b/mod/profile.php index 9bd56044e..d09e0187b 100644 --- a/mod/profile.php +++ b/mod/profile.php @@ -305,8 +305,8 @@ function profile_content(&$a, $update = 0) { && ($item['id'] != $item['parent'])) continue; - $lock = (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid']) - || strlen($item['deny_cid']) || strlen($item['deny_gid'])) + $lock = ((($item['private']) || (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid']) + || strlen($item['deny_cid']) || strlen($item['deny_gid'])))) ? '
' . t('Private Message') . '
' : '
');