diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/PermissionDescription.php | 170 | ||||
-rw-r--r-- | include/acl_selectors.php | 4 | ||||
-rw-r--r-- | include/auth.php | 76 | ||||
-rw-r--r-- | include/channel.php | 25 | ||||
-rw-r--r-- | include/config.php | 4 | ||||
-rwxr-xr-x | include/items.php | 23 | ||||
-rwxr-xr-x | include/plugin.php | 1 | ||||
-rw-r--r-- | include/security.php | 44 | ||||
-rw-r--r-- | include/text.php | 6 | ||||
-rw-r--r-- | include/widgets.php | 11 | ||||
-rw-r--r-- | include/zot.php | 7 |
11 files changed, 148 insertions, 223 deletions
diff --git a/include/PermissionDescription.php b/include/PermissionDescription.php deleted file mode 100644 index 1f7799406..000000000 --- a/include/PermissionDescription.php +++ /dev/null @@ -1,170 +0,0 @@ -<?php - -if(class_exists('PermissionDescription')) return; - -require_once("include/permissions.php"); -require_once("include/language.php"); -require_once("include/text.php"); - - -/** - * Encapsulates information the ACL dialog requires to describe - * permission settings for an item with an empty ACL. - * i.e the caption, icon, and tooltip for the no-ACL option in the ACL dialog. - */ -class PermissionDescription { - - private $global_perm; - private $channel_perm; - private $fallback_description; - - /** - * Constructor is private. - * Use static methods fromGlobalPermission(), fromStandalonePermission(), or fromDescription() - * to create instances. - */ - private function __construct($global_perm, $channel_perm, $description = '') { - - $this->global_perm = $global_perm; - $this->channel_perm = $channel_perm; - - $this->fallback_description = ($description == '') ? t('Visible to your default audience') : $description; - } - - /** - * If the interpretation of an empty ACL can't be summarised with a global default permission - * or a specific permission setting then use this method and describe what it means instead. - * Remember to localize the description first. - * - * @param string $description - the localized caption for the no-ACL option in the ACL dialog. - * @return a new instance of PermissionDescription - */ - public static function fromDescription($description) { - return new PermissionDescription('', 0x80000, $description); - } - - - /** - * Use this method only if the interpretation of an empty ACL doesn't fall back to a global - * default permission. You should pass one of the constants from boot.php - PERMS_PUBLIC, - * PERMS_NETWORK etc. - * - * @param integer $perm - a single enumerated constant permission - PERMS_PUBLIC, PERMS_NETWORK etc. - * @return a new instance of PermissionDescription - */ - public static function fromStandalonePermission($perm) { - - $result = new PermissionDescription('', $perm); - - $checkPerm = $this->get_permission_description(); - if ($checkPerm == $this->fallback_description) { - $result = null; - logger('null PermissionDescription from unknown standalone permission: ' . $perm ,LOGGER_DEBUG, LOG_ERROR); - } - - return $result; - } - - /** - * This is the preferred way to create a PermissionDescription, as it provides the most details. - * Use this method if you know an empty ACL will result in one of the global default permissions - * being used, such as channel_r_stream (for which you would pass 'view_stream'). - * - * @param string $permname - a key for the global perms array from get_perms() in permissions.php, - * e.g. 'view_stream', 'view_profile', etc. - * @return a new instance of PermissionDescription - */ - public static function fromGlobalPermission($permname) { - - $result = null; - - $global_perms = get_perms(); - - if (array_key_exists($permname, $global_perms)) { - - $permDetails = $global_perms[$permname]; - - // It should be OK to always just read the permissions from App::$channel - // - // App::$profile is a union of channel and profile fields. - // The distinction is basically that App::$profile is pointing to the resource - // being observed. App::$channel is referring to the current logged-in channel - // member (if this is a local channel) e.g. the observer. We only show the ACL - // widget to the page owner (observer and observed are the same) so in that case - // I believe either may be safely used here. - $channelPerm = \App::$channel[$permDetails[0]]; - $result = new PermissionDescription($permDetails[1], $channelPerm); - } else { - // The acl dialog can handle null arguments, but it shouldn't happen - logger('null PermissionDescription from unknown global permission: ' . $permname ,LOGGER_DEBUG, LOG_ERROR); - } - return $result; - } - - - /** - * Gets a localized description of the permission, or a generic message if the permission - * is unknown. - * - * @return string description - */ - public function get_permission_description() { - - switch($this->channel_perm) { - - case 0: return t('Only me'); - case PERMS_PUBLIC: return t('Public'); - case PERMS_NETWORK: return t('Anybody in the $Projectname network'); - case PERMS_SITE: return sprintf(t('Any account on %s'), \App::get_hostname()); - case PERMS_CONTACTS: return t('Any of my connections'); - case PERMS_SPECIFIC: return t('Only connections I specifically allow'); - case PERMS_AUTHED: return t('Anybody authenticated (could include visitors from other networks)'); - case PERMS_PENDING: return t('Any connections including those who haven\'t yet been approved'); - default: return $this->fallback_description; - } - } - - /** - * Returns an icon css class name if an appropriate one is available, e.g. "fa-globe" for Public, - * otherwise returns empty string. - * - * @return string icon css class name (often FontAwesome) - */ - public function get_permission_icon() { - - switch($this->channel_perm) { - - case 0:/* only me */ return 'fa-eye-slash'; - case PERMS_PUBLIC: return 'fa-globe'; - case PERMS_NETWORK: return 'fa-share-alt-square'; // fa-share-alt-square is very similiar to the hubzilla logo, but we should create our own logo class to use - case PERMS_SITE: return 'fa-sitemap'; - case PERMS_CONTACTS: return 'fa-group'; - case PERMS_SPECIFIC: return 'fa-list'; - case PERMS_AUTHED: return ''; - case PERMS_PENDING: return ''; - default: return ''; - } - } - - - /** - * Returns a localized description of where the permission came from, if this is known. - * If it's not know, or if the permission is standalone and didn't come from a default - * permission setting, then empty string is returned. - * - * @return string description or empty string - */ - public function get_permission_origin_description() { - - switch($this->global_perm) { - - case PERMS_R_STREAM: return t('This is your default setting for the audience of your normal stream, and posts.'); - case PERMS_R_PROFILE: return t('This is your default setting for who can view your default channel profile'); - case PERMS_R_ABOOK: return t('This is your default setting for who can view your connections'); - case PERMS_R_STORAGE: return t('This is your default setting for who can view your file storage and photos'); - case PERMS_R_PAGES: return t('This is your default setting for the audience of your webpages'); - default: return ''; - } - } - -} diff --git a/include/acl_selectors.php b/include/acl_selectors.php index 89d054e3b..148c67a6c 100644 --- a/include/acl_selectors.php +++ b/include/acl_selectors.php @@ -7,8 +7,6 @@ * @package acl_selectors */ -require_once("include/PermissionDescription.php"); - function group_select($selname,$selclass,$preselected = false,$size = 4) { $o = ''; @@ -231,7 +229,7 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti if(! $emptyACL_description) { $showall_caption = t('Visible to your default audience'); - } else if (is_a($emptyACL_description, 'PermissionDescription')) { + } else if (is_a($emptyACL_description, '\\Zotlabs\\Lib\\PermissionDescription')) { $showall_caption = $emptyACL_description->get_permission_description(); $showall_origin = (($role === 'custom') ? $emptyACL_description->get_permission_origin_description() : ''); $showall_icon = $emptyACL_description->get_permission_icon(); diff --git a/include/auth.php b/include/auth.php index 01fcf0094..79d04c728 100644 --- a/include/auth.php +++ b/include/auth.php @@ -36,22 +36,33 @@ function account_verify_password($email, $pass) { // you have to verify the email and then go through the account approval workflow before // letting them login. - if(($email_verify) && ($register_policy == REGISTER_OPEN) && ($record['account_flags'] & ACCOUNT_UNVERIFIED)) - return null; + // @bug there is no record here + //if(($email_verify) && ($register_policy == REGISTER_OPEN) && ($record['account_flags'] & ACCOUNT_UNVERIFIED)) + // return null; $r = q("select * from account where account_email = '%s'", dbesc($email) ); - if(! ($r && count($r))) - return null; - - foreach($r as $record) { - if(($record['account_flags'] == ACCOUNT_OK) - && (hash('whirlpool', $record['account_salt'] . $pass) === $record['account_password'])) { - logger('password verified for ' . $email); - return $record; + if($r) { + + foreach($r as $record) { + if(($record['account_flags'] == ACCOUNT_OK) + && (hash('whirlpool', $record['account_salt'] . $pass) === $record['account_password'])) { + logger('password verified for ' . $email); + return $record; + } } } + + $x = q("select * from atoken where atoken_name = '%s' and atoken_token = '%s' limit 1", + dbesc($email), + dbesc($pass) + ); + if($x) { + atoken_login($x[0]); + return $x[0]; + } + $error = 'password failed for ' . $email; logger($error); @@ -123,10 +134,18 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) && authenticate_success($x[0], true, true); } } - - $r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where xchan_hash = '%s' limit 1", - dbesc($_SESSION['visitor_id']) - ); + if(array_key_exists('atoken',$_SESSION)) { + $y = q("select * from atoken where atoken_id = %d limit 1", + intval($_SESSION['atoken']) + ); + if($y) + $r = array(atoken_xchan($y[0])); + } + else { + $r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where xchan_hash = '%s' limit 1", + dbesc($_SESSION['visitor_id']) + ); + } if($r) { App::set_observer($r[0]); } @@ -199,20 +218,27 @@ else { call_hooks('authenticate', $addon_auth); + $atoken = false; + if(($addon_auth['authenticated']) && (count($addon_auth['user_record']))) { $record = $addon_auth['user_record']; } else { - $record = App::$account = account_verify_password($_POST['username'], $_POST['password']); - - if(App::$account) { - $_SESSION['account_id'] = App::$account['account_id']; - } - else { - notice( t('Failed authentication') . EOL); + $x = account_verify_password($_POST['username'], $_POST['password']); + if(array_key_exists('atoken',$x)) + $atoken = true; + if(! $atoken) { + $record = App::$account = $x; + + if(App::$account) { + $_SESSION['account_id'] = App::$account['account_id']; + } + else { + notice( t('Failed authentication') . EOL); + } + + logger('authenticate: ' . print_r(App::$account, true), LOGGER_ALL); } - - logger('authenticate: ' . print_r(App::$account, true), LOGGER_ALL); } if((! $record) || (! count($record))) { @@ -252,7 +278,8 @@ else { // if we haven't failed up this point, log them in. $_SESSION['last_login_date'] = datetime_convert(); - authenticate_success($record, true, true); + if(! $atoken) + authenticate_success($record, true, true); } } @@ -270,6 +297,7 @@ else { * @return int|bool * Return channel_id from pconfig or false. */ + function match_openid($authid) { // Query the uid/channel_id from pconfig for a given value. $r = q("SELECT uid FROM pconfig WHERE cat = 'system' AND k = 'openid' AND v = '%s' LIMIT 1", diff --git a/include/channel.php b/include/channel.php index 95506ed78..1a6508803 100644 --- a/include/channel.php +++ b/include/channel.php @@ -1310,13 +1310,12 @@ function get_my_address() { * If somebody arrives at our site using a zid, add their xchan to our DB if we don't have it already. * And if they aren't already authenticated here, attempt reverse magic auth. * - * @param App &$a * * @hooks 'zid_init' * string 'zid' - their zid * string 'url' - the destination url */ -function zid_init(&$a) { +function zid_init() { $tmp_str = get_my_address(); if(validate_email($tmp_str)) { Zotlabs\Daemon\Master::Summon(array('Gprobe',bin2hex($tmp_str))); @@ -1343,6 +1342,28 @@ function zid_init(&$a) { } /** + * @brief + * + * If somebody arrives at our site using a zat, authenticate them + * + */ + +function zat_init() { + if(local_channel() || remote_channel()) + return; + + $r = q("select * from atoken where atoken_token = '%s' limit 1", + dbesc($_REQUEST['zat']) + ); + if($r) { + atoken_login($r[0]); + } + +} + + + +/** * @brief Adds a zid parameter to a url. * * @param string $s diff --git a/include/config.php b/include/config.php index ece22793f..08810e298 100644 --- a/include/config.php +++ b/include/config.php @@ -98,8 +98,8 @@ function del_aconfig($account_id, $family, $key) { } -function load_abconfig($chan,$xhash) { - Zlib\AbConfig::Load($chan,$xhash); +function load_abconfig($chan, $xhash, $family = '') { + return Zlib\AbConfig::Load($chan,$xhash,$family); } function get_abconfig($chan,$xhash,$family,$key) { diff --git a/include/items.php b/include/items.php index 72f0896ad..373090d41 100755 --- a/include/items.php +++ b/include/items.php @@ -4154,32 +4154,19 @@ function update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remo } if($page_type) { - // store page info as an alternate message_id so we can access it via // https://sitename/page/$channelname/$pagetitle // if no pagetitle was given or it couldn't be transliterated into a url, use the first // sixteen bytes of the mid - which makes the link portable and not quite as daunting // as the entire mid. If it were the post_id the link would be less portable. - $r = q("select * from item_id where iid = %d and uid = %d and service = '%s' limit 1", + \Zotlabs\Lib\IConfig::Set( intval($post_id), - intval($channel['channel_id']), - dbesc($page_type) + 'system', + $page_type, + ($pagetitle) ? $pagetitle : substr($mid,0,16), + false ); - if($r) { - q("update item_id set sid = '%s' where id = %d", - dbesc(($pagetitle) ? $pagetitle : substr($mid,0,16)), - intval($r[0]['id']) - ); - } - else { - q("insert into item_id ( iid, uid, sid, service ) values ( %d, %d, '%s','%s' )", - intval($post_id), - intval($channel['channel_id']), - dbesc(($pagetitle) ? $pagetitle : substr($mid,0,16)), - dbesc($page_type) - ); - } } } diff --git a/include/plugin.php b/include/plugin.php index 6dfda1cc9..cb206d944 100755 --- a/include/plugin.php +++ b/include/plugin.php @@ -626,6 +626,7 @@ function head_get_js() { $str = ''; if(App::$js_sources) { + ksort(App::$js_sources,SORT_NUMERIC); foreach(App::$js_sources as $sources) { if(count($sources)) { foreach($sources as $source) { diff --git a/include/security.php b/include/security.php index 38045c8a9..e345636e7 100644 --- a/include/security.php +++ b/include/security.php @@ -82,6 +82,44 @@ function authenticate_success($user_record, $login_initial = false, $interactive /* else just return */ } +function atoken_login($atoken) { + if(! $atoken) + return false; + + $xchan = atoken_xchan($atoken); + + $_SESSION['authenticated'] = 1; + $_SESSION['visitor_id'] = $xchan['xchan_hash']; + $_SESSION['atoken'] = $atoken['atoken_id']; + + \App::set_observer($xchan); + + return [ 'atoken' => true ]; +} + + +function atoken_xchan($atoken) { + + $c = channelx_by_n($atoken['atoken_uid']); + if($c) { + return [ + 'xchan_hash' => substr($c['channel_hash'],0,16) . '.' . $atoken['atoken_name'], + 'xchan_name' => $atoken['atoken_name'], + 'xchan_addr' => t('guest:') . $atoken['atoken_name'] . '@' . \App::get_hostname(), + 'xchan_network' => 'unknown', + 'xchan_hidden' => 1, + 'xchan_photo_mimetype' => 'image/jpeg', + 'xchan_photo_l' => get_default_profile_photo(300), + 'xchan_photo_m' => get_default_profile_photo(80), + 'xchan_photo_s' => get_default_profile_photo(48) + + ]; + } + +} + + + /** * @brief Change to another channel with current logged-in account. * @@ -125,13 +163,17 @@ function change_channel($change_channel) { ); if($x) { $_SESSION['my_url'] = $x[0]['xchan_url']; - $_SESSION['my_address'] = $r[0]['channel_address'] . '@' . substr(z_root(), strpos(z_root(), '://') + 3); + $_SESSION['my_address'] = $r[0]['channel_address'] . '@' . App::get_hostname(); App::set_observer($x[0]); App::set_perms(get_all_perms(local_channel(), $hash)); } if(! is_dir('store/' . $r[0]['channel_address'])) @os_mkdir('store/' . $r[0]['channel_address'], STORAGE_DEFAULT_PERMISSIONS,true); + + $arr = [ 'channel_id' => $change_channel, 'chanx' => $ret ]; + call_hooks('change_channel', $arr); + } return $ret; diff --git a/include/text.php b/include/text.php index 986e3b56c..d4d151f2e 100644 --- a/include/text.php +++ b/include/text.php @@ -687,7 +687,7 @@ function get_tags($s) { // ignore anything in a code block - $s = preg_replace('/\[code\](.*?)\[\/code\]/sm','',$s); + $s = preg_replace('/\[code(.*?)\](.*?)\[\/code\]/sm','',$s); // ignore anything in [style= ] $s = preg_replace('/\[style=(.*?)\]/sm','',$s); @@ -774,6 +774,10 @@ function strip_zids($s) { return preg_replace('/[\?&]zid=(.*?)(&|$)/ism','$2',$s); } +function strip_zats($s) { + return preg_replace('/[\?&]zat=(.*?)(&|$)/ism','$2',$s); +} + // quick and dirty quoted_printable encoding diff --git a/include/widgets.php b/include/widgets.php index a4a6fb55a..da73657f5 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -296,7 +296,7 @@ function widget_filer($arr) { $selected = ((x($_REQUEST,'file')) ? $_REQUEST['file'] : ''); $terms = array(); - $r = q("select distinct(term) from term where uid = %d and ttype = %d order by term asc", + $r = q("select distinct term from term where uid = %d and ttype = %d order by term asc", intval(local_channel()), intval(TERM_FILE) ); @@ -609,6 +609,15 @@ function widget_settings_menu($arr) { 'selected' => ((argv(1) === 'oauth') ? 'active' : ''), ); + if(! UNO) { + $tabs[] = array( + 'label' => t('Guest Access Tokens'), + 'url' => z_root() . '/settings/tokens', + 'selected' => ((argv(1) === 'tokens') ? 'active' : ''), + ); + } + + if($role === false || $role === 'custom') { $tabs[] = array( 'label' => t('Connection Default Permissions'), diff --git a/include/zot.php b/include/zot.php index 6dd789181..45347ef22 100644 --- a/include/zot.php +++ b/include/zot.php @@ -3014,7 +3014,12 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) { if($x['hubloc_host'] == App::get_hostname()) continue; - $synchubs[] = $x; + $y = q("select site_dead from site where site_url = '%s' limit 1", + dbesc($x['hubloc_url']) + ); + + if((! $y) || ($y[0]['site_dead'] == 0)) + $synchubs[] = $x; } if(! $synchubs) |