From 1db3409f36f408bfc49816e1fab3df4b53b8f19e Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 19 Feb 2016 16:19:15 -0800 Subject: add router class --- Zotlabs/Web/Router.php | 200 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 Zotlabs/Web/Router.php (limited to 'Zotlabs/Web') diff --git a/Zotlabs/Web/Router.php b/Zotlabs/Web/Router.php new file mode 100644 index 000000000..4ae96b5da --- /dev/null +++ b/Zotlabs/Web/Router.php @@ -0,0 +1,200 @@ +argc and $a->argv + * + * $a->argv[0] is our module name. We will load the file mod/{$a->argv[0]}.php + * and use it for handling our URL request. + * The module file contains a few functions that we call in various circumstances + * and in the following order: + * + * "module"_init + * "module"_post (only called if there are $_POST variables) + * "module"_content - the string return of this function contains our page body + * + * Modules which emit other serialisations besides HTML (XML,JSON, etc.) should do + * so within the module init and/or post functions and then invoke killme() to terminate + * further processing. + */ + + if(strlen($a->module)) { + + /** + * + * We will always have a module name. + * First see if we have a plugin which is masquerading as a module. + * + */ + + if(is_array($a->plugins) && in_array($a->module,$a->plugins) && file_exists("addon/{$a->module}/{$a->module}.php")) { + include_once("addon/{$a->module}/{$a->module}.php"); + if(function_exists($a->module . '_module')) + $a->module_loaded = true; + } + + if((strpos($a->module,'admin') === 0) && (! is_site_admin())) { + $a->module_loaded = false; + notice( t('Permission denied.') . EOL); + goaway(z_root()); + } + + /** + * If the site has a custom module to over-ride the standard module, use it. + * Otherwise, look for the standard program module in the 'mod' directory + */ + + if(! $a->module_loaded) { + if(file_exists("mod/site/{$a->module}.php")) { + include_once("mod/site/{$a->module}.php"); + $a->module_loaded = true; + } + elseif(file_exists("mod/{$a->module}.php")) { + include_once("mod/{$a->module}.php"); + $a->module_loaded = true; + } + } + + /** + * This provides a place for plugins to register module handlers which don't otherwise exist on the system. + * If the plugin sets 'installed' to true we won't throw a 404 error for the specified module even if + * there is no specific module file or matching plugin name. + * The plugin should catch at least one of the module hooks for this URL. + */ + + $x = array('module' => $a->module, 'installed' => false); + call_hooks('module_loaded', $x); + if($x['installed']) + $a->module_loaded = true; + + /** + * The URL provided does not resolve to a valid module. + * + * On Dreamhost sites, quite often things go wrong for no apparent reason and they send us to '/internal_error.html'. + * We don't like doing this, but as it occasionally accounts for 10-20% or more of all site traffic - + * we are going to trap this and redirect back to the requested page. As long as you don't have a critical error on your page + * this will often succeed and eventually do the right thing. + * + * Otherwise we are going to emit a 404 not found. + */ + + if(! $a->module_loaded) { + + // Stupid browser tried to pre-fetch our Javascript img template. Don't log the event or return anything - just quietly exit. + if((x($_SERVER, 'QUERY_STRING')) && preg_match('/{[0-9]}/', $_SERVER['QUERY_STRING']) !== 0) { + killme(); + } + + if((x($_SERVER, 'QUERY_STRING')) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && $a->config['system']['dreamhost_error_hack']) { + logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI']); + goaway($a->get_baseurl() . $_SERVER['REQUEST_URI']); + } + + logger('index.php: page not found: ' . $_SERVER['REQUEST_URI'] . ' ADDRESS: ' . $_SERVER['REMOTE_ADDR'] . ' QUERY: ' . $_SERVER['QUERY_STRING'], LOGGER_DEBUG); + header($_SERVER['SERVER_PROTOCOL'] . ' 404 ' . t('Not Found')); + $tpl = get_markup_template('404.tpl'); + $a->page['content'] = replace_macros($tpl, array( + '$message' => t('Page not found.') + )); + + // pretend this is a module so it will initialise the theme + $a->module = '404'; + $a->module_loaded = true; + } + } + } + + + function Dispatch(&$a) { + + /** + * Call module functions + */ + + if($a->module_loaded) { + $a->page['page_title'] = $a->module; + $placeholder = ''; + + /** + * No theme has been specified when calling the module_init functions + * For this reason, please restrict the use of templates to those which + * do not provide any presentation details - as themes will not be able + * to over-ride them. + */ + + if(function_exists($a->module . '_init')) { + $arr = array('init' => true, 'replace' => false); + call_hooks($a->module . '_mod_init', $arr); + if(! $arr['replace']) { + $func = $a->module . '_init'; + $func($a); + } + } + + /** + * Do all theme initialiasion here before calling any additional module functions. + * The module_init function may have changed the theme. + * Additionally any page with a Comanche template may alter the theme. + * So we'll check for those now. + */ + + + /** + * In case a page has overloaded a module, see if we already have a layout defined + * otherwise, if a PDL file exists for this module, use it + * The member may have also created a customised PDL that's stored in the config + */ + + load_pdl($a); + + /** + * load current theme info + */ + + $theme_info_file = 'view/theme/' . current_theme() . '/php/theme.php'; + if (file_exists($theme_info_file)){ + require_once($theme_info_file); + } + + if(function_exists(str_replace('-', '_', current_theme()) . '_init')) { + $func = str_replace('-', '_', current_theme()) . '_init'; + $func($a); + } + elseif (x($a->theme_info, 'extends') && file_exists('view/theme/' . $a->theme_info['extends'] . '/php/theme.php')) { + require_once('view/theme/' . $a->theme_info['extends'] . '/php/theme.php'); + if(function_exists(str_replace('-', '_', $a->theme_info['extends']) . '_init')) { + $func = str_replace('-', '_', $a->theme_info['extends']) . '_init'; + $func($a); + } + } + + if(($_SERVER['REQUEST_METHOD'] === 'POST') && (! $a->error) + && (function_exists($a->module . '_post')) + && (! x($_POST, 'auth-params'))) { + call_hooks($a->module . '_mod_post', $_POST); + $func = $a->module . '_post'; + $func($a); + } + + if((! $a->error) && (function_exists($a->module . '_content'))) { + $arr = array('content' => $a->page['content'], 'replace' => false); + call_hooks($a->module . '_mod_content', $arr); + $a->page['content'] = $arr['content']; + if(! $arr['replace']) { + $func = $a->module . '_content'; + $arr = array('content' => $func($a)); + } + call_hooks($a->module . '_mod_aftercontent', $arr); + $a->page['content'] .= $arr['content']; + } + } + } + +} \ No newline at end of file -- cgit v1.2.3 From b101a8f6fb3fd3ec0d5466ba1bb7bc9dc9480fba Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 24 Feb 2016 11:20:46 -0800 Subject: missing function --- Zotlabs/Web/Router.php | 1 - 1 file changed, 1 deletion(-) (limited to 'Zotlabs/Web') diff --git a/Zotlabs/Web/Router.php b/Zotlabs/Web/Router.php index 4ae96b5da..af171437d 100644 --- a/Zotlabs/Web/Router.php +++ b/Zotlabs/Web/Router.php @@ -196,5 +196,4 @@ class Router { } } } - } \ No newline at end of file -- cgit v1.2.3 From d5db25808a0847e09ee3735faeac3552c722e0ae Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 7 Mar 2016 15:03:53 -0800 Subject: Facebook scraper "OpenGraph" support; modules will need to set the required fields (type, image, url) as well as any desired optional or type specific fields. We will set the title during pagebuild. --- Zotlabs/Web/OpenGraph.php | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Zotlabs/Web/OpenGraph.php (limited to 'Zotlabs/Web') diff --git a/Zotlabs/Web/OpenGraph.php b/Zotlabs/Web/OpenGraph.php new file mode 100644 index 000000000..b14b2b989 --- /dev/null +++ b/Zotlabs/Web/OpenGraph.php @@ -0,0 +1,43 @@ +vars = array(); + + } + + function set($property,$value) { + $this->vars[$property] = $value; + } + + function check_required() { + if( + ($this->vars) + && array_key_exists('og:title',$this->vars) + && array_key_exists('og:type', $this->vars) + && array_key_exists('og:image',$this->vars) + && array_key_exists('og:url', $this->vars) + ) + return true; + return false; + } + + function get() { + if($this->check_required()) { + $o = "\r\n"; + foreach($this->vars as $k => $v) { + $o .= '' . "\r\n" ; + } + return $o; + } + return ''; + } + +} \ No newline at end of file -- cgit v1.2.3 From 76467b5a35111c44ff539146ab0810118b42dc70 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 7 Mar 2016 15:11:11 -0800 Subject: allow modules/addons to override the og:title field --- Zotlabs/Web/OpenGraph.php | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'Zotlabs/Web') diff --git a/Zotlabs/Web/OpenGraph.php b/Zotlabs/Web/OpenGraph.php index b14b2b989..f282c82d4 100644 --- a/Zotlabs/Web/OpenGraph.php +++ b/Zotlabs/Web/OpenGraph.php @@ -29,6 +29,13 @@ class OpenGraph { return false; } + function get_field($field) { + if($this->vars && array_key_exists($field,$this->vars) && $this->vars[$field]) + return $this->vars[$field]; + return false; + } + + function get() { if($this->check_required()) { $o = "\r\n"; -- cgit v1.2.3 From 1258f9bb2114bd4a909f623a7519ba446bf8da0d Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 8 Mar 2016 16:06:58 -0800 Subject: turn 'OpenGraph' into a more general purpose HTTP meta facility for setting any meta header --- Zotlabs/Web/HttpMeta.php | 66 +++++++++++++++++++++++++++++++++++++++++++++++ Zotlabs/Web/OpenGraph.php | 50 ----------------------------------- 2 files changed, 66 insertions(+), 50 deletions(-) create mode 100644 Zotlabs/Web/HttpMeta.php delete mode 100644 Zotlabs/Web/OpenGraph.php (limited to 'Zotlabs/Web') diff --git a/Zotlabs/Web/HttpMeta.php b/Zotlabs/Web/HttpMeta.php new file mode 100644 index 000000000..469a9ed8b --- /dev/null +++ b/Zotlabs/Web/HttpMeta.php @@ -0,0 +1,66 @@ +vars = array(); + $this->og = array(); + + } + + function set($property,$value) { + if(strpos($property,'og:') === 0) + $this->og[$property] = $value; + else + $this->vars[$property] = $value; + } + + function check_required() { + if( + ($this->og) + && array_key_exists('og:title',$this->og) + && array_key_exists('og:type', $this->og) + && array_key_exists('og:image',$this->og) + && array_key_exists('og:url', $this->og) + ) + return true; + return false; + } + + function get_field($field) { + if(strpos($field,'og:') === 0) + $arr = $this->og; + else + $arr = $this->vars; + + if($arr && array_key_exists($field,$arr) && $arr[$field]) + return $arr[$field]; + return false; + } + + + function get() { + $o = ''; + if($this->vars) { + foreach($this->vars as $k => $v) { + $o .= '' . "\r\n" ; + } + } + if($this->check_required()) { + foreach($this->og as $k => $v) { + $o .= '' . "\r\n" ; + } + } + if($o) + return "\r\n" . $o; + return $o; + } + +} \ No newline at end of file diff --git a/Zotlabs/Web/OpenGraph.php b/Zotlabs/Web/OpenGraph.php deleted file mode 100644 index f282c82d4..000000000 --- a/Zotlabs/Web/OpenGraph.php +++ /dev/null @@ -1,50 +0,0 @@ -vars = array(); - - } - - function set($property,$value) { - $this->vars[$property] = $value; - } - - function check_required() { - if( - ($this->vars) - && array_key_exists('og:title',$this->vars) - && array_key_exists('og:type', $this->vars) - && array_key_exists('og:image',$this->vars) - && array_key_exists('og:url', $this->vars) - ) - return true; - return false; - } - - function get_field($field) { - if($this->vars && array_key_exists($field,$this->vars) && $this->vars[$field]) - return $this->vars[$field]; - return false; - } - - - function get() { - if($this->check_required()) { - $o = "\r\n"; - foreach($this->vars as $k => $v) { - $o .= '' . "\r\n" ; - } - return $o; - } - return ''; - } - -} \ No newline at end of file -- cgit v1.2.3 From 1cd3b4182595b838a535dd6b6990251db05d49e6 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 30 Mar 2016 22:13:24 -0700 Subject: deprecate $a->get_baseurl() --- Zotlabs/Web/Router.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Web') diff --git a/Zotlabs/Web/Router.php b/Zotlabs/Web/Router.php index af171437d..900ac1e26 100644 --- a/Zotlabs/Web/Router.php +++ b/Zotlabs/Web/Router.php @@ -94,7 +94,7 @@ class Router { if((x($_SERVER, 'QUERY_STRING')) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && $a->config['system']['dreamhost_error_hack']) { logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI']); - goaway($a->get_baseurl() . $_SERVER['REQUEST_URI']); + goaway(z_root() . $_SERVER['REQUEST_URI']); } logger('index.php: page not found: ' . $_SERVER['REQUEST_URI'] . ' ADDRESS: ' . $_SERVER['REMOTE_ADDR'] . ' QUERY: ' . $_SERVER['QUERY_STRING'], LOGGER_DEBUG); -- cgit v1.2.3 From 9abd95fad3784a10fc48bc40f9b8a75d7d74edda Mon Sep 17 00:00:00 2001 From: redmatrix Date: Thu, 31 Mar 2016 16:06:03 -0700 Subject: static App --- Zotlabs/Web/Router.php | 90 ++++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 43 deletions(-) (limited to 'Zotlabs/Web') diff --git a/Zotlabs/Web/Router.php b/Zotlabs/Web/Router.php index 900ac1e26..e2e920f39 100644 --- a/Zotlabs/Web/Router.php +++ b/Zotlabs/Web/Router.php @@ -9,9 +9,9 @@ class Router { /** * - * We have already parsed the server path into $a->argc and $a->argv + * We have already parsed the server path into App::$argc and App::$argv * - * $a->argv[0] is our module name. We will load the file mod/{$a->argv[0]}.php + * App::$argv[0] is our module name. We will load the file mod/{App::$argv[0]}.php * and use it for handling our URL request. * The module file contains a few functions that we call in various circumstances * and in the following order: @@ -25,7 +25,9 @@ class Router { * further processing. */ - if(strlen($a->module)) { + $module = \App::$module; + + if(strlen($module)) { /** * @@ -34,14 +36,14 @@ class Router { * */ - if(is_array($a->plugins) && in_array($a->module,$a->plugins) && file_exists("addon/{$a->module}/{$a->module}.php")) { - include_once("addon/{$a->module}/{$a->module}.php"); - if(function_exists($a->module . '_module')) - $a->module_loaded = true; + if(is_array(\App::$plugins) && in_array(\App::$module,\App::$plugins) && file_exists("addon/{$module}/{\$module}.php")) { + include_once("addon/{$module}/{$module}.php"); + if(function_exists($module . '_module')) + \App::$module_loaded = true; } - if((strpos($a->module,'admin') === 0) && (! is_site_admin())) { - $a->module_loaded = false; + if((strpos($module,'admin') === 0) && (! is_site_admin())) { + \App::$module_loaded = false; notice( t('Permission denied.') . EOL); goaway(z_root()); } @@ -51,17 +53,19 @@ class Router { * Otherwise, look for the standard program module in the 'mod' directory */ - if(! $a->module_loaded) { - if(file_exists("mod/site/{$a->module}.php")) { - include_once("mod/site/{$a->module}.php"); - $a->module_loaded = true; + if(! (\App::$module_loaded)) { + if(file_exists("mod/site/{$module}.php")) { + include_once("mod/site/{$module}.php"); + \App::$module_loaded = true; } - elseif(file_exists("mod/{$a->module}.php")) { - include_once("mod/{$a->module}.php"); - $a->module_loaded = true; + elseif(file_exists("mod/{$module}.php")) { + include_once("mod/{$module}.php"); + \App::$module_loaded = true; } + else logger("mod/{$module}.php not found."); } + /** * This provides a place for plugins to register module handlers which don't otherwise exist on the system. * If the plugin sets 'installed' to true we won't throw a 404 error for the specified module even if @@ -69,10 +73,10 @@ class Router { * The plugin should catch at least one of the module hooks for this URL. */ - $x = array('module' => $a->module, 'installed' => false); + $x = array('module' => $module, 'installed' => false); call_hooks('module_loaded', $x); if($x['installed']) - $a->module_loaded = true; + \App::$module_loaded = true; /** * The URL provided does not resolve to a valid module. @@ -85,14 +89,14 @@ class Router { * Otherwise we are going to emit a 404 not found. */ - if(! $a->module_loaded) { + if(! (\App::$module_loaded)) { // Stupid browser tried to pre-fetch our Javascript img template. Don't log the event or return anything - just quietly exit. if((x($_SERVER, 'QUERY_STRING')) && preg_match('/{[0-9]}/', $_SERVER['QUERY_STRING']) !== 0) { killme(); } - if((x($_SERVER, 'QUERY_STRING')) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && $a->config['system']['dreamhost_error_hack']) { + if((x($_SERVER, 'QUERY_STRING')) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && \App::$config['system']['dreamhost_error_hack']) { logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI']); goaway(z_root() . $_SERVER['REQUEST_URI']); } @@ -100,13 +104,13 @@ class Router { logger('index.php: page not found: ' . $_SERVER['REQUEST_URI'] . ' ADDRESS: ' . $_SERVER['REMOTE_ADDR'] . ' QUERY: ' . $_SERVER['QUERY_STRING'], LOGGER_DEBUG); header($_SERVER['SERVER_PROTOCOL'] . ' 404 ' . t('Not Found')); $tpl = get_markup_template('404.tpl'); - $a->page['content'] = replace_macros($tpl, array( + \App::$page['content'] = replace_macros($tpl, array( '$message' => t('Page not found.') )); // pretend this is a module so it will initialise the theme - $a->module = '404'; - $a->module_loaded = true; + \App::$module = '404'; + \App::$module_loaded = true; } } } @@ -118,8 +122,8 @@ class Router { * Call module functions */ - if($a->module_loaded) { - $a->page['page_title'] = $a->module; + if(\App::$module_loaded) { + \App::$page['page_title'] = \App::$module; $placeholder = ''; /** @@ -129,11 +133,11 @@ class Router { * to over-ride them. */ - if(function_exists($a->module . '_init')) { + if(function_exists(\App::$module . '_init')) { $arr = array('init' => true, 'replace' => false); - call_hooks($a->module . '_mod_init', $arr); + call_hooks(\App::$module . '_mod_init', $arr); if(! $arr['replace']) { - $func = $a->module . '_init'; + $func = \App::$module . '_init'; $func($a); } } @@ -167,32 +171,32 @@ class Router { $func = str_replace('-', '_', current_theme()) . '_init'; $func($a); } - elseif (x($a->theme_info, 'extends') && file_exists('view/theme/' . $a->theme_info['extends'] . '/php/theme.php')) { - require_once('view/theme/' . $a->theme_info['extends'] . '/php/theme.php'); - if(function_exists(str_replace('-', '_', $a->theme_info['extends']) . '_init')) { - $func = str_replace('-', '_', $a->theme_info['extends']) . '_init'; + elseif (x(\App::$theme_info, 'extends') && file_exists('view/theme/' . \App::$theme_info['extends'] . '/php/theme.php')) { + require_once('view/theme/' . \App::$theme_info['extends'] . '/php/theme.php'); + if(function_exists(str_replace('-', '_', \App::$theme_info['extends']) . '_init')) { + $func = str_replace('-', '_', \App::$theme_info['extends']) . '_init'; $func($a); } } - if(($_SERVER['REQUEST_METHOD'] === 'POST') && (! $a->error) - && (function_exists($a->module . '_post')) + if(($_SERVER['REQUEST_METHOD'] === 'POST') && (! \App::$error) + && (function_exists(\App::$module . '_post')) && (! x($_POST, 'auth-params'))) { - call_hooks($a->module . '_mod_post', $_POST); - $func = $a->module . '_post'; + call_hooks(\App::$module . '_mod_post', $_POST); + $func = \App::$module . '_post'; $func($a); } - if((! $a->error) && (function_exists($a->module . '_content'))) { - $arr = array('content' => $a->page['content'], 'replace' => false); - call_hooks($a->module . '_mod_content', $arr); - $a->page['content'] = $arr['content']; + if((! \App::$error) && (function_exists(\App::$module . '_content'))) { + $arr = array('content' => \App::$page['content'], 'replace' => false); + call_hooks(\App::$module . '_mod_content', $arr); + \App::$page['content'] = $arr['content']; if(! $arr['replace']) { - $func = $a->module . '_content'; + $func = \App::$module . '_content'; $arr = array('content' => $func($a)); } - call_hooks($a->module . '_mod_aftercontent', $arr); - $a->page['content'] .= $arr['content']; + call_hooks(\App::$module . '_mod_aftercontent', $arr); + \App::$page['content'] .= $arr['content']; } } } -- cgit v1.2.3 From d09694587d15ce093149cc2321a63b9923554345 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sat, 2 Apr 2016 13:52:16 -0700 Subject: typo in router --- Zotlabs/Web/Router.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zotlabs/Web') diff --git a/Zotlabs/Web/Router.php b/Zotlabs/Web/Router.php index e2e920f39..29f2b5206 100644 --- a/Zotlabs/Web/Router.php +++ b/Zotlabs/Web/Router.php @@ -36,7 +36,7 @@ class Router { * */ - if(is_array(\App::$plugins) && in_array(\App::$module,\App::$plugins) && file_exists("addon/{$module}/{\$module}.php")) { + if(is_array(\App::$plugins) && in_array($module,\App::$plugins) && file_exists("addon/{$module}/{$module}.php")) { include_once("addon/{$module}/{$module}.php"); if(function_exists($module . '_module')) \App::$module_loaded = true; -- cgit v1.2.3 From 9b66b5eee37c1a3958d9ddccb9c1a06ac7ef49ce Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 8 Apr 2016 04:44:10 -0700 Subject: objectify all the session management stuff --- Zotlabs/Web/Session.php | 91 ++++++++++++++++++++++++++++++++++++++++++ Zotlabs/Web/SessionHandler.php | 78 ++++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 Zotlabs/Web/Session.php create mode 100644 Zotlabs/Web/SessionHandler.php (limited to 'Zotlabs/Web') diff --git a/Zotlabs/Web/Session.php b/Zotlabs/Web/Session.php new file mode 100644 index 000000000..ff0070d15 --- /dev/null +++ b/Zotlabs/Web/Session.php @@ -0,0 +1,91 @@ + $v) { + unset($_SESSION[$k]); + } + } + } + + + + function new_cookie($time) { + + $old_sid = session_id(); + + session_regenerate_id(false); + + q("UPDATE session SET sid = '%s' WHERE sid = '%s'", + dbesc(session_id()), + dbesc($old_sid) + ); + + if (x($_COOKIE, 'jsAvailable')) { + if ($time) { + $expires = time() + $time; + } else { + $expires = 0; + } + setcookie('jsAvailable', $_COOKIE['jsAvailable'], $expires); + } + setcookie(session_name(),session_id(),$expires); + } + + +} \ No newline at end of file diff --git a/Zotlabs/Web/SessionHandler.php b/Zotlabs/Web/SessionHandler.php new file mode 100644 index 000000000..ede2bd609 --- /dev/null +++ b/Zotlabs/Web/SessionHandler.php @@ -0,0 +1,78 @@ +session_exists = 0; + $this->session_expire = 180000; + return true; + } + + function read ($id) { + + if(x($id)) + $r = q("SELECT `data` FROM `session` WHERE `sid`= '%s'", dbesc($id)); + + if($r) { + $this->session_exists = true; + return $r[0]['data']; + } + + return ''; + } + + + function write ($id, $data) { + + if(! $id || ! $data) { + return false; + } + + $expire = time() + $this->session_expire; + $default_expire = time() + 300; + + if($this->session_exists) { + q("UPDATE `session` + SET `data` = '%s', `expire` = '%s' WHERE `sid` = '%s'", + dbesc($data), + dbesc($expire), + dbesc($id) + ); + } + else { + q("INSERT INTO `session` (sid, expire, data) values ('%s', '%s', '%s')", + dbesc($id), + dbesc($default_expire), + dbesc($data) + ); + } + + return true; + } + + + function close() { + return true; + } + + + function destroy ($id) { + q("DELETE FROM `session` WHERE `sid` = '%s'", dbesc($id)); + return true; + } + + + function gc($expire) { + q("DELETE FROM session WHERE expire < %d", dbesc(time())); + return true; + } + + +} \ No newline at end of file -- cgit v1.2.3 From c0bdcfedeb8c5b8753587ac77d5b90d48698ec66 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Fri, 8 Apr 2016 05:10:36 -0700 Subject: log if the session handler fails and surface the ssl_cookie config setting --- Zotlabs/Web/Session.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Zotlabs/Web') diff --git a/Zotlabs/Web/Session.php b/Zotlabs/Web/Session.php index ff0070d15..494c02b1d 100644 --- a/Zotlabs/Web/Session.php +++ b/Zotlabs/Web/Session.php @@ -27,7 +27,9 @@ class Session { $handler = new \Zotlabs\Web\SessionHandler(); - session_set_save_handler($handler,true); + $x = session_set_save_handler($handler,true); + if(! $x) + logger('Session save handler initialisation failed.',LOGGER_NORMAL,LOG_ERR); // Force cookies to be secure (https only) if this site is SSL enabled. // Must be done before session_start(). -- cgit v1.2.3 From abfbe9c9375c7505e0422b8adc1d9d5426d7df1a Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 10 Apr 2016 16:56:08 -0700 Subject: a few issues: block public not blocking mod_cal, typo in sql for one clone file sync operation, fix_system_urls not catching cached contact photos, extend sessionhandler expiration when remember_me is enabled as the stored session is expiring long before the browser session. --- Zotlabs/Web/Session.php | 29 +++++++++++++++++------------ Zotlabs/Web/SessionHandler.php | 7 ++++++- 2 files changed, 23 insertions(+), 13 deletions(-) (limited to 'Zotlabs/Web') diff --git a/Zotlabs/Web/Session.php b/Zotlabs/Web/Session.php index 494c02b1d..d25ce5f6a 100644 --- a/Zotlabs/Web/Session.php +++ b/Zotlabs/Web/Session.php @@ -13,6 +13,8 @@ namespace Zotlabs\Web; class Session { + private static $handler = null; + function init() { $gc_probability = 50; @@ -26,6 +28,7 @@ class Session { */ $handler = new \Zotlabs\Web\SessionHandler(); + self::$handler = $handler; $x = session_set_save_handler($handler,true); if(! $x) @@ -67,26 +70,28 @@ class Session { - function new_cookie($time) { + function new_cookie($xtime) { + + $newxtime = (($xtime> 0) ? (time() + $xtime) : 0); $old_sid = session_id(); session_regenerate_id(false); - q("UPDATE session SET sid = '%s' WHERE sid = '%s'", - dbesc(session_id()), - dbesc($old_sid) - ); + if(self::$handler) { + $v = q("UPDATE session SET sid = '%s' WHERE sid = '%s'", + dbesc(session_id()), + dbesc($old_sid) + ); + } + else + logger('no session handler'); if (x($_COOKIE, 'jsAvailable')) { - if ($time) { - $expires = time() + $time; - } else { - $expires = 0; - } - setcookie('jsAvailable', $_COOKIE['jsAvailable'], $expires); + setcookie('jsAvailable', $_COOKIE['jsAvailable'], $newxtime); } - setcookie(session_name(),session_id(),$expires); + setcookie(session_name(),session_id(),$newxtime); + } diff --git a/Zotlabs/Web/SessionHandler.php b/Zotlabs/Web/SessionHandler.php index ede2bd609..670e8f216 100644 --- a/Zotlabs/Web/SessionHandler.php +++ b/Zotlabs/Web/SessionHandler.php @@ -35,7 +35,12 @@ class SessionHandler implements \SessionHandlerInterface { return false; } - $expire = time() + $this->session_expire; + // Can't just use $data here because we can't be certain of the serialisation algorithm + + if($_SESSION && array_key_exists('remember_me',$_SESSION) && intval($_SESSION['remember_me'])) + $expire = time() + (60 * 60 * 24 * 365); + else + $expire = time() + $this->session_expire; $default_expire = time() + 300; if($this->session_exists) { -- cgit v1.2.3 From d1a2aecfa05927b79350500b7c0f9d9b978afbeb Mon Sep 17 00:00:00 2001 From: redmatrix Date: Sun, 10 Apr 2016 19:20:41 -0700 Subject: move more session related stuff such as paranoia handling (IP address changes) into the session object and extend remember_me cookies once a day so that they will never expire (theoretically). The DB session driver will extend its expiration on every session write (in the case of persistent sessions). --- Zotlabs/Web/Session.php | 59 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Web') diff --git a/Zotlabs/Web/Session.php b/Zotlabs/Web/Session.php index d25ce5f6a..e5fe47386 100644 --- a/Zotlabs/Web/Session.php +++ b/Zotlabs/Web/Session.php @@ -68,8 +68,6 @@ class Session { } } - - function new_cookie($xtime) { $newxtime = (($xtime> 0) ? (time() + $xtime) : 0); @@ -94,5 +92,62 @@ class Session { } + function extend_cookie() { + + // if there's a long-term cookie, extend it + + if(intval($_SESSION['remember_me'])) + setcookie(session_name(),session_id(),(time() + (60 * 60 * 24 * 365))); + + } + + + function return_check() { + + // check a returning visitor against IP changes. + // If the change results in being blocked from re-entry with the current cookie + // nuke the session and logout. + // Returning at all indicates the session is still valid. + + // first check if we're enforcing that sessions can't change IP address + // @todo what to do with IPv6 addresses + + if($_SESSION['addr'] && $_SESSION['addr'] != $_SERVER['REMOTE_ADDR']) { + logger('SECURITY: Session IP address changed: ' . $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']); + + $partial1 = substr($_SESSION['addr'], 0, strrpos($_SESSION['addr'], '.')); + $partial2 = substr($_SERVER['REMOTE_ADDR'], 0, strrpos($_SERVER['REMOTE_ADDR'], '.')); + + $paranoia = intval(get_pconfig($_SESSION['uid'], 'system', 'paranoia')); + + if(! $paranoia) + $paranoia = intval(get_config('system', 'paranoia')); + + switch($paranoia) { + case 0: + // no IP checking + break; + case 2: + // check 2 octets + $partial1 = substr($partial1, 0, strrpos($partial1, '.')); + $partial2 = substr($partial2, 0, strrpos($partial2, '.')); + if($partial1 == $partial2) + break; + case 1: + // check 3 octets + if($partial1 == $partial2) + break; + case 3: + default: + // check any difference at all + logger('Session address changed. Paranoid setting in effect, blocking session. ' + . $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']); + self::nuke(); + goaway(z_root()); + break; + } + } + return true; + } } \ No newline at end of file -- cgit v1.2.3 From 482962648fa2f3219e979586abcfbc5c90fcb97f Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Mon, 11 Apr 2016 11:01:53 +0200 Subject: whitespace --- Zotlabs/Web/Session.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'Zotlabs/Web') diff --git a/Zotlabs/Web/Session.php b/Zotlabs/Web/Session.php index e5fe47386..68af74521 100644 --- a/Zotlabs/Web/Session.php +++ b/Zotlabs/Web/Session.php @@ -37,16 +37,16 @@ class Session { // Force cookies to be secure (https only) if this site is SSL enabled. // Must be done before session_start(). - if(intval(\App::$config['system']['ssl_cookie_protection'])) { - $arr = session_get_cookie_params(); - session_set_cookie_params( - ((isset($arr['lifetime'])) ? $arr['lifetime'] : 0), - ((isset($arr['path'])) ? $arr['path'] : '/'), - ((isset($arr['domain'])) ? $arr['domain'] : App::get_hostname()), - ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false), - ((isset($arr['httponly'])) ? $arr['httponly'] : true) + if(intval(\App::$config['system']['ssl_cookie_protection'])) { + $arr = session_get_cookie_params(); + session_set_cookie_params( + ((isset($arr['lifetime'])) ? $arr['lifetime'] : 0), + ((isset($arr['path'])) ? $arr['path'] : '/'), + ((isset($arr['domain'])) ? $arr['domain'] : App::get_hostname()), + ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false), + ((isset($arr['httponly'])) ? $arr['httponly'] : true) ); - } + } } function start() { @@ -150,4 +150,4 @@ class Session { return true; } -} \ No newline at end of file +} -- cgit v1.2.3 From 202035fc68d8b2364436cef75d68ac2a610e42c0 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 11 Apr 2016 19:19:58 -0700 Subject: move all DB session storage logic to SessionHandler where it belongs --- Zotlabs/Web/Session.php | 5 +---- Zotlabs/Web/SessionHandler.php | 9 +++++++++ 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'Zotlabs/Web') diff --git a/Zotlabs/Web/Session.php b/Zotlabs/Web/Session.php index 68af74521..0cd83c15e 100644 --- a/Zotlabs/Web/Session.php +++ b/Zotlabs/Web/Session.php @@ -77,10 +77,7 @@ class Session { session_regenerate_id(false); if(self::$handler) { - $v = q("UPDATE session SET sid = '%s' WHERE sid = '%s'", - dbesc(session_id()), - dbesc($old_sid) - ); + self::$handler->rename($old_sid,session_id()); } else logger('no session handler'); diff --git a/Zotlabs/Web/SessionHandler.php b/Zotlabs/Web/SessionHandler.php index 670e8f216..359279384 100644 --- a/Zotlabs/Web/SessionHandler.php +++ b/Zotlabs/Web/SessionHandler.php @@ -80,4 +80,13 @@ class SessionHandler implements \SessionHandlerInterface { } + // not part of the official interface, used when regenerating the session id + + function rename($old,$new) { + $v = q("UPDATE session SET sid = '%s' WHERE sid = '%s'", + dbesc($new), + dbesc($old) + ); + } + } \ No newline at end of file -- cgit v1.2.3 From 91cc36514306e827c126ceed6c17486c85f5544c Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 12 Apr 2016 22:55:26 -0700 Subject: reverse the logic of the jsenabled setting so that sessions without js are performance penalised instead of regular sessions. --- Zotlabs/Web/Session.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Web') diff --git a/Zotlabs/Web/Session.php b/Zotlabs/Web/Session.php index 55536fdc7..f998df396 100644 --- a/Zotlabs/Web/Session.php +++ b/Zotlabs/Web/Session.php @@ -85,8 +85,8 @@ class Session { else logger('no session handler'); - if (x($_COOKIE, 'jsAvailable')) { - setcookie('jsAvailable', $_COOKIE['jsAvailable'], $newxtime); + if (x($_COOKIE, 'jsdisabled')) { + setcookie('jsdisabled', $_COOKIE['jsdisabled'], $newxtime); } setcookie(session_name(),session_id(),$newxtime); -- cgit v1.2.3 From 9a0b61e4afed94727679eee966afb76e1add2beb Mon Sep 17 00:00:00 2001 From: redmatrix Date: Wed, 13 Apr 2016 16:31:06 -0700 Subject: refactor the js detection into a checkjs class which is only enabled on demand (currently only the channel and display pages). Will probably require a bit more work to hide/disable the cover photo when js is disabled. Have not actually tested without js to discover any other potential page issues. Have only confirmed that the detection class works and redirects to set a jsdisabled cookie and reload the page with that cookie+variable set if called from the channel page. --- Zotlabs/Web/CheckJS.php | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Zotlabs/Web/CheckJS.php (limited to 'Zotlabs/Web') diff --git a/Zotlabs/Web/CheckJS.php b/Zotlabs/Web/CheckJS.php new file mode 100644 index 000000000..3ad5fc1ed --- /dev/null +++ b/Zotlabs/Web/CheckJS.php @@ -0,0 +1,36 @@ +jsdisabled = 1; + if(intval($_COOKIE['jsdisabled'])) + $this->jsdisabled = 1; + + if(! $this->jsdisabled) { + $page = urlencode(\App::$query_string); + + if($test) { + \App::$page['htmlhead'] .= "\r\n" . '' . "\r\n"; + } + else { + \App::$page['htmlhead'] .= "\r\n" . '' . "\r\n"; + } + } + + } + + function disabled() { + return self::$jsdisabled; + } + + +} + + -- cgit v1.2.3