From 285781b8870d1c36cf90a3b38a448719b8bf9d21 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 2 May 2018 13:49:22 -0700 Subject: hubzilla issue #1151 - activitypub mention gets bookmarked --- include/network.php | 4 ++-- include/text.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/network.php b/include/network.php index 8b7490a8a..a00ede6bf 100644 --- a/include/network.php +++ b/include/network.php @@ -797,7 +797,7 @@ function xml2array($contents, $namespaces = true, $get_attributes=1, $priority = if($namespaces) $parser = @xml_parser_create_ns("UTF-8",':'); else - $parser = @xml_parser_create(); + $parser = @xml_parser_create('UTF-8'); if(! $parser) { logger('xml2array: xml_parser_create: no resource'); @@ -807,7 +807,7 @@ function xml2array($contents, $namespaces = true, $get_attributes=1, $priority = xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8"); // http://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); - xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); + xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0); @xml_parse_into_struct($parser, trim($contents), $xml_values); @xml_parser_free($parser); diff --git a/include/text.php b/include/text.php index 24f8e1623..dc3a155de 100644 --- a/include/text.php +++ b/include/text.php @@ -3313,9 +3313,9 @@ function cleanup_bbcode($body) { $body = preg_replace_callback('/\[zrl(.*?)\[\/(zrl)\]/ism','\red_escape_codeblock',$body); - $body = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\ + $body = preg_replace_callback("/([^\]\='".'"'."\/\{]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\ +\,\(\)]+)/ismu", '\nakedoembed', $body); - $body = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\ + $body = preg_replace_callback("/([^\]\='".'"'."\/\{]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\ +\,\(\)]+)/ismu", '\red_zrl_callback', $body); $body = preg_replace_callback('/\[\$b64zrl(.*?)\[\/(zrl)\]/ism','\red_unescape_codeblock',$body); -- cgit v1.2.3 From 406ea67bbc9b67ca4bd80d80eb012bc68afc5262 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 2 May 2018 17:39:12 -0700 Subject: Provide admin delete ability if the viewer is admin but has no existing delete authority. For 3.5+ as a new string is involved. --- Zotlabs/Lib/ThreadItem.php | 4 ++++ Zotlabs/Module/Item.php | 21 ++++++++++++++------- include/items.php | 1 - 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php index 61a012f9d..b7fc8e65d 100644 --- a/Zotlabs/Lib/ThreadItem.php +++ b/Zotlabs/Lib/ThreadItem.php @@ -141,6 +141,10 @@ class ThreadItem { 'delete' => t('Delete'), ); } + elseif(is_site_admin()) { + $drop = [ 'dropping' => true, 'delete' => t('Admin Delete') ]; + } + // FIXME if($observer_is_pageowner) { $multidrop = array( diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index bba1dc02d..87f83e877 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -1084,7 +1084,7 @@ class Item extends \Zotlabs\Web\Controller { if((argc() == 3) && (argv(1) === 'drop') && intval(argv(2))) { require_once('include/items.php'); - $i = q("select id, uid, author_xchan, owner_xchan, source_xchan, item_type from item where id = %d limit 1", + $i = q("select id, uid, item_origin, author_xchan, owner_xchan, source_xchan, item_type from item where id = %d limit 1", intval(argv(2)) ); @@ -1094,14 +1094,21 @@ class Item extends \Zotlabs\Web\Controller { if(local_channel() && local_channel() == $i[0]['uid']) $local_delete = true; - $sys = get_sys_channel(); - if(is_site_admin() && $sys['channel_id'] == $i[0]['uid']) - $can_delete = true; - + // The site admin can delete any post/item on the site. + // If the item originated on this site+channel the deletion will propagate downstream. + // Otherwise just the local copy is removed. + + if(is_site_admin()) { + $local_delete = true; + if(intval($i[0]['item_origin'])) + $can_delete = true; + } + $ob_hash = get_observer_hash(); - if($ob_hash && ($ob_hash === $i[0]['author_xchan'] || $ob_hash === $i[0]['owner_xchan'] || $ob_hash === $i[0]['source_xchan'])) + if($ob_hash && ($ob_hash === $i[0]['author_xchan'] || $ob_hash === $i[0]['owner_xchan'] || $ob_hash === $i[0]['source_xchan'])) { $can_delete = true; - + } + if(! ($can_delete || $local_delete)) { notice( t('Permission denied.') . EOL); return; diff --git a/include/items.php b/include/items.php index 8bc4595b6..2c9d84ef3 100755 --- a/include/items.php +++ b/include/items.php @@ -3561,7 +3561,6 @@ function item_expire($uid,$days,$comment_days = 7) { drop_item($item['id'],false); } -// Zotlabs\Daemon\Master::Summon(array('Notifier','expire',$uid)); } function retain_item($id) { -- cgit v1.2.3 From 9713436f497a031e4369130dda40b415ff285fd8 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 2 May 2018 18:23:42 -0700 Subject: backend work to allow admin to delete photos. Still requires frontend work to give admin access to either the photos and/or the delete link. --- Zotlabs/Module/Item.php | 15 ++++++++++----- Zotlabs/Module/Photos.php | 41 +++++++++++++++++++++++------------------ include/photos.php | 26 ++++++++++++++++++++------ 3 files changed, 53 insertions(+), 29 deletions(-) diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 87f83e877..fd99c4a64 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -1084,6 +1084,8 @@ class Item extends \Zotlabs\Web\Controller { if((argc() == 3) && (argv(1) === 'drop') && intval(argv(2))) { require_once('include/items.php'); + + $i = q("select id, uid, item_origin, author_xchan, owner_xchan, source_xchan, item_type from item where id = %d limit 1", intval(argv(2)) ); @@ -1091,9 +1093,16 @@ class Item extends \Zotlabs\Web\Controller { if($i) { $can_delete = false; $local_delete = false; - if(local_channel() && local_channel() == $i[0]['uid']) + + if(local_channel() && local_channel() == $i[0]['uid']) { $local_delete = true; + } + $ob_hash = get_observer_hash(); + if($ob_hash && ($ob_hash === $i[0]['author_xchan'] || $ob_hash === $i[0]['owner_xchan'] || $ob_hash === $i[0]['source_xchan'])) { + $can_delete = true; + } + // The site admin can delete any post/item on the site. // If the item originated on this site+channel the deletion will propagate downstream. // Otherwise just the local copy is removed. @@ -1104,10 +1113,6 @@ class Item extends \Zotlabs\Web\Controller { $can_delete = true; } - $ob_hash = get_observer_hash(); - if($ob_hash && ($ob_hash === $i[0]['author_xchan'] || $ob_hash === $i[0]['owner_xchan'] || $ob_hash === $i[0]['source_xchan'])) { - $can_delete = true; - } if(! ($can_delete || $local_delete)) { notice( t('Permission denied.') . EOL); diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php index a143c4d4c..e21f3025c 100644 --- a/Zotlabs/Module/Photos.php +++ b/Zotlabs/Module/Photos.php @@ -102,14 +102,7 @@ class Photos extends \Zotlabs\Web\Controller { if($_REQUEST['dropalbum'] == t('Delete Album')) { - - // This is dangerous because we combined file storage and photos into one interface - // This function will remove all photos from any directory with the same name since - // we have not passed the path value. - - // The correct solution would be to use a full pathname from your storage root for 'album' - // We also need to prevent/block removing the storage root folder. - + $folder_hash = ''; $r = q("select * from attach where is_dir = 1 and uid = %d and hash = '%s'", @@ -124,7 +117,8 @@ class Photos extends \Zotlabs\Web\Controller { $res = array(); - + $admin_delete = false; + // get the list of photos we are about to delete if(remote_channel() && (! local_channel())) { @@ -133,6 +127,10 @@ class Photos extends \Zotlabs\Web\Controller { elseif(local_channel()) { $str = photos_album_get_db_idstr(local_channel(),$album); } + elseif(is_site_admin()) { + $str = photos_album_get_db_idstr_admin($page_owner_uid,$album); + $admin_delete = true; + } else { $str = null; } @@ -145,7 +143,7 @@ class Photos extends \Zotlabs\Web\Controller { ); if($r) { foreach($r as $i) { - attach_delete($page_owner_uid, $i['resource_id'], 1 ); + attach_delete($page_owner_uid, $i['resource_id'], true ); } } @@ -158,12 +156,14 @@ class Photos extends \Zotlabs\Web\Controller { // @FIXME do the same for the linked attach if($folder_hash) { - attach_delete($page_owner_uid,$folder_hash, 1); - - $sync = attach_export_data(\App::$data['channel'],$folder_hash, true); + attach_delete($page_owner_uid, $folder_hash, true ); + + if(! $admin_delete) { + $sync = attach_export_data(\App::$data['channel'],$folder_hash, true); - if($sync) - build_sync_packet($page_owner_uid,array('file' => array($sync))); + if($sync) + build_sync_packet($page_owner_uid,array('file' => array($sync))); + } } } @@ -181,17 +181,22 @@ class Photos extends \Zotlabs\Web\Controller { $r = q("SELECT id, resource_id FROM photo WHERE ( xchan = '%s' or uid = %d ) AND resource_id = '%s' LIMIT 1", dbesc($ob_hash), intval(local_channel()), - dbesc(\App::$argv[2]) + dbesc(argv(2)) ); if($r) { - attach_delete($page_owner_uid, $r[0]['resource_id'], 1 ); + attach_delete($page_owner_uid, $r[0]['resource_id'], true ); $sync = attach_export_data(\App::$data['channel'],$r[0]['resource_id'], true); if($sync) build_sync_packet($page_owner_uid,array('file' => array($sync))); } - + elseif(is_site_admin()) { + // If the admin deletes a photo, don't sync + attach_delete($page_owner_uid, argv(2), true); + } + + goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . $_SESSION['album_return']); } diff --git a/include/photos.php b/include/photos.php index 9ae0e6874..495043bbf 100644 --- a/include/photos.php +++ b/include/photos.php @@ -786,17 +786,31 @@ function photos_album_get_db_idstr($channel_id, $album, $remote_xchan = '') { ); } if ($r) { - $arr = array(); - foreach ($r as $rr) { - $arr[] = "'" . dbesc($rr['hash']) . "'" ; - } - $str = implode(',',$arr); - return $str; + return ids_to_querystr($r,'hash',true); } return false; } +function photos_album_get_db_idstr_admin($channel_id, $album) { + + if(! is_site_admin()) + return false; + + $r = q("SELECT hash from attach where uid = %d and folder = '%s' ", + intval($channel_id), + dbesc($album) + ); + + if ($r) { + return ids_to_querystr($r,'hash',true); + } + + return false; +} + + + /** * @brief Creates a new photo item. * -- cgit v1.2.3 From e9f49d9d9c02ef6b2f5259f9a323a8a2a2d75af5 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 2 May 2018 20:08:59 -0700 Subject: admin delete of files --- Zotlabs/Module/Filestorage.php | 39 +++++++++++++++++++++++++++++++-------- Zotlabs/Storage/Browser.php | 4 +++- include/attach.php | 2 +- view/js/main.js | 2 ++ view/tpl/cloud_directory.tpl | 4 ++-- 5 files changed, 39 insertions(+), 12 deletions(-) diff --git a/Zotlabs/Module/Filestorage.php b/Zotlabs/Module/Filestorage.php index 5c8557e5a..cd9ab601d 100644 --- a/Zotlabs/Module/Filestorage.php +++ b/Zotlabs/Module/Filestorage.php @@ -66,7 +66,7 @@ class Filestorage extends \Zotlabs\Web\Controller { $perms = get_all_perms($owner, $ob_hash); - if(! $perms['view_storage']) { + if(! ($perms['view_storage'] || is_site_admin())){ notice( t('Permission denied.') . EOL); return; } @@ -75,15 +75,29 @@ class Filestorage extends \Zotlabs\Web\Controller { // need to return for anyone other than the owner, despite the perms check for now. $is_owner = (((local_channel()) && ($owner == local_channel())) ? true : false); - if(! $is_owner) { + if(! ($is_owner || is_site_admin())){ info( t('Permission Denied.') . EOL ); return; } if(argc() > 3 && argv(3) === 'delete') { + + if(argc() > 4 && argv(4) === 'json') + $json_return = true; + + + $admin_delete = false; + if(! $perms['write_storage']) { - notice( t('Permission denied.') . EOL); - return; + if(is_site_admin()) { + $admin_delete = true; + } + else { + notice( t('Permission denied.') . EOL); + if($json_return) + json_return_and_die([ 'success' => false ]); + return; + } } $file = intval(argv(2)); @@ -92,22 +106,31 @@ class Filestorage extends \Zotlabs\Web\Controller { intval($owner) ); if(! $r) { + if($json_return) + json_return_and_die([ 'success' => false ]); + notice( t('File not found.') . EOL); goaway(z_root() . '/cloud/' . $which); } $f = $r[0]; - $channel = \App::get_channel(); + + $channel = channelx_by_n($owner); $url = get_cloud_url($channel['channel_id'], $channel['channel_address'], $f['hash']); attach_delete($owner, $f['hash']); - $sync = attach_export_data($channel, $f['hash'], true); - if($sync) { - build_sync_packet($channel['channel_id'], array('file' => array($sync))); + if(! $admin_delete) { + $sync = attach_export_data($channel, $f['hash'], true); + if($sync) { + build_sync_packet($channel['channel_id'], array('file' => array($sync))); + } } + if(json_return) + json_return_and_die([ 'success' => true ]); + goaway(dirname($url)); } diff --git a/Zotlabs/Storage/Browser.php b/Zotlabs/Storage/Browser.php index 508c39d22..f4f906ad1 100644 --- a/Zotlabs/Storage/Browser.php +++ b/Zotlabs/Storage/Browser.php @@ -241,7 +241,7 @@ class Browser extends DAV\Browser\Plugin { // put the array for this file together $ft['attachId'] = $this->findAttachIdByHash($attachHash); - $ft['fileStorageUrl'] = substr($fullPath, 0, strpos($fullPath, "cloud/")) . "filestorage/" . $this->auth->getCurrentUser(); + $ft['fileStorageUrl'] = substr($fullPath, 0, strpos($fullPath, "cloud/")) . "filestorage/" . $this->auth->owner_nick; $ft['icon'] = $icon; $ft['photo_icon'] = $photo_icon; $ft['attachIcon'] = (($size) ? $attachIcon : ''); @@ -276,6 +276,8 @@ class Browser extends DAV\Browser\Plugin { '$create' => t('Create'), '$upload' => t('Add Files'), '$is_owner' => $is_owner, + '$is_admin' => is_site_admin(), + '$admin_delete' => t('Admin Delete'), '$parentpath' => $parentpath, '$cpath' => bin2hex(\App::$query_string), '$tiles' => intval($_SESSION['cloud_tiles']), diff --git a/include/attach.php b/include/attach.php index 0d2b43b58..2a9badaac 100644 --- a/include/attach.php +++ b/include/attach.php @@ -1585,8 +1585,8 @@ function get_cloud_url($channel_id, $channel_name, $attachHash) { } } while ($parentHash); - $url = z_root() . '/cloud/' . $channel_name . '/' . $parentFullPath . find_filename_by_hash($channel_id, $attachHash); + $url = z_root() . '/cloud/' . $channel_name . '/' . $parentFullPath . find_filename_by_hash($channel_id, $attachHash); return $url; } diff --git a/view/js/main.js b/view/js/main.js index acb9b462f..3e24e8177 100644 --- a/view/js/main.js +++ b/view/js/main.js @@ -1057,7 +1057,9 @@ function doprofilelike(ident, verb) { $.get('like/' + ident + '?verb=' + verb, function() { window.location.href=window.location.href; }); } + function dropItem(url, object) { + var confirm = confirmDelete(); if(confirm) { $('body').css('cursor', 'wait'); diff --git a/view/tpl/cloud_directory.tpl b/view/tpl/cloud_directory.tpl index 1f0addc95..51178a9ba 100644 --- a/view/tpl/cloud_directory.tpl +++ b/view/tpl/cloud_directory.tpl @@ -65,10 +65,10 @@ {{$item.attachIcon}}
- + {{else}} - + {{if $is_admin}}{{else}}{{/if}} {{/if}} {{*{{$item.type}}*}} {{$item.sizeFormatted}} -- cgit v1.2.3 From 6bf5eea64670996fafb80f92a4b8ec6a44f22bb0 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 2 May 2018 22:05:55 -0700 Subject: make the cloud logging a bit less verbose until we actually need it. --- Zotlabs/Module/Oep.php | 2 +- Zotlabs/Storage/File.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Zotlabs/Module/Oep.php b/Zotlabs/Module/Oep.php index ec40bf9db..0f20a5f9a 100644 --- a/Zotlabs/Module/Oep.php +++ b/Zotlabs/Module/Oep.php @@ -72,7 +72,7 @@ class Oep extends \Zotlabs\Web\Controller { $url = $args['url']; $maxwidth = intval($args['maxwidth']); $maxheight = intval($args['maxheight']); - logger('processing display'); + if(preg_match('#//(.*?)/display/(.*?)(&|\?|$)#',$url,$matches)) { $res = $matches[2]; } diff --git a/Zotlabs/Storage/File.php b/Zotlabs/Storage/File.php index 53d5d3476..4610aceb7 100644 --- a/Zotlabs/Storage/File.php +++ b/Zotlabs/Storage/File.php @@ -49,7 +49,7 @@ class File extends DAV\Node implements DAV\IFile { $this->data = $data; $this->auth = $auth; - logger(print_r($this->data, true), LOGGER_DATA); + // logger(print_r($this->data, true), LOGGER_DATA); } /** -- cgit v1.2.3 From 459ec78a5e3cb09ee908fd7810bbb0b80b2e4713 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 2 May 2018 22:59:21 -0700 Subject: provide easy access to the autoperms setting for forum and repository channels. This may be needed in the future to protect an existing forum from assault by spammers with changing identities. The forum can quickly be turned into membership by approval and either left that way permanently or hopefully reversed at a later date. Previously this would require switching to expert mode or setting a pconfig manually. --- Zotlabs/Module/Settings/Channel.php | 15 +++++++++++++-- view/tpl/settings.tpl | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Zotlabs/Module/Settings/Channel.php b/Zotlabs/Module/Settings/Channel.php index 65b9b197e..beb62a3a3 100644 --- a/Zotlabs/Module/Settings/Channel.php +++ b/Zotlabs/Module/Settings/Channel.php @@ -146,6 +146,7 @@ class Channel { $unkmail = (((x($_POST,'unkmail')) && (intval($_POST['unkmail']) == 1)) ? 1: 0); $cntunkmail = ((x($_POST,'cntunkmail')) ? intval($_POST['cntunkmail']) : 0); $suggestme = ((x($_POST,'suggestme')) ? intval($_POST['suggestme']) : 0); + $autoperms = ((x($_POST,'autoperms')) ? intval($_POST['autoperms']) : 0); $post_newfriend = (($_POST['post_newfriend'] == 1) ? 1: 0); $post_joingroup = (($_POST['post_joingroup'] == 1) ? 1: 0); @@ -252,6 +253,7 @@ class Channel { set_pconfig(local_channel(),'system','default_permcat',$defpermcat); set_pconfig(local_channel(),'system','email_notify_host',$mailhost); set_pconfig(local_channel(),'system','profile_assign',$profile_assign); + set_pconfig(local_channel(),'system','autoperms',$autoperms); $r = q("update channel set channel_name = '%s', channel_pageflags = %d, channel_timezone = '%s', channel_location = '%s', channel_notifyflags = %d, channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d $set_perms where channel_id = %d", dbesc($username), @@ -479,13 +481,21 @@ class Channel { if($permissions_role === 'social_party') $permissions_role = 'social_federation'; - + if(in_array($permissions_role,['forum','repository'])) + $autoperms = replace_macros(get_markup_template('field_checkbox.tpl'), [ + '$field' => [ 'autoperms',t('Automatic membership approval'), ((get_pconfig(local_channel(),'system','autoperms')) ? 1 : 0), t('If enabled, connection requests will be approved without your interaction'), $yes_no ]]); + else + $autoperms = ''; + $permissions_set = (($permissions_role != 'custom') ? true : false); $perm_roles = \Zotlabs\Access\PermissionRoles::roles(); if((get_account_techlevel() < 4) && $permissions_role !== 'custom') unset($perm_roles[t('Other')]); + + + $vnotify = get_pconfig(local_channel(),'system','vnotify'); $always_show_in_notices = get_pconfig(local_channel(),'system','always_show_in_notices'); if($vnotify === false) @@ -497,6 +507,7 @@ class Channel { $disable_discover_tab = intval(get_config('system','disable_discover_tab',1)) == 1; $site_firehose = intval(get_config('system','site_firehose',0)) == 1; + $o .= replace_macros($stpl,array( '$ptitle' => t('Channel Settings'), @@ -553,7 +564,7 @@ class Channel { '$unkmail' => $unkmail, '$cntunkmail' => array('cntunkmail', t('Maximum private messages per day from unknown people:'), intval($channel['channel_max_anon_mail']) ,t("Useful to reduce spamming")), - + '$autoperms' => $autoperms, '$h_not' => t('Notification Settings'), '$activity_options' => t('By default post a status message when:'), '$post_newfriend' => array('post_newfriend', t('accepting a friend request'), $post_newfriend, '', $yes_no), diff --git a/view/tpl/settings.tpl b/view/tpl/settings.tpl index d258f1992..b5e871c36 100755 --- a/view/tpl/settings.tpl +++ b/view/tpl/settings.tpl @@ -45,6 +45,7 @@
{{include file="field_select_grouped.tpl" field=$role}} + {{$autoperms}}
-- cgit v1.2.3