function pubsub_init(&$a) { $nick = argc() > 1 ? escape_tags(trim(argv(1))) : ''; $contact_id = argc() > 2 ? intval(argv(2)) : 0; if ($_SERVER['REQUEST_METHOD'] === 'GET') { $hub_mode = x($_GET, 'hub_mode') ? notags(trim($_GET['hub_mode'])) : ''; $hub_topic = x($_GET, 'hub_topic') ? notags(trim($_GET['hub_topic'])) : ''; $hub_challenge = x($_GET, 'hub_challenge') ? notags(trim($_GET['hub_challenge'])) : ''; $hub_lease = x($_GET, 'hub_lease_seconds') ? notags(trim($_GET['hub_lease_seconds'])) : ''; $hub_verify = x($_GET, 'hub_verify_token') ? notags(trim($_GET['hub_verify_token'])) : ''; logger('pubsub: Subscription from ' . $_SERVER['REMOTE_ADDR']); logger('pubsub: data: ' . print_r($_GET, true), LOGGER_DATA); $subscribe = $hub_mode === 'subscribe' ? 1 : 0; $channel = channelx_by_nick($nick); if (!$channel) { http_status_exit(404, 'not found.'); } $connections = abook_connections($channel['channel_id'], ' and abook_id = ' . $contact_id); if ($connections) { $xchan = $connections[0]; } else { logger('connection ' . $contact_id . ' not found.'); http_status_exit(404, 'not found.'); } if ($hub_verify) { $verify = get_abconfig($channel['channel_id'], $xchan['xchan_hash'], 'pubsubhubbub', 'verify_token'); if ($verify != $hub_verify) { logger('hub verification failed.'); http_status_exit(404, 'not found.'); } } $feed_url = z_root() . '/feed/' . $channel['channel_address']; if ($hub_topic) { if (!link_compare($hub_topic, $feed_url)) { logger('hub topic ' . $hub_topic . ' != ' . $feed_url); // should abort but let's humour them. } } $contact = $r[0]; // We must initiate an unsubscribe request with a verify_token. // Don't allow outsiders to unsubscribe us. if ($hub_mode === 'unsubscribe') { if (!strlen($hub_verify)) { logger('pubsub: bogus unsubscribe'); http_status_exit(403, 'permission denied.'); } logger('pubsub: unsubscribe success'); } if ($hub_mode) { set_abconfig($channel['channel_id'], $xchan['xchan_hash'], 'pubsubhubbub', 'subscribed', intval($subscribe)); } header($_SERVER["SERVER_PROTOCOL"] . ' 200 ' . 'OK'); echo $hub_challenge; killme(); } }
function post() { $channel = \App::get_channel(); check_form_security_token_redirectOnErr('/settings/tokens', 'settings_tokens'); $token_errs = 0; if (array_key_exists('token', $_POST)) { $atoken_id = $_POST['atoken_id'] ? intval($_POST['atoken_id']) : 0; $name = trim(escape_tags($_POST['name'])); $token = trim($_POST['token']); if (!$name || !$token) { $token_errs++; } if (trim($_POST['expires'])) { $expires = datetime_convert(date_default_timezone_get(), 'UTC', $_POST['expires']); } else { $expires = NULL_DATE; } $max_atokens = service_class_fetch(local_channel(), 'access_tokens'); if ($max_atokens) { $r = q("select count(atoken_id) as total where atoken_uid = %d", intval(local_channel())); if ($r && intval($r[0]['total']) >= $max_tokens) { notice(sprintf(t('This channel is limited to %d tokens'), $max_tokens) . EOL); return; } } } if ($token_errs) { notice(t('Name and Password are required.') . EOL); return; } if ($atoken_id) { $r = q("update atoken set atoken_name = '%s', atoken_token = '%s', atoken_expires = '%s' \n\t\t\t\twhere atoken_id = %d and atoken_uid = %d", dbesc($name), dbesc($token), dbesc($expires), intval($atoken_id), intval($channel['channel_id'])); } else { $r = q("insert into atoken ( atoken_aid, atoken_uid, atoken_name, atoken_token, atoken_expires )\n\t\t\t\tvalues ( %d, %d, '%s', '%s', '%s' ) ", intval($channel['channel_account_id']), intval($channel['channel_id']), dbesc($name), dbesc($token), dbesc($expires)); } $atoken_xchan = substr($channel['channel_hash'], 0, 16) . '.' . $name; $all_perms = \Zotlabs\Access\Permissions::Perms(); if ($all_perms) { foreach ($all_perms as $perm => $desc) { if (array_key_exists('perms_' . $perm, $_POST)) { set_abconfig($channel['channel_id'], $atoken_xchan, 'my_perms', $perm, intval($_POST['perms_' . $perm])); } else { set_abconfig($channel['channel_id'], $atoken_xchan, 'my_perms', $perm, 0); } } } info(t('Token saved.') . EOL); return; }
function perm_abook_upgrade($abook) { $x = perms_int_to_array($abook['abook_their_perms']); if ($x) { foreach ($x as $k => $v) { set_abconfig($abook['abook_channel'], $abook['abook_xchan'], 'their_perms', $k, $v); } } $x = perms_int_to_array($abook['abook_my_perms']); if ($x) { foreach ($x as $k => $v) { set_abconfig($abook['abook_channel'], $abook['abook_xchan'], 'my_perms', $k, $v); } } }
function gnusoc_follow_from_feed(&$a, &$b) { $item = $b['item']; $importer = $b['channel']; $xchan = $b['xchan']; $author = $b['author']; $b['caught'] = true; logger('follow activity received'); if ($author && !$xchan) { $r = q("select * from xchan where xchan_guid = '%s' limit 1", dbesc($author['author_link'])); if (!$r) { if (discover_by_webbie($author['author_link'])) { $r = q("select * from xchan where xchan_guid = '%s' limit 1", dbesc($author['author_link'])); if (!$r) { logger('discovery failed'); return; } } $xchan = $r[0]; } $x = \Zotlabs\Access\PermissionRoles::role_perms('social'); $their_perms = \Zotlabs\Access\Permissions::FilledPerms($x['perms_connect']); $r = q("select * from abook where abook_channel = %d and abook_xchan = '%s' limit 1", intval($importer['channel_id']), dbesc($xchan['xchan_hash'])); if ($r) { $contact = $r[0]; $abook_instance = $contact['abook_instance']; if ($abook_instance) { $abook_instance .= ','; } $abook_instance .= z_root(); $r = q("update abook set abook_instance = '%s' where abook_id = %d and abook_channel = %d", dbesc($abook_instance), intval($contact['abook_id']), intval($importer['channel_id'])); foreach ($their_perms as $k => $v) { set_abconfig($importer['channel_id'], $contact['abook_xchan'], 'their_perms', $k, $v); } } else { $role = get_pconfig($importer['channel_id'], 'system', 'permissions_role'); if ($role) { $x = \Zotlabs\Access\PermissionRoles::role_perms($role); if ($x['perms_auto']) { $my_perms = \Zotlabs\Access\Permissions::FilledPerms($x['perms_connect']); } } if (!$my_perms) { $my_perms = \Zotlabs\Access\Permissions::FilledAutoperms($importer['channel_id']); } $closeness = get_pconfig($importer['channel_id'], 'system', 'new_abook_closeness'); if ($closeness === false) { $closeness = 80; } $r = q("insert into abook ( abook_account, abook_channel, abook_xchan, abook_closeness, abook_created, abook_updated, abook_connected, abook_dob, abook_pending, abook_instance ) values ( %d, %d, '%s', %d, '%s', '%s', '%s', '%s', %d, '%s' )", intval($importer['channel_account_id']), intval($importer['channel_id']), dbesc($xchan['xchan_hash']), intval($closeness), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(NULL_DATE), intval($my_perms ? 0 : 1), dbesc(z_root())); if ($r) { if ($my_perms) { foreach ($my_perms as $k => $v) { set_abconfig($importer['channel_id'], $xchan['xchan_hash'], 'my_perms', $k, $v); } } if ($their_perms) { foreach ($their_perms as $k => $v) { set_abconfig($importer['channel_id'], $xchan['xchan_hash'], 'their_perms', $k, $v); } } logger("New GNU-Social follower received for {$importer['channel_name']}"); $new_connection = q("select * from abook left join xchan on abook_xchan = xchan_hash left join hubloc on hubloc_hash = xchan_hash where abook_channel = %d and abook_xchan = '%s' order by abook_created desc limit 1", intval($importer['channel_id']), dbesc($xchan['xchan_hash'])); if ($new_connection) { \Zotlabs\Lib\Enotify::submit(array('type' => NOTIFY_INTRO, 'from_xchan' => $xchan['xchan_hash'], 'to_xchan' => $importer['channel_hash'], 'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id'])); if ($default_perms) { // Send back a sharing notification to them $deliver = gnusoc_remote_follow($importer, $new_connection[0]); if ($deliver) { Zotlabs\Daemon\Master::Summon(array('Deliver', $deliver)); } } $clone = array(); foreach ($new_connection[0] as $k => $v) { if (strpos($k, 'abook_') === 0) { $clone[$k] = $v; } } unset($clone['abook_id']); unset($clone['abook_account']); unset($clone['abook_channel']); $abconfig = load_abconfig($importer['channel_id'], $clone['abook_xchan']); if ($abconfig) { $clone['abconfig'] = $abconfig; } build_sync_packet($importer['channel_id'], array('abook' => array($clone))); } } } return; } }
function new_contact($uid, $url, $channel, $interactive = false, $confirm = false) { $result = array('success' => false, 'message' => ''); $is_red = false; $is_http = strpos($url, '://') !== false ? true : false; if ($is_http && substr($url, -1, 1) === '/') { $url = substr($url, 0, -1); } if (!allowed_url($url)) { $result['message'] = t('Channel is blocked on this site.'); return $result; } if (!$url) { $result['message'] = t('Channel location missing.'); return $result; } // check service class limits $r = q("select count(*) as total from abook where abook_channel = %d and abook_self = 0 ", intval($uid)); if ($r) { $total_channels = $r[0]['total']; } if (!service_class_allows($uid, 'total_channels', $total_channels)) { $result['message'] = upgrade_message(); return $result; } $arr = array('url' => $url, 'channel' => array()); call_hooks('follow', $arr); if ($arr['channel']['success']) { $ret = $arr['channel']; } elseif (!$is_http) { $ret = Zotlabs\Zot\Finger::run($url, $channel); } if ($ret && is_array($ret) && $ret['success']) { $is_red = true; $j = $ret; } $my_perms = get_channel_default_perms($uid); $role = get_pconfig($uid, 'system', 'permissions_role'); if ($role) { $x = \Zotlabs\Access\PermissionRoles::role_perms($role); if ($x['perms_connect']) { $my_perms = $x['perms_connect']; } } if ($is_red && $j) { logger('follow: ' . $url . ' ' . print_r($j, true), LOGGER_DEBUG); if (!($j['success'] && $j['guid'])) { $result['message'] = t('Response from remote channel was incomplete.'); logger('mod_follow: ' . $result['message']); return $result; } // Premium channel, set confirm before callback to avoid recursion if (array_key_exists('connect_url', $j) && $interactive && !$confirm) { goaway(zid($j['connect_url'])); } // do we have an xchan and hubloc? // If not, create them. $x = import_xchan($j); if (array_key_exists('deleted', $j) && intval($j['deleted'])) { $result['message'] = t('Channel was deleted and no longer exists.'); return $result; } if (!$x['success']) { return $x; } $xchan_hash = $x['hash']; if (array_key_exists('permissions', $j) && array_key_exists('data', $j['permissions'])) { $permissions = crypto_unencapsulate(array('data' => $j['permissions']['data'], 'key' => $j['permissions']['key'], 'iv' => $j['permissions']['iv']), $channel['channel_prvkey']); if ($permissions) { $permissions = json_decode($permissions, true); } logger('decrypted permissions: ' . print_r($permissions, true), LOGGER_DATA); } else { $permissions = $j['permissions']; } if (is_array($permissions) && $permissions) { foreach ($permissions as $k => $v) { set_abconfig($channel['channel_uid'], $xchan_hash, 'their_perms', $k, intval($v)); } } } else { $xchan_hash = ''; $r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' limit 1", dbesc($url), dbesc($url)); if (!$r) { // attempt network auto-discovery $d = discover_by_webbie($url); if (!$d && $is_http) { // try RSS discovery if (get_config('system', 'feed_contacts')) { $d = discover_by_url($url); } else { $result['message'] = t('Protocol disabled.'); return $result; } } if ($d) { $r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' limit 1", dbesc($url), dbesc($url)); } } // if discovery was a success we should have an xchan record in $r if ($r) { $xchan = $r[0]; $xchan_hash = $r[0]['xchan_hash']; $their_perms = 0; } } if (!$xchan_hash) { $result['message'] = t('Channel discovery failed.'); logger('follow: ' . $result['message']); return $result; } $allowed = $is_red || $r[0]['xchan_network'] === 'rss' ? 1 : 0; $x = array('channel_id' => $uid, 'follow_address' => $url, 'xchan' => $r[0], 'allowed' => $allowed, 'singleton' => 0); call_hooks('follow_allow', $x); if (!$x['allowed']) { $result['message'] = t('Protocol disabled.'); return $result; } $singleton = intval($x['singleton']); $aid = $channel['channel_account_id']; $hash = get_observer_hash(); $default_group = $channel['channel_default_group']; if ($xchan['xchan_network'] === 'rss') { // check service class feed limits $r = q("select count(*) as total from abook where abook_account = %d and abook_feed = 1 ", intval($aid)); if ($r) { $total_feeds = $r[0]['total']; } if (!service_class_allows($uid, 'total_feeds', $total_feeds)) { $result['message'] = upgrade_message(); return $result; } } if ($hash == $xchan_hash) { $result['message'] = t('Cannot connect to yourself.'); return $result; } $r = q("select abook_xchan, abook_instance from abook where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($xchan_hash), intval($uid)); if ($is_http) { // Always set these "remote" permissions for feeds since we cannot interact with them // to negotiate a suitable permission response set_abconfig($uid, $xchan_hash, 'their_perms', 'view_stream', 1); set_abconfig($uid, $xchan_hash, 'their_perms', 'republish', 1); } if ($r) { $abook_instance = $r[0]['abook_instance']; if ($singleton && strpos($abook_instance, z_root()) === false) { if ($abook_instance) { $abook_instance .= ','; } $abook_instance .= z_root(); } $x = q("update abook set abook_instance = '%s' where abook_id = %d", dbesc($abook_instance), intval($r[0]['abook_id'])); } else { $closeness = get_pconfig($uid, 'system', 'new_abook_closeness'); if ($closeness === false) { $closeness = 80; } $r = q("insert into abook ( abook_account, abook_channel, abook_closeness, abook_xchan, abook_feed, abook_created, abook_updated, abook_instance )\n\t\t\tvalues( %d, %d, %d, '%s', %d, '%s', '%s', '%s' ) ", intval($aid), intval($uid), intval($closeness), dbesc($xchan_hash), intval($is_http ? 1 : 0), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc($singleton ? z_root() : '')); } if (!$r) { logger('mod_follow: abook creation failed'); } $all_perms = \Zotlabs\Access\Permissions::Perms(); if ($all_perms) { foreach ($all_perms as $k => $v) { if (in_array($k, $my_perms)) { set_abconfig($uid, $xchan_hash, 'my_perms', $k, 1); } else { set_abconfig($uid, $xchan_hash, 'my_perms', $k, 0); } } } $r = q("select abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash \n\t\twhere abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($xchan_hash), intval($uid)); if ($r) { $result['abook'] = $r[0]; Zotlabs\Daemon\Master::Summon(array('Notifier', 'permission_create', $result['abook']['abook_id'])); } $arr = array('channel_id' => $uid, 'channel' => $channel, 'abook' => $result['abook']); call_hooks('follow', $arr); /** If there is a default group for this channel, add this connection to it */ if ($default_group) { require_once 'include/group.php'; $g = group_rec_byhash($uid, $default_group); if ($g) { group_add_member($uid, '', $xchan_hash, $g['id']); } } $result['success'] = true; return $result; }
function import_account($account_id) { if (!$account_id) { logger("import_account: No account ID supplied"); return; } $max_identities = account_service_class_fetch($account_id, 'total_identities'); $max_friends = account_service_class_fetch($account_id, 'total_channels'); $max_feeds = account_service_class_fetch($account_id, 'total_feeds'); if ($max_identities !== false) { $r = q("select channel_id from channel where channel_account_id = %d", intval($account_id)); if ($r && count($r) > $max_identities) { notice(sprintf(t('Your service plan only allows %d channels.'), $max_identities) . EOL); return; } } $data = null; $seize = x($_REQUEST, 'make_primary') ? intval($_REQUEST['make_primary']) : 0; $import_posts = x($_REQUEST, 'import_posts') ? intval($_REQUEST['import_posts']) : 0; $src = $_FILES['filename']['tmp_name']; $filename = basename($_FILES['filename']['name']); $filesize = intval($_FILES['filename']['size']); $filetype = $_FILES['filename']['type']; $completed = array_key_exists('import_step', $_SESSION) ? intval($_SESSION['import_step']) : 0; if ($completed) { logger('saved import step: ' . $_SESSION['import_step']); } if ($src) { // This is OS specific and could also fail if your tmpdir isn't very large // mostly used for Diaspora which exports gzipped files. if (strpos($filename, '.gz')) { @rename($src, $src . '.gz'); @system('gunzip ' . escapeshellarg($src . '.gz')); } if ($filesize) { $data = @file_get_contents($src); } unlink($src); } if (!$src) { $old_address = x($_REQUEST, 'old_address') ? $_REQUEST['old_address'] : ''; if (!$old_address) { logger('mod_import: nothing to import.'); notice(t('Nothing to import.') . EOL); return; } $email = x($_REQUEST, 'email') ? $_REQUEST['email'] : ''; $password = x($_REQUEST, 'password') ? $_REQUEST['password'] : ''; $channelname = substr($old_address, 0, strpos($old_address, '@')); $servername = substr($old_address, strpos($old_address, '@') + 1); $scheme = 'https://'; $api_path = '/api/red/channel/export/basic?f=&channel=' . $channelname; if ($import_posts) { $api_path .= '&posts=1'; } $binary = false; $redirects = 0; $opts = array('http_auth' => $email . ':' . $password); $url = $scheme . $servername . $api_path; $ret = z_fetch_url($url, $binary, $redirects, $opts); if (!$ret['success']) { $ret = z_fetch_url('http://' . $servername . $api_path, $binary, $redirects, $opts); } if ($ret['success']) { $data = $ret['body']; } else { notice(t('Unable to download data from old server') . EOL); } } if (!$data) { logger('mod_import: empty file.'); notice(t('Imported file is empty.') . EOL); return; } $data = json_decode($data, true); // logger('import: data: ' . print_r($data,true)); // print_r($data); if (array_key_exists('user', $data) && array_key_exists('version', $data)) { require_once 'include/Import/import_diaspora.php'; import_diaspora($data); return; } $moving = false; if (array_key_exists('compatibility', $data) && array_key_exists('database', $data['compatibility'])) { $v1 = substr($data['compatibility']['database'], -4); $v2 = substr(DB_UPDATE_VERSION, -4); if ($v2 > $v1) { $t = sprintf(t('Warning: Database versions differ by %1$d updates.'), $v2 - $v1); notice($t); } if (array_key_exists('server_role', $data['compatibility']) && $data['compatibility']['server_role'] == 'basic') { $moving = true; } } if ($moving) { $seize = 1; } // import channel $relocate = array_key_exists('relocate', $data) ? $data['relocate'] : null; if (array_key_exists('channel', $data)) { if ($completed < 1) { $channel = import_channel($data['channel'], $account_id, $seize); } else { $r = q("select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1", intval($account_id), dbesc($channel['channel_guid'])); if ($r) { $channel = $r[0]; } } if (!$channel) { logger('mod_import: channel not found. ', print_r($channel, true)); notice(t('Cloned channel not found. Import failed.') . EOL); return; } } if (!$channel) { $channel = \App::get_channel(); } if (!$channel) { logger('mod_import: channel not found. ', print_r($channel, true)); notice(t('No channel. Import failed.') . EOL); return; } if ($completed < 2) { if (is_array($data['config'])) { import_config($channel, $data['config']); } logger('import step 2'); $_SESSION['import_step'] = 2; } if ($completed < 3) { if ($data['photo']) { require_once 'include/photo/photo_driver.php'; import_channel_photo(base64url_decode($data['photo']['data']), $data['photo']['type'], $account_id, $channel['channel_id']); } if (is_array($data['profile'])) { import_profiles($channel, $data['profile']); } logger('import step 3'); $_SESSION['import_step'] = 3; } if ($completed < 4) { if (is_array($data['hubloc']) && !$moving) { import_hublocs($channel, $data['hubloc'], $seize); } logger('import step 4'); $_SESSION['import_step'] = 4; } if ($completed < 5) { // create new hubloc for the new channel at this site $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_network, hubloc_primary, \n\t\t\t\thubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey )\n\t\t\t\tvalues ( '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s' )", dbesc($channel['channel_guid']), dbesc($channel['channel_guid_sig']), dbesc($channel['channel_hash']), dbesc(channel_reddress($channel)), dbesc('zot'), intval($seize ? 1 : 0), dbesc(z_root()), dbesc(base64url_encode(rsa_sign(z_root(), $channel['channel_prvkey']))), dbesc(\App::get_hostname()), dbesc(z_root() . '/post'), dbesc(get_config('system', 'pubkey'))); // reset the original primary hubloc if it is being seized if ($seize) { $r = q("update hubloc set hubloc_primary = 0 where hubloc_primary = 1 and hubloc_hash = '%s' and hubloc_url != '%s' ", dbesc($channel['channel_hash']), dbesc(z_root())); } logger('import step 5'); $_SESSION['import_step'] = 5; } if ($completed < 6) { // import xchans and contact photos if ($seize) { // replace any existing xchan we may have on this site if we're seizing control $r = q("delete from xchan where xchan_hash = '%s'", dbesc($channel['channel_hash'])); $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_l, xchan_photo_m, xchan_photo_s, xchan_addr, xchan_url, xchan_follow, xchan_connurl, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_hidden, xchan_orphan, xchan_censored, xchan_selfcensored, xchan_system, xchan_pubforum, xchan_deleted ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %d )", dbesc($channel['channel_hash']), dbesc($channel['channel_guid']), dbesc($channel['channel_guid_sig']), dbesc($channel['channel_pubkey']), dbesc(z_root() . "/photo/profile/l/" . $channel['channel_id']), dbesc(z_root() . "/photo/profile/m/" . $channel['channel_id']), dbesc(z_root() . "/photo/profile/s/" . $channel['channel_id']), dbesc(channel_reddress($channel)), dbesc(z_root() . '/channel/' . $channel['channel_address']), dbesc(z_root() . '/follow?f=&url=%s'), dbesc(z_root() . '/poco/' . $channel['channel_address']), dbesc($channel['channel_name']), dbesc('zot'), dbesc(datetime_convert()), dbesc(datetime_convert()), 0, 0, 0, 0, 0, 0, 0); } logger('import step 6'); $_SESSION['import_step'] = 6; } if ($completed < 7) { $xchans = $data['xchan']; if ($xchans) { foreach ($xchans as $xchan) { $hash = make_xchan_hash($xchan['xchan_guid'], $xchan['xchan_guid_sig']); if ($xchan['xchan_network'] === 'zot' && $hash !== $xchan['xchan_hash']) { logger('forged xchan: ' . print_r($xchan, true)); continue; } if (!array_key_exists('xchan_hidden', $xchan)) { $xchan['xchan_hidden'] = $xchan['xchan_flags'] & 0x1 ? 1 : 0; $xchan['xchan_orphan'] = $xchan['xchan_flags'] & 0x2 ? 1 : 0; $xchan['xchan_censored'] = $xchan['xchan_flags'] & 0x4 ? 1 : 0; $xchan['xchan_selfcensored'] = $xchan['xchan_flags'] & 0x8 ? 1 : 0; $xchan['xchan_system'] = $xchan['xchan_flags'] & 0x10 ? 1 : 0; $xchan['xchan_pubforum'] = $xchan['xchan_flags'] & 0x20 ? 1 : 0; $xchan['xchan_deleted'] = $xchan['xchan_flags'] & 0x1000 ? 1 : 0; } $r = q("select xchan_hash from xchan where xchan_hash = '%s' limit 1", dbesc($xchan['xchan_hash'])); if ($r) { continue; } dbesc_array($xchan); $r = dbq("INSERT INTO xchan (`" . implode("`, `", array_keys($xchan)) . "`) VALUES ('" . implode("', '", array_values($xchan)) . "')"); require_once 'include/photo/photo_driver.php'; $photos = import_xchan_photo($xchan['xchan_photo_l'], $xchan['xchan_hash']); if ($photos[4]) { $photodate = NULL_DATE; } else { $photodate = $xchan['xchan_photo_date']; } $r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s'\n\t\t\t\t\t\twhere xchan_hash = '%s'", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($photodate), dbesc($xchan['xchan_hash'])); } } logger('import step 7'); $_SESSION['import_step'] = 7; } // FIXME - ensure we have an xchan if somebody is trying to pull a fast one if ($completed < 8) { $friends = 0; $feeds = 0; // import contacts $abooks = $data['abook']; if ($abooks) { foreach ($abooks as $abook) { $abook_copy = $abook; $abconfig = null; if (array_key_exists('abconfig', $abook) && is_array($abook['abconfig']) && count($abook['abconfig'])) { $abconfig = $abook['abconfig']; } unset($abook['abook_id']); unset($abook['abook_rating']); unset($abook['abook_rating_text']); unset($abook['abconfig']); unset($abook['abook_their_perms']); unset($abook['abook_my_perms']); $abook['abook_account'] = $account_id; $abook['abook_channel'] = $channel['channel_id']; if (!array_key_exists('abook_blocked', $abook)) { $abook['abook_blocked'] = $abook['abook_flags'] & 0x1 ? 1 : 0; $abook['abook_ignored'] = $abook['abook_flags'] & 0x2 ? 1 : 0; $abook['abook_hidden'] = $abook['abook_flags'] & 0x4 ? 1 : 0; $abook['abook_archived'] = $abook['abook_flags'] & 0x8 ? 1 : 0; $abook['abook_pending'] = $abook['abook_flags'] & 0x10 ? 1 : 0; $abook['abook_unconnected'] = $abook['abook_flags'] & 0x20 ? 1 : 0; $abook['abook_self'] = $abook['abook_flags'] & 0x80 ? 1 : 0; $abook['abook_feed'] = $abook['abook_flags'] & 0x100 ? 1 : 0; } if ($abook['abook_self']) { $role = get_pconfig($channel['channel_id'], 'system', 'permissions_role'); if ($role === 'forum' || $abook['abook_my_perms'] & PERMS_W_TAGWALL) { q("update xchan set xchan_pubforum = 1 where xchan_hash = '%s' ", dbesc($abook['abook_xchan'])); } } else { if ($max_friends !== false && $friends > $max_friends) { continue; } if ($max_feeds !== false && intval($abook['abook_feed']) && $feeds > $max_feeds) { continue; } } dbesc_array($abook); $r = dbq("INSERT INTO abook (`" . implode("`, `", array_keys($abook)) . "`) VALUES ('" . implode("', '", array_values($abook)) . "')"); $friends++; if (intval($abook['abook_feed'])) { $feeds++; } translate_abook_perms_inbound($channel, $abook_copy); if ($abconfig) { // @fixme does not handle sync of del_abconfig foreach ($abconfig as $abc) { set_abconfig($channel['channel_id'], $abc['xchan'], $abc['cat'], $abc['k'], $abc['v']); } } } } logger('import step 8'); $_SESSION['import_step'] = 8; } if ($completed < 9) { $groups = $data['group']; if ($groups) { $saved = array(); foreach ($groups as $group) { $saved[$group['hash']] = array('old' => $group['id']); if (array_key_exists('name', $group)) { $group['gname'] = $group['name']; unset($group['name']); } unset($group['id']); $group['uid'] = $channel['channel_id']; dbesc_array($group); $r = dbq("INSERT INTO groups (`" . implode("`, `", array_keys($group)) . "`) VALUES ('" . implode("', '", array_values($group)) . "')"); } $r = q("select * from `groups` where uid = %d", intval($channel['channel_id'])); if ($r) { foreach ($r as $rr) { $saved[$rr['hash']]['new'] = $rr['id']; } } } $group_members = $data['group_member']; if ($group_members) { foreach ($group_members as $group_member) { unset($group_member['id']); $group_member['uid'] = $channel['channel_id']; foreach ($saved as $x) { if ($x['old'] == $group_member['gid']) { $group_member['gid'] = $x['new']; } } dbesc_array($group_member); $r = dbq("INSERT INTO group_member (`" . implode("`, `", array_keys($group_member)) . "`) VALUES ('" . implode("', '", array_values($group_member)) . "')"); } } logger('import step 9'); $_SESSION['import_step'] = 9; } if (is_array($data['obj'])) { import_objs($channel, $data['obj']); } if (is_array($data['likes'])) { import_likes($channel, $data['likes']); } if (is_array($data['app'])) { import_apps($channel, $data['app']); } if (is_array($data['chatroom'])) { import_chatrooms($channel, $data['chatroom']); } if (is_array($data['conv'])) { import_conv($channel, $data['conv']); } if (is_array($data['mail'])) { import_mail($channel, $data['mail']); } if (is_array($data['event'])) { import_events($channel, $data['event']); } if (is_array($data['event_item'])) { import_items($channel, $data['event_item'], false, $relocate); } if (is_array($data['menu'])) { import_menus($channel, $data['menu']); } $addon = array('channel' => $channel, 'data' => $data); call_hooks('import_channel', $addon); $saved_notification_flags = notifications_off($channel['channel_id']); if ($import_posts && array_key_exists('item', $data) && $data['item']) { import_items($channel, $data['item'], false, $relocate); } notifications_on($channel['channel_id'], $saved_notification_flags); if (array_key_exists('item_id', $data) && $data['item_id']) { import_item_ids($channel, $data['item_id']); } // FIXME - ensure we have a self entry if somebody is trying to pull a fast one // send out refresh requests // notify old server that it may no longer be primary. \Zotlabs\Daemon\Master::Summon(array('Notifier', 'location', $channel['channel_id'])); // This will indirectly perform a refresh_all *and* update the directory \Zotlabs\Daemon\Master::Summon(array('Directory', $channel['channel_id'])); notice(t('Import completed.') . EOL); change_channel($channel['channel_id']); unset($_SESSION['import_step']); goaway(z_root() . '/network'); }
function post() { $channel = \App::get_channel(); check_form_security_token_redirectOnErr('/settings', 'settings'); call_hooks('settings_post', $_POST); $set_perms = ''; $role = x($_POST, 'permissions_role') ? notags(trim($_POST['permissions_role'])) : ''; $oldrole = get_pconfig(local_channel(), 'system', 'permissions_role'); if ($role != $oldrole || $role === 'custom') { if ($role === 'custom') { $hide_presence = x($_POST, 'hide_presence') && intval($_POST['hide_presence']) == 1 ? 1 : 0; $publish = x($_POST, 'profile_in_directory') && intval($_POST['profile_in_directory']) == 1 ? 1 : 0; $def_group = x($_POST, 'group-selection') ? notags(trim($_POST['group-selection'])) : ''; $r = q("update channel set channel_default_group = '%s' where channel_id = %d", dbesc($def_group), intval(local_channel())); $global_perms = \Zotlabs\Access\Permissions::Perms(); foreach ($global_perms as $k => $v) { \Zotlabs\Access\PermissionLimits::Set(local_channel(), $k, intval($_POST[$k])); } $acl = new \Zotlabs\Access\AccessList($channel); $acl->set_from_array($_POST); $x = $acl->get(); $r = q("update channel set channel_allow_cid = '%s', channel_allow_gid = '%s', \n\t\t\t\t\tchannel_deny_cid = '%s', channel_deny_gid = '%s' where channel_id = %d", dbesc($x['allow_cid']), dbesc($x['allow_gid']), dbesc($x['deny_cid']), dbesc($x['deny_gid']), intval(local_channel())); } else { $role_permissions = \Zotlabs\Access\PermissionRoles::role_perms($_POST['permissions_role']); if (!$role_permissions) { notice('Permissions category could not be found.'); return; } $hide_presence = 1 - intval($role_permissions['online']); if ($role_permissions['default_collection']) { $r = q("select hash from groups where uid = %d and gname = '%s' limit 1", intval(local_channel()), dbesc(t('Friends'))); if (!$r) { require_once 'include/group.php'; group_add(local_channel(), t('Friends')); group_add_member(local_channel(), t('Friends'), $channel['channel_hash']); $r = q("select hash from groups where uid = %d and gname = '%s' limit 1", intval(local_channel()), dbesc(t('Friends'))); } if ($r) { q("update channel set channel_default_group = '%s', channel_allow_gid = '%s', channel_allow_cid = '', channel_deny_gid = '', channel_deny_cid = '' where channel_id = %d", dbesc($r[0]['hash']), dbesc('<' . $r[0]['hash'] . '>'), intval(local_channel())); } else { notice(sprintf('Default privacy group \'%s\' not found. Please create and re-submit permission change.', t('Friends')) . EOL); return; } } else { q("update channel set channel_default_group = '', channel_allow_gid = '', channel_allow_cid = '', channel_deny_gid = '', \n\t\t\t\t\t\tchannel_deny_cid = '' where channel_id = %d", intval(local_channel())); } $x = \Zotlabs\Access\Permissions::FilledPerms($role_permissions['perms_connect']); foreach ($x as $k => $v) { set_abconfig(local_channel(), $channel['channel_hash'], 'my_perms', $k, $v); if ($role_permissions['perms_auto']) { set_pconfig(local_channel(), 'autoperms', $k, $v); } else { del_pconfig(local_channel(), 'autoperms', $k); } } if ($role_permissions['limits']) { foreach ($role_permissions['limits'] as $k => $v) { \Zotlabs\Access\PermissionLimits::Set(local_channel(), $k, $v); } } if (array_key_exists('directory_publish', $role_permissions)) { $publish = intval($role_permissions['directory_publish']); } } set_pconfig(local_channel(), 'system', 'hide_online_status', $hide_presence); set_pconfig(local_channel(), 'system', 'permissions_role', $role); } $username = x($_POST, 'username') ? notags(trim($_POST['username'])) : ''; $timezone = x($_POST, 'timezone_select') ? notags(trim($_POST['timezone_select'])) : ''; $defloc = x($_POST, 'defloc') ? notags(trim($_POST['defloc'])) : ''; $openid = x($_POST, 'openid_url') ? notags(trim($_POST['openid_url'])) : ''; $maxreq = x($_POST, 'maxreq') ? intval($_POST['maxreq']) : 0; $expire = x($_POST, 'expire') ? intval($_POST['expire']) : 0; $evdays = x($_POST, 'evdays') ? intval($_POST['evdays']) : 3; $photo_path = x($_POST, 'photo_path') ? escape_tags(trim($_POST['photo_path'])) : ''; $attach_path = x($_POST, 'attach_path') ? escape_tags(trim($_POST['attach_path'])) : ''; $channel_menu = x($_POST['channel_menu']) ? htmlspecialchars_decode(trim($_POST['channel_menu']), ENT_QUOTES) : ''; $expire_items = x($_POST, 'expire_items') ? intval($_POST['expire_items']) : 0; $expire_starred = x($_POST, 'expire_starred') ? intval($_POST['expire_starred']) : 0; $expire_photos = x($_POST, 'expire_photos') ? intval($_POST['expire_photos']) : 0; $expire_network_only = x($_POST, 'expire_network_only') ? intval($_POST['expire_network_only']) : 0; $allow_location = x($_POST, 'allow_location') && intval($_POST['allow_location']) == 1 ? 1 : 0; $blocktags = x($_POST, 'blocktags') && intval($_POST['blocktags']) == 1 ? 0 : 1; // this setting is inverted! $unkmail = x($_POST, 'unkmail') && intval($_POST['unkmail']) == 1 ? 1 : 0; $cntunkmail = x($_POST, 'cntunkmail') ? intval($_POST['cntunkmail']) : 0; $suggestme = x($_POST, 'suggestme') ? intval($_POST['suggestme']) : 0; $post_newfriend = $_POST['post_newfriend'] == 1 ? 1 : 0; $post_joingroup = $_POST['post_joingroup'] == 1 ? 1 : 0; $post_profilechange = $_POST['post_profilechange'] == 1 ? 1 : 0; $adult = $_POST['adult'] == 1 ? 1 : 0; $cal_first_day = x($_POST, 'first_day') && intval($_POST['first_day']) == 1 ? 1 : 0; $pageflags = $channel['channel_pageflags']; $existing_adult = $pageflags & PAGE_ADULT ? 1 : 0; if ($adult != $existing_adult) { $pageflags = $pageflags ^ PAGE_ADULT; } $notify = 0; if (x($_POST, 'notify1')) { $notify += intval($_POST['notify1']); } if (x($_POST, 'notify2')) { $notify += intval($_POST['notify2']); } if (x($_POST, 'notify3')) { $notify += intval($_POST['notify3']); } if (x($_POST, 'notify4')) { $notify += intval($_POST['notify4']); } if (x($_POST, 'notify5')) { $notify += intval($_POST['notify5']); } if (x($_POST, 'notify6')) { $notify += intval($_POST['notify6']); } if (x($_POST, 'notify7')) { $notify += intval($_POST['notify7']); } if (x($_POST, 'notify8')) { $notify += intval($_POST['notify8']); } $vnotify = 0; if (x($_POST, 'vnotify1')) { $vnotify += intval($_POST['vnotify1']); } if (x($_POST, 'vnotify2')) { $vnotify += intval($_POST['vnotify2']); } if (x($_POST, 'vnotify3')) { $vnotify += intval($_POST['vnotify3']); } if (x($_POST, 'vnotify4')) { $vnotify += intval($_POST['vnotify4']); } if (x($_POST, 'vnotify5')) { $vnotify += intval($_POST['vnotify5']); } if (x($_POST, 'vnotify6')) { $vnotify += intval($_POST['vnotify6']); } if (x($_POST, 'vnotify7')) { $vnotify += intval($_POST['vnotify7']); } if (x($_POST, 'vnotify8')) { $vnotify += intval($_POST['vnotify8']); } if (x($_POST, 'vnotify9')) { $vnotify += intval($_POST['vnotify9']); } if (x($_POST, 'vnotify10')) { $vnotify += intval($_POST['vnotify10']); } if (x($_POST, 'vnotify11')) { $vnotify += intval($_POST['vnotify11']); } $always_show_in_notices = x($_POST, 'always_show_in_notices') ? 1 : 0; $err = ''; $name_change = false; if ($username != $channel['channel_name']) { $name_change = true; require_once 'include/channel.php'; $err = validate_channelname($username); if ($err) { notice($err); return; } } if ($timezone != $channel['channel_timezone']) { if (strlen($timezone)) { date_default_timezone_set($timezone); } } set_pconfig(local_channel(), 'system', 'use_browser_location', $allow_location); set_pconfig(local_channel(), 'system', 'suggestme', $suggestme); set_pconfig(local_channel(), 'system', 'post_newfriend', $post_newfriend); set_pconfig(local_channel(), 'system', 'post_joingroup', $post_joingroup); set_pconfig(local_channel(), 'system', 'post_profilechange', $post_profilechange); set_pconfig(local_channel(), 'system', 'blocktags', $blocktags); set_pconfig(local_channel(), 'system', 'channel_menu', $channel_menu); set_pconfig(local_channel(), 'system', 'vnotify', $vnotify); set_pconfig(local_channel(), 'system', 'always_show_in_notices', $always_show_in_notices); set_pconfig(local_channel(), 'system', 'evdays', $evdays); set_pconfig(local_channel(), 'system', 'photo_path', $photo_path); set_pconfig(local_channel(), 'system', 'attach_path', $attach_path); set_pconfig(local_channel(), 'system', 'cal_first_day', $cal_first_day); $r = q("update channel set channel_name = '%s', channel_pageflags = %d, channel_timezone = '%s', channel_location = '%s', channel_notifyflags = %d, channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d {$set_perms} where channel_id = %d", dbesc($username), intval($pageflags), dbesc($timezone), dbesc($defloc), intval($notify), intval($unkmail), intval($maxreq), intval($expire), intval(local_channel())); if ($r) { info(t('Settings updated.') . EOL); } if (!is_null($publish)) { $r = q("UPDATE profile SET publish = %d WHERE is_default = 1 AND uid = %d", intval($publish), intval(local_channel())); } if ($name_change) { $r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s' where xchan_hash = '%s'", dbesc($username), dbesc(datetime_convert()), dbesc($channel['channel_hash'])); $r = q("update profile set fullname = '%s' where uid = %d and is_default = 1", dbesc($username), intval($channel['channel_id'])); } \Zotlabs\Daemon\Master::Summon(array('Directory', local_channel())); build_sync_packet(); if ($email_changed && \App::$config['system']['register_policy'] == REGISTER_VERIFY) { // FIXME - set to un-verified, blocked and redirect to logout // Why? Are we verifying people or email addresses? } goaway(z_root() . '/settings'); return; // NOTREACHED }
/** * @brief Create a new channel. * * Also creates the related xchan, hubloc, profile, and "self" abook records, * and an empty "Friends" group/collection for the new channel. * * @param array $arr assoziative array with: * * \e string \b name full name of channel * * \e string \b nickname "email/url-compliant" nickname * * \e int \b account_id to attach with this channel * * [other identity fields as desired] * * @returns array * 'success' => boolean true or false * 'message' => optional error text if success is false * 'channel' => if successful the created channel array */ function create_identity($arr) { $ret = array('success' => false); if (!$arr['account_id']) { $ret['message'] = t('No account identifier'); return $ret; } $ret = identity_check_service_class($arr['account_id']); if (!$ret['success']) { return $ret; } // save this for auto_friending $total_identities = $ret['total_identities']; $nick = mb_strtolower(trim($arr['nickname'])); if (!$nick) { $ret['message'] = t('Nickname is required.'); return $ret; } $name = escape_tags($arr['name']); $pageflags = x($arr, 'pageflags') ? intval($arr['pageflags']) : PAGE_NORMAL; $system = x($arr, 'system') ? intval($arr['system']) : 0; $name_error = validate_channelname($arr['name']); if ($name_error) { $ret['message'] = $name_error; return $ret; } if ($nick === 'sys' && !$system) { $ret['message'] = t('Reserved nickname. Please choose another.'); return $ret; } if (check_webbie(array($nick)) !== $nick) { $ret['message'] = t('Nickname has unsupported characters or is already being used on this site.'); return $ret; } $guid = zot_new_uid($nick); $key = new_keypair(4096); $sig = base64url_encode(rsa_sign($guid, $key['prvkey'])); $hash = make_xchan_hash($guid, $sig); // Force a few things on the short term until we can provide a theme or app with choice $publish = 1; if (array_key_exists('publish', $arr)) { $publish = intval($arr['publish']); } $role_permissions = null; if (array_key_exists('permissions_role', $arr) && $arr['permissions_role']) { $role_permissions = \Zotlabs\Access\PermissionRoles::role_perms($arr['permissions_role']); } if ($role_permissions && array_key_exists('directory_publish', $role_permissions)) { $publish = intval($role_permissions['directory_publish']); } $primary = true; if (array_key_exists('primary', $arr)) { $primary = intval($arr['primary']); } $expire = 0; $r = q("insert into channel ( channel_account_id, channel_primary, \n\t\tchannel_name, channel_address, channel_guid, channel_guid_sig,\n\t\tchannel_hash, channel_prvkey, channel_pubkey, channel_pageflags, channel_system, channel_expire_days, channel_timezone )\n\t\tvalues ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s' ) ", intval($arr['account_id']), intval($primary), dbesc($name), dbesc($nick), dbesc($guid), dbesc($sig), dbesc($hash), dbesc($key['prvkey']), dbesc($key['pubkey']), intval($pageflags), intval($system), intval($expire), dbesc(App::$timezone)); $r = q("select * from channel where channel_account_id = %d \n\t\tand channel_guid = '%s' limit 1", intval($arr['account_id']), dbesc($guid)); if (!$r) { $ret['message'] = t('Unable to retrieve created identity'); return $ret; } if ($role_permissions && array_key_exists('limits', $role_permissions)) { $perm_limits = $role_permissions['limits']; } else { $perm_limits = site_default_perms(); } foreach ($perm_limits as $p => $v) { \Zotlabs\Access\PermissionLimits::Set($r[0]['channel_id'], $p, $v); } if ($role_permissions && array_key_exists('perms_auto', $role_permissions)) { set_pconfig($r[0]['channel_id'], 'system', 'autoperms', intval($role_permissions['perms_auto'])); } $ret['channel'] = $r[0]; if (intval($arr['account_id'])) { set_default_login_identity($arr['account_id'], $ret['channel']['channel_id'], false); } // Create a verified hub location pointing to this site. $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_primary, \n\t\thubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_network )\n\t\tvalues ( '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )", dbesc($guid), dbesc($sig), dbesc($hash), dbesc(channel_reddress($ret['channel'])), intval($primary), dbesc(z_root()), dbesc(base64url_encode(rsa_sign(z_root(), $ret['channel']['channel_prvkey']))), dbesc(App::get_hostname()), dbesc(z_root() . '/post'), dbesc(get_config('system', 'pubkey')), dbesc('zot')); if (!$r) { logger('create_identity: Unable to store hub location'); } $newuid = $ret['channel']['channel_id']; $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_l, xchan_photo_m, xchan_photo_s, xchan_addr, xchan_url, xchan_follow, xchan_connurl, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_system ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)", dbesc($hash), dbesc($guid), dbesc($sig), dbesc($key['pubkey']), dbesc(z_root() . "/photo/profile/l/{$newuid}"), dbesc(z_root() . "/photo/profile/m/{$newuid}"), dbesc(z_root() . "/photo/profile/s/{$newuid}"), dbesc(channel_reddress($ret['channel'])), dbesc(z_root() . '/channel/' . $ret['channel']['channel_address']), dbesc(z_root() . '/follow?f=&url=%s'), dbesc(z_root() . '/poco/' . $ret['channel']['channel_address']), dbesc($ret['channel']['channel_name']), dbesc('zot'), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($system)); // Not checking return value. // It's ok for this to fail if it's an imported channel, and therefore the hash is a duplicate $r = q("INSERT INTO profile ( aid, uid, profile_guid, profile_name, is_default, publish, fullname, photo, thumb)\n\t\tVALUES ( %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s') ", intval($ret['channel']['channel_account_id']), intval($newuid), dbesc(random_string()), t('Default Profile'), 1, $publish, dbesc($ret['channel']['channel_name']), dbesc(z_root() . "/photo/profile/l/{$newuid}"), dbesc(z_root() . "/photo/profile/m/{$newuid}")); if ($role_permissions) { $myperms = array_key_exists('perms_connect', $role_permissions) ? $role_permissions['perms_connect'] : array(); } else { $x = \Zotlabs\Access\PermissionRoles::role_perms('social'); $myperms = $x['perms_connect']; } $r = q("insert into abook ( abook_account, abook_channel, abook_xchan, abook_closeness, abook_created, abook_updated, abook_self )\n\t\tvalues ( %d, %d, '%s', %d, '%s', '%s', %d ) ", intval($ret['channel']['channel_account_id']), intval($newuid), dbesc($hash), intval(0), dbesc(datetime_convert()), dbesc(datetime_convert()), intval(1)); $x = \Zotlabs\Access\Permissions::FilledPerms($myperms); foreach ($x as $k => $v) { set_abconfig($newuid, $hash, 'my_perms', $k, $v); } if (intval($ret['channel']['channel_account_id'])) { // Save our permissions role so we can perhaps call it up and modify it later. if ($role_permissions) { set_pconfig($newuid, 'system', 'permissions_role', $arr['permissions_role']); if (array_key_exists('online', $role_permissions)) { set_pconfig($newuid, 'system', 'hide_presence', 1 - intval($role_permissions['online'])); } if (array_key_exists('perms_auto', $role_permissions)) { $autoperms = intval($role_permissions['perms_auto']); set_pconfig($newuid, 'system', 'autoperms', $autoperms); if ($autoperms) { $x = \Zotlabs\Access\Permissions::FilledPerms($role_permissions['perms_connect']); foreach ($x as $k => $v) { set_pconfig($newuid, 'autoperms', $k, $v); } } else { $r = q("delete from pconfig where uid = %d and cat = 'autoperms'", intval($newuid)); } } } // Create a group with yourself as a member. This allows somebody to use it // right away as a default group for new contacts. require_once 'include/group.php'; group_add($newuid, t('Friends')); group_add_member($newuid, t('Friends'), $ret['channel']['channel_hash']); // if our role_permissions indicate that we're using a default collection ACL, add it. if (is_array($role_permissions) && $role_permissions['default_collection']) { $r = q("select hash from groups where uid = %d and gname = '%s' limit 1", intval($newuid), dbesc(t('Friends'))); if ($r) { q("update channel set channel_default_group = '%s', channel_allow_gid = '%s' where channel_id = %d", dbesc($r[0]['hash']), dbesc('<' . $r[0]['hash'] . '>'), intval($newuid)); } } if (!$system) { set_pconfig($ret['channel']['channel_id'], 'system', 'photo_path', '%Y-%m'); set_pconfig($ret['channel']['channel_id'], 'system', 'attach_path', '%Y-%m'); } // auto-follow any of the hub's pre-configured channel choices. // Only do this if it's the first channel for this account; // otherwise it could get annoying. Don't make this list too big // or it will impact registration time. $accts = get_config('system', 'auto_follow'); if ($accts && !$total_identities) { require_once 'include/follow.php'; if (!is_array($accts)) { $accts = array($accts); } foreach ($accts as $acct) { if (trim($acct)) { new_contact($newuid, trim($acct), $ret['channel'], false); } } } call_hooks('create_identity', $newuid); Zotlabs\Daemon\Master::Summon(array('Directory', $ret['channel']['channel_id'])); } $ret['success'] = true; return $ret; }
/** * @brief * * @param array $sender * @param array $arr * @param array $deliveries * @return array */ function process_channel_sync_delivery($sender, $arr, $deliveries) { if (UNO) { return; } require_once 'include/import.php'; /** @FIXME this will sync red structures (channel, pconfig and abook). Eventually we need to make this application agnostic. */ $result = array(); foreach ($deliveries as $d) { $r = q("select * from channel where channel_hash = '%s' limit 1", dbesc($d['hash'])); if (!$r) { $result[] = array($d['hash'], 'not found'); continue; } $channel = $r[0]; $max_friends = service_class_fetch($channel['channel_id'], 'total_channels'); $max_feeds = account_service_class_fetch($channel['channel_account_id'], 'total_feeds'); if ($channel['channel_hash'] != $sender['hash']) { logger('process_channel_sync_delivery: possible forgery. Sender ' . $sender['hash'] . ' is not ' . $channel['channel_hash']); $result[] = array($d['hash'], 'channel mismatch', $channel['channel_name'], ''); continue; } if (array_key_exists('config', $arr) && is_array($arr['config']) && count($arr['config'])) { foreach ($arr['config'] as $cat => $k) { foreach ($arr['config'][$cat] as $k => $v) { set_pconfig($channel['channel_id'], $cat, $k, $v); } } } if (array_key_exists('obj', $arr) && $arr['obj']) { sync_objs($channel, $arr['obj']); } if (array_key_exists('likes', $arr) && $arr['likes']) { import_likes($channel, $arr['likes']); } if (array_key_exists('app', $arr) && $arr['app']) { sync_apps($channel, $arr['app']); } if (array_key_exists('chatroom', $arr) && $arr['chatroom']) { sync_chatrooms($channel, $arr['chatroom']); } if (array_key_exists('conv', $arr) && $arr['conv']) { import_conv($channel, $arr['conv']); } if (array_key_exists('mail', $arr) && $arr['mail']) { sync_mail($channel, $arr['mail']); } if (array_key_exists('event', $arr) && $arr['event']) { sync_events($channel, $arr['event']); } if (array_key_exists('event_item', $arr) && $arr['event_item']) { sync_items($channel, $arr['event_item'], array_key_exists('relocate', $arr) ? $arr['relocate'] : null); } if (array_key_exists('item', $arr) && $arr['item']) { sync_items($channel, $arr['item'], array_key_exists('relocate', $arr) ? $arr['relocate'] : null); } // deprecated, maintaining for a few months for upward compatibility // this should sync webpages, but the logic is a bit subtle if (array_key_exists('item_id', $arr) && $arr['item_id']) { sync_items($channel, $arr['item_id']); } if (array_key_exists('menu', $arr) && $arr['menu']) { sync_menus($channel, $arr['menu']); } if (array_key_exists('file', $arr) && $arr['file']) { sync_files($channel, $arr['file']); } if (array_key_exists('channel', $arr) && is_array($arr['channel']) && count($arr['channel'])) { if (array_key_exists('channel_pageflags', $arr['channel']) && intval($arr['channel']['channel_pageflags'])) { // These flags cannot be sync'd. // remove the bits from the incoming flags. // These correspond to PAGE_REMOVED and PAGE_SYSTEM on redmatrix if ($arr['channel']['channel_pageflags'] & 0x8000) { $arr['channel']['channel_pageflags'] = $arr['channel']['channel_pageflags'] - 0x8000; } if ($arr['channel']['channel_pageflags'] & 0x1000) { $arr['channel']['channel_pageflags'] = $arr['channel']['channel_pageflags'] - 0x1000; } } $disallowed = array('channel_id', 'channel_account_id', 'channel_primary', 'channel_prvkey', 'channel_address', 'channel_notifyflags', 'channel_removed', 'channel_deleted', 'channel_system'); $clean = array(); foreach ($arr['channel'] as $k => $v) { if (in_array($k, $disallowed)) { continue; } $clean[$k] = $v; } if (count($clean)) { foreach ($clean as $k => $v) { $r = dbq("UPDATE channel set " . dbesc($k) . " = '" . dbesc($v) . "' where channel_id = " . intval($channel['channel_id'])); } } } if (array_key_exists('abook', $arr) && is_array($arr['abook']) && count($arr['abook'])) { $total_friends = 0; $total_feeds = 0; $r = q("select abook_id, abook_feed from abook where abook_channel = %d", intval($channel['channel_id'])); if ($r) { // don't count yourself $total_friends = count($r) > 0 ? count($r) - 1 : 0; foreach ($r as $rr) { if (intval($rr['abook_feed'])) { $total_feeds++; } } } $disallowed = array('abook_id', 'abook_account', 'abook_channel', 'abook_rating', 'abook_rating_text'); foreach ($arr['abook'] as $abook) { $abconfig = null; if (array_key_exists('abconfig', $abook) && is_array($abook['abconfig']) && count($abook['abconfig'])) { $abconfig = $abook['abconfig']; } if (!array_key_exists('abook_blocked', $abook)) { // convert from redmatrix $abook['abook_blocked'] = $abook['abook_flags'] & 0x1 ? 1 : 0; $abook['abook_ignored'] = $abook['abook_flags'] & 0x2 ? 1 : 0; $abook['abook_hidden'] = $abook['abook_flags'] & 0x4 ? 1 : 0; $abook['abook_archived'] = $abook['abook_flags'] & 0x8 ? 1 : 0; $abook['abook_pending'] = $abook['abook_flags'] & 0x10 ? 1 : 0; $abook['abook_unconnected'] = $abook['abook_flags'] & 0x20 ? 1 : 0; $abook['abook_self'] = $abook['abook_flags'] & 0x80 ? 1 : 0; $abook['abook_feed'] = $abook['abook_flags'] & 0x100 ? 1 : 0; } $clean = array(); if ($abook['abook_xchan'] && $abook['entry_deleted']) { logger('process_channel_sync_delivery: removing abook entry for ' . $abook['abook_xchan']); $r = q("select abook_id, abook_feed from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1", dbesc($abook['abook_xchan']), intval($channel['channel_id'])); if ($r) { contact_remove($channel['channel_id'], $r[0]['abook_id']); if ($total_friends) { $total_friends--; } if (intval($r[0]['abook_feed'])) { $total_feeds--; } } continue; } // Perform discovery if the referenced xchan hasn't ever been seen on this hub. // This relies on the undocumented behaviour that red sites send xchan info with the abook // and import_author_xchan will look them up on all federated networks if ($abook['abook_xchan'] && $abook['xchan_addr']) { $h = zot_get_hublocs($abook['abook_xchan']); if (!$h) { $xhash = import_author_xchan(encode_item_xchan($abook)); if (!$xhash) { logger('process_channel_sync_delivery: import of ' . $abook['xchan_addr'] . ' failed.'); continue; } } } foreach ($abook as $k => $v) { if (in_array($k, $disallowed) || strpos($k, 'abook') !== 0) { continue; } $clean[$k] = $v; } if (!array_key_exists('abook_xchan', $clean)) { continue; } $r = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($clean['abook_xchan']), intval($channel['channel_id'])); // make sure we have an abook entry for this xchan on this system if (!$r) { if ($max_friends !== false && $total_friends > $max_friends) { logger('process_channel_sync_delivery: total_channels service class limit exceeded'); continue; } if ($max_feeds !== false && intval($clean['abook_feed']) && $total_feeds > $max_feeds) { logger('process_channel_sync_delivery: total_feeds service class limit exceeded'); continue; } q("insert into abook ( abook_xchan, abook_account, abook_channel ) values ('%s', %d, %d ) ", dbesc($clean['abook_xchan']), intval($channel['channel_account_id']), intval($channel['channel_id'])); $total_friends++; if (intval($clean['abook_feed'])) { $total_feeds++; } } if (count($clean)) { foreach ($clean as $k => $v) { if ($k == 'abook_dob') { $v = dbescdate($v); } $r = dbq("UPDATE abook set " . dbesc($k) . " = '" . dbesc($v) . "' where abook_xchan = '" . dbesc($clean['abook_xchan']) . "' and abook_channel = " . intval($channel['channel_id'])); } } if ($abconfig) { // @fixme does not handle sync of del_abconfig foreach ($abconfig as $abc) { set_abconfig($channel['channel_id'], $abc['xchan'], $abc['cat'], $abc['k'], $abc['v']); } } } } // sync collections (privacy groups) oh joy... if (array_key_exists('collections', $arr) && is_array($arr['collections']) && count($arr['collections'])) { $x = q("select * from groups where uid = %d", intval($channel['channel_id'])); foreach ($arr['collections'] as $cl) { $found = false; if ($x) { foreach ($x as $y) { if ($cl['collection'] == $y['hash']) { $found = true; break; } } if ($found) { if ($y['gname'] != $cl['name'] || $y['visible'] != $cl['visible'] || $y['deleted'] != $cl['deleted']) { q("update groups set gname = '%s', visible = %d, deleted = %d where hash = '%s' and uid = %d", dbesc($cl['name']), intval($cl['visible']), intval($cl['deleted']), dbesc($cl['hash']), intval($channel['channel_id'])); } if (intval($cl['deleted']) && !intval($y['deleted'])) { q("delete from group_member where gid = %d", intval($y['id'])); } } } if (!$found) { $r = q("INSERT INTO `groups` ( hash, uid, visible, deleted, gname )\n\t\t\t\t\t\tVALUES( '%s', %d, %d, %d, '%s' ) ", dbesc($cl['collection']), intval($channel['channel_id']), intval($cl['visible']), intval($cl['deleted']), dbesc($cl['name'])); } // now look for any collections locally which weren't in the list we just received. // They need to be removed by marking deleted and removing the members. // This shouldn't happen except for clones created before this function was written. if ($x) { $found_local = false; foreach ($x as $y) { foreach ($arr['collections'] as $cl) { if ($cl['collection'] == $y['hash']) { $found_local = true; break; } } if (!$found_local) { q("delete from group_member where gid = %d", intval($y['id'])); q("update groups set deleted = 1 where id = %d and uid = %d", intval($y['id']), intval($channel['channel_id'])); } } } } // reload the group list with any updates $x = q("select * from groups where uid = %d", intval($channel['channel_id'])); // now sync the members if (array_key_exists('collection_members', $arr) && is_array($arr['collection_members']) && count($arr['collection_members'])) { // first sort into groups keyed by the group hash $members = array(); foreach ($arr['collection_members'] as $cm) { if (!array_key_exists($cm['collection'], $members)) { $members[$cm['collection']] = array(); } $members[$cm['collection']][] = $cm['member']; } // our group list is already synchronised if ($x) { foreach ($x as $y) { // for each group, loop on members list we just received foreach ($members[$y['hash']] as $member) { $found = false; $z = q("select xchan from group_member where gid = %d and uid = %d and xchan = '%s' limit 1", intval($y['id']), intval($channel['channel_id']), dbesc($member)); if ($z) { $found = true; } // if somebody is in the group that wasn't before - add them if (!$found) { q("INSERT INTO `group_member` (`uid`, `gid`, `xchan`)\n\t\t\t\t\t\t\t\t\tVALUES( %d, %d, '%s' ) ", intval($channel['channel_id']), intval($y['id']), dbesc($member)); } } // now retrieve a list of members we have on this site $m = q("select xchan from group_member where gid = %d and uid = %d", intval($y['id']), intval($channel['channel_id'])); if ($m) { foreach ($m as $mm) { // if the local existing member isn't in the list we just received - remove them if (!in_array($mm['xchan'], $members[$y['hash']])) { q("delete from group_member where xchan = '%s' and gid = %d and uid = %d", dbesc($mm['xchan']), intval($y['id']), intval($channel['channel_id'])); } } } } } } } if (array_key_exists('profile', $arr) && is_array($arr['profile']) && count($arr['profile'])) { $disallowed = array('id', 'aid', 'uid', 'guid'); foreach ($arr['profile'] as $profile) { $x = q("select * from profile where profile_guid = '%s' and uid = %d limit 1", dbesc($profile['profile_guid']), intval($channel['channel_id'])); if (!$x) { q("insert into profile ( profile_guid, aid, uid ) values ('%s', %d, %d)", dbesc($profile['profile_guid']), intval($channel['channel_account_id']), intval($channel['channel_id'])); $x = q("select * from profile where profile_guid = '%s' and uid = %d limit 1", dbesc($profile['profile_guid']), intval($channel['channel_id'])); if (!$x) { continue; } } $clean = array(); foreach ($profile as $k => $v) { if (in_array($k, $disallowed)) { continue; } if ($k === 'name') { $clean['fullname'] = $v; } elseif ($k === 'with') { $clean['partner'] = $v; } elseif ($k === 'work') { $clean['employment'] = $v; } elseif (array_key_exists($k, $x[0])) { $clean[$k] = $v; } /** * @TODO * We also need to import local photos if a custom photo is selected */ } if (count($clean)) { foreach ($clean as $k => $v) { $r = dbq("UPDATE profile set `" . dbesc($k) . "` = '" . dbesc($v) . "' where profile_guid = '" . dbesc($profile['profile_guid']) . "' and uid = " . intval($channel['channel_id'])); } } } } $addon = array('channel' => $channel, 'data' => $arr); call_hooks('process_channel_sync_delivery', $addon); // we should probably do this for all items, but usually we only send one. if (array_key_exists('item', $arr) && is_array($arr['item'][0])) { $DR = new Zotlabs\Zot\DReport(z_root(), $d['hash'], $d['hash'], $arr['item'][0]['message_id'], 'channel sync processed'); $DR->addto_recipient($channel['channel_name'] . ' <' . $channel['channel_address'] . '@' . App::get_hostname() . '>'); } else { $DR = new Zotlabs\Zot\DReport(z_root(), $d['hash'], $d['hash'], 'sync packet', 'channel sync delivered'); } $result[] = $DR->get(); } return $result; }
function pubsubhubbub_subscribe($url, $channel, $xchan, $feed, $hubmode = 'subscribe') { $push_url = z_root() . '/pubsub/' . $channel['channel_address'] . '/' . $xchan['abook_id']; $verify = get_abconfig($channel['channel_id'], $xchan['xchan_hash'], 'pubsubhubbub', 'verify_token'); if (!$verify) { $verify = set_abconfig($channel['channel_id'], $xchan['xchan_hash'], 'pubsubhubbub', 'verify_token', random_string(16)); } if ($feed) { set_xconfig($xchan['xchan_hash'], 'system', 'feed_url', $feed); } else { $feed = get_xconfig($xchan['xchan_hash'], 'system', 'feed_url'); } $params = 'hub.mode=' . $hubmode . '&hub.callback=' . urlencode($push_url) . '&hub.topic=' . urlencode($feed) . '&hub.verify=async&hub.verify_token=' . $verify; logger('subscribe_to_hub: ' . $hubmode . ' ' . $xchan['xchan_name'] . ' to hub ' . $url . ' endpoint: ' . $push_url . ' with verifier ' . $verify); $x = z_post_url($url, $params); logger('subscribe_to_hub: returns: ' . $x['return_code'], LOGGER_DEBUG); return; }
function check_for_new_perms() { $pregistered = get_config('system', 'perms'); $pcurrent = array_keys(\Zotlabs\Access\Permissions::Perms()); if (!$pregistered) { set_config('system', 'perms', $pcurrent); return; } $found_new_perm = false; foreach ($pcurrent as $p) { if (!in_array($p, $pregistered)) { $found_new_perm = true; // for all channels $c = q("select channel_id from channel where true"); if ($c) { foreach ($c as $cc) { // get the permission role $r = q("select v from pconfig where uid = %d and cat = 'system' and k = 'permissions_role'", intval($cc['uid'])); if ($r) { // get a list of connections $x = q("select abook_xchan from abook where abook_channel = %d and abook_self = 0", intval($cc['uid'])); // get the permissions role details $rp = \Zotlabs\Access\PermissionRoles::role_perms($r[0]['v']); if ($rp) { // set the channel limits if appropriate or 0 if (array_key_exists('limits', $rp) && array_key_exists($p, $rp['limits'])) { \Zotlabs\Access\PermissionLimits::Set($cc['uid'], $p, $rp['limits'][$p]); } else { \Zotlabs\Access\PermissionLimits::Set($cc['uid'], $p, 0); } $set = array_key_exists('perms_connect', $rp) && array_key_exists($p, $rp['perms_connect']) ? true : false; // foreach connection set to the perms_connect value if ($x) { foreach ($x as $xx) { set_abconfig($cc['uid'], $xx['abook_xchan'], 'my_perms', $p, intval($set)); } } } } } } } } // We should probably call perms_refresh here, but this should get pushed in 24 hours and there is no urgency if ($found_new_perm) { set_config('system', 'perms', $pcurrent); } }
function diaspora_request($importer, $xml) { $a = get_app(); $sender_handle = unxmlify(diaspora_get_author($xml)); $recipient_handle = unxmlify(diaspora_get_recipient($xml)); // @TODO - map these perms to $newperms below if (array_key_exists('following', $xml) && array_key_exists('sharing', $xml)) { $following = unxmlify($xml['following']) === 'true' ? true : false; $sharing = unxmlify($xml['sharing']) === 'true' ? true : false; } else { $following = true; $sharing = true; } if (!$sender_handle || !$recipient_handle) { return; } // Do we already have an abook record? $contact = diaspora_get_contact_by_handle($importer['channel_id'], $sender_handle); // Please note some permissions such as PERMS_R_PAGES are impossible for Disapora. // They cannot currently authenticate to our system. $x = \Zotlabs\Access\PermissionRoles::role_perms('social'); $their_perms = \Zotlabs\Access\Permissions::FilledPerms($x['perms_connect']); if ($contact && $contact['abook_id']) { // perhaps we were already sharing with this person. Now they're sharing with us. // That makes us friends. Maybe. foreach ($their_perms as $k => $v) { set_abconfig($importer['channel_id'], $contact['abook_xchan'], 'their_perms', $k, $v); } $abook_instance = $contact['abook_instance']; if ($abook_instance) { $abook_instance .= ','; } $abook_instance .= z_root(); $r = q("update abook set abook_instance = '%s' where abook_id = %d and abook_channel = %d", dbesc($abook_instance), intval($contact['abook_id']), intval($importer['channel_id'])); return; } $ret = find_diaspora_person_by_handle($sender_handle); if (!$ret || !strstr($ret['xchan_network'], 'diaspora')) { logger('diaspora_request: Cannot resolve diaspora handle ' . $sender_handle . ' for ' . $recipient_handle); return; } $my_perms = false; $role = get_pconfig($importer['channel_id'], 'system', 'permissions_role'); if ($role) { $x = \Zotlabs\Access\PermissionRoles::role_perms($role); if ($x['perms_auto']) { $my_perms = \Zotlabs\Access\Permissions::FilledPerms($x['perms_connect']); } } if (!$my_perms) { $my_perms = \Zotlabs\Access\Permissions::FilledAutoperms($importer['channel_id']); } $closeness = get_pconfig($importer['channel_id'], 'system', 'new_abook_closeness'); if ($closeness === false) { $closeness = 80; } $r = q("insert into abook ( abook_account, abook_channel, abook_xchan, abook_my_perms, abook_their_perms, abook_closeness, abook_created, abook_updated, abook_connected, abook_dob, abook_pending, abook_instance ) values ( %d, %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s', %d, '%s' )", intval($importer['channel_account_id']), intval($importer['channel_id']), dbesc($ret['xchan_hash']), intval($default_perms), intval($their_perms), intval($closeness), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(datetime_convert()), dbesc(NULL_DATE), intval($my_perms ? 0 : 1), dbesc(z_root())); if ($my_perms) { foreach ($my_perms as $k => $v) { set_abconfig($importer['channel_id'], $ret['xchan_hash'], 'my_perms', $k, $v); } } if ($their_perms) { foreach ($their_perms as $k => $v) { set_abconfig($importer['channel_id'], $ret['xchan_hash'], 'their_perms', $k, $v); } } if ($r) { logger("New Diaspora introduction received for {$importer['channel_name']}"); $new_connection = q("select * from abook left join xchan on abook_xchan = xchan_hash left join hubloc on hubloc_hash = xchan_hash where abook_channel = %d and abook_xchan = '%s' order by abook_created desc limit 1", intval($importer['channel_id']), dbesc($ret['xchan_hash'])); if ($new_connection) { \Zotlabs\Lib\Enotify::submit(['type' => NOTIFY_INTRO, 'from_xchan' => $ret['xchan_hash'], 'to_xchan' => $importer['channel_hash'], 'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id']]); if ($my_perms) { // Send back a sharing notification to them $x = diaspora_share($importer, $new_connection[0]); if ($x) { Zotlabs\Daemon\Master::Summon(array('Deliver', $x)); } } $clone = array(); foreach ($new_connection[0] as $k => $v) { if (strpos($k, 'abook_') === 0) { $clone[$k] = $v; } } unset($clone['abook_id']); unset($clone['abook_account']); unset($clone['abook_channel']); $abconfig = load_abconfig($importer['channel_id'], $clone['abook_xchan']); if ($abconfig) { $clone['abconfig'] = $abconfig; } build_sync_packet($importer['channel_id'], ['abook' => array($clone)]); } } // find the abook record we just created $contact_record = diaspora_get_contact_by_handle($importer['channel_id'], $sender_handle); if (!$contact_record) { logger('diaspora_request: unable to locate newly created contact record.'); return; } /** If there is a default group for this channel, add this member to it */ if ($importer['channel_default_group']) { require_once 'include/group.php'; $g = group_rec_byhash($importer['channel_id'], $importer['channel_default_group']); if ($g) { group_add_member($importer['channel_id'], '', $contact_record['xchan_hash'], $g['id']); } } return; }
function post() { if (!local_channel()) { return; } $contact_id = intval(argv(1)); if (!$contact_id) { return; } $channel = \App::get_channel(); // TODO if configured for hassle-free permissions, we'll post the form with ajax as soon as the // connection enable is toggled to a special autopost url and set permissions immediately, leaving // the other form elements alone pending a manual submit of the form. The downside is that there // will be a window of opportunity when the permissions have been set but before you've had a chance // to review and possibly restrict them. The upside is we won't have to warn you that your connection // can't do anything until you save the bloody form. $autopost = argc() > 2 && argv(2) === 'auto' ? true : false; $orig_record = q("SELECT * FROM abook WHERE abook_id = %d AND abook_channel = %d LIMIT 1", intval($contact_id), intval(local_channel())); if (!$orig_record) { notice(t('Could not access contact record.') . EOL); goaway(z_root() . '/connections'); return; // NOTREACHED } call_hooks('contact_edit_post', $_POST); if (intval($orig_record[0]['abook_self'])) { $autoperms = intval($_POST['autoperms']); $is_self = true; } else { $autoperms = null; $is_self = false; } $profile_id = $_POST['profile_assign']; if ($profile_id) { $r = q("SELECT profile_guid FROM profile WHERE profile_guid = '%s' AND `uid` = %d LIMIT 1", dbesc($profile_id), intval(local_channel())); if (!count($r)) { notice(t('Could not locate selected profile.') . EOL); return; } } $abook_incl = escape_tags($_POST['abook_incl']); $abook_excl = escape_tags($_POST['abook_excl']); $hidden = intval($_POST['hidden']); $priority = intval($_POST['poll']); if ($priority > 5 || $priority < 0) { $priority = 0; } $closeness = intval($_POST['closeness']); if ($closeness < 0) { $closeness = 99; } $rating = intval($_POST['rating']); if ($rating < -10) { $rating = -10; } if ($rating > 10) { $rating = 10; } $rating_text = trim(escape_tags($_REQUEST['rating_text'])); $all_perms = \Zotlabs\Access\Permissions::Perms(); if ($all_perms) { foreach ($all_perms as $perm => $desc) { if (array_key_exists('perms_' . $perm, $_POST)) { set_abconfig($channel['channel_id'], $orig_record[0]['abook_xchan'], 'my_perms', $perm, intval($_POST['perms_' . $perm])); if ($autoperms) { set_pconfig($channel['channel_id'], 'autoperms', $perm, intval($_POST['perms_' . $perm])); } } else { set_abconfig($channel['channel_id'], $orig_record[0]['abook_xchan'], 'my_perms', $perm, 0); if ($autoperms) { set_pconfig($channel['channel_id'], 'autoperms', $perm, 0); } } } } if (!is_null($autoperms)) { set_pconfig($channel['channel_id'], 'system', 'autoperms', $autoperms); } $new_friend = false; // only store a record and notify the directory if the rating changed if (!$is_self) { $signed = $orig_record[0]['abook_xchan'] . '.' . $rating . '.' . $rating_text; $sig = base64url_encode(rsa_sign($signed, $channel['channel_prvkey'])); $rated = intval($rating) || strlen($rating_text) ? true : false; $record = 0; $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", dbesc($channel['channel_hash']), dbesc($orig_record[0]['abook_xchan'])); if ($z) { if ($z[0]['xlink_rating'] != $rating || $z[0]['xlink_rating_text'] != $rating_text) { $record = $z[0]['xlink_id']; $w = q("update xlink set xlink_rating = '%d', xlink_rating_text = '%s', xlink_sig = '%s', xlink_updated = '%s'\n\t\t\t\t\t\twhere xlink_id = %d", intval($rating), dbesc($rating_text), dbesc($sig), dbesc(datetime_convert()), intval($record)); } } elseif ($rated) { // only create a record if there's something to save $w = q("insert into xlink ( xlink_xchan, xlink_link, xlink_rating, xlink_rating_text, xlink_sig, xlink_updated, xlink_static ) values ( '%s', '%s', %d, '%s', '%s', '%s', 1 ) ", dbesc($channel['channel_hash']), dbesc($orig_record[0]['abook_xchan']), intval($rating), dbesc($rating_text), dbesc($sig), dbesc(datetime_convert())); $z = q("select * from xlink where xlink_xchan = '%s' and xlink_link = '%s' and xlink_static = 1 limit 1", dbesc($channel['channel_hash']), dbesc($orig_record[0]['abook_xchan'])); if ($z) { $record = $z[0]['xlink_id']; } } if ($record) { \Zotlabs\Daemon\Master::Summon(array('Ratenotif', 'rating', $record)); } } if ($_REQUEST['pending'] && intval($orig_record[0]['abook_pending'])) { $new_friend = true; // @fixme it won't be common, but when you accept a new connection request // the permissions will now be that of your permissions role and ignore // any you may have set manually on the form. We'll probably see a bug if somebody // tries to set the permissions *and* approve the connection in the same // request. The workaround is to approve the connection, then go back and // adjust permissions as desired. $abook_my_perms = get_channel_default_perms(local_channel()); $role = get_pconfig(local_channel(), 'system', 'permissions_role'); if ($role) { $x = \Zotlabs\Access\PermissionRoles::role_perms($role); if ($x['perms_connect']) { $abook_my_perms = $x['perms_connect']; } } $filled_perms = \Zotlabs\Access\Permissions::FilledPerms($abook_my_perms); foreach ($filled_perms as $k => $v) { set_abconfig($channel['channel_id'], $orig_record[0]['abook_xchan'], 'my_perms', $k, $v); } } $abook_pending = $new_friend ? 0 : $orig_record[0]['abook_pending']; $r = q("UPDATE abook SET abook_profile = '%s', abook_closeness = %d, abook_pending = %d,\n\t\t\tabook_incl = '%s', abook_excl = '%s'\n\t\t\twhere abook_id = %d AND abook_channel = %d", dbesc($profile_id), intval($closeness), intval($abook_pending), dbesc($abook_incl), dbesc($abook_excl), intval($contact_id), intval(local_channel())); if ($orig_record[0]['abook_profile'] != $profile_id) { //Update profile photo permissions logger('A new profile was assigned - updating profile photos'); profile_photo_set_profile_perms(local_channel(), $profile_id); } if ($r) { info(t('Connection updated.') . EOL); } else { notice(t('Failed to update connection record.') . EOL); } if (!intval(\App::$poi['abook_self'])) { \Zotlabs\Daemon\Master::Summon(['Notifier', $new_friend ? 'permission_create' : 'permission_update', $contact_id]); } if ($new_friend) { $default_group = $channel['channel_default_group']; if ($default_group) { require_once 'include/group.php'; $g = group_rec_byhash(local_channel(), $default_group); if ($g) { group_add_member(local_channel(), '', \App::$poi['abook_xchan'], $g['id']); } } // Check if settings permit ("post new friend activity" is allowed, and // friends in general or this friend in particular aren't hidden) // and send out a new friend activity $pr = q("select * from profile where uid = %d and is_default = 1 and hide_friends = 0", intval($channel['channel_id'])); if ($pr && !intval($orig_record[0]['abook_hidden']) && intval(get_pconfig($channel['channel_id'], 'system', 'post_newfriend'))) { $xarr = array(); $xarr['verb'] = ACTIVITY_FRIEND; $xarr['item_wall'] = 1; $xarr['item_origin'] = 1; $xarr['item_thread_top'] = 1; $xarr['owner_xchan'] = $xarr['author_xchan'] = $channel['channel_hash']; $xarr['allow_cid'] = $channel['channel_allow_cid']; $xarr['allow_gid'] = $channel['channel_allow_gid']; $xarr['deny_cid'] = $channel['channel_deny_cid']; $xarr['deny_gid'] = $channel['channel_deny_gid']; $xarr['item_private'] = $xarr['allow_cid'] || $xarr['allow_gid'] || $xarr['deny_cid'] || $xarr['deny_gid'] ? 1 : 0; $obj = array('type' => ACTIVITY_OBJ_PERSON, 'title' => \App::$poi['xchan_name'], 'id' => \App::$poi['xchan_hash'], 'link' => array(array('rel' => 'alternate', 'type' => 'text/html', 'href' => \App::$poi['xchan_url']), array('rel' => 'photo', 'type' => \App::$poi['xchan_photo_mimetype'], 'href' => \App::$poi['xchan_photo_l']))); $xarr['obj'] = json_encode($obj); $xarr['obj_type'] = ACTIVITY_OBJ_PERSON; $xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . \App::$poi['xchan_url'] . ']' . \App::$poi['xchan_name'] . '[/zrl]'; $xarr['body'] .= "\n\n\n" . '[zrl=' . \App::$poi['xchan_url'] . '][zmg=80x80]' . \App::$poi['xchan_photo_m'] . '[/zmg][/zrl]'; post_activity_item($xarr); } // pull in a bit of content if there is any to pull in \Zotlabs\Daemon\Master::Summon(array('Onepoll', $contact_id)); } // Refresh the structure in memory with the new data $r = q("SELECT abook.*, xchan.*\n\t\t\tFROM abook left join xchan on abook_xchan = xchan_hash\n\t\t\tWHERE abook_channel = %d and abook_id = %d LIMIT 1", intval(local_channel()), intval($contact_id)); if ($r) { \App::$poi = $r[0]; } if ($new_friend) { $arr = array('channel_id' => local_channel(), 'abook' => \App::$poi); call_hooks('accept_follow', $arr); } $this->connedit_clone($a); if ($_REQUEST['pending'] && !$_REQUEST['done']) { goaway(z_root() . '/connections/ifpending'); } return; }
function post() { if (!local_channel()) { return; } if ($_SESSION['delegate']) { return; } $channel = \App::get_channel(); // logger('mod_settings: ' . print_r($_REQUEST,true)); if (argc() > 1 && argv(1) === 'oauth' && x($_POST, 'remove')) { check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth'); $key = $_POST['remove']; q("DELETE FROM tokens WHERE id='%s' AND uid=%d", dbesc($key), local_channel()); goaway(z_root() . "/settings/oauth/"); return; } if (argc() > 2 && argv(1) === 'oauth' && (argv(2) === 'edit' || argv(2) === 'add') && x($_POST, 'submit')) { check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth'); $name = x($_POST, 'name') ? $_POST['name'] : ''; $key = x($_POST, 'key') ? $_POST['key'] : ''; $secret = x($_POST, 'secret') ? $_POST['secret'] : ''; $redirect = x($_POST, 'redirect') ? $_POST['redirect'] : ''; $icon = x($_POST, 'icon') ? $_POST['icon'] : ''; $ok = true; if ($name == '') { $ok = false; notice(t('Name is required') . EOL); } if ($key == '' || $secret == '') { $ok = false; notice(t('Key and Secret are required') . EOL); } if ($ok) { if ($_POST['submit'] == t("Update")) { $r = q("UPDATE clients SET\n\t\t\t\t\t\t\t\tclient_id='%s',\n\t\t\t\t\t\t\t\tpw='%s',\n\t\t\t\t\t\t\t\tclname='%s',\n\t\t\t\t\t\t\t\tredirect_uri='%s',\n\t\t\t\t\t\t\t\ticon='%s',\n\t\t\t\t\t\t\t\tuid=%d\n\t\t\t\t\t\t\tWHERE client_id='%s'", dbesc($key), dbesc($secret), dbesc($name), dbesc($redirect), dbesc($icon), intval(local_channel()), dbesc($key)); } else { $r = q("INSERT INTO clients (client_id, pw, clname, redirect_uri, icon, uid)\n\t\t\t\t\t\tVALUES ('%s','%s','%s','%s','%s',%d)", dbesc($key), dbesc($secret), dbesc($name), dbesc($redirect), dbesc($icon), intval(local_channel())); $r = q("INSERT INTO xperm (xp_client, xp_channel, xp_perm) VALUES ('%s', %d, '%s') ", dbesc($key), intval(local_channel()), dbesc('all')); } } goaway(z_root() . "/settings/oauth/"); return; } if (argc() > 1 && argv(1) == 'featured') { check_form_security_token_redirectOnErr('/settings/featured', 'settings_featured'); call_hooks('feature_settings_post', $_POST); build_sync_packet(); return; } if (argc() > 1 && argv(1) == 'tokens') { check_form_security_token_redirectOnErr('/settings/tokens', 'settings_tokens'); $token_errs = 0; if (array_key_exists('token', $_POST)) { $atoken_id = $_POST['atoken_id'] ? intval($_POST['atoken_id']) : 0; $name = trim(escape_tags($_POST['name'])); $token = trim($_POST['token']); if (!$name || !$token) { $token_errs++; } if (trim($_POST['expires'])) { $expires = datetime_convert(date_default_timezone_get(), 'UTC', $_POST['expires']); } else { $expires = NULL_DATE; } $max_atokens = service_class_fetch(local_channel(), 'access_tokens'); if ($max_atokens) { $r = q("select count(atoken_id) as total where atoken_uid = %d", intval(local_channel())); if ($r && intval($r[0]['total']) >= $max_tokens) { notice(sprintf(t('This channel is limited to %d tokens'), $max_tokens) . EOL); return; } } } if ($token_errs) { notice(t('Name and Password are required.') . EOL); return; } if ($atoken_id) { $r = q("update atoken set atoken_name = '%s', atoken_token = '%s', atoken_expires = '%s' \n\t\t\t\t\twhere atoken_id = %d and atoken_uid = %d", dbesc($name), dbesc($token), dbesc($expires), intval($atoken_id), intval($channel['channel_id'])); } else { $r = q("insert into atoken ( atoken_aid, atoken_uid, atoken_name, atoken_token, atoken_expires )\n\t\t\t\t\tvalues ( %d, %d, '%s', '%s', '%s' ) ", intval($channel['channel_account_id']), intval($channel['channel_id']), dbesc($name), dbesc($token), dbesc($expires)); } $atoken_xchan = substr($channel['channel_hash'], 0, 16) . '.' . $name; $all_perms = \Zotlabs\Access\Permissions::Perms(); if ($all_perms) { foreach ($all_perms as $perm => $desc) { if (array_key_exists('perms_' . $perm, $_POST)) { set_abconfig($channel['channel_id'], $atoken_xchan, 'my_perms', $perm, intval($_POST['perms_' . $perm])); } else { set_abconfig($channel['channel_id'], $atoken_xchan, 'my_perms', $perm, 0); } } } info(t('Token saved.') . EOL); return; } if (argc() > 1 && argv(1) === 'features') { check_form_security_token_redirectOnErr('/settings/features', 'settings_features'); // Build list of features and check which are set $features = get_features(); $all_features = array(); foreach ($features as $k => $v) { foreach ($v as $f) { $all_features[] = $f[0]; } } foreach ($all_features as $k) { if (x($_POST, "feature_{$k}")) { set_pconfig(local_channel(), 'feature', $k, 1); } else { set_pconfig(local_channel(), 'feature', $k, 0); } } build_sync_packet(); return; } if (argc() > 1 && argv(1) == 'display') { check_form_security_token_redirectOnErr('/settings/display', 'settings_display'); $theme = x($_POST, 'theme') ? notags(trim($_POST['theme'])) : \App::$channel['channel_theme']; $mobile_theme = x($_POST, 'mobile_theme') ? notags(trim($_POST['mobile_theme'])) : ''; $preload_images = x($_POST, 'preload_images') ? intval($_POST['preload_images']) : 0; $user_scalable = x($_POST, 'user_scalable') ? intval($_POST['user_scalable']) : 0; $nosmile = x($_POST, 'nosmile') ? intval($_POST['nosmile']) : 0; $title_tosource = x($_POST, 'title_tosource') ? intval($_POST['title_tosource']) : 0; $channel_list_mode = x($_POST, 'channel_list_mode') ? intval($_POST['channel_list_mode']) : 0; $network_list_mode = x($_POST, 'network_list_mode') ? intval($_POST['network_list_mode']) : 0; $channel_divmore_height = x($_POST, 'channel_divmore_height') ? intval($_POST['channel_divmore_height']) : 400; if ($channel_divmore_height < 50) { $channel_divmore_height = 50; } $network_divmore_height = x($_POST, 'network_divmore_height') ? intval($_POST['network_divmore_height']) : 400; if ($network_divmore_height < 50) { $network_divmore_height = 50; } $browser_update = x($_POST, 'browser_update') ? intval($_POST['browser_update']) : 0; $browser_update = $browser_update * 1000; if ($browser_update < 10000) { $browser_update = 10000; } $itemspage = x($_POST, 'itemspage') ? intval($_POST['itemspage']) : 20; if ($itemspage > 100) { $itemspage = 100; } if ($mobile_theme == "---") { del_pconfig(local_channel(), 'system', 'mobile_theme'); } else { set_pconfig(local_channel(), 'system', 'mobile_theme', $mobile_theme); } set_pconfig(local_channel(), 'system', 'preload_images', $preload_images); set_pconfig(local_channel(), 'system', 'user_scalable', $user_scalable); set_pconfig(local_channel(), 'system', 'update_interval', $browser_update); set_pconfig(local_channel(), 'system', 'itemspage', $itemspage); set_pconfig(local_channel(), 'system', 'no_smilies', 1 - intval($nosmile)); set_pconfig(local_channel(), 'system', 'title_tosource', $title_tosource); set_pconfig(local_channel(), 'system', 'channel_list_mode', $channel_list_mode); set_pconfig(local_channel(), 'system', 'network_list_mode', $network_list_mode); set_pconfig(local_channel(), 'system', 'channel_divmore_height', $channel_divmore_height); set_pconfig(local_channel(), 'system', 'network_divmore_height', $network_divmore_height); if ($theme == \App::$channel['channel_theme']) { // call theme_post only if theme has not been changed if (($themeconfigfile = $this->get_theme_config_file($theme)) != null) { require_once $themeconfigfile; theme_post($a); } } $r = q("UPDATE channel SET channel_theme = '%s' WHERE channel_id = %d", dbesc($theme), intval(local_channel())); call_hooks('display_settings_post', $_POST); build_sync_packet(); goaway(z_root() . '/settings/display'); return; // NOTREACHED } if (argc() > 1 && argv(1) === 'account') { check_form_security_token_redirectOnErr('/settings/account', 'settings_account'); call_hooks('account_settings_post', $_POST); // call_hooks('settings_account', $_POST); $errs = array(); $email = x($_POST, 'email') ? trim(notags($_POST['email'])) : ''; $account = \App::get_account(); if ($email != $account['account_email']) { if (!valid_email($email)) { $errs[] = t('Not valid email.'); } $adm = trim(get_config('system', 'admin_email')); if ($adm && strcasecmp($email, $adm) == 0) { $errs[] = t('Protected email address. Cannot change to that email.'); $email = \App::$user['email']; } if (!$errs) { $r = q("update account set account_email = '%s' where account_id = %d", dbesc($email), intval($account['account_id'])); if (!$r) { $errs[] = t('System failure storing new email. Please try again.'); } } } if ($errs) { foreach ($errs as $err) { notice($err . EOL); } $errs = array(); } if (x($_POST, 'npassword') || x($_POST, 'confirm')) { $origpass = trim($_POST['origpass']); require_once 'include/auth.php'; if (!account_verify_password($email, $origpass)) { $errs[] = t('Password verification failed.'); } $newpass = trim($_POST['npassword']); $confirm = trim($_POST['confirm']); if ($newpass != $confirm) { $errs[] = t('Passwords do not match. Password unchanged.'); } if (!x($newpass) || !x($confirm)) { $errs[] = t('Empty passwords are not allowed. Password unchanged.'); } if (!$errs) { $salt = random_string(32); $password_encoded = hash('whirlpool', $salt . $newpass); $r = q("update account set account_salt = '%s', account_password = '******', account_password_changed = '%s' \n\t\t\t\t\t\twhere account_id = %d", dbesc($salt), dbesc($password_encoded), dbesc(datetime_convert()), intval(get_account_id())); if ($r) { info(t('Password changed.') . EOL); } else { $errs[] = t('Password update failed. Please try again.'); } } } if ($errs) { foreach ($errs as $err) { notice($err . EOL); } } goaway(z_root() . '/settings/account'); } check_form_security_token_redirectOnErr('/settings', 'settings'); call_hooks('settings_post', $_POST); $set_perms = ''; $role = x($_POST, 'permissions_role') ? notags(trim($_POST['permissions_role'])) : ''; $oldrole = get_pconfig(local_channel(), 'system', 'permissions_role'); if ($role != $oldrole || $role === 'custom') { if ($role === 'custom') { $hide_presence = x($_POST, 'hide_presence') && intval($_POST['hide_presence']) == 1 ? 1 : 0; $publish = x($_POST, 'profile_in_directory') && intval($_POST['profile_in_directory']) == 1 ? 1 : 0; $def_group = x($_POST, 'group-selection') ? notags(trim($_POST['group-selection'])) : ''; $r = q("update channel set channel_default_group = '%s' where channel_id = %d", dbesc($def_group), intval(local_channel())); $global_perms = \Zotlabs\Access\Permissions::Perms(); foreach ($global_perms as $k => $v) { \Zotlabs\Access\PermissionLimits::Set(local_channel(), $k, intval($_POST[$k])); } $acl = new \Zotlabs\Access\AccessList($channel); $acl->set_from_array($_POST); $x = $acl->get(); $r = q("update channel set channel_allow_cid = '%s', channel_allow_gid = '%s', \n\t\t\t\t\tchannel_deny_cid = '%s', channel_deny_gid = '%s' where channel_id = %d", dbesc($x['allow_cid']), dbesc($x['allow_gid']), dbesc($x['deny_cid']), dbesc($x['deny_gid']), intval(local_channel())); } else { $role_permissions = \Zotlabs\Access\PermissionRoles::role_perms($_POST['permissions_role']); if (!$role_permissions) { notice('Permissions category could not be found.'); return; } $hide_presence = 1 - intval($role_permissions['online']); if ($role_permissions['default_collection']) { $r = q("select hash from groups where uid = %d and gname = '%s' limit 1", intval(local_channel()), dbesc(t('Friends'))); if (!$r) { require_once 'include/group.php'; group_add(local_channel(), t('Friends')); group_add_member(local_channel(), t('Friends'), $channel['channel_hash']); $r = q("select hash from groups where uid = %d and gname = '%s' limit 1", intval(local_channel()), dbesc(t('Friends'))); } if ($r) { q("update channel set channel_default_group = '%s', channel_allow_gid = '%s', channel_allow_cid = '', channel_deny_gid = '', channel_deny_cid = '' where channel_id = %d", dbesc($r[0]['hash']), dbesc('<' . $r[0]['hash'] . '>'), intval(local_channel())); } else { notice(sprintf('Default privacy group \'%s\' not found. Please create and re-submit permission change.', t('Friends')) . EOL); return; } } else { q("update channel set channel_default_group = '', channel_allow_gid = '', channel_allow_cid = '', channel_deny_gid = '', \n\t\t\t\t\t\tchannel_deny_cid = '' where channel_id = %d", intval(local_channel())); } $x = \Zotlabs\Access\Permissions::FilledPerms($role_permissions['perms_connect']); foreach ($x as $k => $v) { set_abconfig(local_channel(), $channel['channel_hash'], 'my_perms', $k, $v); if ($role_permissions['perms_auto']) { set_pconfig(local_channel(), 'autoperms', $k, $v); } else { del_pconfig(local_channel(), 'autoperms', $k); } } if ($role_permissions['limits']) { foreach ($role_permissions['limits'] as $k => $v) { \Zotlabs\Access\PermissionLimits::Set(local_channel(), $k, $v); } } if (array_key_exists('directory_publish', $role_permissions)) { $publish = intval($role_permissions['directory_publish']); } } set_pconfig(local_channel(), 'system', 'hide_online_status', $hide_presence); set_pconfig(local_channel(), 'system', 'permissions_role', $role); } $username = x($_POST, 'username') ? notags(trim($_POST['username'])) : ''; $timezone = x($_POST, 'timezone_select') ? notags(trim($_POST['timezone_select'])) : ''; $defloc = x($_POST, 'defloc') ? notags(trim($_POST['defloc'])) : ''; $openid = x($_POST, 'openid_url') ? notags(trim($_POST['openid_url'])) : ''; $maxreq = x($_POST, 'maxreq') ? intval($_POST['maxreq']) : 0; $expire = x($_POST, 'expire') ? intval($_POST['expire']) : 0; $evdays = x($_POST, 'evdays') ? intval($_POST['evdays']) : 3; $photo_path = x($_POST, 'photo_path') ? escape_tags(trim($_POST['photo_path'])) : ''; $attach_path = x($_POST, 'attach_path') ? escape_tags(trim($_POST['attach_path'])) : ''; $channel_menu = x($_POST['channel_menu']) ? htmlspecialchars_decode(trim($_POST['channel_menu']), ENT_QUOTES) : ''; $expire_items = x($_POST, 'expire_items') ? intval($_POST['expire_items']) : 0; $expire_starred = x($_POST, 'expire_starred') ? intval($_POST['expire_starred']) : 0; $expire_photos = x($_POST, 'expire_photos') ? intval($_POST['expire_photos']) : 0; $expire_network_only = x($_POST, 'expire_network_only') ? intval($_POST['expire_network_only']) : 0; $allow_location = x($_POST, 'allow_location') && intval($_POST['allow_location']) == 1 ? 1 : 0; $blocktags = x($_POST, 'blocktags') && intval($_POST['blocktags']) == 1 ? 0 : 1; // this setting is inverted! $unkmail = x($_POST, 'unkmail') && intval($_POST['unkmail']) == 1 ? 1 : 0; $cntunkmail = x($_POST, 'cntunkmail') ? intval($_POST['cntunkmail']) : 0; $suggestme = x($_POST, 'suggestme') ? intval($_POST['suggestme']) : 0; $post_newfriend = $_POST['post_newfriend'] == 1 ? 1 : 0; $post_joingroup = $_POST['post_joingroup'] == 1 ? 1 : 0; $post_profilechange = $_POST['post_profilechange'] == 1 ? 1 : 0; $adult = $_POST['adult'] == 1 ? 1 : 0; $cal_first_day = x($_POST, 'first_day') && intval($_POST['first_day']) == 1 ? 1 : 0; $channel = \App::get_channel(); $pageflags = $channel['channel_pageflags']; $existing_adult = $pageflags & PAGE_ADULT ? 1 : 0; if ($adult != $existing_adult) { $pageflags = $pageflags ^ PAGE_ADULT; } $notify = 0; if (x($_POST, 'notify1')) { $notify += intval($_POST['notify1']); } if (x($_POST, 'notify2')) { $notify += intval($_POST['notify2']); } if (x($_POST, 'notify3')) { $notify += intval($_POST['notify3']); } if (x($_POST, 'notify4')) { $notify += intval($_POST['notify4']); } if (x($_POST, 'notify5')) { $notify += intval($_POST['notify5']); } if (x($_POST, 'notify6')) { $notify += intval($_POST['notify6']); } if (x($_POST, 'notify7')) { $notify += intval($_POST['notify7']); } if (x($_POST, 'notify8')) { $notify += intval($_POST['notify8']); } $vnotify = 0; if (x($_POST, 'vnotify1')) { $vnotify += intval($_POST['vnotify1']); } if (x($_POST, 'vnotify2')) { $vnotify += intval($_POST['vnotify2']); } if (x($_POST, 'vnotify3')) { $vnotify += intval($_POST['vnotify3']); } if (x($_POST, 'vnotify4')) { $vnotify += intval($_POST['vnotify4']); } if (x($_POST, 'vnotify5')) { $vnotify += intval($_POST['vnotify5']); } if (x($_POST, 'vnotify6')) { $vnotify += intval($_POST['vnotify6']); } if (x($_POST, 'vnotify7')) { $vnotify += intval($_POST['vnotify7']); } if (x($_POST, 'vnotify8')) { $vnotify += intval($_POST['vnotify8']); } if (x($_POST, 'vnotify9')) { $vnotify += intval($_POST['vnotify9']); } if (x($_POST, 'vnotify10')) { $vnotify += intval($_POST['vnotify10']); } if (x($_POST, 'vnotify11')) { $vnotify += intval($_POST['vnotify11']); } $always_show_in_notices = x($_POST, 'always_show_in_notices') ? 1 : 0; $channel = \App::get_channel(); $err = ''; $name_change = false; if ($username != $channel['channel_name']) { $name_change = true; require_once 'include/channel.php'; $err = validate_channelname($username); if ($err) { notice($err); return; } } if ($timezone != $channel['channel_timezone']) { if (strlen($timezone)) { date_default_timezone_set($timezone); } } set_pconfig(local_channel(), 'system', 'use_browser_location', $allow_location); set_pconfig(local_channel(), 'system', 'suggestme', $suggestme); set_pconfig(local_channel(), 'system', 'post_newfriend', $post_newfriend); set_pconfig(local_channel(), 'system', 'post_joingroup', $post_joingroup); set_pconfig(local_channel(), 'system', 'post_profilechange', $post_profilechange); set_pconfig(local_channel(), 'system', 'blocktags', $blocktags); set_pconfig(local_channel(), 'system', 'channel_menu', $channel_menu); set_pconfig(local_channel(), 'system', 'vnotify', $vnotify); set_pconfig(local_channel(), 'system', 'always_show_in_notices', $always_show_in_notices); set_pconfig(local_channel(), 'system', 'evdays', $evdays); set_pconfig(local_channel(), 'system', 'photo_path', $photo_path); set_pconfig(local_channel(), 'system', 'attach_path', $attach_path); set_pconfig(local_channel(), 'system', 'cal_first_day', $cal_first_day); $r = q("update channel set channel_name = '%s', channel_pageflags = %d, channel_timezone = '%s', channel_location = '%s', channel_notifyflags = %d, channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d {$set_perms} where channel_id = %d", dbesc($username), intval($pageflags), dbesc($timezone), dbesc($defloc), intval($notify), intval($unkmail), intval($maxreq), intval($expire), intval(local_channel())); if ($r) { info(t('Settings updated.') . EOL); } if (!is_null($publish)) { $r = q("UPDATE profile SET publish = %d WHERE is_default = 1 AND uid = %d", intval($publish), intval(local_channel())); } if ($name_change) { $r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s' where xchan_hash = '%s'", dbesc($username), dbesc(datetime_convert()), dbesc($channel['channel_hash'])); $r = q("update profile set fullname = '%s' where uid = %d and is_default = 1", dbesc($username), intval($channel['channel_id'])); } \Zotlabs\Daemon\Master::Summon(array('Directory', local_channel())); build_sync_packet(); //$_SESSION['theme'] = $theme; if ($email_changed && \App::$config['system']['register_policy'] == REGISTER_VERIFY) { // FIXME - set to un-verified, blocked and redirect to logout // Why? Are we verifying people or email addresses? } goaway(z_root() . '/settings'); return; // NOTREACHED }