From 61661e7fb7bd4967028e19cf7659e0a8b498d05b Mon Sep 17 00:00:00 2001 From: Bartek Fabiszewski Date: Wed, 23 Jan 2019 12:23:25 +0100 Subject: [PATCH 1/4] initial PDO support --- config.default.php | 3 +- helpers/config.php | 8 +- helpers/db.php | 30 ++++--- helpers/position.php | 144 +++++++++++++++++-------------- helpers/track.php | 98 ++++++++++++--------- helpers/user.php | 80 ++++++++++-------- scripts/setup.php | 197 ++++++++++++++++++++++++++++++++----------- 7 files changed, 348 insertions(+), 212 deletions(-) diff --git a/config.default.php b/config.default.php index 57e33bb..276ea74 100755 --- a/config.default.php +++ b/config.default.php @@ -41,10 +41,9 @@ $init_longitude = 21.01; $gkey = ""; // MySQL config -$dbhost = ""; // mysql host, eg. localhost +$dbdsn = ""; // DSN eg. "mysql:host=localhost;port=3307;dbname=testdb;charset=utf8" $dbuser = ""; // database user $dbpass = ""; // database pass -$dbname = ""; // database name $dbprefix = ""; // optional table names prefix, eg. "ulogger_" // other diff --git a/helpers/config.php b/helpers/config.php index 8df02bc..03aefc6 100644 --- a/helpers/config.php +++ b/helpers/config.php @@ -44,10 +44,9 @@ static $init_longitude = 21.01; // MySQL config - static $dbhost = ""; // mysql host, eg. localhost + static $dbdsn = ""; // database dsn static $dbuser = ""; // database user static $dbpass = ""; // database pass - static $dbname = ""; // database name static $dbprefix = ""; // optional table names prefix, eg. "ulogger_" // require login/password authentication @@ -82,7 +81,7 @@ static $strokeWeight = 2; static $strokeColor = '#ff0000'; static $strokeOpacity = 1; - + private static $fileLoaded = false; private static $initialized = false; @@ -114,10 +113,9 @@ if (isset($ol_layers)) { self::$ol_layers = $ol_layers; } if (isset($init_latitude)) { self::$init_latitude = $init_latitude; } if (isset($init_longitude)) { self::$init_longitude = $init_longitude; } - if (isset($dbhost)) { self::$dbhost = $dbhost; } + if (isset($dbdsn)) { self::$dbdsn = $dbdsn; } if (isset($dbuser)) { self::$dbuser = $dbuser; } if (isset($dbpass)) { self::$dbpass = $dbpass; } - if (isset($dbname)) { self::$dbname = $dbname; } if (isset($dbprefix)) { self::$dbprefix = $dbprefix; } if (isset($require_authentication)) { self::$require_authentication = (bool) $require_authentication; } if (isset($public_tracks)) { self::$public_tracks = (bool) $public_tracks; } diff --git a/helpers/db.php b/helpers/db.php index eb57a03..fff94e3 100644 --- a/helpers/db.php +++ b/helpers/db.php @@ -20,9 +20,9 @@ require_once(ROOT_DIR . "/helpers/config.php"); /** - * mysqli wrapper + * PDO wrapper */ - class uDb extends mysqli { + class uDb extends PDO { /** * Singleton instance * @@ -38,23 +38,25 @@ protected static $tables; /** - * Private constuctor + * PDO constuctor * - * @param string $host + * @param string $dsn * @param string $user * @param string $pass - * @param string $name - * @param int $port - * @param string $socket */ - public function __construct($host, $user, $pass, $name, $port = null, $socket = null) { - @parent::__construct($host, $user, $pass, $name, $port, $socket); - if ($this->connect_error) { + public function __construct($dsn, $user, $pass) { + try { + $options = [ + PDO::ATTR_EMULATE_PREPARES => false, // try to use native prepared statements + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // throw exceptions + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // return assoc array by default + ]; + @parent::__construct($dsn, $user, $pass, $options); + $this->initTables(); + } catch (PDOException $e) { header("HTTP/1.1 503 Service Unavailable"); - die("Database connection error (" . $this->connect_error . ")"); + die("Database connection error (" . $e->getMessage() . ")"); } - $this->set_charset('utf8'); - $this->initTables(); } /** @@ -75,7 +77,7 @@ */ public static function getInstance() { if (!self::$instance) { - self::$instance = new self(uConfig::$dbhost, uConfig::$dbuser, uConfig::$dbpass, uConfig::$dbname); + self::$instance = new self(uConfig::$dbdsn, uConfig::$dbuser, uConfig::$dbpass); } return self::$instance; } diff --git a/helpers/position.php b/helpers/position.php index 0b9ccab..d70fb4d 100644 --- a/helpers/position.php +++ b/helpers/position.php @@ -54,12 +54,17 @@ $query = "SELECT p.id, UNIX_TIMESTAMP(p.time) AS tstamp, p.user_id, p.track_id, p.latitude, p.longitude, p.altitude, p.speed, p.bearing, p.accuracy, p.provider, p.comment, p.image_id, u.login, t.name - FROM `" . self::db()->table('positions') . "` p - LEFT JOIN `" . self::db()->table('users') . "` u ON (p.user_id = u.id) - LEFT JOIN `" . self::db()->table('tracks') . "` t ON (p.track_id = t.id) + FROM " . self::db()->table('positions') . " p + LEFT JOIN " . self::db()->table('users') . " u ON (p.user_id = u.id) + LEFT JOIN " . self::db()->table('tracks') . " t ON (p.track_id = t.id) WHERE id = ? LIMIT 1"; - $params = [ 'i', $positionId ]; - $this->loadWithQuery($query, $params); + $params = [ $positionId ]; + try { + $this->loadWithQuery($query, $params); + } catch (PDOException $e) { + // TODO: handle exception +throw $e; + } } } @@ -99,19 +104,20 @@ if (is_numeric($lat) && is_numeric($lon) && is_numeric($timestamp) && is_numeric($userId) && is_numeric($trackId)) { $track = new uTrack($trackId); if ($track->isValid && $track->userId == $userId) { - $query = "INSERT INTO `" . self::db()->table('positions') . "` - (user_id, track_id, - time, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_id) - VALUES (?, ?, FROM_UNIXTIME(?), ?, ?, ?, ?, ?, ?, ?, ?, ?)"; - $stmt = self::db()->prepare($query); - $stmt->bind_param('iisddddddssi', - $userId, $trackId, - $timestamp, $lat, $lon, $altitude, $speed, $bearing, $accuracy, $provider, $comment, $imageId); - $stmt->execute(); - if (!self::db()->error && !$stmt->errno) { - $positionId = self::db()->insert_id; + try { + $table = self::db()->table('positions'); + $query = "INSERT INTO $table + (user_id, track_id, + time, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_id) + VALUES (?, ?, FROM_UNIXTIME(?), ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + $stmt = self::db()->prepare($query); + $params = [ $userId, $trackId, + $timestamp, $lat, $lon, $altitude, $speed, $bearing, $accuracy, $provider, $comment, $imageId ]; + $stmt->execute($params); + $positionId = self::db()->lastInsertId("${table}_id_seq"); + } catch (PDOException $e) { + // TODO: handle error } - $stmt->close(); } } return $positionId; @@ -129,21 +135,20 @@ if (!empty($userId)) { $args = []; $where = "WHERE user_id = ?"; - $args[0] = "i"; - $args[1] = &$userId; + $args[] = $userId; if (!empty($trackId)) { $where .= " AND track_id = ?"; - $args[0] .= "i"; - $args[2] = &$trackId; + $args[] = $trackId; } - $query = "DELETE FROM `" . self::db()->table('positions') . "` $where"; - $stmt = self::db()->prepare($query); - call_user_func_array([ $stmt, 'bind_param' ], $args); - $stmt->execute(); - if (!self::db()->error && !$stmt->errno) { + try { + $query = "DELETE FROM " . self::db()->table('positions') . " $where"; + $stmt = self::db()->prepare($query); + $stmt->execute($args); $ret = true; + } catch (PDOException $e) { + // TODO: handle exception +throw $e; } - $stmt->close(); } return $ret; } @@ -158,7 +163,7 @@ public static function getLast($userId = NULL) { if (!empty($userId)) { $where = "WHERE p.user_id = ?"; - $params = [ 'i', $userId ]; + $params = [ $userId ]; } else { $where = ""; $params = NULL; @@ -166,13 +171,18 @@ $query = "SELECT p.id, UNIX_TIMESTAMP(p.time) AS tstamp, p.user_id, p.track_id, p.latitude, p.longitude, p.altitude, p.speed, p.bearing, p.accuracy, p.provider, p.comment, p.image_id, u.login, t.name - FROM `" . self::db()->table('positions') . "` p - LEFT JOIN `" . self::db()->table('users') . "` u ON (p.user_id = u.id) - LEFT JOIN `" . self::db()->table('tracks') . "` t ON (p.track_id = t.id) + FROM " . self::db()->table('positions') . " p + LEFT JOIN " . self::db()->table('users') . " u ON (p.user_id = u.id) + LEFT JOIN " . self::db()->table('tracks') . " t ON (p.track_id = t.id) $where ORDER BY p.time DESC, p.id DESC LIMIT 1"; $position = new uPosition(); - $position->loadWithQuery($query, $params); + try { + $position->loadWithQuery($query, $params); + } catch (PDOException $e) { + // TODO: handle exception +throw $e; + } return $position; } @@ -186,10 +196,10 @@ public static function getAll($userId = NULL, $trackId = NULL) { $rules = []; if (!empty($userId)) { - $rules[] = "p.user_id = '" . self::db()->real_escape_string($userId) ."'"; + $rules[] = "p.user_id = " . self::db()->quote($userId); } if (!empty($trackId)) { - $rules[] = "p.track_id = '" . self::db()->real_escape_string($trackId) ."'"; + $rules[] = "p.track_id = " . self::db()->quote($trackId); } if (!empty($rules)) { $where = "WHERE " . implode(" AND ", $rules); @@ -199,20 +209,21 @@ $query = "SELECT p.id, UNIX_TIMESTAMP(p.time) AS tstamp, p.user_id, p.track_id, p.latitude, p.longitude, p.altitude, p.speed, p.bearing, p.accuracy, p.provider, p.comment, p.image_id, u.login, t.name - FROM `" . self::db()->table('positions') . "` p - LEFT JOIN `" . self::db()->table('users') . "` u ON (p.user_id = u.id) - LEFT JOIN `" . self::db()->table('tracks') . "` t ON (p.track_id = t.id) + FROM " . self::db()->table('positions') . " p + LEFT JOIN " . self::db()->table('users') . " u ON (p.user_id = u.id) + LEFT JOIN " . self::db()->table('tracks') . " t ON (p.track_id = t.id) $where ORDER BY p.time, p.id"; - $result = self::db()->query($query); - if ($result === false) { - return false; + try { + $positionsArr = []; + $result = self::db()->query($query); + while ($row = $result->fetch()) { + $positionsArr[] = self::rowToObject($row); + } + } catch (PDOException $e) { + // TODO: handle exception +throw $e; } - $positionsArr = []; - while ($row = $result->fetch_assoc()) { - $positionsArr[] = self::rowToObject($row); - } - $result->close(); return $positionsArr; } @@ -274,27 +285,32 @@ * Fill class properties with database query result * * @param string $query Query - * @param array|null $bindParams Optional array of bind parameters (types, params) + * @param array|null $params Optional array of bind parameters + * @throws PDOException */ - private function loadWithQuery($query, $bindParams = NULL) { + private function loadWithQuery($query, $params = NULL) { $stmt = self::db()->prepare($query); - if (is_array($bindParams)) { - $params = []; - foreach ($bindParams as &$value) { - $params[] =& $value; - } - call_user_func_array([ $stmt, 'bind_param' ], $params); - } - if ($stmt->execute()) { - $stmt->bind_result($this->id, $this->timestamp, $this->userId, $this->trackId, - $this->latitude, $this->longitude, $this->altitude, $this->speed, - $this->bearing, $this->accuracy, $this->provider, - $this->comment, $this->imageId, $this->userLogin, $this->trackName); - if ($stmt->fetch()) { - $this->isValid = true; - } - } - $stmt->close(); + $stmt->execute($params); + + $stmt->bindColumn('id', $this->id); + $stmt->bindColumn('tstamp', $this->timestamp); + $stmt->bindColumn('user_id', $this->userId); + $stmt->bindColumn('track_id', $this->trackId); + $stmt->bindColumn('latitude', $this->latitude); + $stmt->bindColumn('longitude', $this->longitude); + $stmt->bindColumn('altitude', $this->altitude); + $stmt->bindColumn('speed', $this->speed); + $stmt->bindColumn('bearing', $this->bearing); + $stmt->bindColumn('accuracy', $this->accuracy); + $stmt->bindColumn('provider', $this->provider); + $stmt->bindColumn('comment', $this->comment); + $stmt->bindColumn('image_id', $this->imageId); + $stmt->bindColumn('login', $this->userLogin); + $stmt->bindColumn('name', $this->trackName); + + $stmt->fetch(PDO::FETCH_BOUND); + $this->isValid = true; + $stmt = null; } } diff --git a/helpers/track.php b/helpers/track.php index 3cc4fdf..e0064c1 100644 --- a/helpers/track.php +++ b/helpers/track.php @@ -41,15 +41,20 @@ public function __construct($trackId = NULL) { if (!empty($trackId)) { - $query = "SELECT id, user_id, name, comment FROM `" . self::db()->table('tracks') . "` WHERE id = ? LIMIT 1"; - $stmt = self::db()->prepare($query); - $stmt->bind_param('i', $trackId); - $stmt->execute(); - $stmt->bind_result($this->id, $this->userId, $this->name, $this->comment); - if ($stmt->fetch()) { + try { + $query = "SELECT id, user_id, name, comment FROM " . self::db()->table('tracks') . " WHERE id = ? LIMIT 1"; + $stmt = self::db()->prepare($query); + $stmt->execute([$trackId]); + $stmt->bindColumn('id', $this->id); + $stmt->bindColumn('user_id', $this->userId); + $stmt->bindColumn('name', $this->name); + $stmt->bindColumn('comment', $this->comment); + $stmt->fetch(); $this->isValid = true; + } catch (PDOException $e) { + // TODO: handle exception +throw $e; } - $stmt->close(); } } @@ -77,14 +82,17 @@ public static function add($userId, $name, $comment = NULL) { $trackId = false; if (!empty($userId) && !empty($name)) { - $query = "INSERT INTO `" . self::db()->table('tracks') . "` (user_id, name, comment) VALUES (?, ?, ?)"; - $stmt = self::db()->prepare($query); - $stmt->bind_param('iss', $userId, $name, $comment); - $stmt->execute(); - if (!self::db()->error && !$stmt->errno) { - $trackId = self::db()->insert_id; + try { + $table = self::db()->table('tracks'); + $query = "INSERT INTO $table (user_id, name, comment) VALUES (?, ?, ?)"; + $stmt = self::db()->prepare($query); + $params = [ $userId, $name, $comment ]; + $stmt->execute($params); + $trackId = self::db()->lastInsertId("${table}_id_seq"); + } catch (PDOException $e) { + // TODO: handle exception +throw $e; } - $stmt->close(); } return $trackId; } @@ -125,19 +133,20 @@ return false; } // delete track metadata - $query = "DELETE FROM `" . self::db()->table('tracks') . "` WHERE id = ?"; - $stmt = self::db()->prepare($query); - $stmt->bind_param('i', $this->id); - $stmt->execute(); - if (!self::db()->error && !$stmt->errno) { + try { + $query = "DELETE FROM " . self::db()->table('tracks') . " WHERE id = ?"; + $stmt = self::db()->prepare($query); + $stmt->execute([ $this->id ]); $ret = true; $this->id = NULL; $this->userId = NULL; $this->name = NULL; $this->comment = NULL; $this->isValid = false; + } catch (PDOException $e) { + // TODO: handle exception +throw $e; } - $stmt->close(); } return $ret; } @@ -155,16 +164,18 @@ if (is_null($comment)) { $comment = $this->comment; } if ($comment == "") { $comment = NULL; } if ($this->isValid) { - $query = "UPDATE `" . self::db()->table('tracks') . "` SET name = ?, comment = ? WHERE id = ?"; - $stmt = self::db()->prepare($query); - $stmt->bind_param('ssi', $name, $comment, $this->id); - $stmt->execute(); - if (!self::db()->error && !$stmt->errno) { + try { + $query = "UPDATE " . self::db()->table('tracks') . " SET name = ?, comment = ? WHERE id = ?"; + $stmt = self::db()->prepare($query); + $params = [ $name, $comment, $this->id ]; + $stmt->execute($params); $ret = true; $this->name = $name; $this->comment = $comment; + } catch (PDOException $e) { + // TODO: handle exception +throw $e; } - $stmt->close(); } return $ret; } @@ -181,14 +192,15 @@ // remove all positions if (uPosition::deleteAll($userId) === true) { // remove all tracks - $query = "DELETE FROM `" . self::db()->table('tracks') . "` WHERE user_id = ?"; - $stmt = self::db()->prepare($query); - $stmt->bind_param('i', $userId); - $stmt->execute(); - if (!self::db()->error && !$stmt->errno) { + try { + $query = "DELETE FROM " . self::db()->table('tracks') . " WHERE user_id = ?"; + $stmt = self::db()->prepare($query); + $stmt->execute([ $userId ]); $ret = true; + } catch (PDOException $e) { + // TODO: handle exception +throw $e; } - $stmt->close(); } } @@ -203,20 +215,22 @@ */ public static function getAll($userId = NULL) { if (!empty($userId)) { - $where = "WHERE user_id='" . self::db()->real_escape_string($userId) ."'"; + $where = "WHERE user_id=" . self::db()->quote($userId); } else { $where = ""; } - $query = "SELECT id, user_id, name, comment FROM `" . self::db()->table('tracks') . "` $where ORDER BY id DESC"; - $result = self::db()->query($query); - if ($result === false) { - return false; + $query = "SELECT id, user_id, name, comment FROM " . self::db()->table('tracks') . " $where ORDER BY id DESC"; + try { + $result = self::db()->query($query); + $trackArr = []; + while ($row = $result->fetch()) { + $trackArr[] = self::rowToObject($row); + } + } catch (PDOException $e) { + // TODO: handle exception +throw $e; + $trackArr = false; } - $trackArr = []; - while ($row = $result->fetch_assoc()) { - $trackArr[] = self::rowToObject($row); - } - $result->close(); return $trackArr; } diff --git a/helpers/user.php b/helpers/user.php index e8cf1bc..bfce602 100644 --- a/helpers/user.php +++ b/helpers/user.php @@ -43,15 +43,19 @@ */ public function __construct($login = NULL) { if (!empty($login)) { - $sql = "SELECT id, login, password FROM `" . self::db()->table('users') . "` WHERE login = ? LIMIT 1"; - $stmt = self::db()->prepare($sql); - $stmt->bind_param('s', $login); - $stmt->execute(); - $stmt->bind_result($this->id, $this->login, $this->hash); - if ($stmt->fetch()) { + try { + $query = "SELECT id, login, password FROM " . self::db()->table('users') . " WHERE login = ? LIMIT 1"; + $stmt = self::db()->prepare($query); + $stmt->execute([ $login ]); + $stmt->bindColumn('id', $this->id); + $stmt->bindColumn('login', $this->login); + $stmt->bindColumn('password', $this->hash); + $stmt->fetch(); $this->isValid = true; + } catch (PDOException $e) { + // TODO: handle exception +throw $e; } - $stmt->close(); $this->isAdmin = self::isAdmin($this->login); } } @@ -79,14 +83,16 @@ $userid = false; if (!empty($login) && !empty($pass) && self::validPassStrength($pass)) { $hash = password_hash($pass, PASSWORD_DEFAULT); - $sql = "INSERT INTO `" . self::db()->table('users') . "` (login, password) VALUES (?, ?)"; - $stmt = self::db()->prepare($sql); - $stmt->bind_param('ss', $login, $hash); - $stmt->execute(); - if (!self::db()->error && !$stmt->errno) { - $userid = self::db()->insert_id; + $table = self::db()->table('users'); + try { + $query = "INSERT INTO $table (login, password) VALUES (?, ?)"; + $stmt = self::db()->prepare($query); + $stmt->execute([ $login, $hash ]); + $userid = self::db()->lastInsertId("${table}_id_seq"); + } catch (PDOException $e) { + // TODO: handle exception +throw $e; } - $stmt->close(); } return $userid; } @@ -105,19 +111,20 @@ return false; } // remove user - $sql = "DELETE FROM `" . self::db()->table('users') . "` WHERE id = ?"; - $stmt = self::db()->prepare($sql); - $stmt->bind_param('i', $this->id); - $stmt->execute(); - if (!self::db()->error && !$stmt->errno) { + try { + $query = "DELETE FROM " . self::db()->table('users') . " WHERE id = ?"; + $stmt = self::db()->prepare($query); + $stmt->execute([ $this->id ]); $ret = true; $this->id = NULL; $this->login = NULL; $this->hash = NULL; $this->isValid = false; $this->isAdmin = false; + } catch (PDOException $e) { + // TODO: handle exception +throw $e; } - $stmt->close(); } return $ret; } @@ -132,14 +139,15 @@ $ret = false; if (!empty($this->login) && !empty($pass) && self::validPassStrength($pass)) { $hash = password_hash($pass, PASSWORD_DEFAULT); - $sql = "UPDATE `" . self::db()->table('users') . "` SET password = ? WHERE login = ?"; - $stmt = self::db()->prepare($sql); - $stmt->bind_param('ss', $hash, $this->login); - $stmt->execute(); - if (!self::db()->error && !$stmt->errno) { + try { + $query = "UPDATE " . self::db()->table('users') . " SET password = ? WHERE login = ?"; + $stmt = self::db()->prepare($query); + $stmt->execute([ $hash, $this->login ]); $ret = true; + } catch (PDOException $e) { + // TODO: handle exception +throw $e; } - $stmt->close(); } return $ret; } @@ -193,16 +201,18 @@ * @return array|bool Array of uUser users, false on error */ public static function getAll() { - $query = "SELECT id, login, password FROM `" . self::db()->table('users') . "` ORDER BY login"; - $result = self::db()->query($query); - if ($result === false) { - return false; + try { + $query = "SELECT id, login, password FROM " . self::db()->table('users') . " ORDER BY login"; + $result = self::db()->query($query); + $userArr = []; + while ($row = $result->fetch()) { + $userArr[] = self::rowToObject($row); + } + } catch (PDOException $e) { + // TODO: handle exception +throw $e; + $userArr = false; } - $userArr = []; - while ($row = $result->fetch_assoc()) { - $userArr[] = self::rowToObject($row); - } - $result->close(); return $userArr; } diff --git a/scripts/setup.php b/scripts/setup.php index bcd1cb6..708d2c0 100644 --- a/scripts/setup.php +++ b/scripts/setup.php @@ -18,7 +18,7 @@ */ // This script is disabled by default. Change below to true before running. -$enabled = false; +$enabled = true; /* -------------------------------------------- */ @@ -43,70 +43,27 @@ $tUsers = $prefix . "users"; $messages = []; switch ($command) { case "setup": - $queries = []; - // positions - $queries[] = "DROP TABLE IF EXISTS `$tPositions`"; - $queries[] = "CREATE TABLE `$tPositions` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `user_id` int(11) NOT NULL, - `track_id` int(11) NOT NULL, - `latitude` double NOT NULL, - `longitude` double NOT NULL, - `altitude` double DEFAULT NULL, - `speed` double DEFAULT NULL, - `bearing` double DEFAULT NULL, - `accuracy` int(11) DEFAULT NULL, - `provider` varchar(100) DEFAULT NULL, - `comment` varchar(255) DEFAULT NULL, - `image_id` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `index_trip_id` (`track_id`), - KEY `index_user_id` (`user_id`) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; - - // tracks - $queries[] = "DROP TABLE IF EXISTS `$tTracks`"; - $queries[] = "CREATE TABLE `$tTracks` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` int(11) NOT NULL, - `name` varchar(255) DEFAULT NULL, - `comment` varchar(1024) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `user_id` (`user_id`) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; - - // users - $queries[] = "DROP TABLE IF EXISTS `$tUsers`"; - $queries[] = "CREATE TABLE `$tUsers` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `login` varchar(15) CHARACTER SET latin1 NOT NULL, - `password` varchar(255) CHARACTER SET latin1 NOT NULL DEFAULT '', - PRIMARY KEY (`id`), - UNIQUE KEY `login` (`login`) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; $error = false; - mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); try { - $mysqli = new mysqli(uConfig::$dbhost, uConfig::$dbuser, uConfig::$dbpass, uConfig::$dbname); - } catch (mysqli_sql_exception $e ) { + $db = new PDO(uConfig::$dbdsn, uConfig::$dbuser, uConfig::$dbpass); + } catch (PDOException $e ) { $messages[] = "{$langSetup["dbconnectfailed"]}"; $messages[] = sprintf($langSetup["serversaid"], "" . $e->getMessage() . ""); $messages[] = $langSetup["checkdbsettings"]; break; } try { - $mysqli->set_charset('utf8'); + $queries = getQueries($db); foreach ($queries as $query) { - $mysqli->query($query); + $db->query($query); } - } catch (mysqli_sql_exception $e) { + } catch (PDOException $e) { $messages[] = "{$langSetup["dbqueryfailed"]}"; $messages[] = sprintf($langSetup["serversaid"], "" . $e->getMessage() . ""); $error = true; } - $mysqli->close(); + $db = null; if (!$error) { $messages[] = "{$langSetup["dbtablessuccess"]}"; $messages[] = $langSetup["setupuser"]; @@ -169,6 +126,146 @@ switch ($command) { break; } +function getQueries($db) { + $driver = $db->getAttribute(PDO::ATTR_DRIVER_NAME); + $queries = []; + switch($driver) { + case "mysql": + // positions + $queries[] = "DROP TABLE IF EXISTS `$tPositions`"; + $queries[] = "CREATE TABLE `$tPositions` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `user_id` int(11) NOT NULL, + `track_id` int(11) NOT NULL, + `latitude` double NOT NULL, + `longitude` double NOT NULL, + `altitude` double DEFAULT NULL, + `speed` double DEFAULT NULL, + `bearing` double DEFAULT NULL, + `accuracy` int(11) DEFAULT NULL, + `provider` varchar(100) DEFAULT NULL, + `comment` varchar(255) DEFAULT NULL, + `image_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `index_trip_id` (`track_id`), + KEY `index_user_id` (`user_id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; + + // tracks + $queries[] = "DROP TABLE IF EXISTS `$tTracks`"; + $queries[] = "CREATE TABLE `$tTracks` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `user_id` int(11) NOT NULL, + `name` varchar(255) DEFAULT NULL, + `comment` varchar(1024) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `user_id` (`user_id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; + + // users + $queries[] = "DROP TABLE IF EXISTS `$tUsers`"; + $queries[] = "CREATE TABLE `$tUsers` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `login` varchar(15) CHARACTER SET latin1 NOT NULL, + `password` varchar(255) CHARACTER SET latin1 NOT NULL DEFAULT '', + PRIMARY KEY (`id`), + UNIQUE KEY `login` (`login`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; + break; + + case "pgsql": + // positions + $queries[] = "DROP TABLE IF EXISTS $tPositions"; + $queries[] = "CREATE TABLE $tPositions ( + id SERIAL PRIMARY KEY, + time TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, + user_id INT NOT NULL, + track_id INT NOT NULL, + latitude DOUBLE PRECISION NOT NULL, + longitude DOUBLE PRECISION NOT NULL, + altitude DOUBLE PRECISION DEFAULT NULL, + speed DOUBLE PRECISION DEFAULT NULL, + bearing DOUBLE PRECISION DEFAULT NULL, + accuracy INT DEFAULT NULL, + provider VARCHAR(100) DEFAULT NULL, + comment VARCHAR(255) DEFAULT NULL, + image_id INT DEFAULT NULL + )"; + $queries[] = "CREATE INDEX index_trip_id ON $tPositions (track_id)"; + $queries[] = "CREATE INDEX index_user_id ON $tPositions (user_id)"; + + // tracks + $queries[] = "DROP TABLE IF EXISTS $tTracks"; + $queries[] = "CREATE TABLE $tTracks ( + id SERIAL PRIMARY KEY, + user_id INT NOT NULL, + name VARCHAR(255) DEFAULT NULL, + comment VARCHAR(1024) DEFAULT NULL + )"; + $queries[] = "CREATE INDEX user_id ON $tTracks (user_id)"; + + // users + $queries[] = "DROP TABLE IF EXISTS $tUsers"; + $queries[] = "CREATE TABLE $tUsers ( + id SERIAL PRIMARY KEY, + login varchar(15) NOT NULL UNIQUE, + password varchar(255) NOT NULL DEFAULT '' + )"; + break; + + case "sqlite": + + // positions + $queries[] = "DROP TABLE IF EXISTS `$tPositions`"; + $queries[] = "CREATE TABLE `$tPositions` ( + `id` INTEGER NOT NULL , + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `user_id` INTEGER NOT NULL, + `track_id` INTEGER NOT NULL, + `latitude` double NOT NULL, + `longitude` double NOT NULL, + `altitude` double DEFAULT NULL, + `speed` double DEFAULT NULL, + `bearing` double DEFAULT NULL, + `accuracy` INTEGER DEFAULT NULL, + `provider` TEXT DEFAULT NULL, + `comment` TEXT DEFAULT NULL, + `image_id` INTEGER DEFAULT NULL, + PRIMARY KEY (`id`) + )"; + $queries[] = "CREATE INDEX `positions_index_trip_id` ON `$tPositions` (`track_id`)"; + $queries[] = "CREATE INDEX `positions_index_user_id` ON `$tPositions` (`user_id`)"; + + // tracks + $queries[] = "DROP TABLE IF EXISTS `$tTracks`"; + $queries[] = "CREATE TABLE `$tTracks` ( + `id` INTEGER NOT NULL, + `user_id` INTEGER NOT NULL, + `name` TEXT DEFAULT NULL, + `comment` TEXT DEFAULT NULL, + PRIMARY KEY (`id`) + )"; + $queries[] = "CREATE INDEX `tracks_user_id` ON `$tTracks` (`user_id`)"; + + // users + $queries[] = "DROP TABLE IF EXISTS `$tUsers`"; + $queries[] = "CREATE TABLE `$tUsers` ( + `id` INTEGER NOT NULL , + `login` TEXT NOT NULL, + `password` TEXT NOT NULL DEFAULT '', + PRIMARY KEY (`id`) + )"; + $queries[] = "CREATE UNIQUE INDEX `users_login` ON `$tUsers` (`login`)"; + break; + + default: + throw InvalidArgumentException("Driver not supported"); + } + + +} + ?> From 2d701162ce9b26a598cb04a5b876aba6099e133a Mon Sep 17 00:00:00 2001 From: Bartek Fabiszewski Date: Wed, 23 Jan 2019 15:07:37 +0100 Subject: [PATCH 2/4] Fix setup script --- scripts/setup.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/setup.php b/scripts/setup.php index 708d2c0..f874324 100644 --- a/scripts/setup.php +++ b/scripts/setup.php @@ -114,8 +114,8 @@ switch ($command) { $messages[] = "
"; break; } - if (empty(uConfig::$dbname) || empty(uConfig::$dbhost) || empty(uConfig::$dbuser)) { - $messages[] = sprintf($langSetup["nodbsettings"], "\$dbname, \$dbhost, \$dbuser, \$dbpass"); + if (empty(uConfig::$dbdsn) || empty(uConfig::$dbuser)) { + $messages[] = sprintf($langSetup["nodbsettings"], "\$dbdsn, \$dbuser, \$dbpass"); $messages[] = $langSetup["dorestart"]; $messages[] = "
"; break; From 46ee95dbbe919fcc5f0fe426b6690b2eab4da458 Mon Sep 17 00:00:00 2001 From: Bartek Fabiszewski Date: Thu, 24 Jan 2019 19:07:41 +0100 Subject: [PATCH 3/4] Fix Postgresql issues --- .docker/init.sh | 53 +++-- .docker/run.sh | 8 +- .tests/fixtures/fixture_empty.xml | 4 +- .tests/lib/BaseDatabaseTestCase.php | 65 +++++- .tests/lib/UloggerAPITestCase.php | 1 + .tests/lib/UloggerDatabaseTestCase.php | 8 +- .tests/tests/AuthTest.php | 32 +-- .tests/tests/ClientAPITest.php | 2 +- .tests/tests/ImportTest.php | 12 +- .tests/tests/InternalAPITest.php | 46 ++--- .tests/tests/PositionTest.php | 104 +++++----- .tests/tests/TrackTest.php | 55 ++--- Dockerfile | 13 +- client/index.php | 45 ++-- helpers/auth.php | 23 +-- helpers/db.php | 37 ++++ helpers/position.php | 53 +++-- helpers/track.php | 21 +- helpers/user.php | 19 +- helpers/utils.php | 49 +++++ index.php | 11 +- login.php | 2 +- scripts/migrate_from_phptrackme.php | 222 -------------------- scripts/setup.php | 274 ++++++++++++------------- scripts/ulogger.pgsql | 74 +++++++ scripts/ulogger.sql | 106 ++++------ utils/changepass.php | 8 +- utils/export.php | 6 +- utils/getpositions.php | 4 +- utils/gettracks.php | 2 +- utils/handletrack.php | 7 +- utils/handleuser.php | 6 +- utils/import.php | 2 + 33 files changed, 687 insertions(+), 687 deletions(-) delete mode 100644 scripts/migrate_from_phptrackme.php create mode 100644 scripts/ulogger.pgsql diff --git a/.docker/init.sh b/.docker/init.sh index 12f283d..714d920 100644 --- a/.docker/init.sh +++ b/.docker/init.sh @@ -3,24 +3,45 @@ DB_ROOT_PASS=$1 DB_USER_PASS=$2 -mkdir -p /run/mysqld mkdir -p /run/nginx -chown mysql:mysql /run/mysqld chown nginx:nginx /run/nginx -mysql_install_db --user=mysql -mysqld_safe & -mysqladmin --silent --wait=30 ping -mysqladmin -u root password "${DB_ROOT_PASS}" -mysql -u root -p${DB_ROOT_PASS} < /var/www/html/scripts/ulogger.sql -mysql -u root -p${DB_ROOT_PASS} -e "CREATE USER 'ulogger'@'localhost' IDENTIFIED BY '${DB_USER_PASS}'" -mysql -u root -p${DB_ROOT_PASS} -e "GRANT ALL PRIVILEGES ON ulogger.* TO 'ulogger'@'localhost'" -mysql -u root -p${DB_ROOT_PASS} -e "CREATE USER 'ulogger'@'%' IDENTIFIED BY '${DB_USER_PASS}'" -mysql -u root -p${DB_ROOT_PASS} -e "GRANT ALL PRIVILEGES ON ulogger.* TO 'ulogger'@'%'" -mysql -u root -p${DB_ROOT_PASS} -e "INSERT INTO users (login, password) VALUES ('admin', '\$2y\$10\$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq')" ulogger -mysqladmin -u root -p${DB_ROOT_PASS} shutdown - -sed -i "s/^\$dbhost = .*$/\$dbhost = \"localhost\";/" /var/www/html/config.php -sed -i "s/^\$dbname = .*$/\$dbname = \"ulogger\";/" /var/www/html/config.php sed -i "s/^\$dbuser = .*$/\$dbuser = \"ulogger\";/" /var/www/html/config.php sed -i "s/^\$dbpass = .*$/\$dbpass = \"${DB_USER_PASS}\";/" /var/www/html/config.php + +if [ "$ULOGGER_DB_DRIVER" = "pgsql" ]; then + export PGDATA=/data + mkdir -p ${PGDATA} /run/postgresql /etc/postgres + chown postgres:postgres ${PGDATA} /run/postgresql /etc/postgres + su postgres -c "initdb --auth-host=md5 --auth-local=trust --locale=en_US.utf-8 --encoding=utf8" + sed -ri "s/^#(listen_addresses\s*=\s*)\S+/\1'*'/" ${PGDATA}/postgresql.conf + echo "host all all 0.0.0.0/0 md5" >> ${PGDATA}/pg_hba.conf + su postgres -c "pg_ctl -w start" + su postgres -c "psql -c \"ALTER USER postgres WITH PASSWORD '${DB_ROOT_PASS}'\"" + su postgres -c "psql -c \"CREATE USER ulogger WITH PASSWORD '${DB_USER_PASS}'\"" + su postgres -c "createdb -E UTF8 -l en_US.utf-8 -O ulogger ulogger" + su postgres -c "psql -U ulogger < /var/www/html/scripts/ulogger.pgsql" + su postgres -c "psql -c \"GRANT ALL PRIVILEGES ON DATABASE ulogger TO ulogger\"" + su postgres -c "psql -d ulogger -c \"GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO ulogger\"" + su postgres -c "psql -d ulogger -c \"GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO ulogger\"" + su postgres -c "psql -d ulogger -c \"INSERT INTO users (login, password) VALUES ('admin', '\\\$2y\\\$10\\\$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq')\"" + su postgres -c "pg_ctl -w stop" + sed -i "s/^\$dbdsn = .*$/\$dbdsn = \"pgsql:host=localhost;port=5432;dbname=ulogger\";/" /var/www/html/config.php +elif [ "$ULOGGER_DB_DRIVER" = "sqlite" ]; then + sqlite3 /data/ulogger.db < /var/www/html/scripts/ulogger.sqlite +else + mkdir -p /run/mysqld + chown mysql:mysql /run/mysqld + mysql_install_db --user=mysql --datadir=/data + mysqld_safe --datadir=/data & + mysqladmin --silent --wait=30 ping + mysqladmin -u root password "${DB_ROOT_PASS}" + mysql -u root -p${DB_ROOT_PASS} < /var/www/html/scripts/ulogger.sql + mysql -u root -p${DB_ROOT_PASS} -e "CREATE USER 'ulogger'@'localhost' IDENTIFIED BY '${DB_USER_PASS}'" + mysql -u root -p${DB_ROOT_PASS} -e "GRANT ALL PRIVILEGES ON ulogger.* TO 'ulogger'@'localhost'" + mysql -u root -p${DB_ROOT_PASS} -e "CREATE USER 'ulogger'@'%' IDENTIFIED BY '${DB_USER_PASS}'" + mysql -u root -p${DB_ROOT_PASS} -e "GRANT ALL PRIVILEGES ON ulogger.* TO 'ulogger'@'%'" + mysql -u root -p${DB_ROOT_PASS} -e "INSERT INTO users (login, password) VALUES ('admin', '\$2y\$10\$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq')" ulogger + mysqladmin -u root -p${DB_ROOT_PASS} shutdown + sed -i "s/^\$dbdsn = .*$/\$dbdsn = \"mysql:host=localhost;port=3306;dbname=ulogger;charset=utf8\";/" /var/www/html/config.php +fi diff --git a/.docker/run.sh b/.docker/run.sh index b449e49..5dda0fe 100644 --- a/.docker/run.sh +++ b/.docker/run.sh @@ -15,7 +15,11 @@ echo "ulogger configuration" echo "---------------------" grep '^\$' /var/www/html/config.php -# start services -mysqld_safe & +# start services +if [ "$ULOGGER_DB_DRIVER" = "pgsql" ]; then + su postgres -c 'pg_ctl -D /data start' +else + mysqld_safe --datadir=/data & +fi nginx php-fpm7 -F diff --git a/.tests/fixtures/fixture_empty.xml b/.tests/fixtures/fixture_empty.xml index 51c44ba..764cc13 100644 --- a/.tests/fixtures/fixture_empty.xml +++ b/.tests/fixtures/fixture_empty.xml @@ -1,11 +1,11 @@ - + - + diff --git a/.tests/lib/BaseDatabaseTestCase.php b/.tests/lib/BaseDatabaseTestCase.php index 3303998..5d17f5e 100644 --- a/.tests/lib/BaseDatabaseTestCase.php +++ b/.tests/lib/BaseDatabaseTestCase.php @@ -5,6 +5,7 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase static private $pdo = null; private $conn = null; + static private $driver = "mysql"; protected $testUser = "testUser"; protected $testUser2 = "testUser2"; @@ -29,26 +30,31 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase protected $testComment = "test comment"; protected $testImageId = 1; + // Fixes PostgreSQL: "cannot truncate a table referenced in a foreign key constraint" + protected function getSetUpOperation() { + return PHPUnit_Extensions_Database_Operation_Factory::CLEAN_INSERT(TRUE); + } + + public function setUp() { + parent::setUp(); + + } + public static function setUpBeforeClass() { if (file_exists(__DIR__ . '/../.env')) { $dotenv = new Dotenv\Dotenv(__DIR__ . '/..'); $dotenv->load(); - $dotenv->required(['DB_HOST', 'DB_NAME', 'DB_USER', 'DB_PASS']); + $dotenv->required(['DB_DSN', 'DB_USER', 'DB_PASS']); } - $db_host = getenv('DB_HOST'); - $db_name = getenv('DB_NAME'); + $db_dsn = getenv('DB_DSN'); $db_user = getenv('DB_USER'); $db_pass = getenv('DB_PASS'); - $db_port = getenv('DB_PORT') ?: NULL; - $db_dsn = "mysql:dbname={$db_name};host={$db_host}"; - if (!empty($db_port)) { - $db_dsn .= ";port={$db_port}"; - } // pdo connection if (self::$pdo == null) { - self::$pdo = new PDO($db_dsn, $db_user, $db_pass);; + self::$pdo = new PDO($db_dsn, $db_user, $db_pass); + self::$driver = self::$pdo->getAttribute(PDO::ATTR_DRIVER_NAME); } } @@ -75,9 +81,18 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase * @return PHPUnit_Extensions_Database_DataSet_IDataSet */ protected function getDataSet() { + $this->resetSequences(); return $this->createMySQLXMLDataSet(__DIR__ . '/../fixtures/fixture_empty.xml'); } + protected function resetSequences($users = 1, $tracks = 1, $positions = 1) { + if (self::$driver == "pgsql") { + self::$pdo->query("ALTER SEQUENCE users_id_seq RESTART WITH $users"); + self::$pdo->query("ALTER SEQUENCE tracks_id_seq RESTART WITH $tracks"); + self::$pdo->query("ALTER SEQUENCE positions_id_seq RESTART WITH $positions"); + } + } + /** * Insert to database from array * @@ -180,8 +195,38 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase if (is_null($longitude)) { $longitude = $this->testLon; } $query = "INSERT INTO positions (user_id, track_id, time, latitude, longitude) - VALUES ('$userId', '$trackId', FROM_UNIXTIME($timeStamp), '$latitude', '$longitude')"; + VALUES ('$userId', '$trackId', " . $this->from_unixtime($timeStamp) . ", '$latitude', '$longitude')"; return $this->pdoInsertRaw($query); } + + public function unix_timestamp($column) { + switch (self::$driver) { + default: + case "mysql": + return "UNIX_TIMESTAMP($column)"; + break; + case "pgsql": + return "EXTRACT(EPOCH FROM $column)"; + break; + case "sqlite": + return "STRFTIME('%s', $column)"; + break; + } + } + + public function from_unixtime($column) { + switch (self::$driver) { + default: + case "mysql": + return "FROM_UNIXTIME($column)"; + break; + case "pgsql": + return "TO_TIMESTAMP($column)"; + break; + case "sqlite": + return "DATE($column, 'unixepoch')"; + break; + } + } } ?> diff --git a/.tests/lib/UloggerAPITestCase.php b/.tests/lib/UloggerAPITestCase.php index bdc0336..b44c986 100644 --- a/.tests/lib/UloggerAPITestCase.php +++ b/.tests/lib/UloggerAPITestCase.php @@ -26,6 +26,7 @@ class UloggerAPITestCase extends BaseDatabaseTestCase { } protected function getDataSet() { + $this->resetSequences(2); return $this->createMySQLXMLDataSet(__DIR__ . '/../fixtures/fixture_admin.xml'); } diff --git a/.tests/lib/UloggerDatabaseTestCase.php b/.tests/lib/UloggerDatabaseTestCase.php index ae114db..70133e3 100644 --- a/.tests/lib/UloggerDatabaseTestCase.php +++ b/.tests/lib/UloggerDatabaseTestCase.php @@ -14,21 +14,19 @@ class UloggerDatabaseTestCase extends BaseDatabaseTestCase { if (file_exists(__DIR__ . '/../.env')) { $dotenv = new Dotenv\Dotenv(__DIR__ . '/..'); $dotenv->load(); - $dotenv->required(['DB_HOST', 'DB_NAME', 'DB_USER', 'DB_PASS']); + $dotenv->required(['DB_DSN', 'DB_USER', 'DB_PASS']); } - $db_host = getenv('DB_HOST'); - $db_name = getenv('DB_NAME'); + $db_dsn = getenv('DB_DSN'); $db_user = getenv('DB_USER'); $db_pass = getenv('DB_PASS'); - $db_port = getenv('DB_PORT') ?: NULL; // uDb connection if (self::$udb == null) { self::$udb = new ReflectionClass("uDb"); $dbInstance = self::$udb->getProperty('instance'); $dbInstance->setAccessible(true); - $dbInstance->setValue(new uDb($db_host, $db_user, $db_pass, $db_name, $db_port)); + $dbInstance->setValue(new uDb($db_dsn, $db_user, $db_pass)); } } diff --git a/.tests/tests/AuthTest.php b/.tests/tests/AuthTest.php index 9b56d8d..3620bdf 100644 --- a/.tests/tests/AuthTest.php +++ b/.tests/tests/AuthTest.php @@ -8,19 +8,10 @@ require_once(__DIR__ . "/../../helpers/config.php"); class AuthTest extends UloggerDatabaseTestCase { public function setUp() { - $_REQUEST = []; $_SESSION = []; parent::setUp(); } - private function request($user, $pass) { - $request = []; - $request["action"] = "auth"; - $request["user"] = $user; - $request["pass"] = $pass; - return $request; - } - /** * @runInSeparateProcess */ @@ -28,11 +19,9 @@ class AuthTest extends UloggerDatabaseTestCase { $this->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT)); $this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count"); - $_REQUEST = $this->request($this->testUser, $this->testPass); - $auth = new uAuth(); + $auth->checkLogin($this->testUser, $this->testPass); $this->assertTrue($auth->isAuthenticated(), "Not authenticated"); - $this->assertTrue($auth->isLoginAttempt(), "Not login attempt"); $this->assertTrue($auth->user instanceof uUser, "User variable not set"); $this->assertEquals($this->testUser, $auth->user->login, "Wrong login"); $this->assertEquals($_SESSION["user"]->login, $auth->user->login, "Wrong login"); @@ -46,11 +35,9 @@ class AuthTest extends UloggerDatabaseTestCase { $this->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT)); $this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count"); - $_REQUEST = $this->request($this->testUser, "badPass"); - $auth = new uAuth(); + $auth->checkLogin($this->testUser, "badPass"); $this->assertFalse($auth->isAuthenticated(), "Should not be authenticated"); - $this->assertTrue($auth->isLoginAttempt(), "Not login attempt"); $this->assertTrue(is_null($auth->user), "User not null"); } @@ -61,11 +48,9 @@ class AuthTest extends UloggerDatabaseTestCase { $this->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT)); $this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count"); - $_REQUEST = $this->request("", $this->testPass); - $auth = new uAuth(); + $auth->checkLogin("", $this->testPass); $this->assertFalse($auth->isAuthenticated(), "Should not be authenticated"); - $this->assertTrue($auth->isLoginAttempt(), "Not login attempt"); $this->assertTrue(is_null($auth->user), "User not null"); } @@ -78,7 +63,6 @@ class AuthTest extends UloggerDatabaseTestCase { $auth = new uAuth(); $this->assertFalse($auth->isAuthenticated(), "Should not be authenticated"); - $this->assertFalse($auth->isLoginAttempt(), "Should not be login attempt"); $this->assertTrue(is_null($auth->user), "User not null"); } @@ -98,7 +82,6 @@ class AuthTest extends UloggerDatabaseTestCase { @$auth = new uAuth(); $this->assertTrue($auth->isAuthenticated(), "Should be authenticated"); - $this->assertFalse($auth->isLoginAttempt(), "Should not be login attempt"); $this->assertEquals($this->testUser, $auth->user->login, "Wrong login"); } @@ -109,8 +92,6 @@ class AuthTest extends UloggerDatabaseTestCase { $this->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT)); $this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count"); - $_REQUEST = $this->request($this->testUser, $this->testPass); - $user = new uUser($this->testUser); $this->assertTrue($user->isValid, "User not valid"); session_name("ulogger"); @@ -119,8 +100,8 @@ class AuthTest extends UloggerDatabaseTestCase { unset($user); @$auth = new uAuth(); + $auth->checkLogin($this->testUser, $this->testPass); $this->assertTrue($auth->isAuthenticated(), "Should be authenticated"); - $this->assertFalse($auth->isLoginAttempt(), "Should not be login attempt"); $this->assertEquals($this->testUser, $auth->user->login, "Wrong login"); } @@ -132,9 +113,8 @@ class AuthTest extends UloggerDatabaseTestCase { $this->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT)); $this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count"); - $_REQUEST = $this->request($this->testUser, $this->testPass); - @$auth = new uAuth(); + $auth->checkLogin($this->testUser, $this->testPass); $this->assertTrue($auth->isAuthenticated(), "Should be authenticated"); $this->assertFalse($auth->isAdmin(), "Should not be admin"); } @@ -147,9 +127,9 @@ class AuthTest extends UloggerDatabaseTestCase { $this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count"); uConfig::$admin_user = $this->testUser; - $_REQUEST = $this->request($this->testUser, $this->testPass); @$auth = new uAuth(); + $auth->checkLogin($this->testUser, $this->testPass); $this->assertTrue($auth->isAuthenticated(), "Should be authenticated"); $this->assertTrue($auth->isAdmin(), "Should not be admin"); } diff --git a/.tests/tests/ClientAPITest.php b/.tests/tests/ClientAPITest.php index 0ccd670..445a4a1 100644 --- a/.tests/tests/ClientAPITest.php +++ b/.tests/tests/ClientAPITest.php @@ -251,7 +251,7 @@ class ClientAPITest extends UloggerAPITestCase { ]; $actual = $this->getConnection()->createQueryTable( "positions", - "SELECT id, user_id, track_id, UNIX_TIMESTAMP(time) AS time, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions" + "SELECT id, user_id, track_id, " . $this->unix_timestamp('time') . " AS time, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions" ); $this->assertTableContains($expected, $actual, "Wrong actual table data"); } diff --git a/.tests/tests/ImportTest.php b/.tests/tests/ImportTest.php index b5b3009..0d51750 100644 --- a/.tests/tests/ImportTest.php +++ b/.tests/tests/ImportTest.php @@ -90,7 +90,7 @@ class ImportTest extends UloggerAPITestCase { ]; $actual = $this->getConnection()->createQueryTable( "positions", - "SELECT id, UNIX_TIMESTAMP(time) AS time, user_id, track_id, latitude, longitude, + "SELECT id, " . $this->unix_timestamp('time') . " AS time, user_id, track_id, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions" ); $this->assertTableContains($expected, $actual, "Wrong actual table data"); @@ -206,7 +206,7 @@ class ImportTest extends UloggerAPITestCase { ]; $actual = $this->getConnection()->createQueryTable( "positions", - "SELECT id, UNIX_TIMESTAMP(time) AS time, user_id, track_id, latitude, longitude, + "SELECT id, " . $this->unix_timestamp('time') . " AS time, user_id, track_id, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions" ); $this->assertTableContains($expected, $actual, "Wrong actual table data"); @@ -306,7 +306,7 @@ class ImportTest extends UloggerAPITestCase { ]; $actual = $this->getConnection()->createQueryTable( "positions", - "SELECT id, UNIX_TIMESTAMP(time) AS time, user_id, track_id, latitude, longitude, + "SELECT id, " . $this->unix_timestamp('time') . " AS time, user_id, track_id, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions" ); $this->assertTableContains($expected, $actual, "Wrong actual table data"); @@ -387,7 +387,7 @@ class ImportTest extends UloggerAPITestCase { ]; $actual = $this->getConnection()->createQueryTable( "positions", - "SELECT id, UNIX_TIMESTAMP(time) AS time, user_id, track_id, latitude, longitude, + "SELECT id, " . $this->unix_timestamp('time') . " AS time, user_id, track_id, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions" ); $this->assertTableContains($expected, $actual, "Wrong actual table data"); @@ -474,7 +474,7 @@ class ImportTest extends UloggerAPITestCase { ]; $actual = $this->getConnection()->createQueryTable( "positions", - "SELECT id, UNIX_TIMESTAMP(time) AS time, user_id, track_id, latitude, longitude, + "SELECT id, " . $this->unix_timestamp('time') . " AS time, user_id, track_id, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions" ); $this->assertTableContains($expected, $actual, "Wrong actual table data"); @@ -586,7 +586,7 @@ class ImportTest extends UloggerAPITestCase { ]; $actual = $this->getConnection()->createQueryTable( "positions", - "SELECT id, UNIX_TIMESTAMP(time) AS time, user_id, track_id, latitude, longitude, + "SELECT id, " . $this->unix_timestamp('time') . " AS time, user_id, track_id, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions" ); $this->assertTableContains($expected, $actual, "Wrong actual table data"); diff --git a/.tests/tests/InternalAPITest.php b/.tests/tests/InternalAPITest.php index 48def87..29fc7de 100644 --- a/.tests/tests/InternalAPITest.php +++ b/.tests/tests/InternalAPITest.php @@ -21,9 +21,9 @@ class InternalAPITest extends UloggerAPITestCase { $options = [ "http_errors" => false, - "form_params" => [ "userid" => $this->testUserId, "trackid" => $trackId ], + "query" => [ "userid" => $this->testUserId, "trackid" => $trackId ], ]; - $response = $this->http->post("/utils/getpositions.php", $options); + $response = $this->http->get("/utils/getpositions.php", $options); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code"); $xml = $this->getXMLfromResponse($response); @@ -60,9 +60,9 @@ class InternalAPITest extends UloggerAPITestCase { $options = [ "http_errors" => false, - "form_params" => [ "userid" => $userId, "trackid" => $trackId ], + "query" => [ "userid" => $userId, "trackid" => $trackId ], ]; - $response = $this->http->post("/utils/getpositions.php", $options); + $response = $this->http->get("/utils/getpositions.php", $options); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code"); $xml = $this->getXMLfromResponse($response); @@ -100,9 +100,9 @@ class InternalAPITest extends UloggerAPITestCase { $options = [ "http_errors" => false, - "form_params" => [ "userid" => $this->testUserId, "trackid" => $trackId ], + "query" => [ "userid" => $this->testUserId, "trackid" => $trackId ], ]; - $response = $this->http->post("/utils/getpositions.php", $options); + $response = $this->http->get("/utils/getpositions.php", $options); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code"); $xml = $this->getXMLfromResponse($response); @@ -124,9 +124,9 @@ class InternalAPITest extends UloggerAPITestCase { $options = [ "http_errors" => false, - "form_params" => [ "userid" => $userId, "trackid" => $trackId ], + "query" => [ "userid" => $userId, "trackid" => $trackId ], ]; - $response = $this->http->post("/utils/getpositions.php", $options); + $response = $this->http->get("/utils/getpositions.php", $options); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code"); $xml = $this->getXMLfromResponse($response); @@ -162,9 +162,9 @@ class InternalAPITest extends UloggerAPITestCase { $options = [ "http_errors" => false, - "form_params" => [ "userid" => $this->testUserId ], + "query" => [ "userid" => $this->testUserId ], ]; - $response = $this->http->post("/utils/getpositions.php", $options); + $response = $this->http->get("/utils/getpositions.php", $options); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code"); $xml = $this->getXMLfromResponse($response); @@ -192,9 +192,9 @@ class InternalAPITest extends UloggerAPITestCase { $options = [ "http_errors" => false, - "form_params" => [ "trackid" => $trackId ], + "query" => [ "trackid" => $trackId ], ]; - $response = $this->http->post("/utils/getpositions.php", $options); + $response = $this->http->get("/utils/getpositions.php", $options); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code"); $xml = $this->getXMLfromResponse($response); @@ -211,9 +211,9 @@ class InternalAPITest extends UloggerAPITestCase { $options = [ "http_errors" => false, - "form_params" => [ "userid" => $this->testUserId, "trackid" => $trackId ], + "query" => [ "userid" => $this->testUserId, "trackid" => $trackId ], ]; - $response = $this->http->post("/utils/getpositions.php", $options); + $response = $this->http->get("/utils/getpositions.php", $options); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code"); $xml = $this->getXMLfromResponse($response); @@ -237,9 +237,9 @@ class InternalAPITest extends UloggerAPITestCase { $options = [ "http_errors" => false, - "form_params" => [ "userid" => $this->testUserId ], + "query" => [ "userid" => $this->testUserId ], ]; - $response = $this->http->post("/utils/gettracks.php", $options); + $response = $this->http->get("/utils/gettracks.php", $options); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code"); $xml = $this->getXMLfromResponse($response); @@ -267,9 +267,9 @@ class InternalAPITest extends UloggerAPITestCase { $options = [ "http_errors" => false, - "form_params" => [ "userid" => $userId ], + "query" => [ "userid" => $userId ], ]; - $response = $this->http->post("/utils/gettracks.php", $options); + $response = $this->http->get("/utils/gettracks.php", $options); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code"); $xml = $this->getXMLfromResponse($response); @@ -297,9 +297,9 @@ class InternalAPITest extends UloggerAPITestCase { $options = [ "http_errors" => false, - "form_params" => [ "userid" => $this->testUserId ], + "query" => [ "userid" => $this->testUserId ], ]; - $response = $this->http->post("/utils/gettracks.php", $options); + $response = $this->http->get("/utils/gettracks.php", $options); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code"); $xml = $this->getXMLfromResponse($response); @@ -320,7 +320,7 @@ class InternalAPITest extends UloggerAPITestCase { $options = [ "http_errors" => false, ]; - $response = $this->http->post("/utils/gettracks.php", $options); + $response = $this->http->get("/utils/gettracks.php", $options); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code"); $xml = $this->getXMLfromResponse($response); $this->assertTrue($xml !== false, "XML object is not false"); @@ -336,9 +336,9 @@ class InternalAPITest extends UloggerAPITestCase { $options = [ "http_errors" => false, - "form_params" => [ "userid" => $this->testUserId ], + "query" => [ "userid" => $this->testUserId ], ]; - $response = $this->http->post("/utils/gettracks.php", $options); + $response = $this->http->get("/utils/gettracks.php", $options); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code"); $xml = $this->getXMLfromResponse($response); diff --git a/.tests/tests/PositionTest.php b/.tests/tests/PositionTest.php index 21bcce3..1aebb2b 100644 --- a/.tests/tests/PositionTest.php +++ b/.tests/tests/PositionTest.php @@ -7,18 +7,19 @@ require_once(__DIR__ . "/../../helpers/track.php"); class PositionTest extends UloggerDatabaseTestCase { public function testAddPosition() { - $trackId = $this->addTestTrack($this->testUserId); + $userId = $this->addTestUser(); + $trackId = $this->addTestTrack($userId); $this->assertEquals(1, $this->getConnection()->getRowCount('tracks'), "Wrong row count"); - $posId = uPosition::add($this->testUserId, $trackId + 1, $this->testTimestamp, $this->testLat, $this->testLon, $this->testAltitude, $this->testSpeed, $this->testBearing, $this->testAccuracy, $this->testProvider, $this->testComment, $this->testImageId); + $posId = uPosition::add($userId, $trackId + 1, $this->testTimestamp, $this->testLat, $this->testLon, $this->testAltitude, $this->testSpeed, $this->testBearing, $this->testAccuracy, $this->testProvider, $this->testComment, $this->testImageId); $this->assertEquals(0, $this->getConnection()->getRowCount('positions'), "Wrong row count"); $this->assertFalse($posId, "Adding position with nonexistant track should fail"); - $posId = uPosition::add($this->testUserId2, $trackId, $this->testTimestamp, $this->testLat, $this->testLon, $this->testAltitude, $this->testSpeed, $this->testBearing, $this->testAccuracy, $this->testProvider, $this->testComment, $this->testImageId); + $posId = uPosition::add($userId + 1, $trackId, $this->testTimestamp, $this->testLat, $this->testLon, $this->testAltitude, $this->testSpeed, $this->testBearing, $this->testAccuracy, $this->testProvider, $this->testComment, $this->testImageId); $this->assertEquals(0, $this->getConnection()->getRowCount('positions'), "Wrong row count"); $this->assertFalse($posId, "Adding position with wrong user should fail"); - $posId = uPosition::add($this->testUserId, $trackId, $this->testTimestamp, $this->testLat, $this->testLon, $this->testAltitude, $this->testSpeed, $this->testBearing, $this->testAccuracy, $this->testProvider, $this->testComment, $this->testImageId); + $posId = uPosition::add($userId, $trackId, $this->testTimestamp, $this->testLat, $this->testLon, $this->testAltitude, $this->testSpeed, $this->testBearing, $this->testAccuracy, $this->testProvider, $this->testComment, $this->testImageId); $this->assertEquals(1, $this->getConnection()->getRowCount('positions'), "Wrong row count"); $expected = [ "id" => $posId, @@ -37,60 +38,66 @@ class PositionTest extends UloggerDatabaseTestCase { ]; $actual = $this->getConnection()->createQueryTable( "positions", - "SELECT id, user_id, track_id, UNIX_TIMESTAMP(time) AS time, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions" + "SELECT id, user_id, track_id, " . $this->unix_timestamp('time') . " AS time, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions" ); $this->assertTableContains($expected, $actual, "Wrong actual table data"); - $posId = uPosition::add($this->testUserId, $trackId, NULL, $this->testLat, $this->testLon); + $posId = uPosition::add($userId, $trackId, NULL, $this->testLat, $this->testLon); $this->assertFalse($posId, "Adding position with null time stamp should fail"); - $posId = uPosition::add($this->testUserId, $trackId, $this->testTimestamp, NULL, $this->testLon); + $posId = uPosition::add($userId, $trackId, $this->testTimestamp, NULL, $this->testLon); $this->assertFalse($posId, "Adding position with null latitude should fail"); - $posId = uPosition::add($this->testUserId, $trackId, $this->testTimestamp, $this->testLat, NULL); + $posId = uPosition::add($userId, $trackId, $this->testTimestamp, $this->testLat, NULL); $this->assertFalse($posId, "Adding position with null longitude should fail"); - $posId = uPosition::add($this->testUserId, $trackId, "", $this->testLat, $this->testLon); + $posId = uPosition::add($userId, $trackId, "", $this->testLat, $this->testLon); $this->assertFalse($posId, "Adding position with empty time stamp should fail"); - $posId = uPosition::add($this->testUserId, $trackId, $this->testTimestamp, "", $this->testLon); + $posId = uPosition::add($userId, $trackId, $this->testTimestamp, "", $this->testLon); $this->assertFalse($posId, "Adding position with empty latitude should fail"); - $posId = uPosition::add($this->testUserId, $trackId, $this->testTimestamp, $this->testLat, ""); + $posId = uPosition::add($userId, $trackId, $this->testTimestamp, $this->testLat, ""); $this->assertFalse($posId, "Adding position with empty longitude should fail"); } public function testDeleteAll() { - $trackId = $this->addTestTrack($this->testUserId); - $this->addTestPosition($this->testUserId, $trackId); - $trackId2 = $this->addTestTrack($this->testUserId); - $this->addTestPosition($this->testUserId, $trackId2); - $trackId3 = $this->addTestTrack($this->testUserId2); - $this->addTestPosition($this->testUserId2, $trackId3); + $userId = $this->addTestUser(); + $userId2 = $this->addTestUser($this->testUser2); + $trackId = $this->addTestTrack($userId); + $this->addTestPosition($userId, $trackId); + $trackId2 = $this->addTestTrack($userId); + $this->addTestPosition($userId, $trackId2); + $trackId3 = $this->addTestTrack($userId2); + $this->addTestPosition($userId2, $trackId3); $this->assertEquals(3, $this->getConnection()->getRowCount('tracks'), "Wrong row count"); $this->assertEquals(3, $this->getConnection()->getRowCount('positions'), "Wrong row count"); - $this->assertTrue(uPosition::deleteAll($this->testUserId), "Deleting failed"); + $this->assertTrue(uPosition::deleteAll($userId), "Deleting failed"); $this->assertEquals(1, $this->getConnection()->getRowCount('positions'), "Wrong row count"); } public function testDeleteAllWIthTrackId() { - $trackId = $this->addTestTrack($this->testUserId); - $this->addTestPosition($this->testUserId, $trackId); - $trackId2 = $this->addTestTrack($this->testUserId); - $this->addTestPosition($this->testUserId, $trackId2); - $trackId3 = $this->addTestTrack($this->testUserId2); - $this->addTestPosition($this->testUserId2, $trackId3); + $userId = $this->addTestUser(); + $userId2 = $this->addTestUser($this->testUser2); + $trackId = $this->addTestTrack($userId); + $this->addTestPosition($userId, $trackId); + $trackId2 = $this->addTestTrack($userId); + $this->addTestPosition($userId, $trackId2); + $trackId3 = $this->addTestTrack($userId2); + $this->addTestPosition($userId2, $trackId3); $this->assertEquals(3, $this->getConnection()->getRowCount('tracks'), "Wrong row count"); $this->assertEquals(3, $this->getConnection()->getRowCount('positions'), "Wrong row count"); - $this->assertTrue(uPosition::deleteAll($this->testUserId, $trackId), "Deleting failed"); + $this->assertTrue(uPosition::deleteAll($userId, $trackId), "Deleting failed"); $this->assertEquals(2, $this->getConnection()->getRowCount('positions'), "Wrong row count"); } public function testGetLast() { - $trackId1 = $this->addTestTrack($this->testUserId); - $trackId2 = $this->addTestTrack($this->testUserId); - $pos1 = $this->addTestPosition($this->testUserId, $trackId1, $this->testTimestamp + 3); - $pos2 = $this->addTestPosition($this->testUserId2, $trackId2, $this->testTimestamp + 1); - $pos3 = $this->addTestPosition($this->testUserId, $trackId1, $this->testTimestamp); - $pos4 = $this->addTestPosition($this->testUserId2, $trackId2, $this->testTimestamp + 2); + $userId = $this->addTestUser(); + $userId2 = $this->addTestUser($this->testUser2); + $trackId1 = $this->addTestTrack($userId); + $trackId2 = $this->addTestTrack($userId); + $pos1 = $this->addTestPosition($userId, $trackId1, $this->testTimestamp + 3); + $pos2 = $this->addTestPosition($userId2, $trackId2, $this->testTimestamp + 1); + $pos3 = $this->addTestPosition($userId, $trackId1, $this->testTimestamp); + $pos4 = $this->addTestPosition($userId2, $trackId2, $this->testTimestamp + 2); $this->assertEquals(2, $this->getConnection()->getRowCount('tracks'), "Wrong row count"); $this->assertEquals(4, $this->getConnection()->getRowCount('positions'), "Wrong row count"); $lastPosition = uPosition::getLast(); @@ -100,40 +107,45 @@ class PositionTest extends UloggerDatabaseTestCase { } public function testGetAll() { - $trackId = $this->addTestTrack($this->testUserId); - $this->addTestPosition($this->testUserId, $trackId); - $trackId2 = $this->addTestTrack($this->testUserId); - $this->addTestPosition($this->testUserId, $trackId2); - $trackId3 = $this->addTestTrack($this->testUserId2); - $this->addTestPosition($this->testUserId2, $trackId3); + $userId = $this->addTestUser(); + $userId2 = $this->addTestUser($this->testUser2); + $userId3 = $this->addTestUser("testUser3"); + $trackId = $this->addTestTrack($userId); + $this->addTestPosition($userId, $trackId); + $trackId2 = $this->addTestTrack($userId); + $this->addTestPosition($userId, $trackId2); + $trackId3 = $this->addTestTrack($userId2); + $this->addTestPosition($userId2, $trackId3); $this->assertEquals(3, $this->getConnection()->getRowCount('tracks'), "Wrong row count"); $this->assertEquals(3, $this->getConnection()->getRowCount('positions'), "Wrong row count"); $posArr = uPosition::getAll(); $this->assertEquals(3, count($posArr), "Wrong row count"); - $posArr = uPosition::getAll($this->testUserId); + $posArr = uPosition::getAll($userId); $this->assertEquals(2, count($posArr), "Wrong row count"); - $posArr = uPosition::getAll($this->testUserId, $trackId); + $posArr = uPosition::getAll($userId, $trackId); $this->assertEquals(1, count($posArr), "Wrong row count"); $posArr = uPosition::getAll(NULL, $trackId); $this->assertEquals(1, count($posArr), "Wrong row count"); - $posArr = uPosition::getAll($this->testUserId3); + $posArr = uPosition::getAll($userId3); $this->assertEquals(0, count($posArr), "Wrong row count"); } public function testDistanceTo() { - $trackId = $this->addTestTrack($this->testUserId); - $pos1 = $this->addTestPosition($this->testUserId, $trackId, $this->testTimestamp, 0, 0); - $pos2 = $this->addTestPosition($this->testUserId, $trackId, $this->testTimestamp, 0, 1); + $userId = $this->addTestUser(); + $trackId = $this->addTestTrack($userId); + $pos1 = $this->addTestPosition($userId, $trackId, $this->testTimestamp, 0, 0); + $pos2 = $this->addTestPosition($userId, $trackId, $this->testTimestamp, 0, 1); $posArr = uPosition::getAll(); $this->assertEquals(2, count($posArr), "Wrong row count"); $this->assertEquals(111195, round($posArr[0]->distanceTo($posArr[1])), "Wrong distance"); } public function testSecondsTo() { - $trackId = $this->addTestTrack($this->testUserId); - $pos1 = $this->addTestPosition($this->testUserId, $trackId, $this->testTimestamp); - $pos2 = $this->addTestPosition($this->testUserId, $trackId, $this->testTimestamp + 1); + $userId = $this->addTestUser(); + $trackId = $this->addTestTrack($userId); + $pos1 = $this->addTestPosition($userId, $trackId, $this->testTimestamp); + $pos2 = $this->addTestPosition($userId, $trackId, $this->testTimestamp + 1); $posArr = uPosition::getAll(); $this->assertEquals(2, count($posArr), "Wrong row count"); $this->assertEquals(-1, $posArr[0]->secondsTo($posArr[1]), "Wrong time difference"); diff --git a/.tests/tests/TrackTest.php b/.tests/tests/TrackTest.php index 3ae563c..2d4f089 100644 --- a/.tests/tests/TrackTest.php +++ b/.tests/tests/TrackTest.php @@ -7,7 +7,9 @@ require_once(__DIR__ . "/../../helpers/track.php"); class TrackTest extends UloggerDatabaseTestCase { public function testAddTrack() { + $this->addTestUser(); $trackId = uTrack::add($this->testUserId, $this->testTrackName, $this->testTrackComment); + $this->assertNotFalse($trackId, "Track id should not be false"); $this->assertEquals(1, $this->getConnection()->getRowCount('tracks'), "Wrong row count"); $this->assertEquals(1, $trackId, "Wrong track id returned"); $expected = [ "id" => $trackId, "user_id" => $this->testUserId, "name" => $this->testTrackName, "comment" => $this->testTrackComment ]; @@ -19,8 +21,9 @@ class TrackTest extends UloggerDatabaseTestCase { } public function testDeleteTrack() { - $trackId = $this->addTestTrack($this->testUserId); - $this->addTestPosition($this->testUserId, $trackId); + $userId = $this->addTestUser(); + $trackId = $this->addTestTrack($userId); + $this->addTestPosition($userId, $trackId); $this->assertEquals(1, $this->getConnection()->getRowCount('tracks'), "Wrong row count"); $this->assertEquals(1, $this->getConnection()->getRowCount('positions'), "Wrong row count"); @@ -32,20 +35,22 @@ class TrackTest extends UloggerDatabaseTestCase { } public function testAddPosition() { - $trackId = $this->addTestTrack($this->testUserId); + $userId = $this->addTestUser(); + $userId2 = $this->addTestUser($this->testUser2); + $trackId = $this->addTestTrack($userId); $this->assertEquals(1, $this->getConnection()->getRowCount('tracks'), "Wrong row count"); $track = new uTrack($trackId + 1); - $posId = $track->addPosition($this->testUserId, $this->testTimestamp, $this->testLat, $this->testLon, $this->testAltitude, $this->testSpeed, $this->testBearing, $this->testAccuracy, $this->testProvider, $this->testComment, $this->testImageId); + $posId = $track->addPosition($userId, $this->testTimestamp, $this->testLat, $this->testLon, $this->testAltitude, $this->testSpeed, $this->testBearing, $this->testAccuracy, $this->testProvider, $this->testComment, $this->testImageId); $this->assertEquals(0, $this->getConnection()->getRowCount('positions'), "Wrong row count"); $this->assertFalse($posId, "Adding position with nonexistant track should fail"); $track = new uTrack($trackId); - $posId = $track->addPosition($this->testUserId2, $this->testTimestamp, $this->testLat, $this->testLon, $this->testAltitude, $this->testSpeed, $this->testBearing, $this->testAccuracy, $this->testProvider, $this->testComment, $this->testImageId); + $posId = $track->addPosition($userId2, $this->testTimestamp, $this->testLat, $this->testLon, $this->testAltitude, $this->testSpeed, $this->testBearing, $this->testAccuracy, $this->testProvider, $this->testComment, $this->testImageId); $this->assertEquals(0, $this->getConnection()->getRowCount('positions'), "Wrong row count"); $this->assertFalse($posId, "Adding position with wrong user should fail"); - $posId = $track->addPosition($this->testUserId, $this->testTimestamp, $this->testLat, $this->testLon, $this->testAltitude, $this->testSpeed, $this->testBearing, $this->testAccuracy, $this->testProvider, $this->testComment, $this->testImageId); + $posId = $track->addPosition($userId, $this->testTimestamp, $this->testLat, $this->testLon, $this->testAltitude, $this->testSpeed, $this->testBearing, $this->testAccuracy, $this->testProvider, $this->testComment, $this->testImageId); $this->assertEquals(1, $this->getConnection()->getRowCount('positions'), "Wrong row count"); $expected = [ "id" => $posId, @@ -64,28 +69,28 @@ class TrackTest extends UloggerDatabaseTestCase { ]; $actual = $this->getConnection()->createQueryTable( "positions", - "SELECT id, user_id, track_id, UNIX_TIMESTAMP(time) AS time, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions" + "SELECT id, user_id, track_id, " . $this->unix_timestamp('time') . " AS time, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions" ); $this->assertTableContains($expected, $actual, "Wrong actual table data"); - $posId = $track->addPosition($this->testUserId, NULL, $this->testLat, $this->testLon); + $posId = $track->addPosition($userId, NULL, $this->testLat, $this->testLon); $this->assertFalse($posId, "Adding position with null time stamp should fail"); - $posId = $track->addPosition($this->testUserId, $this->testTimestamp, NULL, $this->testLon); + $posId = $track->addPosition($userId, $this->testTimestamp, NULL, $this->testLon); $this->assertFalse($posId, "Adding position with null latitude should fail"); - $posId = $track->addPosition($this->testUserId, $this->testTimestamp, $this->testLat, NULL); + $posId = $track->addPosition($userId, $this->testTimestamp, $this->testLat, NULL); $this->assertFalse($posId, "Adding position with null longitude should fail"); - $posId = $track->addPosition($this->testUserId, "", $this->testLat, $this->testLon); + $posId = $track->addPosition($userId, "", $this->testLat, $this->testLon); $this->assertFalse($posId, "Adding position with empty time stamp should fail"); - $posId = $track->addPosition($this->testUserId, $this->testTimestamp, "", $this->testLon); + $posId = $track->addPosition($userId, $this->testTimestamp, "", $this->testLon); $this->assertFalse($posId, "Adding position with empty latitude should fail"); - $posId = $track->addPosition($this->testUserId, $this->testTimestamp, $this->testLat, ""); + $posId = $track->addPosition($userId, $this->testTimestamp, $this->testLat, ""); $this->assertFalse($posId, "Adding position with empty longitude should fail"); } public function testGetAll() { - $this->addTestTrack(); - $this->addTestTrack(); + $this->addTestTrack($this->addTestUser()); + $this->addTestTrack($this->addTestUser($this->testUser2)); $this->assertEquals(2, $this->getConnection()->getRowCount('tracks'), "Wrong row count"); $trackArr = uTrack::getAll(); @@ -94,24 +99,27 @@ class TrackTest extends UloggerDatabaseTestCase { } public function testDeleteAll() { - $trackId = $this->addTestTrack(); - $this->addTestTrack(); - $this->addTestPosition($this->testUserId, $trackId); + $userId = $this->addTestUser(); + $trackId = $this->addTestTrack($userId); + $this->addTestTrack($userId); + $this->addTestPosition($userId, $trackId); - $trackId2 = $this->addTestTrack($this->testUserId2); - $this->addTestPosition($this->testUserId2, $trackId2); + $userId2 = $this->addTestUser($this->testUser2); + $trackId2 = $this->addTestTrack($userId2); + $this->addTestPosition($userId2, $trackId2); $this->assertEquals(3, $this->getConnection()->getRowCount('tracks'), "Wrong row count"); $this->assertEquals(2, $this->getConnection()->getRowCount('positions'), "Wrong row count"); - uTrack::deleteAll($this->testUserId); + uTrack::deleteAll($userId); $this->assertEquals(1, $this->getConnection()->getRowCount('tracks'), "Wrong row count"); $this->assertEquals(1, $this->getConnection()->getRowCount('positions'), "Wrong row count"); $this->assertFalse(uTrack::deleteAll(NULL), "User id should not be empty"); } public function testUpdate() { - $trackId = $this->addTestTrack(); + $userId = $this->addTestUser(); + $trackId = $this->addTestTrack($userId); $track = new uTrack($trackId); $track->update("newName", "newComment"); $expected = [ "id" => $trackId, "user_id" => $this->testUserId, "name" => "newName", "comment" => "newComment" ]; @@ -123,7 +131,8 @@ class TrackTest extends UloggerDatabaseTestCase { } public function testIsValid() { - $trackId = $this->addTestTrack(); + $userId = $this->addTestUser(); + $trackId = $this->addTestTrack($userId); $trackValid = new uTrack($trackId); $this->assertTrue($trackValid->isValid, "Track should be valid"); $trackInvalid = new uTrack($trackId + 1); diff --git a/Dockerfile b/Dockerfile index be82807..a80b6a8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,7 @@ LABEL maintainer="Bartek Fabiszewski (https://github.com/bfabiszewski)" ARG DB_ROOT_PASS=secret1 ARG DB_USER_PASS=secret2 +ARG DB_DRIVER=mysql ENV ULOGGER_ADMIN_USER admin ENV ULOGGER_PASS_STRENGTH 0 @@ -13,8 +14,16 @@ ENV ULOGGER_PUBLIC_TRACKS 0 ENV ULOGGER_GKEY "" ENV ULOGGER_LANG en ENV ULOGGER_UNITS metric +ENV ULOGGER_DB_DRIVER ${DB_DRIVER} -RUN apk add --no-cache mariadb mariadb-client nginx php7-ctype php7-fpm php7-json php7-mysqli php7-session php7-simplexml php7-xmlwriter +ENV LANG=en_US.utf-8 + +RUN apk add --no-cache \ + nginx \ + php7-ctype php7-fpm php7-json php7-pdo php7-session php7-simplexml php7-xmlwriter +RUN if [ "${DB_DRIVER}" = "mysql" ]; then apk add --no-cache mariadb mariadb-client php7-pdo_mysql; fi +RUN if [ "${DB_DRIVER}" = "pgsql" ]; then apk add --no-cache postgresql postgresql-client php7-pdo_pgsql; fi +RUN if [ "${DB_DRIVER}" = "sqlite" ]; then apk add --no-cache sqlite php7-pdo_sqlite; fi COPY .docker/run.sh /run.sh RUN chmod +x /run.sh @@ -37,6 +46,6 @@ RUN ln -sf /dev/stdout /var/log/nginx/access.log && \ EXPOSE 80 -VOLUME ["/var/lib/mysql"] +VOLUME ["/data"] CMD ["/run.sh"] diff --git a/client/index.php b/client/index.php index c57eb10..43addbd 100644 --- a/client/index.php +++ b/client/index.php @@ -47,18 +47,25 @@ require_once(dirname(__DIR__) . "/helpers/auth.php"); + $action = uUtils::postString('action'); + $auth = new uAuth(); - if (!$auth->isAuthenticated()) { + if (!$auth->isAuthenticated() && $action != "auth") { $auth->sendUnauthorizedHeader(); exitWithError("Unauthorized"); } - $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null; - switch ($action) { // action: authorize case "auth": - exitWithSuccess(); + $login = uUtils::postString('user'); + $pass = uUtils::postPass('pass'); + if ($auth->checkLogin($login, $pass)) { + exitWithSuccess(); + } else { + $auth->sendUnauthorizedHeader(); + exitWithError("Unauthorized"); + } break; // action: adduser (currently unused) @@ -66,8 +73,8 @@ if (!$auth->user->isAdmin) { exitWithError("Not allowed"); } - $login = isset($_REQUEST['login']) ? $_REQUEST['login'] : NULL; - $pass = isset($_REQUEST['password']) ? $_REQUEST['password'] : NULL; + $login = uUtils::postString('login'); + $pass = uUtils::postPass('password'); if (empty($login) || empty($pass)) { exitWithError("Empty login or password"); } @@ -80,7 +87,7 @@ // action: addtrack case "addtrack": - $trackName = isset($_REQUEST['track']) ? $_REQUEST['track'] : NULL; + $trackName = uUtils::postString('track'); if (empty($trackName)) { exitWithError("Missing required parameter"); } @@ -95,19 +102,19 @@ // action: addposition case "addpos": - $lat = isset($_REQUEST["lat"]) ? $_REQUEST["lat"] : NULL; - $lon = isset($_REQUEST["lon"]) ? $_REQUEST["lon"] : NULL; - $timestamp = isset($_REQUEST["time"]) ? $_REQUEST["time"] : NULL; - $altitude = isset($_REQUEST["altitude"]) ? $_REQUEST["altitude"] : NULL; - $speed = isset($_REQUEST["speed"]) ? $_REQUEST["speed"] : NULL; - $bearing = isset($_REQUEST["bearing"]) ? $_REQUEST["bearing"] : NULL; - $accuracy = isset($_REQUEST["accuracy"]) ? $_REQUEST["accuracy"] : NULL; - $provider = isset($_REQUEST["provider"]) ? $_REQUEST["provider"] : NULL; - $comment = isset($_REQUEST["comment"]) ? $_REQUEST["comment"] : NULL; - $imageId = isset($_REQUEST["imageid"]) ? $_REQUEST["imageid"] : NULL; - $trackId = isset($_REQUEST["trackid"]) ? $_REQUEST["trackid"] : NULL; + $lat = uUtils::postFloat('lat'); + $lon = uUtils::postFloat('lon'); + $timestamp = uUtils::postInt('time'); + $altitude = uUtils::postFloat('altitude'); + $speed = uUtils::postFloat('speed'); + $bearing = uUtils::postFloat('bearing'); + $accuracy = uUtils::postInt('accuracy'); + $provider = uUtils::postString('provider'); + $comment = uUtils::postString('comment'); + $imageId = uUtils::postInt('imageid'); + $trackId = uUtils::postInt('trackid'); - if (!is_numeric($lat) || !is_numeric($lon) || !is_numeric($timestamp) || !is_numeric($trackId)) { + if (!is_float($lat) || !is_float($lon) || !is_int($timestamp) || !is_int($trackId)) { exitWithError("Missing required parameter"); } diff --git a/helpers/auth.php b/helpers/auth.php index 7977d2d..056fac4 100644 --- a/helpers/auth.php +++ b/helpers/auth.php @@ -28,7 +28,6 @@ class uAuth { private $isAuthenticated = false; - private $isLoginAttempt = false; public $user = null; public function __construct() { @@ -37,8 +36,6 @@ $user = (new uUser())->getFromSession(); if ($user->isValid) { $this->setAuthenticated($user); - } else { - $this->checkLogin(); } } @@ -51,15 +48,6 @@ return $this->isAuthenticated; } - /** - * Has user attempted to log in - * - * @return boolean True if attempted login, false otherwise - */ - public function isLoginAttempt() { - return $this->isLoginAttempt; - } - /** * Is authenticated user admin * @@ -121,22 +109,19 @@ * * @return void */ - private function checkLogin() { - $action = isset($_REQUEST["action"]) ? $_REQUEST["action"] : NULL; - $login = isset($_REQUEST["user"]) ? $_REQUEST["user"] : NULL; - $pass = isset($_REQUEST["pass"]) ? $_REQUEST["pass"] : NULL; - - if ($action == "auth" && !is_null($login) && !is_null($pass)) { - $this->isLoginAttempt = true; + public function checkLogin($login, $pass) { + if (!is_null($login) && !is_null($pass)) { if (!empty($login) && !empty($pass)) { $user = new uUser($login); if ($user->isValid && $user->validPassword($pass)) { $this->setAuthenticated($user); $this->sessionCleanup(); $user->storeInSession(); + return true; } } } + return false; } /** diff --git a/helpers/db.php b/helpers/db.php index fff94e3..8ec3c5b 100644 --- a/helpers/db.php +++ b/helpers/db.php @@ -52,6 +52,7 @@ PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // return assoc array by default ]; @parent::__construct($dsn, $user, $pass, $options); + $this->setCharset("utf8"); $this->initTables(); } catch (PDOException $e) { header("HTTP/1.1 503 Service Unavailable"); @@ -91,5 +92,41 @@ public function table($name) { return self::$tables[$name]; } + + public function unix_timestamp($column) { + $driver = $this->getAttribute(PDO::ATTR_DRIVER_NAME); + switch ($driver) { + default: + case "mysql": + return "UNIX_TIMESTAMP($column)"; + break; + case "pgsql": + return "EXTRACT(EPOCH FROM $column)"; + break; + case "sqlite": + return "STRFTIME('%s', $column)"; + break; + } + } + + public function from_unixtime($column) { + $driver = $this->getAttribute(PDO::ATTR_DRIVER_NAME); + switch ($driver) { + default: + case "mysql": + return "FROM_UNIXTIME($column)"; + break; + case "pgsql": + return "TO_TIMESTAMP($column)"; + break; + case "sqlite": + return "DATE($column, 'unixepoch')"; + break; + } + } + + private function setCharset($charset) { + $this->query("SET NAMES '$charset'"); + } } ?> diff --git a/helpers/position.php b/helpers/position.php index d70fb4d..0af1b33 100644 --- a/helpers/position.php +++ b/helpers/position.php @@ -24,20 +24,35 @@ * Positions handling */ class uPosition { + /** @param int Position id */ public $id; + /** @param int Unix time stamp */ public $timestamp; + /** @param int User id */ public $userId; + /** @param String User login */ public $userLogin; + /** @param int Track id */ public $trackId; + /** @param String Track name */ public $trackName; + /** @param double Latitude */ public $latitude; + /** @param double Longitude */ public $longitude; + /** @param double Altitude */ public $altitude; + /** @param double Speed */ public $speed; + /** @param double Bearing */ public $bearing; + /** @param int Accuracy */ public $accuracy; + /** @param String Provider */ public $provider; + /** @param String Comment */ public $comment; // not used yet + /** @param int Image id */ public $imageId; // not used yet public $isValid = false; @@ -51,7 +66,7 @@ public function __construct($positionId = NULL) { if (!empty($positionId)) { - $query = "SELECT p.id, UNIX_TIMESTAMP(p.time) AS tstamp, p.user_id, p.track_id, + $query = "SELECT p.id, " . self::db()->unix_timestamp('p.time') . " AS tstamp, p.user_id, p.track_id, p.latitude, p.longitude, p.altitude, p.speed, p.bearing, p.accuracy, p.provider, p.comment, p.image_id, u.login, t.name FROM " . self::db()->table('positions') . " p @@ -63,7 +78,7 @@ $this->loadWithQuery($query, $params); } catch (PDOException $e) { // TODO: handle exception -throw $e; + syslog(LOG_ERR, $e->getMessage()); } } } @@ -85,7 +100,7 @@ throw $e; * * @param int $userId * @param int $trackId - * @param int $time Unix time stamp + * @param int $timestamp Unix time stamp * @param double $lat * @param double $lon * @param double $altitude Optional @@ -109,7 +124,7 @@ throw $e; $query = "INSERT INTO $table (user_id, track_id, time, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_id) - VALUES (?, ?, FROM_UNIXTIME(?), ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + VALUES (?, ?, " . self::db()->from_unixtime('?') . ", ?, ?, ?, ?, ?, ?, ?, ?, ?)"; $stmt = self::db()->prepare($query); $params = [ $userId, $trackId, $timestamp, $lat, $lon, $altitude, $speed, $bearing, $accuracy, $provider, $comment, $imageId ]; @@ -117,6 +132,7 @@ throw $e; $positionId = self::db()->lastInsertId("${table}_id_seq"); } catch (PDOException $e) { // TODO: handle error + syslog(LOG_ERR, $e->getMessage()); } } } @@ -147,7 +163,7 @@ throw $e; $ret = true; } catch (PDOException $e) { // TODO: handle exception -throw $e; + syslog(LOG_ERR, $e->getMessage()); } } return $ret; @@ -168,7 +184,7 @@ throw $e; $where = ""; $params = NULL; } - $query = "SELECT p.id, UNIX_TIMESTAMP(p.time) AS tstamp, p.user_id, p.track_id, + $query = "SELECT p.id, " . self::db()->unix_timestamp('p.time') . " AS tstamp, p.user_id, p.track_id, p.latitude, p.longitude, p.altitude, p.speed, p.bearing, p.accuracy, p.provider, p.comment, p.image_id, u.login, t.name FROM " . self::db()->table('positions') . " p @@ -181,7 +197,7 @@ throw $e; $position->loadWithQuery($query, $params); } catch (PDOException $e) { // TODO: handle exception -throw $e; + syslog(LOG_ERR, $e->getMessage()); } return $position; } @@ -206,7 +222,7 @@ throw $e; } else { $where = ""; } - $query = "SELECT p.id, UNIX_TIMESTAMP(p.time) AS tstamp, p.user_id, p.track_id, + $query = "SELECT p.id, " . self::db()->unix_timestamp('p.time') . " AS tstamp, p.user_id, p.track_id, p.latitude, p.longitude, p.altitude, p.speed, p.bearing, p.accuracy, p.provider, p.comment, p.image_id, u.login, t.name FROM " . self::db()->table('positions') . " p @@ -222,7 +238,7 @@ throw $e; } } catch (PDOException $e) { // TODO: handle exception -throw $e; + syslog(LOG_ERR, $e->getMessage()); } return $positionsArr; } @@ -292,25 +308,24 @@ throw $e; $stmt = self::db()->prepare($query); $stmt->execute($params); - $stmt->bindColumn('id', $this->id); - $stmt->bindColumn('tstamp', $this->timestamp); - $stmt->bindColumn('user_id', $this->userId); - $stmt->bindColumn('track_id', $this->trackId); + $stmt->bindColumn('id', $this->id, PDO::PARAM_INT); + $stmt->bindColumn('tstamp', $this->timestamp, PDO::PARAM_INT); + $stmt->bindColumn('user_id', $this->userId, PDO::PARAM_INT); + $stmt->bindColumn('track_id', $this->trackId, PDO::PARAM_INT); $stmt->bindColumn('latitude', $this->latitude); $stmt->bindColumn('longitude', $this->longitude); $stmt->bindColumn('altitude', $this->altitude); $stmt->bindColumn('speed', $this->speed); $stmt->bindColumn('bearing', $this->bearing); - $stmt->bindColumn('accuracy', $this->accuracy); + $stmt->bindColumn('accuracy', $this->accuracy, PDO::PARAM_INT); $stmt->bindColumn('provider', $this->provider); $stmt->bindColumn('comment', $this->comment); - $stmt->bindColumn('image_id', $this->imageId); + $stmt->bindColumn('image_id', $this->imageId, PDO::PARAM_INT); $stmt->bindColumn('login', $this->userLogin); $stmt->bindColumn('name', $this->trackName); - - $stmt->fetch(PDO::FETCH_BOUND); - $this->isValid = true; - $stmt = null; + if ($stmt->fetch(PDO::FETCH_BOUND)) { + $this->isValid = true; + } } } diff --git a/helpers/track.php b/helpers/track.php index e0064c1..3dbdb67 100644 --- a/helpers/track.php +++ b/helpers/track.php @@ -45,15 +45,16 @@ $query = "SELECT id, user_id, name, comment FROM " . self::db()->table('tracks') . " WHERE id = ? LIMIT 1"; $stmt = self::db()->prepare($query); $stmt->execute([$trackId]); - $stmt->bindColumn('id', $this->id); - $stmt->bindColumn('user_id', $this->userId); + $stmt->bindColumn('id', $this->id, PDO::PARAM_INT); + $stmt->bindColumn('user_id', $this->userId, PDO::PARAM_INT); $stmt->bindColumn('name', $this->name); $stmt->bindColumn('comment', $this->comment); - $stmt->fetch(); - $this->isValid = true; + if ($stmt->fetch(PDO::FETCH_BOUND)) { + $this->isValid = true; + } } catch (PDOException $e) { // TODO: handle exception -throw $e; + syslog(LOG_ERR, $e->getMessage()); } } @@ -91,7 +92,7 @@ throw $e; $trackId = self::db()->lastInsertId("${table}_id_seq"); } catch (PDOException $e) { // TODO: handle exception -throw $e; + syslog(LOG_ERR, $e->getMessage()); } } return $trackId; @@ -145,7 +146,7 @@ throw $e; $this->isValid = false; } catch (PDOException $e) { // TODO: handle exception -throw $e; + syslog(LOG_ERR, $e->getMessage()); } } return $ret; @@ -174,7 +175,7 @@ throw $e; $this->comment = $comment; } catch (PDOException $e) { // TODO: handle exception -throw $e; + syslog(LOG_ERR, $e->getMessage()); } } return $ret; @@ -199,7 +200,7 @@ throw $e; $ret = true; } catch (PDOException $e) { // TODO: handle exception -throw $e; + syslog(LOG_ERR, $e->getMessage()); } } @@ -228,7 +229,7 @@ throw $e; } } catch (PDOException $e) { // TODO: handle exception -throw $e; + syslog(LOG_ERR, $e->getMessage()); $trackArr = false; } return $trackArr; diff --git a/helpers/user.php b/helpers/user.php index bfce602..b35a115 100644 --- a/helpers/user.php +++ b/helpers/user.php @@ -47,16 +47,17 @@ $query = "SELECT id, login, password FROM " . self::db()->table('users') . " WHERE login = ? LIMIT 1"; $stmt = self::db()->prepare($query); $stmt->execute([ $login ]); - $stmt->bindColumn('id', $this->id); + $stmt->bindColumn('id', $this->id, PDO::PARAM_INT); $stmt->bindColumn('login', $this->login); $stmt->bindColumn('password', $this->hash); - $stmt->fetch(); - $this->isValid = true; + if ($stmt->fetch(PDO::FETCH_BOUND)) { + $this->isValid = true; + $this->isAdmin = self::isAdmin($this->login); + } } catch (PDOException $e) { // TODO: handle exception -throw $e; + syslog(LOG_ERR, $e->getMessage()); } - $this->isAdmin = self::isAdmin($this->login); } } @@ -91,7 +92,7 @@ throw $e; $userid = self::db()->lastInsertId("${table}_id_seq"); } catch (PDOException $e) { // TODO: handle exception -throw $e; + syslog(LOG_ERR, $e->getMessage()); } } return $userid; @@ -123,7 +124,7 @@ throw $e; $this->isAdmin = false; } catch (PDOException $e) { // TODO: handle exception -throw $e; + syslog(LOG_ERR, $e->getMessage()); } } return $ret; @@ -146,7 +147,7 @@ throw $e; $ret = true; } catch (PDOException $e) { // TODO: handle exception -throw $e; + syslog(LOG_ERR, $e->getMessage()); } } return $ret; @@ -210,7 +211,7 @@ throw $e; } } catch (PDOException $e) { // TODO: handle exception -throw $e; + syslog(LOG_ERR, $e->getMessage()); $userArr = false; } return $userArr; diff --git a/helpers/utils.php b/helpers/utils.php index c29dbe0..98b92c7 100644 --- a/helpers/utils.php +++ b/helpers/utils.php @@ -129,6 +129,55 @@ return $proto . str_replace("//", "/", $host . $path . "/"); } + public static function postFloat($name, $default = NULL) { + return self::requestValue($name, $default, INPUT_POST, FILTER_VALIDATE_FLOAT); + } + + public static function getFloat($name, $default = NULL) { + return self::requestValue($name, $default, INPUT_GET, FILTER_VALIDATE_FLOAT); + } + + public static function postPass($name, $default = NULL) { + return self::requestValue($name, $default, INPUT_POST); + } + + public static function postString($name, $default = NULL) { + if (is_string(($val = self::requestValue($name, $default, INPUT_POST)))) { + return trim($val); + } else { + return $val; + } + } + + public static function getBool($name, $default = NULL) { + return self::requestValue($name, $default, INPUT_GET, FILTER_VALIDATE_BOOLEAN); + } + + public static function postInt($name, $default = NULL) { + if (is_float(($val = self::postFloat($name, $default)))) { + return (int) round($val); + } else { + return self::requestValue($name, $default, INPUT_POST, FILTER_VALIDATE_INT); + } + } + + public static function getInt($name, $default = NULL) { + if (is_float(($val = self::getFloat($name, $default)))) { + return (int) round($val); + } else { + return self::requestValue($name, $default, INPUT_GET, FILTER_VALIDATE_INT); + } + } + + public static function requestValue($name, $default = NULL, $type = INPUT_POST, $filters = FILTER_DEFAULT, $flags = NULL) { + $input = filter_input($type, $name, $filters, $flags); + if ($input !== false && !is_null($input)) { + return $input; + } else { + return $default; + } + } + } ?> \ No newline at end of file diff --git a/index.php b/index.php index ea14e57..16e74df 100755 --- a/index.php +++ b/index.php @@ -24,9 +24,16 @@ require_once(ROOT_DIR . "/helpers/utils.php"); require_once(ROOT_DIR . "/lang.php"); - $auth = new uAuth(); + $login = uUtils::postString('user'); + $pass = uUtils::postPass('pass'); + $action = uUtils::postString('action'); - if (!$auth->isAuthenticated() && $auth->isLoginAttempt()) { + $auth = new uAuth(); + if ($action == "auth") { + $auth->checkLogin($login, $pass); + } + + if (!$auth->isAuthenticated() && $action == "auth") { $auth->exitWithRedirect("login.php?auth_error=1"); } if (!$auth->isAuthenticated() && uConfig::$require_authentication) { diff --git a/login.php b/login.php index 6f2156a..3de41ec 100644 --- a/login.php +++ b/login.php @@ -21,7 +21,7 @@ require_once(ROOT_DIR . "/lang.php"); require_once(ROOT_DIR . "/helpers/config.php"); - $auth_error = isset($_REQUEST['auth_error']) ? (bool) $_REQUEST['auth_error'] : false; + $auth_error = uUtils::getBool('auth_error', false); ?> diff --git a/scripts/migrate_from_phptrackme.php b/scripts/migrate_from_phptrackme.php deleted file mode 100644 index 9d07df3..0000000 --- a/scripts/migrate_from_phptrackme.php +++ /dev/null @@ -1,222 +0,0 @@ -. - */ - -/* This script imports data from old phpTrackme database scheme. - * - * However, as μlogger uses more secure password storage methods, - * it is impossible to convert old password hashes to the new format. - * Administrator will have to fill in user passwords manually. - * Alternatively authentication code could be modify in order to - * temporarily accept old hashes and convert it as users log in. - * It should be pretty simple, but this is not a top priority - * for this small project. - */ - -// this script is disabled by default. Change below to true before running. -$enabled = false; - -// path to root folder of phpTrackme -$phpTrackmePath = "../../phpTrackme"; - -// path to root folder of μlogger -$uloggerPath = ".."; - - -/* -------------------------------------------- */ -/* no user modifications should be needed below */ - -if ($enabled == false) { - echo "Script is disabled\n"; - exit(1); -} -$path = realpath(dirname(__FILE__)); -if (!empty($phpTrackmePath) && $phpTrackmePath[0] == ".") { - $phpTrackmePath = $path . "/" . $phpTrackmePath; -} -$phpTrackmeConfig = $phpTrackmePath . "/config.php"; -if (!is_readable($phpTrackmeConfig)) { - echo "Can't find phpTrackme config file: $phpTrackmeConfig\n"; - exit(1); -} -include ($phpTrackmeConfig); -$pt_dbhost = $dbhost; -$pt_dbuser = $dbuser; -$pt_dbpass = $dbpass; -$pt_dbname = $dbname; -$pt_mysqli = new mysqli($pt_dbhost, $pt_dbuser, $pt_dbpass, $pt_dbname); -$pt_mysqli->set_charset("utf8"); -if ($pt_mysqli->connect_errno) { - echo "Can't connect to $pt_dbname database: (" . $pt_mysqli->errno . ") " . $pt_mysqli->error . "\n"; - exit(1); -} -if (!empty($uloggerPath) && $uloggerPath[0] == ".") { - $uloggerPath = $path . "/" . $uloggerPath; -} -$uloggerConfig = $uloggerPath . "/config.php"; -if (!is_readable($uloggerConfig)) { - echo "Can't find μlogger config fiel: $uloggerConfige\n"; - exit(1); -} -include ($uloggerConfig); -$mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname); -$mysqli->set_charset("utf8"); -if ($mysqli->connect_errno) { - echo "Can't connect to $dbname database : (" . $mysqli->errno . ") " . $mysqli->error . "\n"; - exit(1); -} -$prefix = preg_replace('/[^a-z0-9_]/i', '', $dbprefix); -$tPositions = $prefix . "positions"; -$tTracks = $prefix . "tracks"; -$tUsers = $prefix . "users"; - -// import data -if (!$users_result = $pt_mysqli->query("SELECT * FROM users ORDER BY ID")) { - echo "Query failed\n"; - exit(1); -} - -if (!($user_insert = $mysqli->prepare("INSERT INTO `$tUsers` (login, password) VALUES (?, ?)"))) { - echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error . "\n"; - exit(1); -} -$pt_user = null; -$pt_pass = null; -if (!$user_insert->bind_param("ss", $pt_user, $pt_pass)) { - echo "Binding parameters failed: (" . $user_insert->errno . ") " . $user_insert->error . "\n"; - exit(1); -} - -while ($user = $users_result->fetch_assoc()) { - $pt_user = $user['username']; - $pt_pass = $user['password']; - $pt_id = $user['ID']; - if (!$user_insert->execute()) { - echo "Execute failed: (" . $user_insert->errno . ") " . $user_insert->error . "\n"; - exit(1); - } - $user_id = $user_insert->insert_id; - process_user_tracks($user_id); -} -$users_result->close(); -$user_insert->close(); - -$mysqli->close(); -$pt_mysqli->close(); -echo "Import finished successfully\n"; -exit(0); - -/* Helper functions */ - -/** Import tracks metadata for given user - * @param int $user_id User id - */ -function process_user_tracks($user_id) { - global $pt_mysqli, $mysqli; - $sql = "SELECT ID, Name, Comments FROM trips WHERE FK_Users_ID = ? ORDER BY ID"; - if (!($tracks_select = $pt_mysqli->prepare($sql))) { - echo "Prepare failed: (" . $pt_mysqli->errno . ") " . $pt_mysqli->error . "\n"; - exit(1); - } - if (!$tracks_select->bind_param('i', $user_id)) { - echo "Binding parameters failed: (" . $tracks_select->errno . ") " . $tracks_select->error . "\n"; - exit(1); - } - if (!$tracks_select->bind_result($pt_id, $pt_name, $pt_comment)) { - echo "Binding parameters failed: (" . $tracks_select->errno . ") " . $tracks_select->error . "\n"; - exit(1); - } - if (!$tracks_select->execute()) { - echo "Execute failed: (" . $tracks_select->errno . ") " . $tracks_select->error . "\n"; - exit(1); - } - $tracks_select->store_result(); - if (!($track_insert = $mysqli->prepare("INSERT INTO `$tTracks` (user_id, name, comment) VALUES (?, ?, ?)"))) { - echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error . "\n"; - exit(1); - } - $pt_name = null; - $pt_comment = null; - if (!$track_insert->bind_param("iss", $user_id, $pt_name, $pt_comment)) { - echo "Binding parameters failed: (" . $track_insert->errno . ") " . $track_insert->error . "\n"; - exit(1); - } - while ($tracks_select->fetch()) { - if (!$track_insert->execute()) { - echo "Execute failed: (" . $track_insert->errno . ") " . $track_insert->error . "\n"; - exit(1); - } - $track_id = $track_insert->insert_id; - process_track($user_id, $pt_id, $track_id); - } - $tracks_select->free_result(); - $tracks_select->close(); - $track_insert->close(); -} - -/** Import positions for given track - * @param int $user_id User id - * @param int $old_id Old database track id - * @param int $new_id New database track id - */ -function process_track($user_id, $old_id, $new_id) { - global $pt_mysqli, $mysqli; - $sql = "SELECT Latitude, Longitude, Altitude, Speed, Angle, UNIX_TIMESTAMP(DateOccurred), Comments FROM pt_positions WHERE FK_Users_ID = ? AND FK_Trips_ID = ? ORDER BY DateOccurred, ID"; - if (!($pos_select = $pt_mysqli->prepare($sql))) { - echo "Prepare failed: (" . $pt_mysqli->errno . ") " . $pt_mysqli->error . "\n"; - exit(1); - } - if (!$pos_select->bind_param('ii', $user_id, $old_id)) { - echo "Binding parameters failed: (" . $pos_select->errno . ") " . $pos_select->error . "\n"; - exit(1); - } - if (!$pos_select->bind_result($lat, $lon, $altitude, $speed, $bearing, $timestamp, $comment)) { - echo "Binding parameters failed: (" . $pos_select->errno . ") " . $pos_select->error . "\n"; - exit(1); - } - if (!$pos_select->execute()) { - echo "Execute failed: (" . $pos_select->errno . ") " . $pos_select->error . "\n"; - exit(1); - } - $pos_select->store_result(); - if (!($pos_insert = $mysqli->prepare("INSERT INTO `$tPositions` (FROM_UNIXTIME(time), user_id, track_id, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_id) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"))) { - echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error . "\n"; - exit(1); - } - $provider = $comment = $timestamp = $imageid = null; - $lat = $lon = 0; - $altitude = $speed = $bearing = $accuracy = null; - - if (!$pos_insert->bind_param('siiddddddssi', - $timestamp, $user_id, $new_id, $lat, $lon, $altitude, $speed, $bearing, $accuracy, $provider, $comment, $imageid)) { - echo "Binding parameters failed: (" . $pos_insert->errno . ") " . $pos_insert->error . "\n"; - exit(1); - } - while ($pos_select->fetch()) { - $provider = null; - if (!$pos_insert->execute()) { - echo "Execute failed: (" . $pos_insert->errno . ") " . $pos_insert->error . "\n"; - exit(1); - } - } - $pos_insert->close(); - $pos_select->free_result(); - $pos_select->close(); -} -?> \ No newline at end of file diff --git a/scripts/setup.php b/scripts/setup.php index f874324..aa4990b 100644 --- a/scripts/setup.php +++ b/scripts/setup.php @@ -33,7 +33,7 @@ require_once(ROOT_DIR . "/helpers/user.php"); require_once(ROOT_DIR . "/helpers/config.php"); require_once(ROOT_DIR . "/lang.php"); -$command = isset($_REQUEST['command']) ? $_REQUEST['command'] : NULL; +$command = uUtils::postString('command'); $prefix = preg_replace('/[^a-z0-9_]/i', '', uConfig::$dbprefix); $tPositions = $prefix . "positions"; @@ -78,8 +78,8 @@ switch ($command) { break; case "adduser": - $login = isset($_REQUEST['login']) ? $_REQUEST['login'] : NULL; - $pass = isset($_REQUEST['pass']) ? $_REQUEST['pass'] : NULL; + $login = uUtils::postString('login'); + $pass = uUtils::postPass('pass'); if (uUser::add($login, $pass) !== false) { $messages[] = "{$langSetup["congratulations"]}"; @@ -127,143 +127,141 @@ switch ($command) { } function getQueries($db) { - $driver = $db->getAttribute(PDO::ATTR_DRIVER_NAME); - $queries = []; - switch($driver) { - case "mysql": - // positions - $queries[] = "DROP TABLE IF EXISTS `$tPositions`"; - $queries[] = "CREATE TABLE `$tPositions` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `user_id` int(11) NOT NULL, - `track_id` int(11) NOT NULL, - `latitude` double NOT NULL, - `longitude` double NOT NULL, - `altitude` double DEFAULT NULL, - `speed` double DEFAULT NULL, - `bearing` double DEFAULT NULL, - `accuracy` int(11) DEFAULT NULL, - `provider` varchar(100) DEFAULT NULL, - `comment` varchar(255) DEFAULT NULL, - `image_id` int(11) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `index_trip_id` (`track_id`), - KEY `index_user_id` (`user_id`) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; - - // tracks - $queries[] = "DROP TABLE IF EXISTS `$tTracks`"; - $queries[] = "CREATE TABLE `$tTracks` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` int(11) NOT NULL, - `name` varchar(255) DEFAULT NULL, - `comment` varchar(1024) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `user_id` (`user_id`) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; - - // users - $queries[] = "DROP TABLE IF EXISTS `$tUsers`"; - $queries[] = "CREATE TABLE `$tUsers` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `login` varchar(15) CHARACTER SET latin1 NOT NULL, - `password` varchar(255) CHARACTER SET latin1 NOT NULL DEFAULT '', - PRIMARY KEY (`id`), - UNIQUE KEY `login` (`login`) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; - break; - - case "pgsql": - // positions - $queries[] = "DROP TABLE IF EXISTS $tPositions"; - $queries[] = "CREATE TABLE $tPositions ( - id SERIAL PRIMARY KEY, - time TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, - user_id INT NOT NULL, - track_id INT NOT NULL, - latitude DOUBLE PRECISION NOT NULL, - longitude DOUBLE PRECISION NOT NULL, - altitude DOUBLE PRECISION DEFAULT NULL, - speed DOUBLE PRECISION DEFAULT NULL, - bearing DOUBLE PRECISION DEFAULT NULL, - accuracy INT DEFAULT NULL, - provider VARCHAR(100) DEFAULT NULL, - comment VARCHAR(255) DEFAULT NULL, - image_id INT DEFAULT NULL - )"; - $queries[] = "CREATE INDEX index_trip_id ON $tPositions (track_id)"; - $queries[] = "CREATE INDEX index_user_id ON $tPositions (user_id)"; - - // tracks - $queries[] = "DROP TABLE IF EXISTS $tTracks"; - $queries[] = "CREATE TABLE $tTracks ( - id SERIAL PRIMARY KEY, - user_id INT NOT NULL, - name VARCHAR(255) DEFAULT NULL, - comment VARCHAR(1024) DEFAULT NULL - )"; - $queries[] = "CREATE INDEX user_id ON $tTracks (user_id)"; - - // users - $queries[] = "DROP TABLE IF EXISTS $tUsers"; - $queries[] = "CREATE TABLE $tUsers ( - id SERIAL PRIMARY KEY, - login varchar(15) NOT NULL UNIQUE, - password varchar(255) NOT NULL DEFAULT '' - )"; - break; - - case "sqlite": - - // positions - $queries[] = "DROP TABLE IF EXISTS `$tPositions`"; - $queries[] = "CREATE TABLE `$tPositions` ( - `id` INTEGER NOT NULL , - `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `user_id` INTEGER NOT NULL, - `track_id` INTEGER NOT NULL, - `latitude` double NOT NULL, - `longitude` double NOT NULL, - `altitude` double DEFAULT NULL, - `speed` double DEFAULT NULL, - `bearing` double DEFAULT NULL, - `accuracy` INTEGER DEFAULT NULL, - `provider` TEXT DEFAULT NULL, - `comment` TEXT DEFAULT NULL, - `image_id` INTEGER DEFAULT NULL, - PRIMARY KEY (`id`) - )"; - $queries[] = "CREATE INDEX `positions_index_trip_id` ON `$tPositions` (`track_id`)"; - $queries[] = "CREATE INDEX `positions_index_user_id` ON `$tPositions` (`user_id`)"; - - // tracks - $queries[] = "DROP TABLE IF EXISTS `$tTracks`"; - $queries[] = "CREATE TABLE `$tTracks` ( - `id` INTEGER NOT NULL, - `user_id` INTEGER NOT NULL, - `name` TEXT DEFAULT NULL, - `comment` TEXT DEFAULT NULL, - PRIMARY KEY (`id`) - )"; - $queries[] = "CREATE INDEX `tracks_user_id` ON `$tTracks` (`user_id`)"; - - // users - $queries[] = "DROP TABLE IF EXISTS `$tUsers`"; - $queries[] = "CREATE TABLE `$tUsers` ( - `id` INTEGER NOT NULL , - `login` TEXT NOT NULL, - `password` TEXT NOT NULL DEFAULT '', - PRIMARY KEY (`id`) - )"; - $queries[] = "CREATE UNIQUE INDEX `users_login` ON `$tUsers` (`login`)"; - break; - - default: - throw InvalidArgumentException("Driver not supported"); - } + $driver = $db->getAttribute(PDO::ATTR_DRIVER_NAME); + $queries = []; + switch($driver) { + case "mysql": + // users + $queries[] = "DROP TABLE IF EXISTS `$tUsers`"; + $queries[] = "CREATE TABLE `$tUsers` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `login` varchar(15) CHARACTER SET latin1 NOT NULL UNIQUE, + `password` varchar(255) CHARACTER SET latin1 NOT NULL DEFAULT '' + ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; + // tracks + $queries[] = "DROP TABLE IF EXISTS `$tTracks`"; + $queries[] = "CREATE TABLE `$tTracks` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `user_id` int(11) NOT NULL, + `name` varchar(255) DEFAULT NULL, + `comment` varchar(1024) DEFAULT NULL, + INDEX `idx_user_id` (`user_id`), + FOREIGN KEY(`user_id`) REFERENCES `$tUsers`(`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; + + // positions + $queries[] = "DROP TABLE IF EXISTS `$tPositions`"; + $queries[] = "CREATE TABLE `$tPositions` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `user_id` int(11) NOT NULL, + `track_id` int(11) NOT NULL, + `latitude` double NOT NULL, + `longitude` double NOT NULL, + `altitude` double DEFAULT NULL, + `speed` double DEFAULT NULL, + `bearing` double DEFAULT NULL, + `accuracy` int(11) DEFAULT NULL, + `provider` varchar(100) DEFAULT NULL, + `comment` varchar(255) DEFAULT NULL, + `image_id` int(11) DEFAULT NULL, + INDEX `idx_track_id` (`track_id`), + INDEX `idx_user_id` (`user_id`), + FOREIGN KEY(`user_id`) REFERENCES `$tUsers`(`id`), + FOREIGN KEY(`track_id`) REFERENCES `$tTracks`(`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; + break; + + case "pgsql": + // users + $queries[] = "DROP TABLE IF EXISTS $tUsers"; + $queries[] = "CREATE TABLE $tUsers ( + id SERIAL PRIMARY KEY, + login VARCHAR(15) NOT NULL UNIQUE, + password VARCHAR(255) NOT NULL DEFAULT '' + )"; + + // tracks + $queries[] = "DROP TABLE IF EXISTS $tTracks"; + $queries[] = "CREATE TABLE $tTracks ( + id SERIAL PRIMARY KEY, + user_id INT NOT NULL, + name VARCHAR(255) DEFAULT NULL, + comment VARCHAR(1024) DEFAULT NULL, + FOREIGN KEY(user_id) REFERENCES $tUsers(id) + )"; + $queries[] = "CREATE INDEX idx_user_id ON $tTracks(user_id)"; + + // positions + $queries[] = "DROP TABLE IF EXISTS $tPositions"; + $queries[] = "CREATE TABLE $tPositions ( + id SERIAL PRIMARY KEY, + time TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, + user_id INT NOT NULL, + track_id INT NOT NULL, + latitude DOUBLE PRECISION NOT NULL, + longitude DOUBLE PRECISION NOT NULL, + altitude DOUBLE PRECISION DEFAULT NULL, + speed DOUBLE PRECISION DEFAULT NULL, + bearing DOUBLE PRECISION DEFAULT NULL, + accuracy INT DEFAULT NULL, + provider VARCHAR(100) DEFAULT NULL, + comment VARCHAR(255) DEFAULT NULL, + image_id INT DEFAULT NULL, + FOREIGN KEY(user_id) REFERENCES $tUsers(id), + FOREIGN KEY(track_id) REFERENCES $tTracks(id) + )"; + $queries[] = "CREATE INDEX idx_ptrack_id ON $tPositions(track_id)"; + $queries[] = "CREATE INDEX idx_puser_id ON $tPositions(user_id)"; + break; + + case "sqlite": + // users + $queries[] = "DROP TABLE IF EXISTS `$tUsers`"; + $queries[] = "CREATE TABLE `$tUsers` ( + `id` integer PRIMARY KEY AUTOINCREMENT, + `login` varchar(15) NOT NULL UNIQUE, + `password` varchar(255) NOT NULL DEFAULT '' + )"; + // tracks + $queries[] = "DROP TABLE IF EXISTS `$tTracks`"; + $queries[] = "CREATE TABLE `$tTracks` ( + `id` integer PRIMARY KEY AUTOINCREMENT, + `user_id` integer NOT NULL, + `name` varchar(255) DEFAULT NULL, + `comment` varchar(1024) DEFAULT NULL, + FOREIGN KEY(`user_id`) REFERENCES `$tUsers`(`id`) + )"; + $queries[] = "CREATE INDEX `idx_user_id` ON `$tTracks`(`user_id`)"; + + // positions + $queries[] = "DROP TABLE IF EXISTS `$tPositions`"; + $queries[] = "CREATE TABLE `$tPositions` ( + `id` integer PRIMARY KEY AUTOINCREMENT, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `user_id` integer NOT NULL, + `track_id` integer NOT NULL, + `latitude` double NOT NULL, + `longitude` double NOT NULL, + `altitude` double DEFAULT NULL, + `speed` double DEFAULT NULL, + `bearing` double DEFAULT NULL, + `accuracy` integer DEFAULT NULL, + `provider` varchar(100) DEFAULT NULL, + `comment` varchar(255) DEFAULT NULL, + `image_id` integer DEFAULT NULL, + FOREIGN KEY(`user_id`) REFERENCES `$tUsers`(`id`), + FOREIGN KEY(`track_id`) REFERENCES `$tTracks`(`id`) + )"; + $queries[] = "CREATE INDEX `idx_ptrack_id` ON `$tPositions`(`track_id`)"; + $queries[] = "CREATE INDEX `idx_puser_id` ON `$tPositions`(`user_id`)"; + break; + + default: + throw InvalidArgumentException("Driver not supported"); + } } ?> diff --git a/scripts/ulogger.pgsql b/scripts/ulogger.pgsql new file mode 100644 index 0000000..568ebec --- /dev/null +++ b/scripts/ulogger.pgsql @@ -0,0 +1,74 @@ +-- +-- Database: `ulogger` +-- + +CREATE DATABASE ulogger WITH ENCODING='UTF8' LC_COLLATE = 'en_US.utf-8' LC_CTYPE = 'en_US.utf-8'; +\connect ulogger; + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `users` +-- + +DROP TABLE IF EXISTS users; +CREATE TABLE users ( + id serial PRIMARY KEY, + login varchar(15) NOT NULL UNIQUE, + password varchar(255) NOT NULL DEFAULT '' +); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `tracks` +-- + +DROP TABLE IF EXISTS tracks; +CREATE TABLE tracks ( + id serial PRIMARY KEY, + user_id int NOT NULL, + name varchar(255) DEFAULT NULL, + comment varchar(1024) DEFAULT NULL, + FOREIGN KEY(user_id) REFERENCES users(id) +); + +CREATE INDEX idx_user_id ON tracks(user_id); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `positions` +-- + +DROP TABLE IF EXISTS positions; +CREATE TABLE positions ( + id serial PRIMARY KEY, + time timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, + user_id int NOT NULL, + track_id int NOT NULL, + latitude double precision NOT NULL, + longitude double precision NOT NULL, + altitude double precision DEFAULT NULL, + speed double precision DEFAULT NULL, + bearing double precision DEFAULT NULL, + accuracy int DEFAULT NULL, + provider varchar(100) DEFAULT NULL, + comment varchar(255) DEFAULT NULL, + image_id int DEFAULT NULL, + FOREIGN KEY(user_id) REFERENCES users(id), + FOREIGN KEY(track_id) REFERENCES tracks(id) +); + +CREATE INDEX idx_ptrack_id ON positions(track_id); +CREATE INDEX idx_puser_id ON positions(user_id); + + +-- +-- This will add default user admin with password admin +-- The password should be changed immediatelly after installation +-- Uncomment if needed +-- +-- INSERT INTO `users` (`id`, `login`, `password`) VALUES +-- (1, 'admin', '$2y$10$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq'); \ No newline at end of file diff --git a/scripts/ulogger.sql b/scripts/ulogger.sql index fd3d69e..cd90b8e 100755 --- a/scripts/ulogger.sql +++ b/scripts/ulogger.sql @@ -5,6 +5,36 @@ CREATE DATABASE IF NOT EXISTS `ulogger` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; USE `ulogger`; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `users` +-- + +DROP TABLE IF EXISTS `users`; +CREATE TABLE `users` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `login` varchar(15) CHARACTER SET latin1 NOT NULL UNIQUE, + `password` varchar(255) CHARACTER SET latin1 NOT NULL DEFAULT '' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `tracks` +-- + +DROP TABLE IF EXISTS `tracks`; +CREATE TABLE `tracks` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `user_id` int(11) NOT NULL, + `name` varchar(255) DEFAULT NULL, + `comment` varchar(1024) DEFAULT NULL, + INDEX `idx_user_id` (`user_id`), + FOREIGN KEY(`user_id`) REFERENCES `users`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + -- -------------------------------------------------------- -- @@ -13,7 +43,7 @@ USE `ulogger`; DROP TABLE IF EXISTS `positions`; CREATE TABLE `positions` ( - `id` int(11) NOT NULL, + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `user_id` int(11) NOT NULL, `track_id` int(11) NOT NULL, @@ -25,77 +55,13 @@ CREATE TABLE `positions` ( `accuracy` int(11) DEFAULT NULL, `provider` varchar(100) DEFAULT NULL, `comment` varchar(255) DEFAULT NULL, - `image_id` int(11) DEFAULT NULL + `image_id` int(11) DEFAULT NULL, + INDEX `idx_ptrack_id` (`track_id`), + INDEX `index_puser_id` (`user_id`), + FOREIGN KEY(`user_id`) REFERENCES `users`(`id`), + FOREIGN KEY(`track_id`) REFERENCES `tracks`(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; --- -------------------------------------------------------- - --- --- Table structure for table `tracks` --- - -DROP TABLE IF EXISTS `tracks`; -CREATE TABLE `tracks` ( - `id` int(11) NOT NULL, - `user_id` int(11) NOT NULL, - `name` varchar(255) DEFAULT NULL, - `comment` varchar(1024) DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- --- Table structure for table `users` --- - -DROP TABLE IF EXISTS `users`; -CREATE TABLE `users` ( - `id` int(11) NOT NULL, - `login` varchar(15) CHARACTER SET latin1 NOT NULL, - `password` varchar(255) CHARACTER SET latin1 NOT NULL DEFAULT '' -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- --- Indexes for dumped tables --- - --- --- Indexes for table `positions` --- -ALTER TABLE `positions` - ADD PRIMARY KEY (`id`), ADD KEY `index_trip_id` (`track_id`), ADD KEY `index_user_id` (`user_id`); - --- --- Indexes for table `tracks` --- -ALTER TABLE `tracks` - ADD PRIMARY KEY (`id`), ADD KEY `user_id` (`user_id`); - --- --- Indexes for table `users` --- -ALTER TABLE `users` - ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `login` (`login`); - --- --- AUTO_INCREMENT for dumped tables --- - --- --- AUTO_INCREMENT for table `positions` --- -ALTER TABLE `positions` - MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; --- --- AUTO_INCREMENT for table `tracks` --- -ALTER TABLE `tracks` - MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; --- --- AUTO_INCREMENT for table `users` --- -ALTER TABLE `users` - MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; -- -- This will add default user admin with password admin diff --git a/utils/changepass.php b/utils/changepass.php index 679fc1a..398c7ec 100644 --- a/utils/changepass.php +++ b/utils/changepass.php @@ -26,10 +26,10 @@ uUtils::exitWithError("Unauthorized"); } - $login = isset($_REQUEST['login']) ? trim($_REQUEST['login']) : NULL; - $oldpass = isset($_REQUEST['oldpass']) ? $_REQUEST['oldpass'] : NULL; - $pass = isset($_REQUEST['pass']) ? $_REQUEST['pass'] : NULL; - // FIXME: stings need to be localized + $login = uUtils::postString('login'); + $oldpass = uUtils::postPass('oldpass'); + $pass = uUtils::postPass('pass'); + // FIXME: strings need to be localized if (empty($pass)) { uUtils::exitWithError("Empty password"); } diff --git a/utils/export.php b/utils/export.php index 990a1e7..db668ed 100755 --- a/utils/export.php +++ b/utils/export.php @@ -57,9 +57,9 @@ function toHMS($s) { return (($d > 0) ? "$d d " : "") . sprintf("%02d:%02d:%02d", $h, $m, $s); } -$type = isset($_REQUEST["type"]) ? $_REQUEST["type"] : "kml"; -$userId = (isset($_REQUEST["userid"]) && is_numeric($_REQUEST["userid"])) ? (int) $_REQUEST["userid"] : NULL; -$trackId = (isset($_REQUEST["trackid"]) && is_numeric($_REQUEST["trackid"])) ? (int) $_REQUEST["trackid"] : NULL; +$type = uUtils::postString('type', 'kml'); +$userId = uUtils::postInt('userid'); +$trackId = uUtils::postInt('trackid'); if (!uConfig::$public_tracks && (!$auth->isAuthenticated() || (!$auth->isAdmin() && $auth->user->id !== $userId))) { diff --git a/utils/getpositions.php b/utils/getpositions.php index 5822483..90bf365 100755 --- a/utils/getpositions.php +++ b/utils/getpositions.php @@ -23,8 +23,8 @@ require_once(ROOT_DIR . "/helpers/utils.php"); $auth = new uAuth(); -$userId = (isset($_REQUEST["userid"]) && is_numeric($_REQUEST["userid"])) ? (int) $_REQUEST["userid"] : NULL; -$trackId = (isset($_REQUEST["trackid"]) && is_numeric($_REQUEST["trackid"])) ? (int) $_REQUEST["trackid"] : NULL; +$userId = uUtils::getInt('userid'); +$trackId = uUtils::getInt('trackid'); $positionsArr = []; if ($userId) { diff --git a/utils/gettracks.php b/utils/gettracks.php index c13d62b..de3296a 100755 --- a/utils/gettracks.php +++ b/utils/gettracks.php @@ -22,7 +22,7 @@ require_once(ROOT_DIR . "/helpers/track.php"); $auth = new uAuth(); -$userId = (isset($_REQUEST["userid"]) && is_numeric($_REQUEST["userid"])) ? (int) $_REQUEST["userid"] : NULL; +$userId = uUtils::getInt('userid'); $tracksArr = []; if ($userId) { diff --git a/utils/handletrack.php b/utils/handletrack.php index d57568f..164f6a3 100644 --- a/utils/handletrack.php +++ b/utils/handletrack.php @@ -24,9 +24,10 @@ $auth = new uAuth(); - $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : NULL; - $trackId = isset($_REQUEST['trackid']) ? trim($_REQUEST['trackid']) : NULL; - $trackName = isset($_REQUEST['trackname']) ? trim($_REQUEST['trackname']) : NULL; + $action = uUtils::postString('action'); + $trackId = uUtils::postInt('trackid'); + $trackName = uUtils::postString('trackname'); + if (empty($action) || empty($trackId)) { uUtils::exitWithError($lang["servererror"]); } diff --git a/utils/handleuser.php b/utils/handleuser.php index 1fe1fef..d2800b6 100644 --- a/utils/handleuser.php +++ b/utils/handleuser.php @@ -23,9 +23,9 @@ $auth = new uAuth(); - $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : NULL; - $login = isset($_REQUEST['login']) ? trim($_REQUEST['login']) : NULL; - $pass = isset($_REQUEST['pass']) ? $_REQUEST['pass'] : NULL; + $action = uUtils::postString('action'); + $login = uUtils::postString('login'); + $pass = uUtils::postPass('pass'); if (!$auth->isAuthenticated() || !$auth->isAdmin() || $auth->user->login == $login || empty($action) || empty($login)) { uUtils::exitWithError($lang["servererror"]); } diff --git a/utils/import.php b/utils/import.php index 49629e3..36410ef 100755 --- a/utils/import.php +++ b/utils/import.php @@ -43,6 +43,8 @@ if (!isset($_FILES["gpx"])) { $lastErr = error_get_last(); if (!empty($lastErr)) { $message .= ": " . $lastErr["message"]; + } else { + $message .= ": no uploaded file"; } uUtils::exitWithError($message); } From c8535cce86744a7de1988057e9a373e1edc55fad Mon Sep 17 00:00:00 2001 From: Bartek Fabiszewski Date: Mon, 28 Jan 2019 23:03:03 +0100 Subject: [PATCH 4/4] Add sqlite support --- .docker/init.sh | 10 ++++- .docker/run.sh | 2 +- .tests/fixtures/fixture_admin.xml | 23 +++------- .tests/fixtures/fixture_empty.xml | 17 +++----- .tests/lib/BaseDatabaseTestCase.php | 13 +++--- .tests/lib/UloggerAPITestCase.php | 4 +- .tests/tests/ClientAPITest.php | 1 - helpers/db.php | 20 ++++++--- helpers/utils.php | 36 +++++++++------ scripts/setup.php | 55 ++++++++++++++++++----- scripts/ulogger.sqlite | 68 +++++++++++++++++++++++++++++ utils/export.php | 6 +-- 12 files changed, 183 insertions(+), 72 deletions(-) create mode 100644 scripts/ulogger.sqlite diff --git a/.docker/init.sh b/.docker/init.sh index 714d920..377ccd1 100644 --- a/.docker/init.sh +++ b/.docker/init.sh @@ -6,6 +6,10 @@ DB_USER_PASS=$2 mkdir -p /run/nginx chown nginx:nginx /run/nginx +# Fix permission issues on mounted volume in macOS +sed -i "s/^nobody:.*$/nobody:x:1000:50::nobody:\/:\/sbin\/nologin/" /etc/passwd +sed -i "s/^nobody:.*$/nobody:x:50:/" /etc/group + sed -i "s/^\$dbuser = .*$/\$dbuser = \"ulogger\";/" /var/www/html/config.php sed -i "s/^\$dbpass = .*$/\$dbpass = \"${DB_USER_PASS}\";/" /var/www/html/config.php @@ -28,7 +32,11 @@ if [ "$ULOGGER_DB_DRIVER" = "pgsql" ]; then su postgres -c "pg_ctl -w stop" sed -i "s/^\$dbdsn = .*$/\$dbdsn = \"pgsql:host=localhost;port=5432;dbname=ulogger\";/" /var/www/html/config.php elif [ "$ULOGGER_DB_DRIVER" = "sqlite" ]; then - sqlite3 /data/ulogger.db < /var/www/html/scripts/ulogger.sqlite + mkdir -p /data + chown nobody:nobody /data + sqlite3 -init /var/www/html/scripts/ulogger.sqlite /data/ulogger.db + sqlite3 -line /data/ulogger.db "INSERT INTO users (login, password) VALUES ('admin', '\$2y\$10\$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq')" + sed -i "s/^\$dbdsn = .*$/\$dbdsn = \"sqlite:\/data\/sqlite\/ulogger.db\";/" /var/www/html/config.php else mkdir -p /run/mysqld chown mysql:mysql /run/mysqld diff --git a/.docker/run.sh b/.docker/run.sh index 5dda0fe..3e1856c 100644 --- a/.docker/run.sh +++ b/.docker/run.sh @@ -18,7 +18,7 @@ grep '^\$' /var/www/html/config.php # start services if [ "$ULOGGER_DB_DRIVER" = "pgsql" ]; then su postgres -c 'pg_ctl -D /data start' -else +elif [ "$ULOGGER_DB_DRIVER" = "mysql" ]; then mysqld_safe --datadir=/data & fi nginx diff --git a/.tests/fixtures/fixture_admin.xml b/.tests/fixtures/fixture_admin.xml index a8319bb..2abb77c 100644 --- a/.tests/fixtures/fixture_admin.xml +++ b/.tests/fixtures/fixture_admin.xml @@ -1,17 +1,6 @@ - - - - - - - - - - - 1 - admin - $2y$10$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq - - - - + + + + + + diff --git a/.tests/fixtures/fixture_empty.xml b/.tests/fixtures/fixture_empty.xml index 764cc13..4a92520 100644 --- a/.tests/fixtures/fixture_empty.xml +++ b/.tests/fixtures/fixture_empty.xml @@ -1,11 +1,6 @@ - - - - - - - - - - - + + + + + + diff --git a/.tests/lib/BaseDatabaseTestCase.php b/.tests/lib/BaseDatabaseTestCase.php index 5d17f5e..b321b79 100644 --- a/.tests/lib/BaseDatabaseTestCase.php +++ b/.tests/lib/BaseDatabaseTestCase.php @@ -37,7 +37,6 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase public function setUp() { parent::setUp(); - } public static function setUpBeforeClass() { @@ -81,15 +80,19 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase * @return PHPUnit_Extensions_Database_DataSet_IDataSet */ protected function getDataSet() { - $this->resetSequences(); - return $this->createMySQLXMLDataSet(__DIR__ . '/../fixtures/fixture_empty.xml'); + $this->resetAutoincrement(); + return $this->createFlatXMLDataSet(__DIR__ . '/../fixtures/fixture_empty.xml'); } - protected function resetSequences($users = 1, $tracks = 1, $positions = 1) { + protected function resetAutoincrement($users = 1, $tracks = 1, $positions = 1) { if (self::$driver == "pgsql") { self::$pdo->query("ALTER SEQUENCE users_id_seq RESTART WITH $users"); self::$pdo->query("ALTER SEQUENCE tracks_id_seq RESTART WITH $tracks"); self::$pdo->query("ALTER SEQUENCE positions_id_seq RESTART WITH $positions"); + } else if (self::$driver == "sqlite") { + self::$pdo->query("DELETE FROM sqlite_sequence WHERE NAME = 'users'"); + self::$pdo->query("DELETE FROM sqlite_sequence WHERE NAME = 'tracks'"); + self::$pdo->query("DELETE FROM sqlite_sequence WHERE NAME = 'positions'"); } } @@ -224,7 +227,7 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase return "TO_TIMESTAMP($column)"; break; case "sqlite": - return "DATE($column, 'unixepoch')"; + return "DATETIME($column, 'unixepoch')"; break; } } diff --git a/.tests/lib/UloggerAPITestCase.php b/.tests/lib/UloggerAPITestCase.php index b44c986..0bd4fb4 100644 --- a/.tests/lib/UloggerAPITestCase.php +++ b/.tests/lib/UloggerAPITestCase.php @@ -26,8 +26,8 @@ class UloggerAPITestCase extends BaseDatabaseTestCase { } protected function getDataSet() { - $this->resetSequences(2); - return $this->createMySQLXMLDataSet(__DIR__ . '/../fixtures/fixture_admin.xml'); + $this->resetAutoincrement(2); + return $this->createFlatXMLDataSet(__DIR__ . '/../fixtures/fixture_admin.xml'); } /** diff --git a/.tests/tests/ClientAPITest.php b/.tests/tests/ClientAPITest.php index 445a4a1..1b99e8d 100644 --- a/.tests/tests/ClientAPITest.php +++ b/.tests/tests/ClientAPITest.php @@ -43,7 +43,6 @@ class ClientAPITest extends UloggerAPITestCase { public function testAddUser() { $this->assertTrue($this->authenticate(), "Authentication failed"); - $this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count"); $options = [ diff --git a/helpers/db.php b/helpers/db.php index 8ec3c5b..195589d 100644 --- a/helpers/db.php +++ b/helpers/db.php @@ -37,6 +37,13 @@ */ protected static $tables; + /** + * Database driver name + * + * @var String Driver + */ + protected static $driver; + /** * PDO constuctor * @@ -52,6 +59,7 @@ PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // return assoc array by default ]; @parent::__construct($dsn, $user, $pass, $options); + self::$driver = $this->getAttribute(PDO::ATTR_DRIVER_NAME); $this->setCharset("utf8"); $this->initTables(); } catch (PDOException $e) { @@ -94,8 +102,7 @@ } public function unix_timestamp($column) { - $driver = $this->getAttribute(PDO::ATTR_DRIVER_NAME); - switch ($driver) { + switch (self::$driver) { default: case "mysql": return "UNIX_TIMESTAMP($column)"; @@ -110,8 +117,7 @@ } public function from_unixtime($column) { - $driver = $this->getAttribute(PDO::ATTR_DRIVER_NAME); - switch ($driver) { + switch (self::$driver) { default: case "mysql": return "FROM_UNIXTIME($column)"; @@ -120,13 +126,15 @@ return "TO_TIMESTAMP($column)"; break; case "sqlite": - return "DATE($column, 'unixepoch')"; + return "DATETIME($column, 'unixepoch')"; break; } } private function setCharset($charset) { - $this->query("SET NAMES '$charset'"); + if (self::$driver == "pgsql" || self::$driver == "mysql") { + $this->query("SET NAMES '$charset'"); + } } } ?> diff --git a/helpers/utils.php b/helpers/utils.php index 98b92c7..2fbe3ff 100644 --- a/helpers/utils.php +++ b/helpers/utils.php @@ -142,11 +142,11 @@ } public static function postString($name, $default = NULL) { - if (is_string(($val = self::requestValue($name, $default, INPUT_POST)))) { - return trim($val); - } else { - return $val; - } + return self::requestString($name, $default, INPUT_POST); + } + + public static function getString($name, $default = NULL) { + return self::requestString($name, $default, INPUT_GET); } public static function getBool($name, $default = NULL) { @@ -154,22 +154,30 @@ } public static function postInt($name, $default = NULL) { - if (is_float(($val = self::postFloat($name, $default)))) { - return (int) round($val); - } else { - return self::requestValue($name, $default, INPUT_POST, FILTER_VALIDATE_INT); - } + return self::requestInt($name, $default, INPUT_POST); } public static function getInt($name, $default = NULL) { - if (is_float(($val = self::getFloat($name, $default)))) { - return (int) round($val); + return self::requestInt($name, $default, INPUT_GET); + } + + private static function requestString($name, $default, $type) { + if (is_string(($val = self::requestValue($name, $default, $type)))) { + return trim($val); } else { - return self::requestValue($name, $default, INPUT_GET, FILTER_VALIDATE_INT); + return $val; } } - public static function requestValue($name, $default = NULL, $type = INPUT_POST, $filters = FILTER_DEFAULT, $flags = NULL) { + private static function requestInt($name, $default, $type) { + if (is_float(($val = self::requestValue($name, $default, $type, FILTER_VALIDATE_FLOAT)))) { + return (int) round($val); + } else { + return self::requestValue($name, $default, $type, FILTER_VALIDATE_INT); + } + } + + private static function requestValue($name, $default, $type, $filters = FILTER_DEFAULT, $flags = NULL) { $input = filter_input($type, $name, $filters, $flags); if ($input !== false && !is_null($input)) { return $input; diff --git a/scripts/setup.php b/scripts/setup.php index aa4990b..e3aedff 100644 --- a/scripts/setup.php +++ b/scripts/setup.php @@ -18,7 +18,7 @@ */ // This script is disabled by default. Change below to true before running. -$enabled = true; +$enabled = false; /* -------------------------------------------- */ @@ -31,6 +31,7 @@ if (version_compare(PHP_VERSION, '5.4.0', '<')) { define("ROOT_DIR", dirname(__DIR__)); require_once(ROOT_DIR . "/helpers/user.php"); require_once(ROOT_DIR . "/helpers/config.php"); +require_once(ROOT_DIR . "/helpers/utils.php"); require_once(ROOT_DIR . "/lang.php"); $command = uUtils::postString('command'); @@ -39,6 +40,7 @@ $prefix = preg_replace('/[^a-z0-9_]/i', '', uConfig::$dbprefix); $tPositions = $prefix . "positions"; $tTracks = $prefix . "tracks"; $tUsers = $prefix . "users"; +$dbDriver = null; $messages = []; switch ($command) { @@ -46,7 +48,9 @@ switch ($command) { $error = false; try { - $db = new PDO(uConfig::$dbdsn, uConfig::$dbuser, uConfig::$dbpass); + $options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ]; + $pdo = new PDO(uConfig::$dbdsn, uConfig::$dbuser, uConfig::$dbpass, $options); + $dbDriver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME); } catch (PDOException $e ) { $messages[] = "{$langSetup["dbconnectfailed"]}"; $messages[] = sprintf($langSetup["serversaid"], "" . $e->getMessage() . ""); @@ -54,16 +58,16 @@ switch ($command) { break; } try { - $queries = getQueries($db); + $queries = getQueries($pdo); foreach ($queries as $query) { - $db->query($query); + $pdo->query($query); } } catch (PDOException $e) { $messages[] = "{$langSetup["dbqueryfailed"]}"; $messages[] = sprintf($langSetup["serversaid"], "" . $e->getMessage() . ""); $error = true; } - $db = null; + $pdo = null; if (!$error) { $messages[] = "{$langSetup["dbtablessuccess"]}"; $messages[] = $langSetup["setupuser"]; @@ -114,22 +118,28 @@ switch ($command) { $messages[] = "
"; break; } - if (empty(uConfig::$dbdsn) || empty(uConfig::$dbuser)) { - $messages[] = sprintf($langSetup["nodbsettings"], "\$dbdsn, \$dbuser, \$dbpass"); + if (empty(uConfig::$dbdsn) || ($dbDriver != "sqlite" && empty(uConfig::$dbuser))) { + if ($dbDriver == "sqlite") { + $required = "\$dbdsn"; + } else { + $required = "\$dbdsn, \$dbuser, \$dbpass"; + } + $messages[] = sprintf($langSetup["nodbsettings"], $required); $messages[] = $langSetup["dorestart"]; $messages[] = "
"; break; } - $messages[] = sprintf($langSetup["scriptdesc"], "'$tPositions', '$tTracks', '$tUsers'", "" . uConfig::$dbname . ""); + $messages[] = sprintf($langSetup["scriptdesc"], "'$tPositions', '$tTracks', '$tUsers'", "" . getDbname(uConfig::$dbdsn) . ""); $messages[] = $langSetup["scriptdesc2"]; $messages[] = "
"; break; } -function getQueries($db) { - $driver = $db->getAttribute(PDO::ATTR_DRIVER_NAME); +function getQueries($pdo) { + global $tPositions, $tUsers, $tTracks, $dbDriver; + $queries = []; - switch($driver) { + switch($dbDriver) { case "mysql": // users $queries[] = "DROP TABLE IF EXISTS `$tUsers`"; @@ -262,6 +272,29 @@ function getQueries($db) { default: throw InvalidArgumentException("Driver not supported"); } + return $queries; +} + +function getDbname($dsn) { + if (strpos($dsn, ':') !== false) { + list($scheme, $dsnWithoutScheme) = explode(':', $dsn, 2); + switch ($scheme) { + case 'sqlite': + case 'sqlite2': + case 'sqlite3': + return $dsnWithoutScheme; + break; + + default: + $pattern = '~dbname=([^;]*)(?:;|$)~'; + $result = preg_match($pattern, $dsnWithoutScheme, $matches); + if ($result === 1 && !empty($matches[1])) { + return $matches[1]; + } + break; + } + } + return "noname"; } ?> diff --git a/scripts/ulogger.sqlite b/scripts/ulogger.sqlite new file mode 100644 index 0000000..2171d96 --- /dev/null +++ b/scripts/ulogger.sqlite @@ -0,0 +1,68 @@ +-- +-- Database: `ulogger` +-- + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `users` +-- + +DROP TABLE IF EXISTS `users`; +CREATE TABLE `users` ( + `id` integer PRIMARY KEY AUTOINCREMENT, + `login` varchar(15) NOT NULL UNIQUE, + `password` varchar(255) NOT NULL DEFAULT '' +); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `tracks` +-- + +DROP TABLE IF EXISTS `tracks`; +CREATE TABLE `tracks` ( + `id` integer PRIMARY KEY AUTOINCREMENT, + `user_id` integer NOT NULL, + `name` varchar(255) DEFAULT NULL, + `comment` varchar(1024) DEFAULT NULL, + FOREIGN KEY(`user_id`) REFERENCES `users`(`id`) +); +CREATE INDEX `idx_user_id` ON `tracks`(`user_id`); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `positions` +-- + +DROP TABLE IF EXISTS `positions`; +CREATE TABLE `positions` ( + `id` integer PRIMARY KEY AUTOINCREMENT, + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `user_id` integer NOT NULL, + `track_id` integer NOT NULL, + `latitude` double NOT NULL, + `longitude` double NOT NULL, + `altitude` double DEFAULT NULL, + `speed` double DEFAULT NULL, + `bearing` double DEFAULT NULL, + `accuracy` integer DEFAULT NULL, + `provider` varchar(100) DEFAULT NULL, + `comment` varchar(255) DEFAULT NULL, + `image_id` integer DEFAULT NULL, + FOREIGN KEY(`user_id`) REFERENCES `users`(`id`), + FOREIGN KEY(`track_id`) REFERENCES `tracks`(`id`) +); +CREATE INDEX `idx_ptrack_id` ON `positions`(`track_id`); +CREATE INDEX `idx_puser_id` ON `positions`(`user_id`); + +-- +-- This will add default user admin with password admin +-- The password should be changed immediatelly after installation +-- Uncomment if needed +-- +-- INSERT INTO `users` (`id`, `login`, `password`) VALUES +-- (1, 'admin', '$2y$10$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq'); diff --git a/utils/export.php b/utils/export.php index db668ed..2f30666 100755 --- a/utils/export.php +++ b/utils/export.php @@ -57,9 +57,9 @@ function toHMS($s) { return (($d > 0) ? "$d d " : "") . sprintf("%02d:%02d:%02d", $h, $m, $s); } -$type = uUtils::postString('type', 'kml'); -$userId = uUtils::postInt('userid'); -$trackId = uUtils::postInt('trackid'); +$type = uUtils::getString('type', 'kml'); +$userId = uUtils::getInt('userid'); +$trackId = uUtils::getInt('trackid'); if (!uConfig::$public_tracks && (!$auth->isAuthenticated() || (!$auth->isAdmin() && $auth->user->id !== $userId))) {