/** * @param string|bool $name */ protected function getActiveClients($name = false) { $context = $this->getContext(); $db = $context->getDB(); $nameQuery = $name ? 'AND name = \'' . $db->strEncode($name) . '\'' : ''; $results = array(); $rows = $db->getRows(str_queryf("SELECT\n\t\t\t\tid,\n\t\t\t\tname,\n\t\t\t\tuseragent,\n\t\t\t\tupdated,\n\t\t\t\tcreated\n\t\t\tFROM\n\t\t\t\tclients\n\t\t\tWHERE updated >= %s\n\t\t\t{$nameQuery}\n\t\t\tORDER BY created DESC;", swarmdb_dateformat(Client::getMaxAge($context)))); if ($rows) { foreach ($rows as $row) { $bi = BrowserInfo::newFromContext($this->getContext(), $row->useragent); $resultRow = $db->getRow(str_queryf('SELECT id, run_id, client_id, status, total, fail, error, updated, created FROM runresults WHERE client_id = %u ORDER BY created DESC LIMIT 1;', $row->id)); $client = array('id' => $row->id, 'name' => $row->name, 'uaID' => $bi->getSwarmUaID(), 'uaRaw' => $bi->getRawUA(), 'uaData' => $bi->getUaData(), 'viewUrl' => swarmpath("client/{$row->id}"), 'lastResult' => !$resultRow ? null : array('id' => intval($resultRow->id), 'viewUrl' => swarmpath("result/{$resultRow->id}"), 'status' => JobAction::getRunresultsStatus($resultRow))); self::addTimestampsTo($client, $row->created, 'connected'); self::addTimestampsTo($client, $row->updated, 'pinged'); $results[$row->id] = $client; } } return $results; }
protected function serveRawResults($resultsID) { $db = $this->getContext()->getDB(); $this->setRobots('noindex,nofollow'); $row = $db->getRow(str_queryf('SELECT status, report_html FROM runresults WHERE id = %u;', $resultsID)); header('Content-Type: text/html; charset=utf-8'); if ($row) { $status = intval($row->status); // If it finished or was aborted, there should be // a (at least partial) html report. if ($status === ResultAction::$STATE_FINISHED || $status === ResultAction::$STATE_ABORTED || $status === ResultAction::$STATE_HEARTBEAT) { if ($row->report_html) { header('Content-Encoding: gzip'); echo $row->report_html; } else { $this->outputMini('No Content', 'Client saved results but did not attach an HTML report.'); } // Client timed-out } elseif ($status === ResultAction::$STATE_LOST) { $this->outputMini('Client Lost', 'Client lost connection with the swarm.'); // Still busy? Or some unknown status? } else { $this->outputMini('In Progress', 'Client did not submit results yet. Please try again later.'); } } else { self::httpStatusHeader(404); $this->outputMini('Not Found'); } // This is a raw HTML response, the Page should not build. exit; }
/** * @actionNote This action takes no parameters. */ public function doAction() { $browserInfo = $this->getContext()->getBrowserInfo(); $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); // Get runs that were given to a client (status=1), // but haven't responded with a save (status=2) within 5 minutes. $rows = $db->getRows(str_queryf("SELECT\n\t\t\t\trun_id,\n\t\t\t\tclient_id,\n\t\t\t\tuseragent_id\n\t\t\tFROM\n\t\t\t\trun_client, clients\n\t\t\tWHERE run_client.updated < %s\n\t\t\tAND clients.id = run_client.client_id\n\t\t\tAND run_client.status = 1;", swarmdb_dateformat(strtotime('5 minutes ago')))); $resetTimedoutRuns = 0; if ($rows) { $resetTimedoutRuns = count($rows); foreach ($rows as $row) { // Undo runcount and reset status $db->query(str_queryf("UPDATE\n\t\t\t\t\t\trun_useragent\n\t\t\t\t\tSET\n\t\t\t\t\t\truns = runs - 1,\n\t\t\t\t\t\tstatus = 0\n\t\t\t\t\tWHERE run_id = %u\n\t\t\t\t\tAND useragent_id = %s;", $row->run_id, $row->useragent_id)); // Remove run_client entry, // after 5 minutes we'll assume the client crashed, refreshed, closed the browser // or something else... $db->query(str_queryf("DELETE FROM\n\t\t\t\t\t\trun_client\n\t\t\t\t\tWHERE run_id = %u\n\t\t\t\t\tAND client_id = %u;", $row->run_id, $row->client_id)); } } // Reset runs that race-condition deleted themselves $db->query("UPDATE\n\t\t\t\trun_useragent\n\t\t\tSET\n\t\t\t\truns = 0,\n\t\t\t\tcompleted = 0,\n\t\t\t\tstatus = 0\n\t\t\tWHERE runs = max\n\t\t\tAND NOT EXISTS (\n\t\t\t\tSELECT *\n\t\t\t\tFROM run_client, clients\n\t\t\t\tWHERE run_client.run_id = run_useragent.run_id\n\t\t\t\tAND run_client.client_id = clients.id\n\t\t\t\tAND clients.useragent_id = run_useragent.useragent_id\n\t\t\t);"); $resetRaceConditionDeleted = $db->getAffectedRows(); $this->setData(array("resetTimedoutRuns" => $resetTimedoutRuns, "resetRaceConditionDeleted" => $resetRaceConditionDeleted)); }
/** * * @actionMethod POST: Required. * @actionParam id int * @actionParam name string * */ public function doAction() { $request = $this->getContext()->getRequest(); if (!$request->wasPosted()) { $this->setError("requires-post"); return; } $json = json_decode(file_get_contents('php://input')); if (!$json->id) { $this->setError("missing-id"); return; } if (!$json->name) { $this->setError("missing-name"); return; } // Save data $db = $this->getContext()->getDB(); $db->query(str_queryf('UPDATE clients SET device_name = %s WHERE id = %u;', $json->name, $json->id)); $this->setData('OK'); }
protected function purgeData($timestamp, $batchSize) { $date = swarmdb_dateformat($timestamp); // Based on ManageProjectScript::delete() $stats = array(); $db = $this->getContext()->getDB(); while (true) { $jobRows = $db->getRows(str_queryf('SELECT id FROM jobs WHERE created < %s LIMIT %u;', $date, $batchSize)); if (!$jobRows) { // Done break; } $jobIDs = array_map(function ($row) { return $row->id; }, $jobRows); $this->out('...deleting ' . count($jobIDs) . ' jobs'); $action = WipejobAction::newFromContext($this->getContext()); $result = $action->doWipeJobs('delete', $jobIDs, $batchSize); $this->mergeStats($stats, $result); } // TODO: Purge rows from clients table for clients that are no // longer active and don't have 0 runresults after the purge. foreach ($stats as $key => $val) { $this->out("deleted {$key} rows: {$val}"); } $this->out(''); $this->out('Done!'); }
protected function execute() { $db = $this->getContext()->getDB(); $id = $this->getOption('id'); // Verify parameters if (!$id) { $this->error('--id is required.'); } $checkId = $db->getOne(str_queryf('SELECT id FROM projects WHERE id = %s;', $id)); if (!$checkId || $checkId !== $id) { $this->error('Project "' . $id . '" does not exist.'); } if (!$this->getOption('quick')) { $this->timeWarningForScriptWill('invalidate the existing token'); } // New token $authToken = LoginAction::generateRandomHash(40); $authTokenHash = sha1($authToken); $isUpdated = $db->query(str_queryf('UPDATE projects SET auth_token = %s WHERE id = %s LIMIT 1;', $authTokenHash, $id)); if (!$isUpdated) { $this->error('Updating of row into database failed.'); } $this->out('Authentication token of project "' . $id . '" has been succesfully refreshed!' . PHP_EOL . 'The following auth token has been generated for this project:' . PHP_EOL . $authToken . PHP_EOL . PHP_EOL); }
/** * @requestParam browserSet string: Show useragents from a specific * browserset only. * @requestParam onlyactive bool: If true, only user agents that * have online clients and/or pending runs are included. * If both "browserSet" and "onlyactive" are used, the overlaping * subset will be output. */ public function doAction() { $conf = $this->getContext()->getConf(); $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); $showOnlyactive = $request->hasKey("onlyactive"); $filterBrowserSet = $request->getVal("browserSet", false); $data = array("userAgents" => array()); $uaIndex = BrowserInfo::getSwarmUAIndex(); foreach ($uaIndex as $uaID => $uaData) { if ($filterBrowserSet && isset($conf->browserSets->{$filterBrowserSet}) && !in_array($uaID, $conf->browserSets->{$filterBrowserSet})) { continue; } // Count online clients with this UA $clients = $db->getOne(str_queryf("SELECT\n\t\t\t\t\tCOUNT(id)\n\t\t\t\tFROM clients\n\t\t\t\tWHERE useragent_id = %s\n\t\t\t\tAND updated > %s", $uaID, swarmdb_dateformat(strtotime('1 minute ago')))); $clients = intval($clients); // Count pending runs for this UA $pendingRuns = $db->getOne(str_queryf("SELECT\n\t\t\t\t\tCOUNT(*)\n\t\t\t\tFROM run_useragent\n\t\t\t\tWHERE useragent_id = %s\n\t\t\t\tAND status = 0;", $uaID)); $pendingRuns = intval($pendingRuns); // Count past runs that can still be re-run to // possibly fix non-passing results $pendingReRuns = $db->getOne(str_queryf("SELECT\n\t\t\t\t\tCOUNT(*)\n\t\t\t\tFROM run_useragent\n\t\t\t\tWHERE useragent_id = %s\n\t\t\t\tAND runs < max\n\t\t\t\tAND completed > 0;", $uaID)); $pendingReRuns = intval($pendingReRuns); if ($showOnlyactive && !$clients && !$pendingRuns && !$pendingReRuns) { continue; } $data["userAgents"][$uaID] = array("data" => $uaData, "stats" => array("onlineClients" => $clients, "pendingRuns" => $pendingRuns, "pendingReRuns" => $pendingReRuns)); } $this->setData($data); }
/** * @actionNote This action takes no parameters. */ public function doAction() { $browserInfo = $this->getContext()->getBrowserInfo(); $db = $this->getContext()->getDB(); $conf = $this->getContext()->getConf(); $request = $this->getContext()->getRequest(); // Get runs that were given to a client (status=1), // but haven't pinged back when they should. $maxage = time() - $conf->client->runTimeout - $conf->client->saveRetryMax * ($conf->client->saveReqTimeout + $conf->client->saveRetrySleep); $rows = $db->getRows(str_queryf("SELECT\n\t\t\t\tid,\n\t\t\t\tresults_id\n\t\t\tFROM\n\t\t\t\trun_useragent\n\t\t\tWHERE status = 1\n\t\t\tAND updated < %s;", swarmdb_dateformat($maxage))); $resetTimedoutRuns = 0; // For clients that have stopped pinging, // assume disconnection (browser crashed, network lost, closed browser, ..) // @todo: Incorrect, the above query finds runs that have timed out. // Not dead runs from no longer connected clients, both should be checked. // The latter involves 3 cross-checks. Get runresults entry. Get client_id. // Get clients entry. Check updated property against pingTime+pingTimeMargin (see UserAction/SwarmstateAction). // Make 2 arrays of runUaIds and runresultsIds and unique them before the if(). Change if to if-count() if ($rows) { $resetTimedoutRuns = count($rows); foreach ($rows as $row) { $db->query(str_queryf("UPDATE run_useragent\n\t\t\t\t\tSET\n\t\t\t\t\t\tstatus = 0,\n\t\t\t\t\t\tresults_id = NULL\n\t\t\t\t\tWHERE id = %u;", $row->id)); // Record runresults status as having timed-out (status=3) $db->query(str_queryf("UPDATE runresults\n\t\t\t\t\tSET status = %s\n\t\t\t\t\tWHERE id = %u;", ResultAction::$STATE_LOST, $row->results_id)); } } $this->setData(array("resetTimedoutRuns" => $resetTimedoutRuns)); }
/** * @actionMethod POST: Required. * @actionParam int job_id * @actionParam string type: one of 'delete', 'reset'. * @actionAuth: Required. */ public function doAction() { $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); $jobID = $request->getInt('job_id'); $wipeType = $request->getVal('type'); if (!$jobID || !$wipeType) { $this->setError('missing-parameters'); return; } if (!in_array($wipeType, array('delete', 'reset'))) { $this->setError('invalid-input', 'Invalid wipeType'); return; } $projectID = $db->getOne(str_queryf('SELECT project_id FROM jobs WHERE id = %u;', $jobID)); if (!$projectID) { $this->setError('invalid-input', 'Job not found'); return; } // Check authentication if (!$this->doRequireAuth($projectID)) { return; } $runRows = $db->getRows(str_queryf('SELECT id FROM runs WHERE job_id = %u;', $jobID)); if ($runRows) { foreach ($runRows as $runRow) { if ($wipeType === 'delete') { $db->query(str_queryf('DELETE FROM run_useragent WHERE run_id = %u;', $runRow->id)); } elseif ($wipeType === 'reset') { $db->query(str_queryf('UPDATE run_useragent SET status = 0, completed = 0, results_id = NULL, updated = %s WHERE run_id = %u;', swarmdb_dateformat(SWARM_NOW), $runRow->id)); } } } // This should be outside the if for $runRows, because jobs // can sometimes be created without any runs (by accidently). // Those should be deletable as well, thus this has to be outside the loop. // Also, no need to do this in a loop, just delete them all in one query. if ($wipeType === 'delete') { $db->query(str_queryf('DELETE FROM runs WHERE job_id = %u;', $jobID)); $db->query(str_queryf('DELETE FROM jobs WHERE id = %u;', $jobID)); } $this->setData(array('jobID' => $jobID, 'type' => $wipeType, 'result' => 'ok')); }
/** * @actionNote This action takes no parameters. */ public function doAction() { $context = $this->getContext(); $browserInfo = $context->getBrowserInfo(); $db = $context->getDB(); $conf = $context->getConf(); $request = $context->getRequest(); $resetTimedoutRuns = 0; // Get clients that are considered disconnected (not responding to the latest pings). // Then mark the runresults of its active runs as timed-out, and reset those runs so // they become available again for different clients in GetrunAction. $rows = $db->getRows(str_queryf("SELECT\n\t\t\t\trunresults.id as id\n\t\t\tFROM\n\t\t\t\trunresults\n\t\t\tINNER JOIN clients ON runresults.client_id = clients.id\n\t\t\tWHERE runresults.status = 1\n\t\t\tAND clients.updated < %s;", swarmdb_dateformat(Client::getMaxAge($context)))); if ($rows) { foreach ($rows as $row) { // Reset the run $ret = $db->query(str_queryf("UPDATE run_useragent\n\t\t\t\t\tSET\n\t\t\t\t\t\tstatus = 0,\n\t\t\t\t\t\tresults_id = NULL\n\t\t\t\t\tWHERE results_id = %u;", $row->id)); // If the previous UPDATE query failed for whatever // reason, don't do the below query as that will lead // to data corruption (results with state LOST must never // be referenced from run_useragent.results_id). if ($ret) { // Update status of the result $ret = $db->query(str_queryf("UPDATE runresults\n\t\t\t\t\t\tSET status = %s\n\t\t\t\t\t\tWHERE id = %u;", ResultAction::$STATE_LOST, $row->id)); } if ($ret) { $resetTimedoutRuns++; } } } $this->setData(array("resetTimedoutRuns" => $resetTimedoutRuns)); }
/** * @actionMethod POST: Required. * @actionParam username string * @actionParam password string */ public function doAction() { $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); // Already logged in ? if ($request->getSessionData("username") && $request->getSessionData("auth") == "yes") { $username = $request->getSessionData("username"); // Try logging in } else { if (!$request->wasPosted()) { $this->setError("requires-post"); return; } $username = $request->getVal("username"); $password = $request->getVal("password"); if (!$username || !$password) { $this->setError("missing-parameters"); return; } $res = $db->query(str_queryf("SELECT id\n\t\t\t\tFROM users\n\t\t\t\tWHERE\tname = %s\n\t\t\t\tAND \tpassword = SHA1(CONCAT(seed, %s))\n\t\t\t\tLIMIT 1;", $username, $password)); if ($res && $db->getNumRows($res) > 0) { // Start logged-in session $request->setSessionData("username", $username); $request->setSessionData("auth", "yes"); } else { $this->setError("invalid-input"); return; } } // We're still here, logged-in succeeded! $this->setData(array("status" => "logged-in", "username" => $username)); return; }
/** * Enforce user authentication. Centralized logic. * @param string|int $user [optional] Additionally, verify that the * user is of a certain ID or username. * @return false|int: user id */ protected final function doRequireAuth($user = null) { $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); if (!$request->wasPosted()) { $this->setError('requires-post'); return false; } $authUsername = $request->getVal('authUsername'); $authToken = $request->getVal('authToken'); if (!$authUsername || !$authToken) { $this->setError('missing-parameters'); return false; } if (is_string($user) && $user !== $authUsername) { $this->setError('unauthorized'); return false; } // Check authentication $userRow = $db->getRow(str_queryf('SELECT id FROM users WHERE name = %s AND auth = %s;', $authUsername, $authToken)); if (!$userRow) { $this->setError('unauthorized'); return false; } $userId = (int) $userRow->id; if (is_int($user) && $user !== $userId) { $this->setError('unauthorized'); return false; } return $userId; }
protected function loadNew() { $browserInfo = $this->context->getBrowserInfo(); $db = $this->context->getDB(); $request = $this->context->getRequest(); // If the useragent isn't known, abort with an error message if (!$browserInfo->isInSwarmUaIndex()) { throw new SwarmException('Your browser is not needed by this swarm.'); } $clientName = $request->getVal('item', 'anonymous'); if (!$clientName) { // The UI javascript injects a default value and if the field is missing // the above WebRequest#getVal fallback catches it. But if the field // was submitted with an empty string, then just ignore it and go to anonymous as well. // We don't want to hold back potential swarm joiners. $clientName = 'anonymous'; } if (!self::isValidName($clientName)) { throw new SwarmException('Invalid client name. Names should be no longer than 128 characters.'); } // Insert in a new record for the client and get its ID $db->query(str_queryf('INSERT INTO clients (name, useragent_id, useragent, ip, updated, created) VALUES(%s, %s, %s, %s, %s, %s);', $clientName, $browserInfo->getSwarmUaID(), $browserInfo->getRawUA(), $request->getIP(), swarmdb_dateformat(SWARM_NOW), swarmdb_dateformat(SWARM_NOW))); $this->clientRow = $db->getRow(str_queryf('SELECT * FROM clients WHERE id = %u LIMIT 1;', $db->getInsertId())); }
protected function loadNew() { $browserInfo = $this->context->getBrowserInfo(); $db = $this->context->getDB(); $request = $this->context->getRequest(); // If the useragent isn't known, abort with an error message if (!$browserInfo->isInSwarmUaIndex()) { throw new SwarmException("Your browser is not suported in this TestSwarm " . "(useragent string: {$browserInfo->getRawUA()})."); } // Running a client doesn't require being logged in $username = $request->getSessionData("username", $request->getVal("item")); if (!$username) { throw new SwarmException("Username required."); } // Figure out what the user's ID number is $userRow = $db->getRow(str_queryf("SELECT * FROM users WHERE name = %s LIMIT 1;", $username)); // If the user doesn't have one, create a new user row for this name if (!$userRow || !$userRow->id) { $db->query(str_queryf("INSERT INTO users (name, updated, created) VALUES(%s, %s, %s);", $username, swarmdb_dateformat(SWARM_NOW), swarmdb_dateformat(SWARM_NOW))); $userRow = $db->getRow(str_queryf("SELECT * FROM users WHERE id = %u LIMIT 1;", $db->getInsertId())); } // Insert in a new record for the client and get its ID $db->query(str_queryf("INSERT INTO clients (user_id, useragent_id, useragent, ip, updated, created)\n\t\t\tVALUES(%u, %s, %s, %s, %s, %s);", $userRow->id, $browserInfo->getSwarmUaID(), $browserInfo->getRawUA(), $request->getIP(), swarmdb_dateformat(SWARM_NOW), swarmdb_dateformat(SWARM_NOW))); $this->clientRow = $db->getRow(str_queryf("SELECT * FROM clients WHERE id = %u LIMIT 1;", $db->getInsertId())); $this->userRow = $userRow; }
/** * Update client 'alive' and refresh client config. * * @actionMethod POST: Required. * @actionParam run_token string * @actionParam client_id int */ public function doAction() { $conf = $this->getContext()->getConf(); $request = $this->getContext()->getRequest(); if (!$request->wasPosted()) { $this->setError('requires-post'); return; } $runToken = $request->getVal('run_token'); if ($conf->client->requireRunToken && !$runToken) { $this->setError('missing-parameters', 'This TestSwarm does not allow unauthorized clients to join the swarm.'); return; } $clientID = $request->getInt('client_id'); if (!$clientID) { $this->setError('missing-parameters'); return; } // Create a Client object that verifies client id, user agent and run token. // Also updates the client 'alive' timestamp. // Throws exception (caught higher up) if stuff is invalid. $client = Client::newFromContext($this->getContext(), $runToken, $clientID); $db = $this->getContext()->getDB(); $device_name = $db->getOne(str_queryf("SELECT device_name FROM clients WHERE id = %u;", $clientID)); if (!isset($device_name)) { $device_name = 'Testswarm ID = ' . $clientID; } $this->setData(array('status' => 'ok', 'confUpdate' => array('client' => $conf->client, 'deviceName' => $device_name))); }
public function execute() { $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); $this->setRobots("noindex,nofollow"); $runID = $request->getInt("run_id"); $clientID = $request->getInt("client_id"); if ($runID && $clientID) { $row = $db->getRow(str_queryf("SELECT\n\t\t\t\t\tresults\n\t\t\t\tFROM\n\t\t\t\t\trun_client\n\t\t\t\tWHERE run_id = %u\n\t\t\t\tAND client_id = %u;", $runID, $clientID)); if ($row) { if ($row->results) { header("Content-Type: text/html; charset=utf-8"); header("Content-Encoding: gzip"); echo $row->results; // Prevent Page from building exit; } else { // The row exists but there are no results yet $this->runClientFound = true; } } } // We're still here, continue building the page, parent::execute(); }
protected function execute() { $db = $this->getContext()->getDB(); $corrupt = 0; $this->out("Scanning..."); $resultRows = $db->getRows('SELECT id FROM runresults WHERE status=4;'); if ($resultRows) { foreach ($resultRows as $resultRow) { $runRow = $db->getOne(str_queryf('SELECT 1 FROM run_useragent WHERE results_id=%u;', $resultRow->id)); if ($runRow) { $corrupt++; $this->outRaw("Result #{$resultRow->id}"); // See also CleanupAction::doAction $executed = $db->query(str_queryf("UPDATE run_useragent\n\t\t\t\t\t\tSET\n\t\t\t\t\t\t\tstatus = 0,\n\t\t\t\t\t\t\tresults_id = NULL\n\t\t\t\t\t\tWHERE results_id = %u;", $resultRow->id)); if ($executed) { $this->outRaw(" ... Fixed!\n"); } else { $this->outRaw(" ... Failed!\n"); } $this->out("..."); } } } $this->out("Found {$corrupt} instances of corrupted data."); }
/** * @actionMethod POST: Required. * @actionParam client_id int * @actionParam run_token string * @actionParam run_id int * @actionParam fail int * @actionParam error int * @actionParam total int * @actionParam results string: HTML snapshot of the test results page. */ public function doAction() { $browserInfo = $this->getContext()->getBrowserInfo(); $conf = $this->getContext()->getConf(); $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); if (!$request->wasPosted()) { $this->setError("requires-post"); return; } $runToken = $request->getVal("run_token"); if ($conf->client->requireRunToken && !$runToken) { $this->setError("invalid-input", "This TestSwarm does not allow unauthorized clients to join the swarm."); return; } $clientID = $request->getInt("client_id"); if (!$clientID) { $this->setError("invalid-input"); return; } // Create a Client object that verifies client id, user agent and run token. // Also updates the client 'alive' timestamp. // Throws exception (caught higher up) if stuff is invalid. $client = Client::newFromContext($this->getContext(), $runToken, $clientID); $runID = $request->getInt("run_id"); $fail = $request->getInt("fail"); $error = $request->getInt("error"); $total = $request->getInt("total"); $results = gzencode($request->getVal("results", "")); $db->query(str_queryf("UPDATE\n\t\t\t\trun_client\n\t\t\tSET\n\t\t\t\tstatus = 2,\n\t\t\t\tfail = %u,\n\t\t\t\terror = %u,\n\t\t\t\ttotal = %u,\n\t\t\t\tresults = %s,\n\t\t\t\tupdated = %s\n\t\t\tWHERE client_id = %u\n\t\t\tAND run_id = %u\n\t\t\tLIMIT 1;", $fail, $error, $total, $results, swarmdb_dateformat(SWARM_NOW), $clientID, $runID)); if (mysql_affected_rows() > 0) { // If we're 100% passing we don't need any more runs // Clear out other entries from other browsers for the same run // that were bad, since we now have a good one. if ($total > 0 && $fail === 0 && $error === 0) { $rows = $db->getRows(str_queryf("SELECT client_id\n\t\t\t\t\tFROM\n\t\t\t\t\t\trun_client, clients\n\t\t\t\t\tWHERE run_id = %u\n\t\t\t\t\tAND client_id != %u\n\t\t\t\t\tAND (total <= 0 OR error > 0 OR fail > 0)\n\t\t\t\t\tAND clients.id = client_id\n\t\t\t\t\tAND clients.useragent_id = %s;", $runID, $clientID, $client->getClientRow()->useragent_id)); if ($rows) { foreach ($rows as $row) { $db->query(str_queryf("DELETE\n\t\t\t\t\t\t\tFROM run_client\n\t\t\t\t\t\t\tWHERE run_id = %u\n\t\t\t\t\t\t\tAND client_id = %u;", $runID, $row->client_id)); } } $db->query(str_queryf("UPDATE\n\t\t\t\t\t\trun_useragent\n\t\t\t\t\tSET\n\t\t\t\t\t\truns = max,\n\t\t\t\t\t\tcompleted = completed + 1,\n\t\t\t\t\t\tstatus = 2,\n\t\t\t\t\t\tupdated = %s\n\t\t\t\t\tWHERE useragent_id = %s\n\t\t\t\t\tAND run_id = %u\n\t\t\t\t\tLIMIT 1;", swarmdb_dateformat(SWARM_NOW), $browserInfo->getSwarmUaID(), $runID)); } else { // Clear out old runs that timed out. if ($total > 0) { $rows = $db->getRows(str_queryf("SELECT\n\t\t\t\t\t\t\tclient_id\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\trun_client\n\t\t\t\t\t\tWHERE run_id = %u\n\t\t\t\t\t\tAND client_id != %u\n\t\t\t\t\t\tAND total <= 0;", $runID, $clientID)); if ($rows) { foreach ($rows as $row) { $db->query(str_queryf("DELETE\n\t\t\t\t\t\t\t\tFROM run_client\n\t\t\t\t\t\t\t\tWHERE run_id = %u\n\t\t\t\t\t\t\t\tAND client_id = %u;", $runID, $row->client_id)); } } } $db->query(str_queryf("UPDATE\n\t\t\t\t\t\trun_useragent\n\t\t\t\t\tSET\n\t\t\t\t\t\tcompleted = completed + 1,\n\t\t\t\t\t\tstatus = IF(completed + 1 < max, 1, 2),\n\t\t\t\t\t\tupdated = %s\n\t\t\t\t\tWHERE useragent_id = %s\n\t\t\t\t\tAND run_id = %u\n\t\t\t\t\tLIMIT 1;", swarmdb_dateformat(SWARM_NOW), $browserInfo->getSwarmUaID(), $runID)); } } $this->setData("ok"); }
public function doAction() { $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); $runID = $request->getInt("run_id"); $clientID = $request->getInt("client_id"); $useragentID = $request->getVal("useragent_id"); if (!$runID || !$clientID) { $this->setError("missing-parameters"); return; } $jobID = (int) $db->getOne(str_queryf('SELECT job_id FROM runs WHERE id = %u;', $runID)); if (!$jobID) { $this->setError("invalid-input", "Run {$runID} not found."); return; } $jobOwner = $db->getOne(str_queryf('SELECT users.name as user_name FROM jobs, users WHERE jobs.id = %u AND users.id = jobs.user_id LIMIT 1;', $jobID)); if (!$jobOwner) { $this->setError("invalid-input", "Job {$jobID} not found."); return; } // Check authentication $userId = $this->doRequireAuth($jobOwner); if (!$userId) { return; } $runJobID = (int) $db->getOne(str_queryf('SELECT job_id FROM runs WHERE id = %u;', $runID)); if ($runJobID !== $jobID) { $this->setError("invalid-input", "Run {$runID} does not belong to job {$jobID}."); return; } $clientUseragentID = $db->getOne(str_queryf('SELECT useragent_id FROM clients WHERE id = %u;', $clientID)); if ($clientUseragentID !== $useragentID) { $this->setError("invalid-input", "Client {$clientID} does not run useragent {$useragentID}"); return; } $db->query(str_queryf('UPDATE run_useragent SET status = 0, completed = 0, results_id = NULL, updated = %s WHERE run_id = %u AND useragent_id = %s;', swarmdb_dateformat(SWARM_NOW), $runID, $useragentID)); $this->setData(array("jobID" => $jobID, "runID" => $runID, "clientID" => $clientID, "useragentID" => $useragentID, "result" => "ok")); }
public static function getLogoutFormFieldsHtml(TestSwarmContext $context) { $db = $context->getDB(); $request = $context->getRequest(); $userName = $request->getSessionData('username'); $userAuthToken = $db->getOne(str_queryf('SELECT auth FROM users WHERE name = %s', $userName)); return '<input type="hidden" name="authUsername" value="' . htmlspecialchars($userName) . '">' . '<input type="hidden" name="authToken" value="' . htmlspecialchars($userAuthToken) . '">'; }
/** * @actionMethod POST: Required. * @actionParam int job_id * @actionParam string type: one of 'delete', 'reset' */ public function doAction() { $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); if (!$request->wasPosted()) { $this->setError("requires-post"); return; } $jobID = $request->getInt("job_id"); $wipeType = $request->getVal("type"); if (!$jobID || !$wipeType) { $this->setError("missing-parameters"); return; } if (!in_array($wipeType, array("delete", "reset", "cancel"))) { $this->setError("invalid-input"); return; } $jobOwner = $db->getOne(str_queryf("SELECT\n\t\t\t\tusers.name as user_name\n\t\t\tFROM jobs, users\n\t\t\tWHERE jobs.id = %u\n\t\t\tAND users.id = jobs.user_id\n\t\t\tLIMIT 1;", $jobID)); if (!$jobOwner) { // Job row by this ID didn't exist $this->setError("invalid-input"); return; } // Check authentication if ($request->getSessionData("auth") !== "yes" || $request->getSessionData("username") !== $jobOwner) { $this->setError("requires-auth"); return; } $runRows = $db->getRows(str_queryf("SELECT id\n\t\t\tFROM runs\n\t\t\tWHERE job_id = %u;", $jobID)); if ($runRows) { foreach ($runRows as $runRow) { switch ($wipeType) { case "delete": $db->query(str_queryf("DELETE\n\t\t\t\t\t\t\tFROM run_useragent\n\t\t\t\t\t\t\tWHERE run_id = %u;", $runRow->id)); break; case "reset": $db->query(str_queryf("UPDATE run_useragent\n\t\t\t\t\t\t\tSET\n\t\t\t\t\t\t\t\tstatus = 0,\n\t\t\t\t\t\t\t\tcompleted = 0,\n\t\t\t\t\t\t\t\tresults_id = NULL,\n\t\t\t\t\t\t\t\tupdated = %s\n\t\t\t\t\t\t\tWHERE run_id = %u;", swarmdb_dateformat(SWARM_NOW), $runRow->id)); break; case "cancel": $db->query(str_queryf("UPDATE run_useragent\n\t\t\t\t\t\t\tSET\n\t\t\t\t\t\t\t\tstatus = 3,\n\t\t\t\t\t\t\t\tupdated = %s\n\t\t\t\t\t\t\tWHERE run_id = %u \n\t\t\t\t\t\t\t\tAND status = 0;", swarmdb_dateformat(SWARM_NOW), $runRow->id)); break; } } } // This should be outside the if for $runRows, because jobs // can sometimes be created without any runs (by accidently). // Those should be deletable as well, thus this has to be outside the loop. // Also, no need to do this in a loop, just delete them all in one query. if ($wipeType === "delete") { $db->query(str_queryf("DELETE\n\t\t\t\tFROM runs\n\t\t\t\tWHERE job_id = %u;", $jobID)); $db->query(str_queryf("DELETE\n\t\t\t\tFROM jobs\n\t\t\t\tWHERE id = %u;", $jobID)); } $this->setData(array("jobID" => $jobID, "type" => $wipeType, "result" => "ok")); }
/** * @actionParam string sort: [optional] What to sort the results by. * Must be one of "title", "id" or "creation". Defaults to "title". * @actionParam string sort_dir: [optional] * Must be one of "asc" (ascending) or "desc" (decending). Defaults to "asc". */ public function doAction() { $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); $sortField = $request->getVal('sort', 'title'); $sortDir = $request->getVal('sort_dir', 'asc'); if (!in_array($sortField, array('title', 'id', 'creation'))) { $this->setError('invalid-input', "Unknown sort `{$sortField}`."); return; } if (!in_array($sortDir, array('asc', 'desc'))) { $this->setError('invalid-input', "Unknown sort direction `{$sortDir}`."); return; } $sortDirQuery = ''; switch ($sortDir) { case 'asc': $sortDirQuery = 'ASC'; break; case 'desc': $sortDirQuery = 'DESC'; break; } $sortFieldQuery = ''; switch ($sortField) { case 'title': $sortFieldQuery = "ORDER BY display_title {$sortDirQuery}"; break; case 'id': $sortFieldQuery = "ORDER BY id {$sortDirQuery}"; break; case 'creation': $sortFieldQuery = "ORDER BY created {$sortDirQuery}"; break; } $projects = array(); $projectRows = $db->getRows("SELECT\n\t\t\t\tid,\n\t\t\t\tdisplay_title,\n\t\t\t\tcreated\n\t\t\tFROM projects\n\t\t\t{$sortFieldQuery};"); if ($projectRows) { foreach ($projectRows as $projectRow) { // Get information about the latest job (if any) $jobRow = $db->getRow(str_queryf('SELECT id FROM jobs WHERE project_id = %s ORDER BY id DESC LIMIT 1;', $projectRow->id)); if (!$jobRow) { $job = false; } else { $jobAction = JobAction::newFromContext($this->getContext()->createDerivedRequestContext(array('item' => $jobRow->id))); $jobAction->doAction(); $job = $jobAction->getData(); } $project = array('id' => $projectRow->id, 'displayTitle' => $projectRow->display_title, 'job' => $job); self::addTimestampsTo($project, $projectRow->created, 'created'); $projects[] = $project; } } $this->setData($projects); }
/** * @actionMethod POST: Required. * @actionParam string jobName: May contain HTML. * @actionParam int runMax * @actionParam array runNames * @actionParam array runUrls * @actionParam array browserSets * @actionAuth: Required. */ public function doAction() { $conf = $this->getContext()->getConf(); $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); $projectID = $this->doRequireAuth(); if (!$projectID) { return; } $jobId = $request->getInt("job_id"); $testName = $request->getVal("test_name"); $uaId = $request->getVal("ua_id"); $db->query(str_queryf("LOCK TABLES runs WRITE;")); $runId = $db->getOne(str_queryf('SELECT id FROM runs WHERE job_id = %u AND name = %s ORDER BY id DESC LIMIT 1;', $jobId, $testName)); if (!$runId) { // Create this run $isInserted = $db->query(str_queryf("INSERT INTO runs (job_id, name, url, created)\n VALUES(%u, %s, %s, %s);", $jobId, $testName, "http://localhost", swarmdb_dateformat(SWARM_NOW))); $runId = $db->getInsertId(); } $db->query(str_queryf("UNLOCK TABLES;")); if (!$runId) { $this->setError("internal-error", "Could not get or create run id"); return; } $db->query(str_queryf("LOCK TABLES clients WRITE;")); $clientId = $db->getOne(str_queryf('SELECT id FROM clients WHERE useragent_id = %s LIMIT 1;', $uaId)); if (!$clientId) { $isNew = true; $isInserted = $db->query(str_queryf("INSERT INTO clients (name, useragent_id, useragent, ip, updated, created)\n VALUES(%s, %s, %s, %s, %s, %s);", $uaId, $uaId, "SauceLabs", "123.456.789.000", swarmdb_dateformat(SWARM_NOW), swarmdb_dateformat(SWARM_NOW))); $clientId = $db->getInsertId(); } $db->query(str_queryf("UNLOCK TABLES;")); $resultInserted = $db->query(str_queryf('INSERT INTO runresults (run_id, client_id, status, store_token, updated, created) VALUES(%u, %u, 1, %s, %s, %s);', $runId, $clientId, 0, swarmdb_dateformat(SWARM_NOW), swarmdb_dateformat(SWARM_NOW))); $runresultsId = $db->getInsertId(); $isInserted = $db->query(str_queryf("INSERT INTO run_useragent (run_id, useragent_id, max, results_id, updated, created)\n VALUES(%u, %s, %u, %u, %s, %s);", $runId, $uaId, 1, $runresultsId, swarmdb_dateformat(SWARM_NOW), swarmdb_dateformat(SWARM_NOW))); $newRunUAId = $db->getInsertId(); $this->setData(array("resultsId" => $runresultsId, "runUAId" => $newRunUAId)); }
/** * @requestParam browserSet string: Show useragents from a specific * browserset only. * @requestParam onlyactive bool: If true, only user agents that * have online clients and/or pending runs are included. * If both "browserSet" and "onlyactive" are used, the overlaping * subset will be output. */ public function doAction() { $conf = $this->getContext()->getConf(); $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); $showOnlyactive = $request->getBool('onlyactive'); $filterBrowserSet = $request->getVal('browserSet', false); $data = array('userAgents' => array()); $uaIndex = BrowserInfo::getSwarmUAIndex(); foreach ($uaIndex as $uaID => $uaData) { if ($filterBrowserSet && isset($conf->browserSets->{$filterBrowserSet}) && !in_array($uaID, $conf->browserSets->{$filterBrowserSet})) { continue; } // Count online clients with this UA $clients = $db->getOne(str_queryf('SELECT COUNT(id) FROM clients WHERE useragent_id = %s AND updated > %s', $uaID, swarmdb_dateformat(time() - ($conf->client->pingTime + $conf->client->pingTimeMargin)))); $clients = intval($clients); // Count active runs for this UA $activeRuns = $db->getOne(str_queryf('SELECT COUNT(*) FROM run_useragent WHERE useragent_id = %s AND status = 1;', $uaID)); $activeRuns = intval($activeRuns); // Count pending runs for this UA $pendingRuns = $db->getOne(str_queryf('SELECT COUNT(*) FROM run_useragent WHERE useragent_id = %s AND status = 0 AND completed = 0;', $uaID)); $pendingRuns = intval($pendingRuns); // Count past runs that can still be re-run to // possibly fix non-passing results $pendingReRuns = $db->getOne(str_queryf('SELECT COUNT(*) FROM run_useragent WHERE useragent_id = %s AND status = 0 AND completed > 0;', $uaID)); $pendingReRuns = intval($pendingReRuns); if ($showOnlyactive && !$clients && !$activeRuns && !$pendingRuns && !$pendingReRuns) { continue; } $data['userAgents'][$uaID] = array('data' => $uaData, 'stats' => array('onlineClients' => $clients, 'activeRuns' => $activeRuns, 'pendingRuns' => $pendingRuns, 'pendingReRuns' => $pendingReRuns)); } $this->setData($data); }
/** * @requestParam sort string: [optional] What to sort the results by. * Must be one of "name", "id", "creation" or "jobcount". Defaults to "name". * @requestParam sort_order string: [optional] * Must be one of "asc" (ascending" or "desc" (decending). Defaults to "asc". */ public function doAction() { $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); $filterSort = $request->getVal('sort', 'name'); $filterSortOrder = $request->getVal('sort_order', 'asc'); if (!in_array($filterSort, array('name', 'id', 'creation', 'jobcount'))) { $this->setError('invalid-input', "Unknown sort `{$filterSort}`."); return; } if (!in_array($filterSortOrder, array('asc', 'desc'))) { $this->setError('invalid-input', "Unknown sort order `{$filterSortOrder}`."); return; } $filterSortOrderQuery = ''; switch ($filterSortOrder) { case 'asc': $filterSortOrderQuery = 'ASC'; break; case 'desc': $filterSortOrderQuery = 'DESC'; break; } $filterSortQuery = ''; switch ($filterSort) { case 'name': $filterSortQuery = "ORDER BY users.name {$filterSortOrderQuery}"; break; case 'id': $filterSortQuery = "ORDER BY users.id {$filterSortOrderQuery}"; break; case 'creation': $filterSortQuery = "ORDER BY users.created {$filterSortOrderQuery}"; break; case 'jobcount': $filterSortQuery = "ORDER BY job_count {$filterSortOrderQuery}"; break; } $projects = array(); $projectRows = $db->getRows("SELECT\n\t\t\t\tDISTINCT(jobs.user_id) as user_id,\n\t\t\t\tusers.name as user_name,\n\t\t\t\tusers.created as user_created,\n\t\t\t\tCOUNT(jobs.id) as job_count,\n\t\t\t\tMAX(jobs.id) as job_latest\n\t\t\tFROM jobs, users\n\t\t\tWHERE users.id = jobs.user_id\n\t\t\tGROUP BY jobs.user_id\n\t\t\t{$filterSortQuery};"); if ($projectRows) { foreach ($projectRows as $projectRow) { $project = array('id' => intval($projectRow->user_id), 'name' => $projectRow->user_name, 'jobCount' => intval($projectRow->job_count), 'jobLatest' => intval($projectRow->job_latest)); $job_latest_created = $db->getOne(str_queryf('SELECT created FROM jobs WHERE id=%u;', $projectRow->job_latest)); self::addTimestampsTo($project, $projectRow->user_created, 'created'); self::addTimestampsTo($project, $job_latest_created, 'jobLatestCreated'); $projects[] = $project; } } $this->setData($projects); }
/** * @requestParam "item" integer: job id * @requestParam "type" string: one of 'delete', 'reset' */ public function doAction() { $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); if (!$request->wasPosted()) { $this->setError("requires-post"); return; } $jobID = $request->getInt("job_id"); $wipeType = $request->getVal("type"); if (!$jobID || !$wipeType) { $this->setError("missing-parameters"); return; } if (!in_array($wipeType, array("delete", "reset"))) { $this->setError("invalid-input"); return; } $jobOwner = $db->getOne(str_queryf("SELECT\n\t\t\t\tusers.name as user_name\n\t\t\tFROM jobs, users\n\t\t\tWHERE jobs.id = %u\n\t\t\tAND users.id = jobs.user_id\n\t\t\tLIMIT 1;", $jobID)); if (!$jobOwner) { // Job row by this ID didn't exist $this->setError("invalid-input"); return; } // Check authentication if ($request->getSessionData("auth") !== "yes" || $request->getSessionData("username") !== $jobOwner) { $this->setError("requires-auth"); return; } $runRows = $db->getRows(str_queryf("SELECT\n\t\t\t\tid\n\t\t\tFROM\n\t\t\t\truns\n\t\t\tWHERE runs.job_id = %u;", $jobID)); // Put this outside the if for runRows, // otherwise bogus jobs with 0 runs can't be deleted if ($wipeType === "delete") { $db->query(str_queryf("DELETE\n\t\t\t\tFROM run_client\n\t\t\t\tWHERE run_id in (\n\t\t\t\t\tSELECT id\n\t\t\t\t\tFROM runs\n\t\t\t\t\tWHERE job_id = %u\n\t\t\t\t);", $jobID)); $db->query(str_queryf("DELETE\n\t\t\t\tFROM run_useragent\n\t\t\t\tWHERE run_id in (\n\t\t\t\t\tSELECT id\n\t\t\t\t\tFROM runs\n\t\t\t\t\tWHERE job_id = %u\n\t\t\t\t);", $jobID)); $db->query(str_queryf("DELETE\n\t\t\t\tFROM runs\n\t\t\t\tWHERE job_id = %u;", $jobID)); $db->query(str_queryf("DELETE\n\t\t\t\tFROM jobs\n\t\t\t\tWHERE id = %u;", $jobID)); } if ($runRows) { foreach ($runRows as $runRow) { $db->query(str_queryf("DELETE\n\t\t\t\t\tFROM run_client\n\t\t\t\t\tWHERE run_id = %u;", $runRow->id)); if ($wipeType === "delete") { $db->query(str_queryf("DELETE\n\t\t\t\t\t\tFROM run_useragent\n\t\t\t\t\t\tWHERE run_id = %u;", $runRow->id)); } elseif ($wipeType === "reset") { $db->query(str_queryf("UPDATE run_useragent\n\t\t\t\t\t\tSET\n\t\t\t\t\t\t\truns = 0,\n\t\t\t\t\t\t\tcompleted = 0,\n\t\t\t\t\t\t\tstatus = 0,\n\t\t\t\t\t\t\tupdated = %s\n\t\t\t\t\t\tWHERE run_id = %u;", swarmdb_dateformat(SWARM_NOW), $runRow->id)); } } } $this->setData(array("jobID" => $jobID, "type" => $wipeType, "result" => "ok")); }
/** * @actionMethod POST: Required. * @actionParam string jobName: May contain HTML. * @actionParam int runMax * @actionParam array runNames * @actionParam array runUrls * @actionParam array browserSets * @actionAuth: Required. */ public function doAction() { $conf = $this->getContext()->getConf(); $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); $projectID = $this->doRequireAuth(); if (!$projectID) { return; } $jobId = $request->getInt("job_id"); $testName = $request->getVal("test_name"); $uaId = $request->getVal("ua_id"); $total = $request->getVal("total"); $fail = $request->getInt("fail"); $numRetries = $request->getInt("num_retries"); $resultUrl = $request->getVal("result_url"); $buildUrl = $request->getVal("build_url"); $runId = $db->getOne(str_queryf('SELECT id FROM runs WHERE job_id = %u AND name = %s ORDER BY id DESC LIMIT 1;', $jobId, $testName)); if (!$runId) { $this->setError("internal-error", "Could not get run id"); return; } $clientId = $db->getOne(str_queryf('SELECT id FROM clients WHERE useragent_id = %s LIMIT 1;', $uaId)); if (!$clientId) { $this->setError("internal-error", "Could not get client id"); return; } $resultId = $db->getOne(str_queryf('SELECT id FROM runresults WHERE run_id = %u AND client_id = %u LIMIT 1;', $runId, $clientId)); $ret = $db->query(str_queryf("UPDATE runresults\n SET status = 2, total = %u, fail = %u, num_retries=%u, result_url=%s, build_url=%s\n WHERE id = %u;", $total, $fail, $numRetries, $resultUrl, $buildUrl, $resultId, $row->id)); $this->setData(array("result" => $ret)); }
/** * @actionMethod GET: Required. * @actionParam int run_id * @actionParam string type: one of 'specStart', 'timeoutCheck' */ public function doAction() { $request = $this->getContext()->getRequest(); $runID = $request->getInt("run_id"); $type = $request->getVal("type"); if (!$runID || !$type) { $this->setError("missing-parameters"); return; } if (!in_array($type, array("specStart", "timeoutCheck"))) { $this->setError("invalid-input"); return; } $now = time(); $db = $this->getContext()->getDB(); $result = ""; switch ($type) { case "specStart": if (!$request->wasGetted()) { $this->setError("requires-get"); return; } $beatRate = $request->getInt("beatRate"); $fail = $request->getInt("fail"); $error = $request->getInt("error"); $total = $request->getInt("total"); if (!$beatRate) { $this->setError("missing-parameters"); return; } $expected_update = $now + $beatRate; $db->query(str_queryf("UPDATE runresults\n\t\t\t\t\tSET\n\t\t\t\t\t\tfail = %u,\n\t\t\t\t\t\terror = %u,\n\t\t\t\t\t\ttotal = %u,\n\t\t\t\t\t\texpected_update = %s,\n\t\t\t\t\t\tupdated = %s\n\t\t\t\t\tWHERE run_id = %u\n\t\t\t\t\tAND status = 1\n\t\t\t\t\tAND ( expected_update IS NULL OR expected_update < %u );", $fail, $error, $total, swarmdb_dateformat($expected_update), swarmdb_dateformat($now), $runID, swarmdb_dateformat($expected_update))); $result = "ok"; break; case "timeoutCheck": if (!$request->wasPosted()) { $this->setError("requires-post"); return; } $timeoutMargin = 10; // 10 seconds margin $timestamp = $now + $timeoutMargin; // Check if run is timedout. Null expected_update stands for not timedout. $isTimedout = (bool) $db->getOne(str_queryf("SELECT IF(expected_update IS NULL, false, expected_update > %u)\n\t\t\t\t\tFROM runresults\n\t\t\t\t\tWHERE run_id = %u;", swarmdb_dateformat($timestamp), $runID)); $result = array("testTimedout" => $isTimedout ? 'true' : 'false'); break; } $this->setData($result); }
/** * @actionMethod POST: Required. * @actionParam string projectID * @actionParam string projectPassword */ public function doAction() { $context = $this->getContext(); $db = $context->getDB(); $request = $context->getRequest(); $auth = $context->getAuth(); // Already logged-in if ($auth) { $projectID = $auth->project->id; // Try logging in } else { if (!$request->wasPosted()) { $this->setError("requires-post"); return; } $projectID = $request->getVal('projectID'); $projectPassword = $request->getVal('projectPassword'); if (!$projectID || !$projectPassword) { $this->setError("missing-parameters"); return; } $projectRow = $db->getRow(str_queryf('SELECT id, display_title, site_url, password, auth_token, updated, created FROM projects WHERE id = %s;', $projectID)); if (!$projectRow) { $this->setError("invalid-input"); return; } $passwordHash = $projectRow->password; unset($projectRow->password); if (self::comparePasswords($passwordHash, $projectPassword)) { // Start auth session $request->setSessionData('auth', (object) array('project' => $projectRow, 'sessionToken' => self::generateRandomHash(40))); } else { $this->setError("invalid-input"); return; } } // We're still here, authentication succeeded! $this->setData(array('id' => $projectID)); }
public function doAction() { $db = $this->getContext()->getDB(); $request = $this->getContext()->getRequest(); if (!$request->wasPosted()) { $this->setError("requires-post"); return; } $runID = $request->getInt("run_id"); $clientID = $request->getInt("client_id"); $useragentID = $request->getVal("useragent_id"); if (!$runID || !$clientID) { $this->setError("missing-parameters"); return; } $jobID = (int) $db->getOne(str_queryf("SELECT job_id FROM runs WHERE id = %u;", $runID)); if (!$jobID) { $this->setError("invalid-input", "Run {$runID} not found."); return; } $jobOwner = $db->getOne(str_queryf("SELECT\n\t\t\t\tusers.name as user_name\n\t\t\tFROM jobs, users\n\t\t\tWHERE jobs.id = %u\n\t\t\tAND users.id = jobs.user_id\n\t\t\tLIMIT 1;", $jobID)); if (!$jobOwner) { $this->setError("invalid-input", "Job {$jobID} not found."); return; } // Check authentication if ($request->getSessionData("auth") !== "yes" || $request->getSessionData("username") !== $jobOwner) { $this->setError("requires-auth"); return; } $runJobID = (int) $db->getOne(str_queryf("SELECT job_id\n\t\t\tFROM runs\n\t\t\tWHERE id = %u;", $runID)); if ($runJobID !== $jobID) { $this->setError("invalid-input", "Run {$runID} does not belong to job {$jobID}."); return; } $clientUseragentID = $db->getOne(str_queryf("SELECT useragent_id\n\t\t\tFROM clients\n\t\t\tWHERE id = %u;", $clientID)); if ($clientUseragentID !== $useragentID) { $this->setError("invalid-input", "Client {$clientID} does not run useragent {$useragentID}"); return; } $db->query(str_queryf("UPDATE\n\t\t\t\trun_useragent\n\t\t\tSET\n\t\t\t\tstatus = 0,\n\t\t\t\tcompleted = 0,\n\t\t\t\tresults_id = NULL,\n\t\t\t\tupdated = %s\n\t\t\tWHERE run_id = %u\n\t\t\tAND useragent_id = %s;", swarmdb_dateformat(SWARM_NOW), $runID, $useragentID)); $this->setData(array("jobID" => $jobID, "runID" => $runID, "clientID" => $clientID, "useragentID" => $useragentID, "result" => "ok")); }