aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Zotlabs/Lib/Activity.php25
-rw-r--r--Zotlabs/Module/Item.php51
-rw-r--r--Zotlabs/Module/Lockview.php41
-rw-r--r--Zotlabs/Module/Photo.php19
-rw-r--r--Zotlabs/Module/Settings/Privacy.php5
-rw-r--r--Zotlabs/Module/Wall_attach.php22
-rw-r--r--Zotlabs/Module/Wall_upload.php1
-rw-r--r--include/attach.php54
-rw-r--r--include/items.php130
-rw-r--r--include/security.php12
-rw-r--r--view/tpl/settings_privacy.tpl1
11 files changed, 307 insertions, 54 deletions
diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php
index db2dfd84a..8bb157347 100644
--- a/Zotlabs/Lib/Activity.php
+++ b/Zotlabs/Lib/Activity.php
@@ -459,6 +459,27 @@ class Activity {
$ret['id'] = ((strpos($i['mid'], 'http') === 0) ? $i['mid'] : z_root() . '/item/' . urlencode($i['mid']));
$ret['diaspora:guid'] = $i['uuid'];
+ $images = [];
+ $has_images = preg_match_all('/\[[zi]mg(.*?)](.*?)\[/ism', $i['body'], $images, PREG_SET_ORDER);
+
+ // provide ocap access token for private media.
+ // set this for descendants even if the current item is not private
+ // because it may have been relayed from a private item.
+
+ $token = get_iconfig($i, 'ocap', 'relay');
+ if ($token && $has_images) {
+ for ($n = 0; $n < count($images); $n++) {
+ $match = $images[$n];
+ if (str_starts_with($match[1], '=http') && str_contains($match[1], z_root() . '/photo/')) {
+ $i['body'] = str_replace($match[1], $match[1] . '?token=' . $token, $i['body']);
+ $images[$n][2] = substr($match[1], 1) . '?token=' . $token;
+ } elseif (str_contains($match[2], z_root() . '/photo/')) {
+ $i['body'] = str_replace($match[2], $match[2] . '?token=' . $token, $i['body']);
+ $images[$n][2] = $match[2] . '?token=' . $token;
+ }
+ }
+ }
+
if ($i['title'])
$ret['name'] = $i['title'];
@@ -627,10 +648,10 @@ class Activity {
}
if (isset($att['type']) && strpos($att['type'], 'image')) {
- $ret[] = ['type' => 'Image', 'url' => $att['href']];
+ $ret[] = ['type' => 'Image', 'mediaType' => $att['type'], 'name' => $att['title'], 'url' => $att['href']];
}
else {
- $ret[] = ['type' => 'Link', 'mediaType' => $att['type'], 'href' => $att['href']];
+ $ret[] = ['type' => 'Link', 'mediaType' => $att['type'], 'name' => $att['title'], 'href' => $att['href']];
}
}
}
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index a5f66d72e..b564396c9 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -218,6 +218,22 @@ class Item extends Controller {
);
}
+ $bear = Activity::token_from_request();
+ if ($bear) {
+ logger('bear: ' . $bear, LOGGER_DEBUG);
+ if (!$i) {
+ $t = q("select * from iconfig where cat = 'ocap' and k = 'relay' and v = '%s'",
+ dbesc($bear)
+ );
+ if ($t) {
+ $i = q("select id as item_id from item where uuid = '%s' and id = %d $item_normal limit 1",
+ dbesc($item_id),
+ intval($t[0]['iid'])
+ );
+ }
+ }
+ }
+
if (!$i) {
http_status_exit(403, 'Forbidden');
}
@@ -286,7 +302,9 @@ class Item extends Controller {
if ((!local_channel()) && (!remote_channel()) && (!x($_REQUEST, 'anonname')))
return;
- $uid = local_channel();
+ $uid = local_channel();
+ $token = '';
+
$channel = null;
$observer = null;
$datarray = [];
@@ -809,7 +827,6 @@ class Item extends Controller {
require_once('include/text.php');
-
// BBCODE alert: the following functions assume bbcode input
// and will require alternatives for alternative content-types (text/html, text/markdown, text/plain, etc.)
// we may need virtual or template classes to implement the possible alternatives
@@ -845,6 +862,21 @@ class Item extends Controller {
$private = 2;
}
+ if ($private && get_pconfig($profile_uid, 'system', 'ocap_enabled')) {
+ // for edited posts, re-use any existing OCAP token (if found).
+ // Otherwise generate a new one.
+
+ if ($iconfig) {
+ foreach ($iconfig as $cfg) {
+ if ($cfg['cat'] === 'ocap' && $cfg['k'] === 'relay') {
+ $token = $cfg['v'];
+ }
+ }
+ }
+ if (!$token) {
+ $token = new_token();
+ }
+ }
/**
*
@@ -866,9 +898,9 @@ class Item extends Controller {
*/
if (!$preview) {
- fix_attached_photo_permissions($profile_uid, $owner_xchan['xchan_hash'], ((strpos($body, '[/crypt]')) ? $_POST['media_str'] : $body), $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
- fix_attached_photo_permissions($profile_uid, $owner_xchan['xchan_hash'], ((strpos($summary, '[/crypt]')) ? $_POST['media_str'] : $summary), $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
- fix_attached_file_permissions($channel, $observer['xchan_hash'], ((strpos($body, '[/crypt]')) ? $_POST['media_str'] : $body), $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
+ fix_attached_permissions($profile_uid, ((strpos($body, '[/crypt]')) ? $_POST['media_str'] : $body), $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny, $token);
+ //fix_attached_photo_permissions($profile_uid, $owner_xchan['xchan_hash'], ((strpos($body, '[/crypt]')) ? $_POST['media_str'] : $body), $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny, $token);
+ //fix_attached_file_permissions($channel, $observer['xchan_hash'], ((strpos($body, '[/crypt]')) ? $_POST['media_str'] : $body), $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny, $token);
}
$attachments = '';
@@ -951,14 +983,12 @@ class Item extends Controller {
}
}
-
$item_unseen = ((local_channel() != $profile_uid) ? 1 : 0);
$item_wall = ((isset($_REQUEST['type']) && ($_REQUEST['type'] === 'wall' || $_REQUEST['type'] === 'wall-comment')) ? 1 : 0);
$item_origin = (($origin) ? 1 : 0);
$item_consensus = (($consensus) ? 1 : 0);
$item_nocomment = (($nocomment) ? 1 : 0);
-
// determine if this is a wall post
if ($parent) {
@@ -1107,8 +1137,13 @@ class Item extends Controller {
if (!empty_acl($datarray))
$datarray['public_policy'] = '';
- if ($iconfig)
+ if ($iconfig) {
$datarray['iconfig'] = $iconfig;
+ }
+
+ if ($token) {
+ IConfig::set($datarray, 'ocap', 'relay', $token);
+ }
// preview mode - prepare the body for display and send it via json
diff --git a/Zotlabs/Module/Lockview.php b/Zotlabs/Module/Lockview.php
index bac3a7eb9..0c8e23f8c 100644
--- a/Zotlabs/Module/Lockview.php
+++ b/Zotlabs/Module/Lockview.php
@@ -15,6 +15,7 @@ class Lockview extends Controller {
$atoken_xchans = [];
$access_list = [];
$guest_access_list = [];
+ $ocap_access_list = [];
if (local_channel()) {
$at = q("select * from atoken where atoken_uid = %d",
@@ -166,6 +167,24 @@ class Lockview extends Controller {
}
}
}
+ $ocap_tokens = [];
+ foreach ($allowed_users as $allowed_user) {
+ $allowed_user = trim($allowed_user, '\'');
+ if (str_starts_with($allowed_user, 'token:')) {
+ $ocap_tokens[] = str_replace('token:', '', $allowed_user);
+ }
+ }
+
+ if ($ocap_tokens) {
+ stringify_array_elms($ocap_tokens, true);
+ $ocap_mids = dbq("select id, mid from item where id in (select iid from iconfig where cat = 'ocap' and k = 'relay' and v in (" . implode(', ', $ocap_tokens) . "))");
+
+ foreach ($ocap_mids as $ocap) {
+ $ocap_access_list[] = '<a href="' . $ocap['mid'] . '" class="dropdown-item-text" target="_blank">' . t('Item') . ' ' . $ocap['id'] . '</a>';
+ }
+
+ }
+
}
$profile_groups = [];
@@ -205,9 +224,6 @@ class Lockview extends Controller {
}
if ($atokens && $allowed_xchans && $url) {
-
- $guest_access_list = [];
-
$allowed_xchans = array_unique($allowed_xchans);
foreach ($atokens as $atoken) {
if (in_array($atoken['xchan_hash'], $allowed_xchans)) {
@@ -216,22 +232,25 @@ class Lockview extends Controller {
}
}
- $access_list_header = '';
+ $access_list_header = '<div class="dropdown-header text-uppercase h6">' . t('Access') . '</div>';
+ $guest_access_list_header = '<div class="dropdown-header text-uppercase h6">' . t('Guest access') . '</div>';
+ $ocap_access_list_header = '<div class="dropdown-header text-uppercase h6">' . t('OCAP access') . '</div>';
+ $divider = '<div class="dropdown-divider"></div>';
+ $str = '';
+
if ($access_list) {
- $access_list_header = '<div class="dropdown-header text-uppercase h6">' . t('Access') . '</div>';
+ $str .= $access_list_header . implode($access_list);
}
- $guest_access_list_header = '';
if ($guest_access_list) {
- $guest_access_list_header = '<div class="dropdown-header text-uppercase h6">' . t('Guest access') . '</div>';
+ $str .= $divider . $guest_access_list_header . implode($guest_access_list);
}
- $divider = '';
- if ($access_list && $guest_access_list) {
- $divider = '<div class="dropdown-divider"></div>';
+ if ($ocap_access_list) {
+ $str .= $divider . $ocap_access_list_header . implode($ocap_access_list);
}
- echo $access_list_header . implode($access_list) . $divider . $guest_access_list_header . implode($guest_access_list);
+ echo $str;
killme();
}
diff --git a/Zotlabs/Module/Photo.php b/Zotlabs/Module/Photo.php
index fa87d96e5..cb83d78d3 100644
--- a/Zotlabs/Module/Photo.php
+++ b/Zotlabs/Module/Photo.php
@@ -46,7 +46,7 @@ class Photo extends \Zotlabs\Web\Controller {
dbesc(argv(1))
);
if ($r) {
- $allowed = attach_can_view($r[0]['uid'],$observer_xchan,argv(1)/*,$bear*/);
+ $allowed = attach_can_view($r[0]['uid'], $observer_xchan, argv(1), $bear);
}
if (! $allowed) {
http_status_exit(404,'Permission denied.');
@@ -154,6 +154,11 @@ class Photo extends \Zotlabs\Web\Controller {
}
else {
+ $bear = Activity::token_from_request();
+ if ($bear) {
+ logger('bear: ' . $bear, LOGGER_DEBUG);
+ }
+
/**
* Other photos
*/
@@ -223,7 +228,7 @@ class Photo extends \Zotlabs\Web\Controller {
}
if($allowed === (-1))
- $allowed = attach_can_view($r[0]['uid'],$observer_xchan,$photo);
+ $allowed = attach_can_view($r[0]['uid'], $observer_xchan, $photo, $bear);
$channel = channelx_by_n($r[0]['uid']);
@@ -262,13 +267,13 @@ class Photo extends \Zotlabs\Web\Controller {
http_status_exit(404,'not found');
}
- if(! $data)
- killme();
+ if(! $data)
+ killme();
- $etag = '"' . md5($data . $modified) . '"';
+ $etag = '"' . md5($data . $modified) . '"';
- if($modified == 0)
- $modified = time();
+ if($modified == 0)
+ $modified = time();
header_remove('Pragma');
if((isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] === $etag) || (!isset($_SERVER['HTTP_IF_NONE_MATCH']) && isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $_SERVER['HTTP_IF_MODIFIED_SINCE'] === gmdate("D, d M Y H:i:s", $modified) . " GMT")) {
diff --git a/Zotlabs/Module/Settings/Privacy.php b/Zotlabs/Module/Settings/Privacy.php
index 65d5b538e..911c03aa5 100644
--- a/Zotlabs/Module/Settings/Privacy.php
+++ b/Zotlabs/Module/Settings/Privacy.php
@@ -25,6 +25,9 @@ class Privacy {
$permit_all_mentions = (((x($_POST, 'permit_all_mentions')) && (intval($_POST['permit_all_mentions']) == 1)) ? 1 : 0);
set_pconfig(local_channel(), 'system', 'permit_all_mentions', $permit_all_mentions);
+ $ocap_enabled = (((x($_POST, 'ocap_enabled')) && (intval($_POST['ocap_enabled']) == 1)) ? 1 : 0);
+ set_pconfig(local_channel(), 'system', 'ocap_enabled', $ocap_enabled);
+
$role = get_pconfig(local_channel(), 'system', 'permissions_role');
if ($role === 'custom') {
@@ -103,6 +106,7 @@ class Privacy {
$index_opt_out = get_pconfig(local_channel(), 'system', 'index_opt_out');
$group_actor = get_pconfig(local_channel(), 'system', 'group_actor');
$permit_all_mentions = get_pconfig(local_channel(), 'system', 'permit_all_mentions');
+ $ocap_enabled = get_pconfig(local_channel(), 'system', 'ocap_enabled');
$permissions_role = get_pconfig(local_channel(), 'system', 'permissions_role', 'custom');
$permission_limits = ($permissions_role === 'custom');
@@ -125,6 +129,7 @@ class Privacy {
'$index_opt_out' => ['index_opt_out', t('Opt-out of search engine indexing'), $index_opt_out, '', [t('No'), t('Yes')]],
'$group_actor' => ['group_actor', t('Group actor'), $group_actor, t('Allow this channel to act as a forum'), [t('No'), t('Yes')]],
'$permit_all_mentions' => ['permit_all_mentions', t('Accept all messages which mention you'), $permit_all_mentions, t('This setting bypasses normal permissions'), [t('No'), t('Yes')]],
+ '$ocap_enabled' => ['ocap_enabled', t('Enable OCAP access'), $ocap_enabled, t('Allow limited posts access to linked private media'), [t('No'), t('Yes')]],
]);
return $o;
diff --git a/Zotlabs/Module/Wall_attach.php b/Zotlabs/Module/Wall_attach.php
index 2c0eeec77..80892f0f3 100644
--- a/Zotlabs/Module/Wall_attach.php
+++ b/Zotlabs/Module/Wall_attach.php
@@ -18,10 +18,10 @@ class Wall_attach extends \Zotlabs\Web\Controller {
function post() {
-
+
$using_api = false;
- $result = [];
+ $result = [];
if($_REQUEST['api_source'] && array_key_exists('media',$_FILES)) {
$using_api = true;
@@ -69,7 +69,7 @@ class Wall_attach extends \Zotlabs\Web\Controller {
];
}
}
- else {
+ else {
if(! array_key_exists('userfile',$_FILES)) {
$_FILES['userfile'] = [
'name' => $_FILES['files']['name'],
@@ -82,18 +82,18 @@ class Wall_attach extends \Zotlabs\Web\Controller {
}
$observer = \App::get_observer();
-
-
+
+
$def_album = get_pconfig($channel['channel_id'],'system','photo_path');
$def_attach = get_pconfig($channel['channel_id'],'system','attach_path');
-
- $r = attach_store($channel,(($observer) ? $observer['xchan_hash'] : ''),'', array('source' => 'editor', 'visible' => 0, 'album' => $def_album, 'directory' => $def_attach, 'allow_cid' => '<' . $channel['channel_hash'] . '>'));
+
+ $r = attach_store($channel,(($observer) ? $observer['xchan_hash'] : ''),'', array('source' => 'editor', 'visible' => 0, 'album' => $def_album, 'directory' => $def_attach, 'flags' => 1, 'allow_cid' => '<' . $channel['channel_hash'] . '>'));
if(! $r['success']) {
notice( $r['message'] . EOL);
killme();
}
-
+
if(intval($r['data']['is_photo'])) {
$s = "\n\n" . $r['body'] . "\n\n";
}
@@ -130,7 +130,7 @@ class Wall_attach extends \Zotlabs\Web\Controller {
logger('unable to read svg data file: ' . 'store/' . $channel['channel_address'] . '/' . $r['data']['os_path']);
}
}
-
+
$s .= "\n\n" . '[attachment]' . $r['data']['hash'] . ',' . $r['data']['revision'] . '[/attachment]' . "\n";
}
@@ -144,8 +144,8 @@ class Wall_attach extends \Zotlabs\Web\Controller {
$result['message'] = $s;
json_return_and_die($result);
-
+
}
-
+
}
diff --git a/Zotlabs/Module/Wall_upload.php b/Zotlabs/Module/Wall_upload.php
index 3e979588c..4a6eee8f9 100644
--- a/Zotlabs/Module/Wall_upload.php
+++ b/Zotlabs/Module/Wall_upload.php
@@ -12,7 +12,6 @@ class Wall_upload extends \Zotlabs\Web\Controller {
function post() {
-
$using_api = ((x($_FILES,'media')) ? true : false);
if($using_api) {
diff --git a/include/attach.php b/include/attach.php
index b7fb17f38..4465a67fe 100644
--- a/include/attach.php
+++ b/include/attach.php
@@ -338,36 +338,46 @@ function attach_by_id($id, $observer_hash) {
return $ret;
}
-function attach_can_view($uid,$ob_hash,$resource) {
+function attach_can_view($uid, $ob_hash, $resource, $token = EMPTY_STR) {
- $sql_extra = permissions_sql($uid,$ob_hash);
+ $sql_extra = permissions_sql($uid, $ob_hash, '', $token);
$hash = $resource;
- if(! perm_is_allowed($uid,$ob_hash,'view_storage')) {
- return false;
+ if (!$token) {
+ if(! perm_is_allowed($uid, $ob_hash, 'view_storage')) {
+ return false;
+ }
}
$r = q("select folder from attach where hash = '%s' and uid = %d $sql_extra",
dbesc($hash),
intval($uid)
);
- if(! $r) {
+
+ if(!$r) {
return false;
}
- return attach_can_view_folder($uid,$ob_hash,$r[0]['folder']);
+ // don't perform recursive folder check when using OCAP. Only when using ACL access.
+ // For OCAP if the token is valid they can see the thing.
+
+ if ($token) {
+ return true;
+ }
+
+ return attach_can_view_folder($uid, $ob_hash, $r[0]['folder'], $token);
}
-function attach_can_view_folder($uid,$ob_hash,$folder_hash) {
+function attach_can_view_folder($uid, $ob_hash, $folder_hash, $token = EMPTY_STR) {
- $sql_extra = permissions_sql($uid,$ob_hash);
+ $sql_extra = permissions_sql($uid, $ob_hash, '', $token);
$hash = $folder_hash;
- if(! $folder_hash) {
- return perm_is_allowed($uid,$ob_hash,'view_storage');
+ if(!$folder_hash && !$token) {
+ return perm_is_allowed($uid, $ob_hash, 'view_storage');
}
@@ -508,7 +518,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
$upload_path = $arr['directory'] ?? '';
$visible = $arr['visible'] ?? 0;
$notify = $arr['notify'] ?? 0;
-
+ $flags = (($arr && array_key_exists('flags', $arr)) ? intval($arr['flags']) : 0);
$observer = array();
$dosync = ((array_key_exists('nosync',$arr) && $arr['nosync']) ? 0 : 1);
@@ -933,8 +943,8 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
);
}
else {
- $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, content, created, edited, os_path, display_path, allow_cid, allow_gid,deny_cid, deny_gid )
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
+ $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, flags, content, created, edited, os_path, display_path, allow_cid, allow_gid,deny_cid, deny_gid )
+ VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
intval($channel['channel_account_id']),
intval($channel_id),
dbesc($hash),
@@ -946,6 +956,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
intval(0),
intval(1),
intval($is_photo),
+ intval($flags),
dbescbin($os_basepath . $os_relpath),
dbesc($created),
dbesc($created),
@@ -1413,6 +1424,23 @@ function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gi
if(! $r)
return;
+ $private = $allow_cid || $allow_gid || $deny_cid || $deny_gid;
+
+ // preserve any existing tokens that may have been set for this file
+ // @fixme - we need a way to unconditionally clear these if desired.
+
+ if ($private) {
+ $token_matches = null;
+ if (preg_match_all('/\<token:(.*?)\>/', $r[0]['allow_cid'], $token_matches, PREG_SET_ORDER)) {
+ foreach ($token_matches as $m) {
+ $tok = '<token:' . $m[1] . '>';
+ if (!str_contains($allow_cid, $tok)) {
+ $allow_cid .= $tok;
+ }
+ }
+ }
+ }
+
if(intval($r[0]['is_dir'])) {
if($recurse) {
$r = q("select hash, flags, is_dir from attach where folder = '%s' and uid = %d",
diff --git a/include/items.php b/include/items.php
index f6a93cc2c..a74fe8b50 100644
--- a/include/items.php
+++ b/include/items.php
@@ -5009,6 +5009,136 @@ function fix_attached_file_permissions($channel,$observer_hash,$body,
}
}
+function list_attached_local_files($body) {
+
+ $files = [];
+ $match = [];
+
+ // match img and zmg image links
+ if (preg_match_all("/\[[zi]mg(.*?)](.*?)\[\/[zi]mg]/", $body, $match)) {
+ $images = array_merge($match[1], $match[2]);
+ if ($images) {
+ foreach ($images as $image) {
+ if (!stristr($image, z_root() . '/photo/')) {
+ continue;
+ }
+ $image_uri = substr($image,strrpos($image,'/') + 1);
+ if (str_contains($image_uri, '-')) {
+ $image_uri = substr($image_uri,0, strrpos($image_uri,'-'));
+ }
+ if (str_contains($image_uri, '.')) {
+ $image_uri = substr($image_uri,0, strpos($image_uri,'.'));
+ }
+ if ($image_uri && !in_array($image_uri, $files)) {
+ $files[] = $image_uri;
+ }
+ }
+ }
+ }
+ if (preg_match_all("/\[attachment](.*?)\[\/attachment]/",$body,$match)) {
+ $attaches = $match[1];
+ if ($attaches) {
+ foreach ($attaches as $attach) {
+ $hash = substr($attach,0,strpos($attach,','));
+ if ($hash && !in_array($hash, $files)) {
+ $files[] = $hash;
+ }
+ }
+ }
+ }
+
+ return $files;
+}
+
+function fix_attached_permissions($uid, $body, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny, $token = EMPTY_STR) {
+
+ $files = list_attached_local_files($body);
+
+ if (! $files) {
+ return;
+ }
+
+ foreach ($files as $file) {
+ $attach_q = q("select id, hash, flags, is_photo, allow_cid, allow_gid, deny_cid, deny_gid from attach where hash = '%s' and uid = %d",
+ dbesc($file),
+ intval($uid)
+ );
+
+ if (! $attach_q) {
+ continue;
+ }
+
+ $attach = array_shift($attach_q);
+
+ $new_public = !(($str_contact_allow || $str_group_allow || $str_contact_deny || $str_group_deny));
+ $existing_public = !(($attach['allow_cid'] || $attach['allow_gid'] || $attach['deny_cid'] || $attach['deny_gid']));
+
+ if ($existing_public) {
+ // permissions have already been fixed and they are public. There's nothing for us to do.
+ continue;
+ }
+
+ // if flags & 1, the attachment was uploaded directly into a post and needs to have permissions corrected
+ // or - if it is a private file and a new token was generated, we'll need to add the token to the ACL.
+
+ if (((intval($attach['flags']) & 1) !== 1) && (! $token)) {
+ continue;
+ }
+
+ $item_private = 0;
+
+ if ($new_public === false) {
+ $item_private = (($str_group_allow || ($str_contact_allow && substr_count($str_contact_allow,'<') > 2)) ? 1 : 2);
+
+ // preserve any existing tokens that may have been set for this file
+ $token_matches = null;
+ if (preg_match_all('/<token:(.*?)>/',$attach['allow_cid'],$token_matches, PREG_SET_ORDER)) {
+ foreach ($token_matches as $m) {
+ $tok = '<token:' . $m[1] . '>';
+ if (!str_contains($str_contact_allow, $tok)) {
+ $str_contact_allow .= $tok;
+ }
+ }
+ }
+ if ($token && !str_contains($str_contact_allow, $token)) {
+ $str_contact_allow .= '<token:' . $token . '>';
+ }
+ }
+
+ q("update attach SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', flags = 0
+ WHERE id = %d AND uid = %d",
+ dbesc($str_contact_allow),
+ dbesc($str_group_allow),
+ dbesc($str_contact_deny),
+ dbesc($str_group_deny),
+ intval($attach['id']),
+ intval($uid)
+ );
+
+ if ($attach['is_photo']) {
+ $r = q("UPDATE photo SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s'
+ WHERE resource_id = '%s' AND uid = %d ",
+ dbesc($str_contact_allow),
+ dbesc($str_group_allow),
+ dbesc($str_contact_deny),
+ dbesc($str_group_deny),
+ dbesc($file),
+ intval($uid)
+ );
+
+ $r = q("UPDATE item SET allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', item_private = %d
+ WHERE resource_id = '%s' AND 'resource_type' = 'photo' AND uid = %d",
+ dbesc($str_contact_allow),
+ dbesc($str_group_allow),
+ dbesc($str_contact_deny),
+ dbesc($str_group_deny),
+ intval($item_private),
+ dbesc($file),
+ intval($uid)
+ );
+ }
+ }
+}
function item_create_edit_activity($post) {
diff --git a/include/security.php b/include/security.php
index 2fbe1da1a..539e5f5b5 100644
--- a/include/security.php
+++ b/include/security.php
@@ -330,7 +330,7 @@ function change_channel($change_channel) {
* @return string additional SQL where statement
*/
-function permissions_sql($owner_id, $remote_observer = null, $table = '') {
+function permissions_sql($owner_id, $remote_observer = null, $table = '', $token = EMPTY_STR) {
$local_channel = local_channel();
@@ -412,6 +412,16 @@ function permissions_sql($owner_id, $remote_observer = null, $table = '') {
dbesc($gs)
);
}
+
+ /*
+ * OCAP token access
+ */
+
+ elseif ($token) {
+ $sql = " AND ( {$table}allow_cid like '" . protect_sprintf('%<token:' . $token . '>%') .
+ "' OR ( {$table}allow_cid = '' AND {$table}allow_gid = '' AND {$table}deny_cid = '' AND {$table}deny_gid = '' ) )";
+ }
+
}
return $sql;
diff --git a/view/tpl/settings_privacy.tpl b/view/tpl/settings_privacy.tpl
index 77d125e41..ae81cee78 100644
--- a/view/tpl/settings_privacy.tpl
+++ b/view/tpl/settings_privacy.tpl
@@ -11,6 +11,7 @@
{{include file="field_checkbox.tpl" field=$index_opt_out}}
{{include file="field_checkbox.tpl" field=$autoperms}}
{{include file="field_checkbox.tpl" field=$permit_all_mentions}}
+ {{include file="field_checkbox.tpl" field=$ocap_enabled}}
{{if $sec_addon}}
{{$sec_addon}}