public function login(StatTracker $app) { $response = null; if (wp_validate_auth_cookie('', 'logged_in')) { if ($app['session']->get("agent") === null) { $user = wp_get_current_user(); // Allow a plugin to grant/deny this user. See wiki for details $user = apply_filters(ST_USER_AUTH_FILTER, $user); if (!$user instanceof \WP_User) { if (is_string($user)) { $response = AuthResponse::registrationRequired($user); } else { $response = AuthResponse::registrationRequired("Access was denied. Please contact @" . ADMIN_AGENT); } $this->logger->info(sprintf("Registration required for %s", $email_address)); } else { $agent = Agent::lookupAgentName($user->user_email); if (!$agent->isValid()) { $name = apply_filters(ST_AGENT_NAME_FILTER, $user->user_login); $this->logger->info(sprintf("Adding new agent %s", $name)); $agent->name = $name; // Insert them into the DB $stmt = $app->db()->prepare("INSERT INTO Agent (email, agent) VALUES (?, ?) ON DUPLICATE KEY UPDATE agent = ?;"); $stmt->execute(array($user->user_email, $name, $name)); $stmt->closeCursor(); // Generate an API token $this->generateAPIToken($agent); $agent = Agent::lookupAgentName($user->user_email); if (!$agent->isValid()) { $this->logger->error(sprintf("%s still not a valid agent", $agent->name)); return AuthResponse::error("An unrecoverable error has occured"); } } $app['session']->set("agent", $agent); $response = AuthResponse::okay($agent); $this->logger->info(sprintf("%s authenticated successfully", $agent->name)); } } else { $agent = $app['session']->get("agent"); if (Agent::lookupAgentByToken($agent->getToken())->isValid()) { $response = AuthResponse::okay($agent); } else { $this->logger->info(sprintf("Invalid token for %s. Logging out", $agent->name)); return $this->logout($app); } } return $response; } else { $app['session']->set("agent", null); $response = AuthResponse::authenticationRequired($this); } return $response; }
public function __construct() { parent::__construct(); $this['debug'] = filter_var(StatTracker::getConstant("DEBUG", false), FILTER_VALIDATE_BOOLEAN); $this->basedir = dirname($_SERVER['SCRIPT_FILENAME']); $this->logger = new Logger(LOG_DIR, $this['debug'] ? LogLevel::DEBUG : LogLevel::INFO); $this->register(new \Silex\Provider\SessionServiceProvider()); $this->register(new \Silex\Provider\TwigServiceProvider(), array('twig.path' => array($this->basedir . "/views", $this->basedir . "/resources", $this->basedir . "/resources/scripts"))); $this['twig']->addFilter(new \Twig_SimpleFilter('name_sort', function ($array) { usort($array, function ($a, $b) { return strcmp($a->name, $b->name); }); return $array; })); }
<?php require_once "config.php"; require_once "src/autoload.php"; require_once "vendor/autoload.php"; use BlueHerons\StatTracker\Agent; use BlueHerons\StatTracker\OCR; use BlueHerons\StatTracker\StatTracker; use Curl\Curl; use Endroid\QrCode\QrCode; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpKernel\HttpKernelInterface; $StatTracker = new StatTracker(); // Assert that token and stat parameters, if present, match expected format $validateRequest = function (Request $request, Silex\Application $StatTracker) { function validateParameter($param, $regex) { if (strlen($param) > 0) { return preg_match($regex, $param) === 1; } else { return true; } } // Ensure {token} is 6 hexidecimal digits if (!validateParameter($request->get("token"), "/^[a-f0-9]{64}\$/i")) { return $StatTracker->abort(400); } // Ensure {stat} is alpha characters and an underscore if (!validateParameter($request->get("stat"), "/^[a-z_]+\$/")) {
} })->assert('page', '[a-z-]+')->value('page', 'dashboard'); $StatTracker->get('/page/{page}', function (Request $request, $page) use($StatTracker) { $page_parameters = array(); if ($page == "submit-stats") { $date = $request->get("date"); $date = $StatTracker->isValidDate($date) ? $date : null; if ($date == null || new DateTime() < new DateTime($date)) { $StatTracker->getAgent()->getStats("latest", true); $date = date("Y-m-d"); } else { $StatTracker->getAgent()->getStats($date, true); } $page_parameters['date'] = $date; } return $StatTracker['twig']->render($page . ".twig", array("agent" => $StatTracker->getAgent(), "constants" => array("admin_agent" => StatTracker::getConstant("ADMIN_AGENT"), "email_submission" => StatTracker::getConstant("EMAIL_SUBMISSION")), "stats" => $StatTracker->getStats(), "faction_class" => $StatTracker->getAgent()->faction == "R" ? "resistance-agent" : "enlightened-agent", "faction_color" => $StatTracker->getAgent()->faction == "R" ? RES_BLUE : ENL_GREEN, "parameters" => $page_parameters)); }); $StatTracker->get("/resources/{resource_dir}/{resource}", function (Request $request, $resource) use($StatTracker) { switch ($resource) { case "style.css": $file = "./resources/css/style.less"; $lastModified = filemtime($file); $css = new Symfony\Component\HttpFoundation\Response("", 200, array("Content-Type" => "text/css")); $css->setLastModified(new \DateTime("@" . filemtime($file))); if ($css->isNotModified($request)) { $css->setNotModified(); } else { $parser = new Less_Parser(array("compress" => true)); $parser->parseFile($file, $request->getBaseUrl()); $css->setLastModified(new \DateTime("@" . filemtime($file))); $css->setContent($parser->getCss());
/** * Updates the agent's stats. * * @param array $data associative array where key is stat and value is the value for the stat. */ public function updateStats($data, $allow_lower) { // Get lowest submission date $stmt = StatTracker::db()->prepare("SELECT COALESCE(MIN(date), CAST(NOW() AS Date)) `min_date` FROM Data WHERE agent = ?"); try { $stmt->execute(array($this->name)); extract($stmt->fetch()); $ts = date("Y-m-d 00:00:00"); $dt = $data['date'] == null ? date("Y-m-d") : $data['date']; $select_stmt = StatTracker::db()->prepare("SELECT value `current_value` FROM Data WHERE agent = ? AND date = ? AND stat = ?"); $insert_stmt = StatTracker::db()->prepare("INSERT INTO Data (agent, date, timepoint, stat, value) VALUES (?, ?, DATEDIFF(?, ?) + 1, ?, ?) ON DUPLICATE KEY UPDATE value = VALUES(value);"); StatTracker::db()->beginTransaction(); foreach ($data as $stat => $value) { if ($stat == "date") { continue; } $value = filter_var($data[$stat], FILTER_SANITIZE_NUMBER_INT); $value = !is_numeric($value) ? 0 : $value; if ($allow_lower) { $insert_stmt->execute(array($this->name, $dt, $dt, $min_date, $stat, $value)); } else { $select_stmt->execute(array($this->name, $dt, $stat)); extract($select_stmt->fetch()); $select_stmt->closeCursor(); if ($current_value <= $value) { $insert_stmt->execute(array($this->name, $dt, $dt, $min_date, $stat, $value)); } else { StatTracker::db()->rollback(); return sprintf("Stats cannot be updated. %s is lower than %s for %s.", number_format($value), number_format($current_value), StatTracker::getStats()[$stat]->name); } } } StatTracker::db()->commit(); return true; } catch (Exception $e) { throw $e; } finally { $select_stmt->closeCursor(); $insert_stmt->closeCursor(); } }
/** * Generates an authorization code for the given email address. If the email address is not * already in the database, it will be inserted. If it already exists, the authorization code * will be updated. * * @param string $email_address the email address retrieved from authentication * @param bool $newIfExists Whether or not to issue a new auth code if one already exists * * @return void */ private function generateAuthCode($email_address, $newIfExists = false) { $length = 6; $code = md5($email_address); $code = str_shuffle($code); $start = rand(0, strlen($code) - $length - 1); $code = substr($code, $start, $length); $num_rows = 0; if (!$newIfExists) { $stmt = StatTracker::db()->prepare("SELECT agent FROM Agent WHERE email = ?;"); $stmt->execute(array($email_address)); $num_rows = $stmt->rowCount(); $stmt->closeCursor(); } if ($num_rows != 1 || $newIfExists) { try { $stmt = StatTracker::db()->prepare("INSERT INTO Agent (`email`, `auth_code`) VALUES (?, ?) ON DUPLICATE KEY UPDATE auth_code = VALUES(auth_code);"); $stmt->execute(array($email_address, $code)); $stmt->closeCursor(); } catch (PDOException $e) { // Failing to insert an auth code will cause a generic registration email to be sent to the user. error_log($e); } } }
/** * Generates an authorization code for the given email address. If the email address is not * already in the database, it will be inserted. If it already exists, the authorization code * will be updated. * * @param string $email_address the email address retrieved from authentication * @param bool $newIfExists Whether or not to issue a new auth code if one already exists * * @return void */ private function createNewAgent($email_address, $agent_name) { try { $stmt = StatTracker::db()->prepare("INSERT INTO Agent (`email`, `agent`) VALUES (?, ?) ON DUPLICATE KEY UPDATE agent = VALUES(agent);"); $stmt->execute(array($email_address, $agent_name)); $stmt->closeCursor(); } catch (PDOException $e) { // Failing to insert an auth code will cause a generic registration email to be sent to the user. error_log($e); } }