/** * 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(); }
/** * Saves the name of a session (AJAX) * * @return void */ public function renameTask() { $mwdb = \Components\Tools\Helpers\Utils::getMWDBO(); $id = Request::getInt('id', 0); $name = trim(Request::getVar('name', '')); if ($id && $name) { $ms = new \Components\Tools\Tables\Session($mwdb); $ms->load($id); $ms->sessname = $name; $ms->store(); } echo $name; }
/** * Method to setup Windows filesharing connection * * @apiMethod GET * @apiUri /tools/{sessionid}/fileshare * @apiParameter { * "name": "sessionid", * "description": "Tool session identifier", * "type": "integer", * "required": true, * "default": 0 * } * @apiParameter { * "name": "username", * "description": "Username", * "type": "string", * "required": false, * "default": null * } * @apiParameter { * "name": "private_ip", * "description": "Private IP Address", * "type": "string", * "required": false, * "default": null * } * @apiParameter { * "name": "public_ip", * "description": "Public IP Address", * "type": "string", * "required": false, * "default": null * } * @return void * * * * @TODO: This is just a rough draft. needs a little polishing. * */ public function fileshareTask() { //$this->requiresAuthentication(); require_once dirname(dirname(__DIR__)) . DS . 'tables' . DS . 'session.php'; require_once dirname(dirname(__DIR__)) . DS . 'tables' . DS . 'viewperm.php'; // instantiate middleware database object $mwdb = \Components\Tools\Helpers\Utils::getMWDBO(); // get any request vars $username = Request::getVar('username'); $sessionid = Request::getVar('id'); $private_ip = Request::getVar('private_ip'); $public_ip = Request::getVar('public_ip', Request::ip()); // check to make sure we have a valid sessionid if ($sessionid == '' || !is_numeric($sessionid)) { throw new Exception(Lang::txt('No session ID Specified.'), 401); } // load session $ms = new \Components\Tools\Tables\Session($mwdb); $sess = $ms->loadSession($sessionid); $command = "/usr/bin/sudo /usr/bin/hzappstream --remote 128.46.19.124 fileshare add {$username} {$sessionid} {$public_ip} {$private_ip} --ipsec-use-default-psk"; $command = escapeshellcmd($command); $descriptorspec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w")); $process = proc_open($command, $descriptorspec, $pipes, "/", NULL); if (is_resource($process)) { // $pipes now looks like this: // 0 => writeable handle connected to child stdin // 1 => readable handle connected to child stdout // Any error output will be appended to /tmp/error-output.txt fclose($pipes[0]); $output = stream_get_contents($pipes[1]); fclose($pipes[1]); $error = stream_get_contents($pipes[2]); fclose($pipes[2]); // It is important that you close any pipes before calling // proc_close in order to avoid a deadlock $return_value = proc_close($process); $output = strstr($output, '{'); $joutput = json_decode($output); $object = array('fileserver' => '128.46.19.124', 'username' => $username, 'session' => $sessionid, 'ipsec_ip1' => $public_ip, 'ipsec_ip2' => $private_ip, 'smb_username' => 'smb-' . $sessionid); $object['smb_password'] = $joutput->smb_password; } else { $object = array('fileserver' => '128.46.19.124', 'username' => $username, 'session' => $sessionid, 'ipsec_ip1' => $public_ip, 'ipsec_ip2' => $private_ip, 'ipsec_password' => NULL, 'smb_username' => 'smb-' . $sessionid, 'smb_password' => NULL); } $this->send($object); }
/** * Runs a rappture job. * * This is more than just invoking a tool. We're expecting a driver file to pass to the * tool to be picked up and automatically run by rappture. * * @apiMethod POST * @apiUri /tools/run * @apiParameter { * "name": "app", * "description": "Name of app installed as a tool in the hub", * "type": "string", * "required": true, * } * @apiParameter { * "name": "revision", * "description": "The specific requested revision of the app", * "type": "string", * "required": false, * "default": "default", * } * @apiParameter { * "name": "xml", * "description": "Content of the driver file that rappture will use to invoke the given app", * "type": "string", * "required": true, * } * @return void */ public function runTask() { $this->requiresAuthentication(); // Get the user_id and attempt to load user profile $userid = App::get('authn')['user_id']; $profile = \Hubzero\User\Profile::getInstance($userid); // Make sure we have a user if ($profile === false) { return $this->not_found(); } // Grab tool name and version $tool_name = Request::getVar('app', ''); $tool_version = Request::getVar('revision', 'default'); // Build application object $app = new stdClass(); $app->name = trim(str_replace(':', '-', $tool_name)); $app->version = $tool_version; $app->ip = $_SERVER["REMOTE_ADDR"]; // Check to make sure we have an app to invoke if (!$app->name) { throw new Exception(Lang::txt('A valid app name must be provided'), 404); } // Include needed tool libraries require_once dirname(dirname(__DIR__)) . DS . 'tables' . DS . 'version.php'; require_once dirname(dirname(__DIR__)) . DS . 'tables' . DS . 'session.php'; require_once dirname(dirname(__DIR__)) . DS . 'tables' . DS . 'viewperm.php'; // Create database object $database = \App::get('db'); // Load the tool version $tv = new \Components\Tools\Tables\Version($database); switch ($app->version) { case 1: 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') && !$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); // Make sure we have a valid tool if ($app->title == '' || $app->toolname == '') { throw new Exception(Lang::txt('The tool "%s" does not exist on the HUB.', $tool_name), 404); } // Get tool access $toolAccess = \Components\Tools\Helpers\Utils::getToolAccess($app->name, $profile->get('username')); // Do we have access if ($toolAccess->valid != 1) { throw new Exception($toolAccess->error->message, 500); } // Log the launch attempt \Components\Tools\Helpers\Utils::recordToolUsage($app->toolname, $profile->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($profile->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($database); $preferences->loadByUser($profile->get('uidNumber')); if (!$preferences || !$preferences->id) { $default = $preferences->find('one', array('alias' => 'default')); $preferences->user_id = $profile->get('uidNumber'); $preferences->class_id = $default->id; $preferences->jobs = $default->jobs; $preferences->store(); } $remain = $preferences->jobs - $jobs; //can we open another session if ($remain <= 0) { throw new Exception(Lang::txt('You are using all (%s) your available job slots.', $jobs), 401); } // Check for an incoming driver file if ($driver = Request::getVar('xml', false, 'post', 'none', 2)) { // Build a path to where the driver file will go through webdav $base = DS . 'webdav' . DS . 'home'; $user = DS . $profile->get('username'); $data = DS . 'data'; $drvr = DS . '.queued_drivers'; $inst = DS . md5(time()) . '.xml'; // Real home directory $homeDir = $profile->get('homeDirectory'); // First, make sure webdav is there and that the necessary folders are there if (!\Filesystem::exists($base)) { throw new Exception(Lang::txt('Home directories are unavailable'), 500); } // Now see if the user has a home directory yet if (!\Filesystem::exists($homeDir)) { // Try to create their home directory require_once dirname(dirname(__DIR__)) . DS . 'helpers' . DS . 'utils.php'; if (!\Components\Tools\Helpers\Utils::createHomeDirectory($profile->get('username'))) { throw new Exception(Lang::txt('Failed to create user home directory'), 500); } } // Check for, and create if needed a session data directory if (!\Filesystem::exists($base . $user . $data) && !\Filesystem::makeDirectory($base . $user . $data, 0700)) { throw new Exception(Lang::txt('Failed to create data directory'), 500); } // Check for, and create if needed a queued drivers directory if (!\Filesystem::exists($base . $user . $data . $drvr) && !\Filesystem::makeDirectory($base . $user . $data . $drvr, 0700)) { throw new Exception(Lang::txt('Failed to create drivers directory'), 500); } // Write the driver file out if (!\Filesystem::write($base . $user . $data . $drvr . $inst, $driver)) { throw new Exception(Lang::txt('Failed to create driver file'), 500); } } else { throw new Exception(Lang::txt('No driver file provided'), 404); } // Now build params path that will be included with tool execution // We know from the checks above that this directory already exists $params = 'file(execute):' . $homeDir . DS . 'data' . DS . '.queued_drivers' . $inst; $encoded = ' params=' . rawurlencode($params) . ' '; $command = 'start user='******'username') . " ip={$app->ip} app={$app->name} version={$app->version}" . $encoded; $status = \Components\Tools\Helpers\Utils::middleware($command, $output); $this->send(array('success' => true, 'session' => $output->session)); }
/** * Grabs the output from a tool session * * @apiMethod GET * @apiUri /tools/{session}/output * @return void */ public function outputTask() { $this->requiresAuthentication(); $session = Request::getInt('session_num', 0); $runFile = Request::getVar('run_file', false); if (!$session) { throw new Exception(Lang::txt('Session not found.'), 404); } // Get the middleware database $mwdb = \Components\Tools\Helpers\Utils::getMWDBO(); // Make sure it's a valid sesssion number and the user is/was the owner of it require_once dirname(dirname(__DIR__)) . DS . 'tables' . DS . 'session.php'; require_once dirname(dirname(__DIR__)) . DS . 'tables' . DS . 'viewperm.php'; $ms = new \Components\Tools\Tables\Session($mwdb); if (!$ms->checkSession($session)) { throw new Exception(Lang::txt('You can only check the status of your sessions.'), 401); } // Check for specific sesssion entry $dir = DS . 'webdav' . DS . 'home' . DS . User::get('username') . DS . 'data' . DS . 'results' . DS . $session; if (!is_dir($dir)) { throw new Exception(Lang::txt('No results directory found.'), 404); } $outputFile = $dir . DS . $runFile; if (!is_file($outputFile)) { throw new Exception(Lang::txt('No run file found.'), 404); } $output = file_get_contents($outputFile); $this->send(array('success' => true, 'output' => $output)); }
/** * Generate a Windows tool invoke URL to redirect to * * @param string $option Name of the component * @param string $appid * @param object $user * @param string $ip * @return string */ public function generateInvokeUrl($option, $appid = null, $user = null, $ip = null) { $appid = $appid ?: Request::getVar('appid'); if (!$appid) { return ''; } $user = $user ?: User::getInstance(); $ip = $ip ?: Request::ip(); // Get summary usage data $startdate = new \DateTime('midnight first day of this month'); $enddate = new \DateTime('midnight first day of next month'); $db = App::get('db'); $sql = 'SELECT truncate(sum(walltime)/60/60,3) as totalhours FROM `sessionlog` '; $sql .= 'WHERE start >' . $db->quote($startdate->format('Y-m-d H:i:s')) . ' '; $sql .= 'AND start <' . $db->quote($enddate->format('Y-m-d H:i:s')); $db->setQuery($sql); $totalUsageFigure = $db->loadObjectList(); $params = Component::params('com_tools'); $maxhours = $params->get('windows_monthly_max_hours', '100'); if (floatval($totalUsageFigure[0]->totalhours) > floatval($maxhours)) { return ''; } // Get the middleware database $mwdb = \Components\Tools\Helpers\Utils::getMWDBO(); // Get the session table $ms = new \Components\Tools\Tables\Session($mwdb); $ms->bind(array('username' => $user->get('username'), 'remoteip' => $ip)); // Save the entry $ms->store(); // Get back the ID $sessionID = $ms->sessnum; // Opaque data $od = "username="******",email=" . $user->get('email'); $od = $od . ",userip=" . $ip; $od = $od . ",sessionid=" . $sessionID; $od = $od . ",ts=" . (new \DateTime())->format('Y.m.d.H.i.s'); $eurl = exec("/usr/bin/hz-aws-appstream getentitlementurl --appid '" . $appid . "' --opaquedata '" . $od . "'"); return $eurl; }
/** * 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); }