/** * Display module content * * @return void */ public function display() { // Include mw libraries include_once Component::path('com_tools') . DS . 'helpers' . DS . 'utils.php'; include_once Component::path('com_tools') . DS . 'tables' . DS . 'job.php'; include_once Component::path('com_tools') . DS . 'tables' . DS . 'view.php'; include_once Component::path('com_tools') . DS . 'tables' . DS . 'viewperm.php'; include_once Component::path('com_tools') . DS . 'tables' . DS . 'session.php'; include_once Component::path('com_tools') . DS . 'tables' . DS . 'host.php'; include_once Component::path('com_tools') . DS . 'tables' . DS . 'hosttype.php'; include_once Component::path('com_tools') . DS . 'tables' . DS . 'recent.php'; require_once Component::path('com_members') . DS . 'models' . DS . 'member.php'; // Get database object $this->database = \App::get('db'); // Get a connection to the middleware database $mwdb = \Components\Tools\Helpers\Utils::getMWDBO(); // Get tool paras $this->toolsConfig = Component::params('com_tools'); // Set ACL for com_tools $authorized = User::authorise('core.manage', 'com_tools'); // Ensure we have a connection to the middleware $this->error = false; if (!$mwdb || !$mwdb->connected() || !$this->toolsConfig->get('mw_on') || $this->toolsConfig->get('mw_on') > 1 && !$authorized) { $this->error = true; return false; } // Run middleware command to create screenshots // only take snapshots if screenshots are on if ($this->params->get('show_screenshots', 1)) { $cmd = "/bin/sh " . Component::path('com_tools') . "/scripts/mw screenshot " . User::get('username') . " 2>&1 </dev/null"; exec($cmd, $results, $status); } // Get sessions $session = new \Components\Tools\Tables\Session($mwdb); $this->sessions = $session->getRecords(User::get('username'), '', false); // Output module require $this->getLayoutPath(); }
/** * Invoke a tool session * * @return void */ public function invokeTask() { // Check that the user is logged in if (User::isGuest()) { $this->loginTask(); return; } $params = Request::getString('params', '', 'default', JREQUEST_ALLOWRAW); if (!empty($params)) { $params_whitelist = explode(',', $this->config->get('params_whitelist', '')); $separator = "\r\n"; $line = trim(strtok($params, $separator)); $verified_params = array(); while ($line !== false) { $re = "/\\s*(directory|file|int)\\s*(?:\\:|\\(\\s*(.*?)\\s*\\)\\s*:)\\s*(.*?)\\s*\$/"; if (preg_match($re, $line, $matches) != false) { $type = $matches[1]; $key = $matches[2]; $value = $matches[3]; if ($type == 'directory' || $type == 'file') { // Replace ~/ prefix with user's home directory if (strncmp($value, "~/", 2) === 0) { $homeDirectory = rtrim(User::get('homeDirectory'), '/'); if (!isset($homeDirectory[0]) || $homeDirectory[0] !== '/') { break; } $value = substr_replace($value, $homeDirectory, 0, 1); } // Fail if $value doesn't start with '/' if ($value[0] != '/') { break; } // Fail if unable to normalize $value $value = $this->normalize_path($value, $type == 'file'); if ($value === false) { break; } // Fail if $value contains a control charcater (0x00-0x1F) or an invalid utf-8 string if (preg_match('/^[^\\x00-\\x1f]*$/u', $value) == 0) { break; } // Fail if whitelist is empty if (empty($params_whitelist)) { break; } // Fail if $value isn't prefixed with a whitelisted directory foreach ($params_whitelist as $wl) { if (empty($wl)) { continue; } $wl = rtrim(trim($wl), '/') . '/'; // make sure we compare against a full path element if (strncmp($wl, $value, strlen($wl)) === 0) { $match = $wl; break; } } if (!isset($match)) { break; } // Add verified parameter to array if ($key) { $verified_params[] = $type . '(' . $key . '):' . $value; } else { $verified_params[] = $type . ':' . $value; } } else { if ($type == 'int') { // Fail if $value contains a control charcater (0x00-0x1F) or an invalid utf-8 string if (preg_match('/^[^\\x00-\\x1f]*$/u', $value) == 0) { break; } // Fail if $value not an integer if (preg_match('/^[-+]?[0-9]+$/', $value) == 0) { break; } // Add verified parameter to array if ($key) { $verified_params[] = $type . '(' . $key . '):' . $value; } else { $verified_params[] = $type . ':' . $value; } } } } else { if (!empty($line)) { break; } } $line = strtok($separator); // Get next line } if ($line !== false) { $this->badparamsTask($params); return; } } // Incoming $app = new stdClass(); $app->name = trim(str_replace(':', '-', Request::getVar('app', ''))); //$app->number = 0; $app->version = Request::getVar('version', 'default'); // Get the user's IP address $app->ip = Request::ip(); // Make sure we have an app to invoke if (!$app->name) { App::redirect(Route::url($this->config->get('stopRedirect', 'index.php?option=com_members&task=myaccount'))); return; } // Get the parent toolname (appname without any revision number "_r423") include_once dirname(dirname(__DIR__)) . DS . 'tables' . DS . 'version.php'; $tv = new \Components\Tools\Tables\Version($this->database); switch ($app->version) { case 1: case 'current': case 'default': $app->name = $tv->getCurrentVersionProperty($app->name, 'instance'); break; case 'test': case 'dev': $app->name .= '_dev'; break; default: $app->name .= '_r' . $app->version; break; } $app->toolname = $app->name; if ($parent = $tv->getToolname($app->name)) { $app->toolname = $parent; } // Check of the toolname has a revision indicator $r = substr(strrchr($app->name, '_'), 1); if (substr($r, 0, 1) != 'r' && substr($r, 0, 3) != 'dev') { $r = ''; } // No version passed and no revision if ((!$app->version || $app->version == 'default' || $app->version == 'current') && !$r) { // Get the latest version $app->version = $tv->getCurrentVersionProperty($app->toolname, 'revision'); $app->name = $app->toolname . '_r' . $app->version; } // Get the caption/session title $tv->loadFromInstance($app->name); $app->caption = stripslashes($tv->title); $app->title = stripslashes($tv->title); // Check if they have access to run this tool $hasaccess = $this->_getToolAccess($app->name); //$status2 = ($hasaccess) ? "PASSED" : "FAILED"; //Log::debug("mw::invoke " . $app->name . " by " . User::get('username') . " from " . $app->ip . " _getToolAccess " . $status2); if ($this->getError()) { echo '<!-- ' . $this->getError() . ' -->'; } if (!$hasaccess) { //$this->_redirect = Route::url('index.php?option=' . $this->_option . '&task=accessdenied'); $this->app = $app; $this->accessdeniedTask(); return; } $country = \Hubzero\Geocode\Geocode::ipcountry($app->ip); //die($app->ip . $country); // Log the launch attempt $this->_recordUsage($app->toolname, User::get('id')); // Get the middleware database $mwdb = \Components\Tools\Helpers\Utils::getMWDBO(); // Find out how many sessions the user is running. $ms = new \Components\Tools\Tables\Session($mwdb); $jobs = $ms->getCount(User::get('username')); // Find out how many sessions the user is ALLOWED to run. include_once dirname(dirname(__DIR__)) . DS . 'tables' . DS . 'preferences.php'; $preferences = new \Components\Tools\Tables\Preferences($this->database); $preferences->loadByUser(User::get('id')); if (!$preferences || !$preferences->id) { include_once dirname(dirname(__DIR__)) . DS . 'tables' . DS . 'sessionclass.php'; $scls = new \Components\Tools\Tables\SessionClass($this->database); $default = $scls->find('one', array('alias' => 'default')); $preferences->user_id = User::get('id'); $preferences->class_id = $default->id; $preferences->jobs = $default->jobs ? $default->jobs : 3; $preferences->store(); } $remain = $preferences->jobs - $jobs; // Have they reached their session quota? if ($remain <= 0) { $this->quotaexceededTask(); return; } if ($this->config->get('warn_multiples', 0) && !Request::getInt('newinstance', 0)) { $sessions = $ms->getRecords(User::get('username'), $app->name, false); if ($sessions && count($sessions) > 0) { $this->view->setLayout('list'); $this->view->app = $app; $this->view->config = $this->config; $this->view->sessions = $sessions; foreach ($this->getErrors() as $error) { $view->setError($error); } $this->view->display(); return; } } // Get their disk space usage $this->_getDiskUsage(); $this->_redirect = ''; $app->percent = 0; if ($this->config->get('show_storage', 1)) { $app->percent = $this->percent; } if ($this->percent >= 100) { App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=storage')); return; } // Get plugins Plugin::import('mw', $app->toolname); // Trigger any events that need to be called before session invoke Event::trigger('mw.onBeforeSessionInvoke', array($app->toolname, $app->version)); $toolparams = ''; if (!empty($params)) { $toolparams = " params=" . rawurlencode($params) . " "; } // Determine zone $app->zone_id = 0; if ($this->config->get('zones')) { $middleware = new \Components\Tools\Models\Middleware(); $this->database->setQuery("SELECT zone_id FROM `#__tool_version_zone` WHERE tool_version_id=" . $this->database->quote($tv->id)); $middleware->set('allowed', $this->database->loadColumn()); if ($zone = $middleware->zoning($app->ip, $middleware->get('allowed'))) { if ($zone->exists()) { $toolparams .= ' zone=' . $zone->get('zone'); $app->zone_id = $zone->get('id'); } } } // We've passed all checks so let's actually start the session $status = $this->middleware("start user="******" ip=" . $app->ip . " app=" . $app->name . " version=" . $app->version . $toolparams, $output); if ($this->getError()) { //App::abort(500, $this->getError()); //return; App::redirect(Route::url($this->config->get('stopRedirect', 'index.php?option=com_members&task=myaccount')), Lang::txt('COM_TOOLS_ERROR_SESSION_INVOKE_FAILED'), 'error'); return; } $app->sess = !empty($output->session) ? $output->session : ''; // Trigger any events that need to be called after session invoke Event::trigger('mw.onAfterSessionInvoke', array($app->toolname, $app->version)); // Get a count of the number of sessions of this specific tool $appcount = $ms->getCount(User::get('username'), $app->name); // Do we have more than one session of this tool? if ($appcount > 1) { // We do, so let's append a timestamp $app->caption .= ' (' . Date::toLocal('g:i a') . ')'; } // Save the changed caption $ms->load($app->sess); $ms->sessname = $app->caption; $ms->params = $params; if (!$ms->store()) { App::abort(500, $ms->getError()); } $rtrn = Request::getVar('return', ''); $url = 'index.php?option=' . $this->_option . '&controller=' . $this->_controller . '&app=' . $app->toolname . '&task=session&sess=' . $app->sess . '&return=' . $rtrn . (Request::getWord('viewer') ? '&viewer=' . Request::getWord('viewer') : ''); // Log activity Event::trigger('system.logActivity', ['activity' => ['action' => 'created', 'scope' => 'tool.session', 'scope_id' => $app->sess, 'description' => Lang::txt('COM_TOOLS_ACTIVITY_SESSION_CREATED', $app->sess, '<a href="' . Route::url($url) . '">' . $app->caption . '</a>'), 'details' => array('tool' => $app->name, 'url' => $url)], 'recipients' => array(['user', User::get('id')])]); App::redirect(Route::url($url, false)); }
/** * Get a member's tool sessions * * @apiMethod GET * @apiUri /members/{id}/tools/sessions * @apiParameter { * "name": "id", * "description": "Member identifier", * "type": "integer", * "required": true, * "default": null * } * @return void */ public function sessionsTask() { $this->requiresAuthentication(); $userid = Request::getInt('id', 0); $result = User::getInstance($userid); if ($result === false) { throw new Exception(Lang::txt('COM_MEMBERS_ERROR_USER_NOT_FOUND'), 404); } // Include middleware utilities include_once Component::path('com_tools') . DS . 'helpers' . DS . 'utils.php'; include_once Component::path('com_tools') . DS . 'tables' . DS . 'session.php'; // Get db connection $db = \App::get('db'); // Get Middleware DB connection $mwdb = \Components\Tools\Helpers\Utils::getMWDBO(); // Get com_tools params $mconfig = Component::params('com_tools'); // Check to make sure we have a connection to the middleware and its on if (!$mwdb || !$mconfig->get('mw_on') || $mconfig->get('mw_on') > 1) { throw new Exception(Lang::txt('Middleware Service Unavailable'), 503); } // Get request vars $format = Request::getVar('format', 'json'); $order = Request::getVar('order', 'id_asc'); // Get my sessions $ms = new \Components\Tools\Tables\Session($mwdb); $sessions = $ms->getRecords($result->get("username"), '', false); // Run middleware command to create screenshots $cmd = "/bin/sh " . Component::path('com_tools') . "/scripts/mw screenshot " . $result->get('username') . " 2>&1 </dev/null"; exec($cmd, $results, $status); $results = array(); foreach ($sessions as $session) { $r = array('id' => $session->sessnum, 'app' => $session->appname, 'name' => $session->sessname, 'started' => $session->start, 'accessed' => $session->accesstime, 'owner' => $result->get('username') == $session->username ? 1 : 0, 'ready-only' => $session->readonly == 'No' ? 0 : 1); $results[] = $r; } // Make sure we have an acceptable ordering $accepted_ordering = array('id_asc', 'id_desc', 'started_asc', 'started_desc', 'accessed_asc', 'accessed_desc'); if (in_array($order, $accepted_ordering)) { switch ($order) { case 'id_asc': break; case 'id_desc': usort($results, array($this, "id_sort_desc")); break; case 'started_asc': break; case 'started_desc': usort($results, array($this, "started_date_sort_desc")); break; case 'accessed_asc': usort($results, array($this, "accessed_date_sort_asc")); break; case 'accessed_desc': usort($results, array($this, "accessed_date_sort_desc")); break; } } // Encode sessions for return $object = new stdClass(); $object->sessions = $results; // Set format and content $this->send($object); }