diff --git a/include/cli/modules/serve.php b/include/cli/modules/serve.php new file mode 100644 index 0000000000000000000000000000000000000000..26075c6bd14e9b76b210665a105bd6c198a5998f --- /dev/null +++ b/include/cli/modules/serve.php @@ -0,0 +1,95 @@ +<?php + +class CliServerModule extends Module { + var $prologue = "Run a CLI server for osTicket"; + + var $options = array( + 'port' => array('-p','--port', + 'default'=>'8000', + 'help'=>'Specify the listening port number. Default is 8000', + ), + 'host' => array('-h','--host', + 'default'=>'localhost', + 'help'=>'Specify the bind address. Default is "localhost"', + ), + ); + + function make_router() { + $temp = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; + $router_path = $temp + . substr(md5('osticket-router'.getcwd()), -12) + . '.php'; + + // Ensure that the router file is cleaned up on exit + $cleanup = function() use ($router_path) { + @unlink($router_path); + }; + if (function_exists('pcntl_signal')) + pcntl_signal(SIGINT, $cleanup); + + // This will very likely not fire + register_shutdown_function($cleanup); + + $fp = fopen($router_path, 'wt'); + fwrite($fp, <<<EOF +<?php +\$full_path = \$_SERVER["DOCUMENT_ROOT"] . \$_SERVER["REQUEST_URI"]; +# Ensure trailing slash on folders +if (is_dir(\$full_path) + && rtrim(\$full_path, '/') == \$full_path +) { + header("Location: " . \$_SERVER["REQUEST_URI"] . '/'); +} +elseif (file_exists(\$_SERVER['SCRIPT_FILENAME'])) { + return false; +} +// Support various dispatchers +elseif (\$offs = stripos(\$_SERVER["REQUEST_URI"], 'scp/apps/')) { + \$_SERVER["PATH_INFO"] = substr(\$_SERVER["REQUEST_URI"], \$offs + 8); + chdir('scp/'); + require "apps/dispatcher.php"; +} +elseif (\$offs = stripos(\$_SERVER["REQUEST_URI"], 'pages/')) { + \$_SERVER["PATH_INFO"] = substr(\$_SERVER["REQUEST_URI"], \$offs + 5); + require "pages/index.php"; +} +elseif (\$offs = stripos(\$_SERVER["REQUEST_URI"], 'api/')) { + \$_SERVER["PATH_INFO"] = substr(\$_SERVER["REQUEST_URI"], \$offs + 3); + require "api/http.php"; +} +EOF + ); + fclose($fp); + + return $router_path; + } + + function run($args, $options) { + $router = $this->make_router(); + $pipes = array(); + $php = proc_open( + sprintf("php -S %s:%s -t %s %s", $options['host'], $options['port'], + ROOT_DIR, $router), + array( + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w'), + ), $pipes); + + stream_set_blocking($pipes[1], 0); + stream_set_blocking($pipes[2], 0); + + while (true) { + if (feof($pipes[1]) || feof($pipes[2])) { + fclose($pipes[1]); + fclose($pipes[2]); + break; + } + if ($block = fgets($pipes[1], 1024)) + fwrite(STDOUT, $block); + if ($block = fgets($pipes[2], 1024)) + fwrite(STDERR, $block); + usleep(100); + } + } +} +Module::register('serve', 'CliServerModule'); diff --git a/include/staff/footer.inc.php b/include/staff/footer.inc.php index a646f5eeae2ef7350ff15e7e7445a01c1dcba433..5d0cc65aef0a245665d6921d8f7a2bb14b4be8be 100644 --- a/include/staff/footer.inc.php +++ b/include/staff/footer.inc.php @@ -8,7 +8,7 @@ if(is_object($thisstaff) && $thisstaff->isStaff()) { ?> <div> <!-- Do not remove <img src="autocron.php" alt="" width="1" height="1" border="0" /> or your auto cron will cease to function --> - <img src="autocron.php" alt="" width="1" height="1" border="0" /> + <img src="<?php echo ROOT_PATH; ?>scp/autocron.php" alt="" width="1" height="1" border="0" /> <!-- Do not remove <img src="autocron.php" alt="" width="1" height="1" border="0" /> or your auto cron will cease to function --> </div> <?php @@ -41,20 +41,20 @@ if(is_object($thisstaff) && $thisstaff->isStaff()) { ?> </div> <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/jquery.pjax.js"></script> -<script type="text/javascript" src="./js/bootstrap-typeahead.js"></script> -<script type="text/javascript" src="./js/scp.js"></script> +<script type="text/javascript" src="<?php echo ROOT_PATH; ?>scp/js/bootstrap-typeahead.js"></script> +<script type="text/javascript" src="<?php echo ROOT_PATH; ?>scp/js/scp.js"></script> <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/jquery-ui-1.10.3.custom.min.js"></script> <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/filedrop.field.js"></script> <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/select2.min.js"></script> -<script type="text/javascript" src="./js/tips.js"></script> +<script type="text/javascript" src="<?php echo ROOT_PATH; ?>scp/js/tips.js"></script> <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor.min.js"></script> <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor-osticket.js"></script> <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor-plugins.js"></script> -<script type="text/javascript" src="./js/jquery.translatable.js"></script> -<script type="text/javascript" src="./js/jquery.dropdown.js"></script> -<script type="text/javascript" src="./js/bootstrap-tooltip.js"></script> +<script type="text/javascript" src="<?php echo ROOT_PATH; ?>scp/js/jquery.translatable.js"></script> +<script type="text/javascript" src="<?php echo ROOT_PATH; ?>scp/js/jquery.dropdown.js"></script> +<script type="text/javascript" src="<?php echo ROOT_PATH; ?>scp/js/bootstrap-tooltip.js"></script> <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/fabric.min.js"></script> -<link type="text/css" rel="stylesheet" href="./css/tooltip.css"> +<link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH; ?>scp/css/tooltip.css"> <script type="text/javascript"> getConfig().resolve(<?php include INCLUDE_DIR . 'ajax.config.php'; diff --git a/include/staff/header.inc.php b/include/staff/header.inc.php index 0bb3b3b779e74b7c56d92e2152a38296f42417fc..13a122c54df8a1fb40a03435e431b068d9fd05bd 100644 --- a/include/staff/header.inc.php +++ b/include/staff/header.inc.php @@ -25,21 +25,21 @@ if ($lang) { <![endif]--> <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/jquery-1.11.2.min.js"></script> <link rel="stylesheet" href="<?php echo ROOT_PATH ?>css/thread.css" media="all"> - <link rel="stylesheet" href="./css/scp.css" media="all"> + <link rel="stylesheet" href="<?php echo ROOT_PATH ?>scp/css/scp.css" media="all"> <link rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/redactor.css" media="screen"> - <link rel="stylesheet" href="./css/typeahead.css" media="screen"> + <link rel="stylesheet" href="<?php echo ROOT_PATH ?>scp/css/typeahead.css" media="screen"> <link type="text/css" href="<?php echo ROOT_PATH; ?>css/ui-lightness/jquery-ui-1.10.3.custom.min.css" rel="stylesheet" media="screen" /> <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/font-awesome.min.css"> <!--[if IE 7]> <link rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/font-awesome-ie7.min.css"> <![endif]--> - <link type="text/css" rel="stylesheet" href="./css/dropdown.css"> + <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH ?>scp/css/dropdown.css"> <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/loadingbar.css"/> <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/flags.css"> <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/select2.min.css"> <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH; ?>css/rtl.css"/> - <link type="text/css" rel="stylesheet" href="./css/translatable.css"/> + <link type="text/css" rel="stylesheet" href="<?php echo ROOT_PATH ?>scp/css/translatable.css"/> <?php if($ost && ($headers=$ost->getExtraHeaders())) { @@ -61,16 +61,16 @@ if ($lang) { <p id="info" class="pull-right no-pjax"><?php echo sprintf(__('Welcome, %s.'), '<strong>'.$thisstaff->getFirstName().'</strong>'); ?> <?php if($thisstaff->isAdmin() && !defined('ADMINPAGE')) { ?> - | <a href="admin.php" class="no-pjax"><?php echo __('Admin Panel'); ?></a> + | <a href="<?php echo ROOT_PATH ?>scp/admin.php" class="no-pjax"><?php echo __('Admin Panel'); ?></a> <?php }else{ ?> - | <a href="index.php" class="no-pjax"><?php echo __('Agent Panel'); ?></a> + | <a href="<?php echo ROOT_PATH ?>scp/index.php" class="no-pjax"><?php echo __('Agent Panel'); ?></a> <?php } ?> - | <a href="profile.php"><?php echo __('Profile'); ?></a> - | <a href="logout.php?auth=<?php echo $ost->getLinkToken(); ?>" class="no-pjax"><?php echo __('Log Out'); ?></a> + | <a href="<?php echo ROOT_PATH ?>scp/profile.php"><?php echo __('Profile'); ?></a> + | <a href="<?php echo ROOT_PATH ?>scp/logout.php?auth=<?php echo $ost->getLinkToken(); ?>" class="no-pjax"><?php echo __('Log Out'); ?></a> </p> - <a href="index.php" class="no-pjax" id="logo"> + <a href="<?php echo ROOT_PATH ?>scp/index.php" class="no-pjax" id="logo"> <span class="valign-helper"></span> - <img src="logo.php?<?php echo strtotime($cfg->lastModified('staff_logo_id')); ?>" alt="osTicket — <?php echo __('Customer Support System'); ?>"/> + <img src="<?php echo ROOT_PATH ?>scp/logo.php?<?php echo strtotime($cfg->lastModified('staff_logo_id')); ?>" alt="osTicket — <?php echo __('Customer Support System'); ?>"/> </a> </div> <div id="pjax-container" class="<?php if ($_POST) echo 'no-pjax'; ?>"> diff --git a/include/staff/templates/navigation.tmpl.php b/include/staff/templates/navigation.tmpl.php index 8f0444999c7d0c169acbc599dfbfa69285a2462d..5c86f47153b767c1c9bfd3d47c13b5f4e501236e 100644 --- a/include/staff/templates/navigation.tmpl.php +++ b/include/staff/templates/navigation.tmpl.php @@ -1,6 +1,8 @@ <?php if(($tabs=$nav->getTabs()) && is_array($tabs)){ foreach($tabs as $name =>$tab) { + if ($tab['href'][0] != '/') + $tab['href'] = ROOT_PATH . 'scp/' . $tab['href']; echo sprintf('<li class="%s %s"><a href="%s">%s</a>', $tab['active'] ? 'active':'inactive', @$tab['class'] ?: '', @@ -10,6 +12,8 @@ if(($tabs=$nav->getTabs()) && is_array($tabs)){ foreach($subnav as $k => $item) { if (!($id=$item['id'])) $id="nav$k"; + if ($item['href'][0] != '/') + $item['href'] = ROOT_PATH . 'scp/' . $item['href']; echo sprintf( '<li><a class="%s" href="%s" title="%s" id="%s">%s</a></li>', diff --git a/scp/admin.inc.php b/scp/admin.inc.php index 434589acaa0584d7164fa32afc48c6848adea88c..9f701eb0bbeaa7d9e53bb227ba09c1061077cd4d 100644 --- a/scp/admin.inc.php +++ b/scp/admin.inc.php @@ -13,7 +13,7 @@ vim: expandtab sw=4 ts=4 sts=4: **********************************************************************/ -require('staff.inc.php'); +require_once 'staff.inc.php'; //Make sure config is loaded and the staff is set and of admin type if(!$ost or !$thisstaff or !$thisstaff->isAdmin()){ header('Location: index.php'); diff --git a/scp/apps/dispatcher.php b/scp/apps/dispatcher.php index ac5ac585040ffdbc0bcbc8d9056c2cd651628e31..63255923a7bc73d2c38989d1f658fb295d5e511e 100644 --- a/scp/apps/dispatcher.php +++ b/scp/apps/dispatcher.php @@ -14,19 +14,14 @@ vim: expandtab sw=4 ts=4 sts=4: **********************************************************************/ -# Override staffLoginPage() defined in staff.inc.php to return an -# HTTP/Forbidden status rather than the actual login page. -# XXX: This should be moved to the AjaxController class -function staffLoginPage($msg='Unauthorized') { - Http::response(403,'Must login: '.Format::htmlchars($msg)); - exit; -} +if (basename($_SERVER['SCRIPT_NAME'])==basename(__FILE__)) + die('Access denied'); //Say hi to our friend.. require('staff.inc.php'); //Clean house...don't let the world see your crap. -ini_set('display_errors','0'); //Disable error display -ini_set('display_startup_errors','0'); +#ini_set('display_errors','0'); //Disable error display +#ini_set('display_startup_errors','0'); //TODO: disable direct access via the browser? i,e All request must have REFER? if(!defined('INCLUDE_DIR')) Http::response(500, 'Server configuration error'); @@ -34,7 +29,17 @@ if(!defined('INCLUDE_DIR')) Http::response(500, 'Server configuration error'); require_once INCLUDE_DIR.'/class.dispatcher.php'; $dispatcher = new Dispatcher(); -Signal::send('apps.scp', $dispatcher); +$PI = $ost->get_path_info(); +if (strpos(strtolower($PI), '/admin/') === 0) { + require('admin.inc.php'); + $PI = substr($PI, 6); + Signal::send('apps.admin', $dispatcher); +} +else { + Signal::send('apps.scp', $dispatcher); +} + +$nav->setActiveTab('apps'); # Call the respective function -print $dispatcher->resolve($ost->get_path_info()); +print $dispatcher->resolve($PI); diff --git a/scp/staff.inc.php b/scp/staff.inc.php index bb06f3eb8e92dcf8094b1f1500137c282eddceec..757befc8d5a449b78326531b2500387e904df846 100644 --- a/scp/staff.inc.php +++ b/scp/staff.inc.php @@ -49,7 +49,9 @@ if(!function_exists('staffLoginPage')) { //Ajax interface can pre-declare the fu $_SESSION['_staff']['auth']['dest'] = '/' . ltrim($_SERVER['REQUEST_URI'], '/'); $_SESSION['_staff']['auth']['msg']=$msg; - require(SCP_DIR.'login.php'); + + // Redirect here with full path for application-type plugins + Http::redirect(ROOT_PATH.'scp/login.php'); exit; } }