Merge branch 'pdo'

This commit is contained in:
Bartek Fabiszewski 2019-01-30 23:24:42 +01:00
commit 7e796990d4
37 changed files with 1008 additions and 761 deletions

View File

@ -3,24 +3,53 @@
DB_ROOT_PASS=$1 DB_ROOT_PASS=$1
DB_USER_PASS=$2 DB_USER_PASS=$2
mkdir -p /run/mysqld
mkdir -p /run/nginx mkdir -p /run/nginx
chown mysql:mysql /run/mysqld
chown nginx:nginx /run/nginx chown nginx:nginx /run/nginx
mysql_install_db --user=mysql # Fix permission issues on mounted volume in macOS
mysqld_safe & sed -i "s/^nobody:.*$/nobody:x:1000:50::nobody:\/:\/sbin\/nologin/" /etc/passwd
mysqladmin --silent --wait=30 ping sed -i "s/^nobody:.*$/nobody:x:50:/" /etc/group
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/^\$dbuser = .*$/\$dbuser = \"ulogger\";/" /var/www/html/config.php
sed -i "s/^\$dbpass = .*$/\$dbpass = \"${DB_USER_PASS}\";/" /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
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
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

View File

@ -16,6 +16,10 @@ echo "---------------------"
grep '^\$' /var/www/html/config.php grep '^\$' /var/www/html/config.php
# start services # start services
mysqld_safe & if [ "$ULOGGER_DB_DRIVER" = "pgsql" ]; then
su postgres -c 'pg_ctl -D /data start'
elif [ "$ULOGGER_DB_DRIVER" = "mysql" ]; then
mysqld_safe --datadir=/data &
fi
nginx nginx
php-fpm7 -F php-fpm7 -F

View File

@ -1,17 +1,6 @@
<?xml version="1.0"?> <?xml version="1.0" ?>
<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <dataset>
<database name="ulogger"> <users id="1" login="admin" password="$2y$10$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq" />
<table_data name="positions"> <tracks />
</table_data> <positions />
<table_data name="tracks"> </dataset>
</table_data>
<table_data name="users">
<!-- admin:admin -->
<row>
<field name="id">1</field>
<field name="login">admin</field>
<field name="password">$2y$10$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq</field>
</row>
</table_data>
</database>
</mysqldump>

View File

@ -1,11 +1,6 @@
<?xml version="1.0"?> <?xml version="1.0" ?>
<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <dataset>
<database name="ulogger"> <users />
<table_data name="positions"> <tracks />
</table_data> <positions />
<table_data name="tracks"> </dataset>
</table_data>
<table_data name="users">
</table_data>
</database>
</mysqldump>

View File

@ -5,6 +5,7 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase
static private $pdo = null; static private $pdo = null;
private $conn = null; private $conn = null;
static private $driver = "mysql";
protected $testUser = "testUser"; protected $testUser = "testUser";
protected $testUser2 = "testUser2"; protected $testUser2 = "testUser2";
@ -29,26 +30,30 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase
protected $testComment = "test comment"; protected $testComment = "test comment";
protected $testImageId = 1; 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() { public static function setUpBeforeClass() {
if (file_exists(__DIR__ . '/../.env')) { if (file_exists(__DIR__ . '/../.env')) {
$dotenv = new Dotenv\Dotenv(__DIR__ . '/..'); $dotenv = new Dotenv\Dotenv(__DIR__ . '/..');
$dotenv->load(); $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_dsn = getenv('DB_DSN');
$db_name = getenv('DB_NAME');
$db_user = getenv('DB_USER'); $db_user = getenv('DB_USER');
$db_pass = getenv('DB_PASS'); $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 // pdo connection
if (self::$pdo == null) { 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,7 +80,20 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase
* @return PHPUnit_Extensions_Database_DataSet_IDataSet * @return PHPUnit_Extensions_Database_DataSet_IDataSet
*/ */
protected function getDataSet() { protected function getDataSet() {
return $this->createMySQLXMLDataSet(__DIR__ . '/../fixtures/fixture_empty.xml'); $this->resetAutoincrement();
return $this->createFlatXMLDataSet(__DIR__ . '/../fixtures/fixture_empty.xml');
}
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'");
}
} }
/** /**
@ -180,8 +198,38 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase
if (is_null($longitude)) { $longitude = $this->testLon; } if (is_null($longitude)) { $longitude = $this->testLon; }
$query = "INSERT INTO positions (user_id, track_id, time, latitude, longitude) $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); 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 "DATETIME($column, 'unixepoch')";
break;
}
}
} }
?> ?>

View File

@ -26,7 +26,8 @@ class UloggerAPITestCase extends BaseDatabaseTestCase {
} }
protected function getDataSet() { protected function getDataSet() {
return $this->createMySQLXMLDataSet(__DIR__ . '/../fixtures/fixture_admin.xml'); $this->resetAutoincrement(2);
return $this->createFlatXMLDataSet(__DIR__ . '/../fixtures/fixture_admin.xml');
} }
/** /**

View File

@ -14,21 +14,19 @@ class UloggerDatabaseTestCase extends BaseDatabaseTestCase {
if (file_exists(__DIR__ . '/../.env')) { if (file_exists(__DIR__ . '/../.env')) {
$dotenv = new Dotenv\Dotenv(__DIR__ . '/..'); $dotenv = new Dotenv\Dotenv(__DIR__ . '/..');
$dotenv->load(); $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_dsn = getenv('DB_DSN');
$db_name = getenv('DB_NAME');
$db_user = getenv('DB_USER'); $db_user = getenv('DB_USER');
$db_pass = getenv('DB_PASS'); $db_pass = getenv('DB_PASS');
$db_port = getenv('DB_PORT') ?: NULL;
// uDb connection // uDb connection
if (self::$udb == null) { if (self::$udb == null) {
self::$udb = new ReflectionClass("uDb"); self::$udb = new ReflectionClass("uDb");
$dbInstance = self::$udb->getProperty('instance'); $dbInstance = self::$udb->getProperty('instance');
$dbInstance->setAccessible(true); $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));
} }
} }

View File

@ -8,19 +8,10 @@ require_once(__DIR__ . "/../../helpers/config.php");
class AuthTest extends UloggerDatabaseTestCase { class AuthTest extends UloggerDatabaseTestCase {
public function setUp() { public function setUp() {
$_REQUEST = [];
$_SESSION = []; $_SESSION = [];
parent::setUp(); parent::setUp();
} }
private function request($user, $pass) {
$request = [];
$request["action"] = "auth";
$request["user"] = $user;
$request["pass"] = $pass;
return $request;
}
/** /**
* @runInSeparateProcess * @runInSeparateProcess
*/ */
@ -28,11 +19,9 @@ class AuthTest extends UloggerDatabaseTestCase {
$this->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT)); $this->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT));
$this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count"); $this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count");
$_REQUEST = $this->request($this->testUser, $this->testPass);
$auth = new uAuth(); $auth = new uAuth();
$auth->checkLogin($this->testUser, $this->testPass);
$this->assertTrue($auth->isAuthenticated(), "Not authenticated"); $this->assertTrue($auth->isAuthenticated(), "Not authenticated");
$this->assertTrue($auth->isLoginAttempt(), "Not login attempt");
$this->assertTrue($auth->user instanceof uUser, "User variable not set"); $this->assertTrue($auth->user instanceof uUser, "User variable not set");
$this->assertEquals($this->testUser, $auth->user->login, "Wrong login"); $this->assertEquals($this->testUser, $auth->user->login, "Wrong login");
$this->assertEquals($_SESSION["user"]->login, $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->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT));
$this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count"); $this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count");
$_REQUEST = $this->request($this->testUser, "badPass");
$auth = new uAuth(); $auth = new uAuth();
$auth->checkLogin($this->testUser, "badPass");
$this->assertFalse($auth->isAuthenticated(), "Should not be authenticated"); $this->assertFalse($auth->isAuthenticated(), "Should not be authenticated");
$this->assertTrue($auth->isLoginAttempt(), "Not login attempt");
$this->assertTrue(is_null($auth->user), "User not null"); $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->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT));
$this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count"); $this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count");
$_REQUEST = $this->request("", $this->testPass);
$auth = new uAuth(); $auth = new uAuth();
$auth->checkLogin("", $this->testPass);
$this->assertFalse($auth->isAuthenticated(), "Should not be authenticated"); $this->assertFalse($auth->isAuthenticated(), "Should not be authenticated");
$this->assertTrue($auth->isLoginAttempt(), "Not login attempt");
$this->assertTrue(is_null($auth->user), "User not null"); $this->assertTrue(is_null($auth->user), "User not null");
} }
@ -78,7 +63,6 @@ class AuthTest extends UloggerDatabaseTestCase {
$auth = new uAuth(); $auth = new uAuth();
$this->assertFalse($auth->isAuthenticated(), "Should not be authenticated"); $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"); $this->assertTrue(is_null($auth->user), "User not null");
} }
@ -98,7 +82,6 @@ class AuthTest extends UloggerDatabaseTestCase {
@$auth = new uAuth(); @$auth = new uAuth();
$this->assertTrue($auth->isAuthenticated(), "Should be authenticated"); $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"); $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->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT));
$this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count"); $this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count");
$_REQUEST = $this->request($this->testUser, $this->testPass);
$user = new uUser($this->testUser); $user = new uUser($this->testUser);
$this->assertTrue($user->isValid, "User not valid"); $this->assertTrue($user->isValid, "User not valid");
session_name("ulogger"); session_name("ulogger");
@ -119,8 +100,8 @@ class AuthTest extends UloggerDatabaseTestCase {
unset($user); unset($user);
@$auth = new uAuth(); @$auth = new uAuth();
$auth->checkLogin($this->testUser, $this->testPass);
$this->assertTrue($auth->isAuthenticated(), "Should be authenticated"); $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"); $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->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT));
$this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count"); $this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count");
$_REQUEST = $this->request($this->testUser, $this->testPass);
@$auth = new uAuth(); @$auth = new uAuth();
$auth->checkLogin($this->testUser, $this->testPass);
$this->assertTrue($auth->isAuthenticated(), "Should be authenticated"); $this->assertTrue($auth->isAuthenticated(), "Should be authenticated");
$this->assertFalse($auth->isAdmin(), "Should not be admin"); $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"); $this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count");
uConfig::$admin_user = $this->testUser; uConfig::$admin_user = $this->testUser;
$_REQUEST = $this->request($this->testUser, $this->testPass);
@$auth = new uAuth(); @$auth = new uAuth();
$auth->checkLogin($this->testUser, $this->testPass);
$this->assertTrue($auth->isAuthenticated(), "Should be authenticated"); $this->assertTrue($auth->isAuthenticated(), "Should be authenticated");
$this->assertTrue($auth->isAdmin(), "Should not be admin"); $this->assertTrue($auth->isAdmin(), "Should not be admin");
} }

View File

@ -43,7 +43,6 @@ class ClientAPITest extends UloggerAPITestCase {
public function testAddUser() { public function testAddUser() {
$this->assertTrue($this->authenticate(), "Authentication failed"); $this->assertTrue($this->authenticate(), "Authentication failed");
$this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count"); $this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count");
$options = [ $options = [
@ -251,7 +250,7 @@ class ClientAPITest extends UloggerAPITestCase {
]; ];
$actual = $this->getConnection()->createQueryTable( $actual = $this->getConnection()->createQueryTable(
"positions", "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"); $this->assertTableContains($expected, $actual, "Wrong actual table data");
} }

View File

@ -90,7 +90,7 @@ class ImportTest extends UloggerAPITestCase {
]; ];
$actual = $this->getConnection()->createQueryTable( $actual = $this->getConnection()->createQueryTable(
"positions", "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" altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions"
); );
$this->assertTableContains($expected, $actual, "Wrong actual table data"); $this->assertTableContains($expected, $actual, "Wrong actual table data");
@ -206,7 +206,7 @@ class ImportTest extends UloggerAPITestCase {
]; ];
$actual = $this->getConnection()->createQueryTable( $actual = $this->getConnection()->createQueryTable(
"positions", "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" altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions"
); );
$this->assertTableContains($expected, $actual, "Wrong actual table data"); $this->assertTableContains($expected, $actual, "Wrong actual table data");
@ -306,7 +306,7 @@ class ImportTest extends UloggerAPITestCase {
]; ];
$actual = $this->getConnection()->createQueryTable( $actual = $this->getConnection()->createQueryTable(
"positions", "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" altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions"
); );
$this->assertTableContains($expected, $actual, "Wrong actual table data"); $this->assertTableContains($expected, $actual, "Wrong actual table data");
@ -387,7 +387,7 @@ class ImportTest extends UloggerAPITestCase {
]; ];
$actual = $this->getConnection()->createQueryTable( $actual = $this->getConnection()->createQueryTable(
"positions", "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" altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions"
); );
$this->assertTableContains($expected, $actual, "Wrong actual table data"); $this->assertTableContains($expected, $actual, "Wrong actual table data");
@ -474,7 +474,7 @@ class ImportTest extends UloggerAPITestCase {
]; ];
$actual = $this->getConnection()->createQueryTable( $actual = $this->getConnection()->createQueryTable(
"positions", "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" altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions"
); );
$this->assertTableContains($expected, $actual, "Wrong actual table data"); $this->assertTableContains($expected, $actual, "Wrong actual table data");
@ -586,7 +586,7 @@ class ImportTest extends UloggerAPITestCase {
]; ];
$actual = $this->getConnection()->createQueryTable( $actual = $this->getConnection()->createQueryTable(
"positions", "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" altitude, speed, bearing, accuracy, provider, comment, image_id FROM positions"
); );
$this->assertTableContains($expected, $actual, "Wrong actual table data"); $this->assertTableContains($expected, $actual, "Wrong actual table data");

View File

@ -21,9 +21,9 @@ class InternalAPITest extends UloggerAPITestCase {
$options = [ $options = [
"http_errors" => false, "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"); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code");
$xml = $this->getXMLfromResponse($response); $xml = $this->getXMLfromResponse($response);
@ -60,9 +60,9 @@ class InternalAPITest extends UloggerAPITestCase {
$options = [ $options = [
"http_errors" => false, "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"); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code");
$xml = $this->getXMLfromResponse($response); $xml = $this->getXMLfromResponse($response);
@ -100,9 +100,9 @@ class InternalAPITest extends UloggerAPITestCase {
$options = [ $options = [
"http_errors" => false, "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"); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code");
$xml = $this->getXMLfromResponse($response); $xml = $this->getXMLfromResponse($response);
@ -124,9 +124,9 @@ class InternalAPITest extends UloggerAPITestCase {
$options = [ $options = [
"http_errors" => false, "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"); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code");
$xml = $this->getXMLfromResponse($response); $xml = $this->getXMLfromResponse($response);
@ -162,9 +162,9 @@ class InternalAPITest extends UloggerAPITestCase {
$options = [ $options = [
"http_errors" => false, "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"); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code");
$xml = $this->getXMLfromResponse($response); $xml = $this->getXMLfromResponse($response);
@ -192,9 +192,9 @@ class InternalAPITest extends UloggerAPITestCase {
$options = [ $options = [
"http_errors" => false, "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"); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code");
$xml = $this->getXMLfromResponse($response); $xml = $this->getXMLfromResponse($response);
@ -211,9 +211,9 @@ class InternalAPITest extends UloggerAPITestCase {
$options = [ $options = [
"http_errors" => false, "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"); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code");
$xml = $this->getXMLfromResponse($response); $xml = $this->getXMLfromResponse($response);
@ -237,9 +237,9 @@ class InternalAPITest extends UloggerAPITestCase {
$options = [ $options = [
"http_errors" => false, "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"); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code");
$xml = $this->getXMLfromResponse($response); $xml = $this->getXMLfromResponse($response);
@ -267,9 +267,9 @@ class InternalAPITest extends UloggerAPITestCase {
$options = [ $options = [
"http_errors" => false, "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"); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code");
$xml = $this->getXMLfromResponse($response); $xml = $this->getXMLfromResponse($response);
@ -297,9 +297,9 @@ class InternalAPITest extends UloggerAPITestCase {
$options = [ $options = [
"http_errors" => false, "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"); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code");
$xml = $this->getXMLfromResponse($response); $xml = $this->getXMLfromResponse($response);
@ -320,7 +320,7 @@ class InternalAPITest extends UloggerAPITestCase {
$options = [ $options = [
"http_errors" => false, "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"); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code");
$xml = $this->getXMLfromResponse($response); $xml = $this->getXMLfromResponse($response);
$this->assertTrue($xml !== false, "XML object is not false"); $this->assertTrue($xml !== false, "XML object is not false");
@ -336,9 +336,9 @@ class InternalAPITest extends UloggerAPITestCase {
$options = [ $options = [
"http_errors" => false, "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"); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code");
$xml = $this->getXMLfromResponse($response); $xml = $this->getXMLfromResponse($response);

View File

@ -7,18 +7,19 @@ require_once(__DIR__ . "/../../helpers/track.php");
class PositionTest extends UloggerDatabaseTestCase { class PositionTest extends UloggerDatabaseTestCase {
public function testAddPosition() { 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"); $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->assertEquals(0, $this->getConnection()->getRowCount('positions'), "Wrong row count");
$this->assertFalse($posId, "Adding position with nonexistant track should fail"); $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->assertEquals(0, $this->getConnection()->getRowCount('positions'), "Wrong row count");
$this->assertFalse($posId, "Adding position with wrong user should fail"); $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"); $this->assertEquals(1, $this->getConnection()->getRowCount('positions'), "Wrong row count");
$expected = [ $expected = [
"id" => $posId, "id" => $posId,
@ -37,60 +38,66 @@ class PositionTest extends UloggerDatabaseTestCase {
]; ];
$actual = $this->getConnection()->createQueryTable( $actual = $this->getConnection()->createQueryTable(
"positions", "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"); $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"); $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"); $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"); $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"); $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"); $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"); $this->assertFalse($posId, "Adding position with empty longitude should fail");
} }
public function testDeleteAll() { public function testDeleteAll() {
$trackId = $this->addTestTrack($this->testUserId); $userId = $this->addTestUser();
$this->addTestPosition($this->testUserId, $trackId); $userId2 = $this->addTestUser($this->testUser2);
$trackId2 = $this->addTestTrack($this->testUserId); $trackId = $this->addTestTrack($userId);
$this->addTestPosition($this->testUserId, $trackId2); $this->addTestPosition($userId, $trackId);
$trackId3 = $this->addTestTrack($this->testUserId2); $trackId2 = $this->addTestTrack($userId);
$this->addTestPosition($this->testUserId2, $trackId3); $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('tracks'), "Wrong row count");
$this->assertEquals(3, $this->getConnection()->getRowCount('positions'), "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"); $this->assertEquals(1, $this->getConnection()->getRowCount('positions'), "Wrong row count");
} }
public function testDeleteAllWIthTrackId() { public function testDeleteAllWIthTrackId() {
$trackId = $this->addTestTrack($this->testUserId); $userId = $this->addTestUser();
$this->addTestPosition($this->testUserId, $trackId); $userId2 = $this->addTestUser($this->testUser2);
$trackId2 = $this->addTestTrack($this->testUserId); $trackId = $this->addTestTrack($userId);
$this->addTestPosition($this->testUserId, $trackId2); $this->addTestPosition($userId, $trackId);
$trackId3 = $this->addTestTrack($this->testUserId2); $trackId2 = $this->addTestTrack($userId);
$this->addTestPosition($this->testUserId2, $trackId3); $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('tracks'), "Wrong row count");
$this->assertEquals(3, $this->getConnection()->getRowCount('positions'), "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"); $this->assertEquals(2, $this->getConnection()->getRowCount('positions'), "Wrong row count");
} }
public function testGetLast() { public function testGetLast() {
$trackId1 = $this->addTestTrack($this->testUserId); $userId = $this->addTestUser();
$trackId2 = $this->addTestTrack($this->testUserId); $userId2 = $this->addTestUser($this->testUser2);
$pos1 = $this->addTestPosition($this->testUserId, $trackId1, $this->testTimestamp + 3); $trackId1 = $this->addTestTrack($userId);
$pos2 = $this->addTestPosition($this->testUserId2, $trackId2, $this->testTimestamp + 1); $trackId2 = $this->addTestTrack($userId);
$pos3 = $this->addTestPosition($this->testUserId, $trackId1, $this->testTimestamp); $pos1 = $this->addTestPosition($userId, $trackId1, $this->testTimestamp + 3);
$pos4 = $this->addTestPosition($this->testUserId2, $trackId2, $this->testTimestamp + 2); $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(2, $this->getConnection()->getRowCount('tracks'), "Wrong row count");
$this->assertEquals(4, $this->getConnection()->getRowCount('positions'), "Wrong row count"); $this->assertEquals(4, $this->getConnection()->getRowCount('positions'), "Wrong row count");
$lastPosition = uPosition::getLast(); $lastPosition = uPosition::getLast();
@ -100,40 +107,45 @@ class PositionTest extends UloggerDatabaseTestCase {
} }
public function testGetAll() { public function testGetAll() {
$trackId = $this->addTestTrack($this->testUserId); $userId = $this->addTestUser();
$this->addTestPosition($this->testUserId, $trackId); $userId2 = $this->addTestUser($this->testUser2);
$trackId2 = $this->addTestTrack($this->testUserId); $userId3 = $this->addTestUser("testUser3");
$this->addTestPosition($this->testUserId, $trackId2); $trackId = $this->addTestTrack($userId);
$trackId3 = $this->addTestTrack($this->testUserId2); $this->addTestPosition($userId, $trackId);
$this->addTestPosition($this->testUserId2, $trackId3); $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('tracks'), "Wrong row count");
$this->assertEquals(3, $this->getConnection()->getRowCount('positions'), "Wrong row count"); $this->assertEquals(3, $this->getConnection()->getRowCount('positions'), "Wrong row count");
$posArr = uPosition::getAll(); $posArr = uPosition::getAll();
$this->assertEquals(3, count($posArr), "Wrong row count"); $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"); $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"); $this->assertEquals(1, count($posArr), "Wrong row count");
$posArr = uPosition::getAll(NULL, $trackId); $posArr = uPosition::getAll(NULL, $trackId);
$this->assertEquals(1, count($posArr), "Wrong row count"); $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"); $this->assertEquals(0, count($posArr), "Wrong row count");
} }
public function testDistanceTo() { public function testDistanceTo() {
$trackId = $this->addTestTrack($this->testUserId); $userId = $this->addTestUser();
$pos1 = $this->addTestPosition($this->testUserId, $trackId, $this->testTimestamp, 0, 0); $trackId = $this->addTestTrack($userId);
$pos2 = $this->addTestPosition($this->testUserId, $trackId, $this->testTimestamp, 0, 1); $pos1 = $this->addTestPosition($userId, $trackId, $this->testTimestamp, 0, 0);
$pos2 = $this->addTestPosition($userId, $trackId, $this->testTimestamp, 0, 1);
$posArr = uPosition::getAll(); $posArr = uPosition::getAll();
$this->assertEquals(2, count($posArr), "Wrong row count"); $this->assertEquals(2, count($posArr), "Wrong row count");
$this->assertEquals(111195, round($posArr[0]->distanceTo($posArr[1])), "Wrong distance"); $this->assertEquals(111195, round($posArr[0]->distanceTo($posArr[1])), "Wrong distance");
} }
public function testSecondsTo() { public function testSecondsTo() {
$trackId = $this->addTestTrack($this->testUserId); $userId = $this->addTestUser();
$pos1 = $this->addTestPosition($this->testUserId, $trackId, $this->testTimestamp); $trackId = $this->addTestTrack($userId);
$pos2 = $this->addTestPosition($this->testUserId, $trackId, $this->testTimestamp + 1); $pos1 = $this->addTestPosition($userId, $trackId, $this->testTimestamp);
$pos2 = $this->addTestPosition($userId, $trackId, $this->testTimestamp + 1);
$posArr = uPosition::getAll(); $posArr = uPosition::getAll();
$this->assertEquals(2, count($posArr), "Wrong row count"); $this->assertEquals(2, count($posArr), "Wrong row count");
$this->assertEquals(-1, $posArr[0]->secondsTo($posArr[1]), "Wrong time difference"); $this->assertEquals(-1, $posArr[0]->secondsTo($posArr[1]), "Wrong time difference");

View File

@ -7,7 +7,9 @@ require_once(__DIR__ . "/../../helpers/track.php");
class TrackTest extends UloggerDatabaseTestCase { class TrackTest extends UloggerDatabaseTestCase {
public function testAddTrack() { public function testAddTrack() {
$this->addTestUser();
$trackId = uTrack::add($this->testUserId, $this->testTrackName, $this->testTrackComment); $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, $this->getConnection()->getRowCount('tracks'), "Wrong row count");
$this->assertEquals(1, $trackId, "Wrong track id returned"); $this->assertEquals(1, $trackId, "Wrong track id returned");
$expected = [ "id" => $trackId, "user_id" => $this->testUserId, "name" => $this->testTrackName, "comment" => $this->testTrackComment ]; $expected = [ "id" => $trackId, "user_id" => $this->testUserId, "name" => $this->testTrackName, "comment" => $this->testTrackComment ];
@ -19,8 +21,9 @@ class TrackTest extends UloggerDatabaseTestCase {
} }
public function testDeleteTrack() { public function testDeleteTrack() {
$trackId = $this->addTestTrack($this->testUserId); $userId = $this->addTestUser();
$this->addTestPosition($this->testUserId, $trackId); $trackId = $this->addTestTrack($userId);
$this->addTestPosition($userId, $trackId);
$this->assertEquals(1, $this->getConnection()->getRowCount('tracks'), "Wrong row count"); $this->assertEquals(1, $this->getConnection()->getRowCount('tracks'), "Wrong row count");
$this->assertEquals(1, $this->getConnection()->getRowCount('positions'), "Wrong row count"); $this->assertEquals(1, $this->getConnection()->getRowCount('positions'), "Wrong row count");
@ -32,20 +35,22 @@ class TrackTest extends UloggerDatabaseTestCase {
} }
public function testAddPosition() { 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"); $this->assertEquals(1, $this->getConnection()->getRowCount('tracks'), "Wrong row count");
$track = new uTrack($trackId + 1); $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->assertEquals(0, $this->getConnection()->getRowCount('positions'), "Wrong row count");
$this->assertFalse($posId, "Adding position with nonexistant track should fail"); $this->assertFalse($posId, "Adding position with nonexistant track should fail");
$track = new uTrack($trackId); $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->assertEquals(0, $this->getConnection()->getRowCount('positions'), "Wrong row count");
$this->assertFalse($posId, "Adding position with wrong user should fail"); $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"); $this->assertEquals(1, $this->getConnection()->getRowCount('positions'), "Wrong row count");
$expected = [ $expected = [
"id" => $posId, "id" => $posId,
@ -64,28 +69,28 @@ class TrackTest extends UloggerDatabaseTestCase {
]; ];
$actual = $this->getConnection()->createQueryTable( $actual = $this->getConnection()->createQueryTable(
"positions", "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"); $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"); $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"); $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"); $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"); $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"); $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"); $this->assertFalse($posId, "Adding position with empty longitude should fail");
} }
public function testGetAll() { public function testGetAll() {
$this->addTestTrack(); $this->addTestTrack($this->addTestUser());
$this->addTestTrack(); $this->addTestTrack($this->addTestUser($this->testUser2));
$this->assertEquals(2, $this->getConnection()->getRowCount('tracks'), "Wrong row count"); $this->assertEquals(2, $this->getConnection()->getRowCount('tracks'), "Wrong row count");
$trackArr = uTrack::getAll(); $trackArr = uTrack::getAll();
@ -94,24 +99,27 @@ class TrackTest extends UloggerDatabaseTestCase {
} }
public function testDeleteAll() { public function testDeleteAll() {
$trackId = $this->addTestTrack(); $userId = $this->addTestUser();
$this->addTestTrack(); $trackId = $this->addTestTrack($userId);
$this->addTestPosition($this->testUserId, $trackId); $this->addTestTrack($userId);
$this->addTestPosition($userId, $trackId);
$trackId2 = $this->addTestTrack($this->testUserId2); $userId2 = $this->addTestUser($this->testUser2);
$this->addTestPosition($this->testUserId2, $trackId2); $trackId2 = $this->addTestTrack($userId2);
$this->addTestPosition($userId2, $trackId2);
$this->assertEquals(3, $this->getConnection()->getRowCount('tracks'), "Wrong row count"); $this->assertEquals(3, $this->getConnection()->getRowCount('tracks'), "Wrong row count");
$this->assertEquals(2, $this->getConnection()->getRowCount('positions'), "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('tracks'), "Wrong row count");
$this->assertEquals(1, $this->getConnection()->getRowCount('positions'), "Wrong row count"); $this->assertEquals(1, $this->getConnection()->getRowCount('positions'), "Wrong row count");
$this->assertFalse(uTrack::deleteAll(NULL), "User id should not be empty"); $this->assertFalse(uTrack::deleteAll(NULL), "User id should not be empty");
} }
public function testUpdate() { public function testUpdate() {
$trackId = $this->addTestTrack(); $userId = $this->addTestUser();
$trackId = $this->addTestTrack($userId);
$track = new uTrack($trackId); $track = new uTrack($trackId);
$track->update("newName", "newComment"); $track->update("newName", "newComment");
$expected = [ "id" => $trackId, "user_id" => $this->testUserId, "name" => "newName", "comment" => "newComment" ]; $expected = [ "id" => $trackId, "user_id" => $this->testUserId, "name" => "newName", "comment" => "newComment" ];
@ -123,7 +131,8 @@ class TrackTest extends UloggerDatabaseTestCase {
} }
public function testIsValid() { public function testIsValid() {
$trackId = $this->addTestTrack(); $userId = $this->addTestUser();
$trackId = $this->addTestTrack($userId);
$trackValid = new uTrack($trackId); $trackValid = new uTrack($trackId);
$this->assertTrue($trackValid->isValid, "Track should be valid"); $this->assertTrue($trackValid->isValid, "Track should be valid");
$trackInvalid = new uTrack($trackId + 1); $trackInvalid = new uTrack($trackId + 1);

View File

@ -4,6 +4,7 @@ LABEL maintainer="Bartek Fabiszewski (https://github.com/bfabiszewski)"
ARG DB_ROOT_PASS=secret1 ARG DB_ROOT_PASS=secret1
ARG DB_USER_PASS=secret2 ARG DB_USER_PASS=secret2
ARG DB_DRIVER=mysql
ENV ULOGGER_ADMIN_USER admin ENV ULOGGER_ADMIN_USER admin
ENV ULOGGER_PASS_STRENGTH 0 ENV ULOGGER_PASS_STRENGTH 0
@ -13,8 +14,16 @@ ENV ULOGGER_PUBLIC_TRACKS 0
ENV ULOGGER_GKEY "" ENV ULOGGER_GKEY ""
ENV ULOGGER_LANG en ENV ULOGGER_LANG en
ENV ULOGGER_UNITS metric 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 COPY .docker/run.sh /run.sh
RUN chmod +x /run.sh RUN chmod +x /run.sh
@ -37,6 +46,6 @@ RUN ln -sf /dev/stdout /var/log/nginx/access.log && \
EXPOSE 80 EXPOSE 80
VOLUME ["/var/lib/mysql"] VOLUME ["/data"]
CMD ["/run.sh"] CMD ["/run.sh"]

View File

@ -47,18 +47,25 @@
require_once(dirname(__DIR__) . "/helpers/auth.php"); require_once(dirname(__DIR__) . "/helpers/auth.php");
$action = uUtils::postString('action');
$auth = new uAuth(); $auth = new uAuth();
if (!$auth->isAuthenticated()) { if (!$auth->isAuthenticated() && $action != "auth") {
$auth->sendUnauthorizedHeader(); $auth->sendUnauthorizedHeader();
exitWithError("Unauthorized"); exitWithError("Unauthorized");
} }
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null;
switch ($action) { switch ($action) {
// action: authorize // action: authorize
case "auth": case "auth":
$login = uUtils::postString('user');
$pass = uUtils::postPass('pass');
if ($auth->checkLogin($login, $pass)) {
exitWithSuccess(); exitWithSuccess();
} else {
$auth->sendUnauthorizedHeader();
exitWithError("Unauthorized");
}
break; break;
// action: adduser (currently unused) // action: adduser (currently unused)
@ -66,8 +73,8 @@
if (!$auth->user->isAdmin) { if (!$auth->user->isAdmin) {
exitWithError("Not allowed"); exitWithError("Not allowed");
} }
$login = isset($_REQUEST['login']) ? $_REQUEST['login'] : NULL; $login = uUtils::postString('login');
$pass = isset($_REQUEST['password']) ? $_REQUEST['password'] : NULL; $pass = uUtils::postPass('password');
if (empty($login) || empty($pass)) { if (empty($login) || empty($pass)) {
exitWithError("Empty login or password"); exitWithError("Empty login or password");
} }
@ -80,7 +87,7 @@
// action: addtrack // action: addtrack
case "addtrack": case "addtrack":
$trackName = isset($_REQUEST['track']) ? $_REQUEST['track'] : NULL; $trackName = uUtils::postString('track');
if (empty($trackName)) { if (empty($trackName)) {
exitWithError("Missing required parameter"); exitWithError("Missing required parameter");
} }
@ -95,19 +102,19 @@
// action: addposition // action: addposition
case "addpos": case "addpos":
$lat = isset($_REQUEST["lat"]) ? $_REQUEST["lat"] : NULL; $lat = uUtils::postFloat('lat');
$lon = isset($_REQUEST["lon"]) ? $_REQUEST["lon"] : NULL; $lon = uUtils::postFloat('lon');
$timestamp = isset($_REQUEST["time"]) ? $_REQUEST["time"] : NULL; $timestamp = uUtils::postInt('time');
$altitude = isset($_REQUEST["altitude"]) ? $_REQUEST["altitude"] : NULL; $altitude = uUtils::postFloat('altitude');
$speed = isset($_REQUEST["speed"]) ? $_REQUEST["speed"] : NULL; $speed = uUtils::postFloat('speed');
$bearing = isset($_REQUEST["bearing"]) ? $_REQUEST["bearing"] : NULL; $bearing = uUtils::postFloat('bearing');
$accuracy = isset($_REQUEST["accuracy"]) ? $_REQUEST["accuracy"] : NULL; $accuracy = uUtils::postInt('accuracy');
$provider = isset($_REQUEST["provider"]) ? $_REQUEST["provider"] : NULL; $provider = uUtils::postString('provider');
$comment = isset($_REQUEST["comment"]) ? $_REQUEST["comment"] : NULL; $comment = uUtils::postString('comment');
$imageId = isset($_REQUEST["imageid"]) ? $_REQUEST["imageid"] : NULL; $imageId = uUtils::postInt('imageid');
$trackId = isset($_REQUEST["trackid"]) ? $_REQUEST["trackid"] : NULL; $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"); exitWithError("Missing required parameter");
} }

View File

@ -41,10 +41,9 @@ $init_longitude = 21.01;
$gkey = ""; $gkey = "";
// MySQL config // MySQL config
$dbhost = ""; // mysql host, eg. localhost $dbdsn = ""; // DSN eg. "mysql:host=localhost;port=3307;dbname=testdb;charset=utf8"
$dbuser = ""; // database user $dbuser = ""; // database user
$dbpass = ""; // database pass $dbpass = ""; // database pass
$dbname = ""; // database name
$dbprefix = ""; // optional table names prefix, eg. "ulogger_" $dbprefix = ""; // optional table names prefix, eg. "ulogger_"
// other // other

View File

@ -28,7 +28,6 @@
class uAuth { class uAuth {
private $isAuthenticated = false; private $isAuthenticated = false;
private $isLoginAttempt = false;
public $user = null; public $user = null;
public function __construct() { public function __construct() {
@ -37,8 +36,6 @@
$user = (new uUser())->getFromSession(); $user = (new uUser())->getFromSession();
if ($user->isValid) { if ($user->isValid) {
$this->setAuthenticated($user); $this->setAuthenticated($user);
} else {
$this->checkLogin();
} }
} }
@ -51,15 +48,6 @@
return $this->isAuthenticated; 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 * Is authenticated user admin
* *
@ -121,22 +109,19 @@
* *
* @return void * @return void
*/ */
private function checkLogin() { public function checkLogin($login, $pass) {
$action = isset($_REQUEST["action"]) ? $_REQUEST["action"] : NULL; if (!is_null($login) && !is_null($pass)) {
$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;
if (!empty($login) && !empty($pass)) { if (!empty($login) && !empty($pass)) {
$user = new uUser($login); $user = new uUser($login);
if ($user->isValid && $user->validPassword($pass)) { if ($user->isValid && $user->validPassword($pass)) {
$this->setAuthenticated($user); $this->setAuthenticated($user);
$this->sessionCleanup(); $this->sessionCleanup();
$user->storeInSession(); $user->storeInSession();
return true;
} }
} }
} }
return false;
} }
/** /**

View File

@ -44,10 +44,9 @@
static $init_longitude = 21.01; static $init_longitude = 21.01;
// MySQL config // MySQL config
static $dbhost = ""; // mysql host, eg. localhost static $dbdsn = ""; // database dsn
static $dbuser = ""; // database user static $dbuser = ""; // database user
static $dbpass = ""; // database pass static $dbpass = ""; // database pass
static $dbname = ""; // database name
static $dbprefix = ""; // optional table names prefix, eg. "ulogger_" static $dbprefix = ""; // optional table names prefix, eg. "ulogger_"
// require login/password authentication // require login/password authentication
@ -114,10 +113,9 @@
if (isset($ol_layers)) { self::$ol_layers = $ol_layers; } if (isset($ol_layers)) { self::$ol_layers = $ol_layers; }
if (isset($init_latitude)) { self::$init_latitude = $init_latitude; } if (isset($init_latitude)) { self::$init_latitude = $init_latitude; }
if (isset($init_longitude)) { self::$init_longitude = $init_longitude; } 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($dbuser)) { self::$dbuser = $dbuser; }
if (isset($dbpass)) { self::$dbpass = $dbpass; } if (isset($dbpass)) { self::$dbpass = $dbpass; }
if (isset($dbname)) { self::$dbname = $dbname; }
if (isset($dbprefix)) { self::$dbprefix = $dbprefix; } if (isset($dbprefix)) { self::$dbprefix = $dbprefix; }
if (isset($require_authentication)) { self::$require_authentication = (bool) $require_authentication; } if (isset($require_authentication)) { self::$require_authentication = (bool) $require_authentication; }
if (isset($public_tracks)) { self::$public_tracks = (bool) $public_tracks; } if (isset($public_tracks)) { self::$public_tracks = (bool) $public_tracks; }

View File

@ -20,9 +20,9 @@
require_once(ROOT_DIR . "/helpers/config.php"); require_once(ROOT_DIR . "/helpers/config.php");
/** /**
* mysqli wrapper * PDO wrapper
*/ */
class uDb extends mysqli { class uDb extends PDO {
/** /**
* Singleton instance * Singleton instance
* *
@ -38,23 +38,34 @@
protected static $tables; protected static $tables;
/** /**
* Private constuctor * Database driver name
* *
* @param string $host * @var String Driver
*/
protected static $driver;
/**
* PDO constuctor
*
* @param string $dsn
* @param string $user * @param string $user
* @param string $pass * @param string $pass
* @param string $name
* @param int $port
* @param string $socket
*/ */
public function __construct($host, $user, $pass, $name, $port = null, $socket = null) { public function __construct($dsn, $user, $pass) {
@parent::__construct($host, $user, $pass, $name, $port, $socket); try {
if ($this->connect_error) { $options = [
header("HTTP/1.1 503 Service Unavailable"); PDO::ATTR_EMULATE_PREPARES => false, // try to use native prepared statements
die("Database connection error (" . $this->connect_error . ")"); PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // throw exceptions
} PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // return assoc array by default
$this->set_charset('utf8'); ];
@parent::__construct($dsn, $user, $pass, $options);
self::$driver = $this->getAttribute(PDO::ATTR_DRIVER_NAME);
$this->setCharset("utf8");
$this->initTables(); $this->initTables();
} catch (PDOException $e) {
header("HTTP/1.1 503 Service Unavailable");
die("Database connection error (" . $e->getMessage() . ")");
}
} }
/** /**
@ -75,7 +86,7 @@
*/ */
public static function getInstance() { public static function getInstance() {
if (!self::$instance) { 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; return self::$instance;
} }
@ -89,5 +100,41 @@
public function table($name) { public function table($name) {
return self::$tables[$name]; return self::$tables[$name];
} }
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 "DATETIME($column, 'unixepoch')";
break;
}
}
private function setCharset($charset) {
if (self::$driver == "pgsql" || self::$driver == "mysql") {
$this->query("SET NAMES '$charset'");
}
}
} }
?> ?>

View File

@ -24,20 +24,35 @@
* Positions handling * Positions handling
*/ */
class uPosition { class uPosition {
/** @param int Position id */
public $id; public $id;
/** @param int Unix time stamp */
public $timestamp; public $timestamp;
/** @param int User id */
public $userId; public $userId;
/** @param String User login */
public $userLogin; public $userLogin;
/** @param int Track id */
public $trackId; public $trackId;
/** @param String Track name */
public $trackName; public $trackName;
/** @param double Latitude */
public $latitude; public $latitude;
/** @param double Longitude */
public $longitude; public $longitude;
/** @param double Altitude */
public $altitude; public $altitude;
/** @param double Speed */
public $speed; public $speed;
/** @param double Bearing */
public $bearing; public $bearing;
/** @param int Accuracy */
public $accuracy; public $accuracy;
/** @param String Provider */
public $provider; public $provider;
/** @param String Comment */
public $comment; // not used yet public $comment; // not used yet
/** @param int Image id */
public $imageId; // not used yet public $imageId; // not used yet
public $isValid = false; public $isValid = false;
@ -51,15 +66,20 @@
public function __construct($positionId = NULL) { public function __construct($positionId = NULL) {
if (!empty($positionId)) { 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.latitude, p.longitude, p.altitude, p.speed, p.bearing, p.accuracy, p.provider,
p.comment, p.image_id, u.login, t.name p.comment, p.image_id, u.login, t.name
FROM `" . self::db()->table('positions') . "` p FROM " . self::db()->table('positions') . " p
LEFT JOIN `" . self::db()->table('users') . "` u ON (p.user_id = u.id) 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) LEFT JOIN " . self::db()->table('tracks') . " t ON (p.track_id = t.id)
WHERE id = ? LIMIT 1"; WHERE id = ? LIMIT 1";
$params = [ 'i', $positionId ]; $params = [ $positionId ];
try {
$this->loadWithQuery($query, $params); $this->loadWithQuery($query, $params);
} catch (PDOException $e) {
// TODO: handle exception
syslog(LOG_ERR, $e->getMessage());
}
} }
} }
@ -80,7 +100,7 @@
* *
* @param int $userId * @param int $userId
* @param int $trackId * @param int $trackId
* @param int $time Unix time stamp * @param int $timestamp Unix time stamp
* @param double $lat * @param double $lat
* @param double $lon * @param double $lon
* @param double $altitude Optional * @param double $altitude Optional
@ -99,19 +119,21 @@
if (is_numeric($lat) && is_numeric($lon) && is_numeric($timestamp) && is_numeric($userId) && is_numeric($trackId)) { if (is_numeric($lat) && is_numeric($lon) && is_numeric($timestamp) && is_numeric($userId) && is_numeric($trackId)) {
$track = new uTrack($trackId); $track = new uTrack($trackId);
if ($track->isValid && $track->userId == $userId) { if ($track->isValid && $track->userId == $userId) {
$query = "INSERT INTO `" . self::db()->table('positions') . "` try {
$table = self::db()->table('positions');
$query = "INSERT INTO $table
(user_id, track_id, (user_id, track_id,
time, latitude, longitude, altitude, speed, bearing, accuracy, provider, comment, image_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); $stmt = self::db()->prepare($query);
$stmt->bind_param('iisddddddssi', $params = [ $userId, $trackId,
$userId, $trackId, $timestamp, $lat, $lon, $altitude, $speed, $bearing, $accuracy, $provider, $comment, $imageId ];
$timestamp, $lat, $lon, $altitude, $speed, $bearing, $accuracy, $provider, $comment, $imageId); $stmt->execute($params);
$stmt->execute(); $positionId = self::db()->lastInsertId("${table}_id_seq");
if (!self::db()->error && !$stmt->errno) { } catch (PDOException $e) {
$positionId = self::db()->insert_id; // TODO: handle error
syslog(LOG_ERR, $e->getMessage());
} }
$stmt->close();
} }
} }
return $positionId; return $positionId;
@ -129,21 +151,20 @@
if (!empty($userId)) { if (!empty($userId)) {
$args = []; $args = [];
$where = "WHERE user_id = ?"; $where = "WHERE user_id = ?";
$args[0] = "i"; $args[] = $userId;
$args[1] = &$userId;
if (!empty($trackId)) { if (!empty($trackId)) {
$where .= " AND track_id = ?"; $where .= " AND track_id = ?";
$args[0] .= "i"; $args[] = $trackId;
$args[2] = &$trackId;
} }
$query = "DELETE FROM `" . self::db()->table('positions') . "` $where"; try {
$query = "DELETE FROM " . self::db()->table('positions') . " $where";
$stmt = self::db()->prepare($query); $stmt = self::db()->prepare($query);
call_user_func_array([ $stmt, 'bind_param' ], $args); $stmt->execute($args);
$stmt->execute();
if (!self::db()->error && !$stmt->errno) {
$ret = true; $ret = true;
} catch (PDOException $e) {
// TODO: handle exception
syslog(LOG_ERR, $e->getMessage());
} }
$stmt->close();
} }
return $ret; return $ret;
} }
@ -158,21 +179,26 @@
public static function getLast($userId = NULL) { public static function getLast($userId = NULL) {
if (!empty($userId)) { if (!empty($userId)) {
$where = "WHERE p.user_id = ?"; $where = "WHERE p.user_id = ?";
$params = [ 'i', $userId ]; $params = [ $userId ];
} else { } else {
$where = ""; $where = "";
$params = NULL; $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.latitude, p.longitude, p.altitude, p.speed, p.bearing, p.accuracy, p.provider,
p.comment, p.image_id, u.login, t.name p.comment, p.image_id, u.login, t.name
FROM `" . self::db()->table('positions') . "` p FROM " . self::db()->table('positions') . " p
LEFT JOIN `" . self::db()->table('users') . "` u ON (p.user_id = u.id) 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) LEFT JOIN " . self::db()->table('tracks') . " t ON (p.track_id = t.id)
$where $where
ORDER BY p.time DESC, p.id DESC LIMIT 1"; ORDER BY p.time DESC, p.id DESC LIMIT 1";
$position = new uPosition(); $position = new uPosition();
try {
$position->loadWithQuery($query, $params); $position->loadWithQuery($query, $params);
} catch (PDOException $e) {
// TODO: handle exception
syslog(LOG_ERR, $e->getMessage());
}
return $position; return $position;
} }
@ -186,33 +212,34 @@
public static function getAll($userId = NULL, $trackId = NULL) { public static function getAll($userId = NULL, $trackId = NULL) {
$rules = []; $rules = [];
if (!empty($userId)) { if (!empty($userId)) {
$rules[] = "p.user_id = '" . self::db()->real_escape_string($userId) ."'"; $rules[] = "p.user_id = " . self::db()->quote($userId);
} }
if (!empty($trackId)) { if (!empty($trackId)) {
$rules[] = "p.track_id = '" . self::db()->real_escape_string($trackId) ."'"; $rules[] = "p.track_id = " . self::db()->quote($trackId);
} }
if (!empty($rules)) { if (!empty($rules)) {
$where = "WHERE " . implode(" AND ", $rules); $where = "WHERE " . implode(" AND ", $rules);
} else { } else {
$where = ""; $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.latitude, p.longitude, p.altitude, p.speed, p.bearing, p.accuracy, p.provider,
p.comment, p.image_id, u.login, t.name p.comment, p.image_id, u.login, t.name
FROM `" . self::db()->table('positions') . "` p FROM " . self::db()->table('positions') . " p
LEFT JOIN `" . self::db()->table('users') . "` u ON (p.user_id = u.id) 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) LEFT JOIN " . self::db()->table('tracks') . " t ON (p.track_id = t.id)
$where $where
ORDER BY p.time, p.id"; ORDER BY p.time, p.id";
$result = self::db()->query($query); try {
if ($result === false) {
return false;
}
$positionsArr = []; $positionsArr = [];
while ($row = $result->fetch_assoc()) { $result = self::db()->query($query);
while ($row = $result->fetch()) {
$positionsArr[] = self::rowToObject($row); $positionsArr[] = self::rowToObject($row);
} }
$result->close(); } catch (PDOException $e) {
// TODO: handle exception
syslog(LOG_ERR, $e->getMessage());
}
return $positionsArr; return $positionsArr;
} }
@ -274,28 +301,32 @@
* Fill class properties with database query result * Fill class properties with database query result
* *
* @param string $query Query * @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); $stmt = self::db()->prepare($query);
if (is_array($bindParams)) { $stmt->execute($params);
$params = [];
foreach ($bindParams as &$value) { $stmt->bindColumn('id', $this->id, PDO::PARAM_INT);
$params[] =& $value; $stmt->bindColumn('tstamp', $this->timestamp, PDO::PARAM_INT);
} $stmt->bindColumn('user_id', $this->userId, PDO::PARAM_INT);
call_user_func_array([ $stmt, 'bind_param' ], $params); $stmt->bindColumn('track_id', $this->trackId, PDO::PARAM_INT);
} $stmt->bindColumn('latitude', $this->latitude);
if ($stmt->execute()) { $stmt->bindColumn('longitude', $this->longitude);
$stmt->bind_result($this->id, $this->timestamp, $this->userId, $this->trackId, $stmt->bindColumn('altitude', $this->altitude);
$this->latitude, $this->longitude, $this->altitude, $this->speed, $stmt->bindColumn('speed', $this->speed);
$this->bearing, $this->accuracy, $this->provider, $stmt->bindColumn('bearing', $this->bearing);
$this->comment, $this->imageId, $this->userLogin, $this->trackName); $stmt->bindColumn('accuracy', $this->accuracy, PDO::PARAM_INT);
if ($stmt->fetch()) { $stmt->bindColumn('provider', $this->provider);
$stmt->bindColumn('comment', $this->comment);
$stmt->bindColumn('image_id', $this->imageId, PDO::PARAM_INT);
$stmt->bindColumn('login', $this->userLogin);
$stmt->bindColumn('name', $this->trackName);
if ($stmt->fetch(PDO::FETCH_BOUND)) {
$this->isValid = true; $this->isValid = true;
} }
} }
$stmt->close();
}
} }
?> ?>

View File

@ -41,15 +41,21 @@
public function __construct($trackId = NULL) { public function __construct($trackId = NULL) {
if (!empty($trackId)) { if (!empty($trackId)) {
$query = "SELECT id, user_id, name, comment FROM `" . self::db()->table('tracks') . "` WHERE id = ? LIMIT 1"; try {
$query = "SELECT id, user_id, name, comment FROM " . self::db()->table('tracks') . " WHERE id = ? LIMIT 1";
$stmt = self::db()->prepare($query); $stmt = self::db()->prepare($query);
$stmt->bind_param('i', $trackId); $stmt->execute([$trackId]);
$stmt->execute(); $stmt->bindColumn('id', $this->id, PDO::PARAM_INT);
$stmt->bind_result($this->id, $this->userId, $this->name, $this->comment); $stmt->bindColumn('user_id', $this->userId, PDO::PARAM_INT);
if ($stmt->fetch()) { $stmt->bindColumn('name', $this->name);
$stmt->bindColumn('comment', $this->comment);
if ($stmt->fetch(PDO::FETCH_BOUND)) {
$this->isValid = true; $this->isValid = true;
} }
$stmt->close(); } catch (PDOException $e) {
// TODO: handle exception
syslog(LOG_ERR, $e->getMessage());
}
} }
} }
@ -77,14 +83,17 @@
public static function add($userId, $name, $comment = NULL) { public static function add($userId, $name, $comment = NULL) {
$trackId = false; $trackId = false;
if (!empty($userId) && !empty($name)) { if (!empty($userId) && !empty($name)) {
$query = "INSERT INTO `" . self::db()->table('tracks') . "` (user_id, name, comment) VALUES (?, ?, ?)"; try {
$table = self::db()->table('tracks');
$query = "INSERT INTO $table (user_id, name, comment) VALUES (?, ?, ?)";
$stmt = self::db()->prepare($query); $stmt = self::db()->prepare($query);
$stmt->bind_param('iss', $userId, $name, $comment); $params = [ $userId, $name, $comment ];
$stmt->execute(); $stmt->execute($params);
if (!self::db()->error && !$stmt->errno) { $trackId = self::db()->lastInsertId("${table}_id_seq");
$trackId = self::db()->insert_id; } catch (PDOException $e) {
// TODO: handle exception
syslog(LOG_ERR, $e->getMessage());
} }
$stmt->close();
} }
return $trackId; return $trackId;
} }
@ -125,19 +134,20 @@
return false; return false;
} }
// delete track metadata // delete track metadata
$query = "DELETE FROM `" . self::db()->table('tracks') . "` WHERE id = ?"; try {
$query = "DELETE FROM " . self::db()->table('tracks') . " WHERE id = ?";
$stmt = self::db()->prepare($query); $stmt = self::db()->prepare($query);
$stmt->bind_param('i', $this->id); $stmt->execute([ $this->id ]);
$stmt->execute();
if (!self::db()->error && !$stmt->errno) {
$ret = true; $ret = true;
$this->id = NULL; $this->id = NULL;
$this->userId = NULL; $this->userId = NULL;
$this->name = NULL; $this->name = NULL;
$this->comment = NULL; $this->comment = NULL;
$this->isValid = false; $this->isValid = false;
} catch (PDOException $e) {
// TODO: handle exception
syslog(LOG_ERR, $e->getMessage());
} }
$stmt->close();
} }
return $ret; return $ret;
} }
@ -155,16 +165,18 @@
if (is_null($comment)) { $comment = $this->comment; } if (is_null($comment)) { $comment = $this->comment; }
if ($comment == "") { $comment = NULL; } if ($comment == "") { $comment = NULL; }
if ($this->isValid) { if ($this->isValid) {
$query = "UPDATE `" . self::db()->table('tracks') . "` SET name = ?, comment = ? WHERE id = ?"; try {
$query = "UPDATE " . self::db()->table('tracks') . " SET name = ?, comment = ? WHERE id = ?";
$stmt = self::db()->prepare($query); $stmt = self::db()->prepare($query);
$stmt->bind_param('ssi', $name, $comment, $this->id); $params = [ $name, $comment, $this->id ];
$stmt->execute(); $stmt->execute($params);
if (!self::db()->error && !$stmt->errno) {
$ret = true; $ret = true;
$this->name = $name; $this->name = $name;
$this->comment = $comment; $this->comment = $comment;
} catch (PDOException $e) {
// TODO: handle exception
syslog(LOG_ERR, $e->getMessage());
} }
$stmt->close();
} }
return $ret; return $ret;
} }
@ -181,14 +193,15 @@
// remove all positions // remove all positions
if (uPosition::deleteAll($userId) === true) { if (uPosition::deleteAll($userId) === true) {
// remove all tracks // remove all tracks
$query = "DELETE FROM `" . self::db()->table('tracks') . "` WHERE user_id = ?"; try {
$query = "DELETE FROM " . self::db()->table('tracks') . " WHERE user_id = ?";
$stmt = self::db()->prepare($query); $stmt = self::db()->prepare($query);
$stmt->bind_param('i', $userId); $stmt->execute([ $userId ]);
$stmt->execute();
if (!self::db()->error && !$stmt->errno) {
$ret = true; $ret = true;
} catch (PDOException $e) {
// TODO: handle exception
syslog(LOG_ERR, $e->getMessage());
} }
$stmt->close();
} }
} }
@ -203,20 +216,22 @@
*/ */
public static function getAll($userId = NULL) { public static function getAll($userId = NULL) {
if (!empty($userId)) { if (!empty($userId)) {
$where = "WHERE user_id='" . self::db()->real_escape_string($userId) ."'"; $where = "WHERE user_id=" . self::db()->quote($userId);
} else { } else {
$where = ""; $where = "";
} }
$query = "SELECT id, user_id, name, comment FROM `" . self::db()->table('tracks') . "` $where ORDER BY id DESC"; $query = "SELECT id, user_id, name, comment FROM " . self::db()->table('tracks') . " $where ORDER BY id DESC";
try {
$result = self::db()->query($query); $result = self::db()->query($query);
if ($result === false) {
return false;
}
$trackArr = []; $trackArr = [];
while ($row = $result->fetch_assoc()) { while ($row = $result->fetch()) {
$trackArr[] = self::rowToObject($row); $trackArr[] = self::rowToObject($row);
} }
$result->close(); } catch (PDOException $e) {
// TODO: handle exception
syslog(LOG_ERR, $e->getMessage());
$trackArr = false;
}
return $trackArr; return $trackArr;
} }

View File

@ -43,17 +43,22 @@
*/ */
public function __construct($login = NULL) { public function __construct($login = NULL) {
if (!empty($login)) { if (!empty($login)) {
$sql = "SELECT id, login, password FROM `" . self::db()->table('users') . "` WHERE login = ? LIMIT 1"; try {
$stmt = self::db()->prepare($sql); $query = "SELECT id, login, password FROM " . self::db()->table('users') . " WHERE login = ? LIMIT 1";
$stmt->bind_param('s', $login); $stmt = self::db()->prepare($query);
$stmt->execute(); $stmt->execute([ $login ]);
$stmt->bind_result($this->id, $this->login, $this->hash); $stmt->bindColumn('id', $this->id, PDO::PARAM_INT);
if ($stmt->fetch()) { $stmt->bindColumn('login', $this->login);
$stmt->bindColumn('password', $this->hash);
if ($stmt->fetch(PDO::FETCH_BOUND)) {
$this->isValid = true; $this->isValid = true;
}
$stmt->close();
$this->isAdmin = self::isAdmin($this->login); $this->isAdmin = self::isAdmin($this->login);
} }
} catch (PDOException $e) {
// TODO: handle exception
syslog(LOG_ERR, $e->getMessage());
}
}
} }
/** /**
@ -79,14 +84,16 @@
$userid = false; $userid = false;
if (!empty($login) && !empty($pass) && self::validPassStrength($pass)) { if (!empty($login) && !empty($pass) && self::validPassStrength($pass)) {
$hash = password_hash($pass, PASSWORD_DEFAULT); $hash = password_hash($pass, PASSWORD_DEFAULT);
$sql = "INSERT INTO `" . self::db()->table('users') . "` (login, password) VALUES (?, ?)"; $table = self::db()->table('users');
$stmt = self::db()->prepare($sql); try {
$stmt->bind_param('ss', $login, $hash); $query = "INSERT INTO $table (login, password) VALUES (?, ?)";
$stmt->execute(); $stmt = self::db()->prepare($query);
if (!self::db()->error && !$stmt->errno) { $stmt->execute([ $login, $hash ]);
$userid = self::db()->insert_id; $userid = self::db()->lastInsertId("${table}_id_seq");
} catch (PDOException $e) {
// TODO: handle exception
syslog(LOG_ERR, $e->getMessage());
} }
$stmt->close();
} }
return $userid; return $userid;
} }
@ -105,19 +112,20 @@
return false; return false;
} }
// remove user // remove user
$sql = "DELETE FROM `" . self::db()->table('users') . "` WHERE id = ?"; try {
$stmt = self::db()->prepare($sql); $query = "DELETE FROM " . self::db()->table('users') . " WHERE id = ?";
$stmt->bind_param('i', $this->id); $stmt = self::db()->prepare($query);
$stmt->execute(); $stmt->execute([ $this->id ]);
if (!self::db()->error && !$stmt->errno) {
$ret = true; $ret = true;
$this->id = NULL; $this->id = NULL;
$this->login = NULL; $this->login = NULL;
$this->hash = NULL; $this->hash = NULL;
$this->isValid = false; $this->isValid = false;
$this->isAdmin = false; $this->isAdmin = false;
} catch (PDOException $e) {
// TODO: handle exception
syslog(LOG_ERR, $e->getMessage());
} }
$stmt->close();
} }
return $ret; return $ret;
} }
@ -132,14 +140,15 @@
$ret = false; $ret = false;
if (!empty($this->login) && !empty($pass) && self::validPassStrength($pass)) { if (!empty($this->login) && !empty($pass) && self::validPassStrength($pass)) {
$hash = password_hash($pass, PASSWORD_DEFAULT); $hash = password_hash($pass, PASSWORD_DEFAULT);
$sql = "UPDATE `" . self::db()->table('users') . "` SET password = ? WHERE login = ?"; try {
$stmt = self::db()->prepare($sql); $query = "UPDATE " . self::db()->table('users') . " SET password = ? WHERE login = ?";
$stmt->bind_param('ss', $hash, $this->login); $stmt = self::db()->prepare($query);
$stmt->execute(); $stmt->execute([ $hash, $this->login ]);
if (!self::db()->error && !$stmt->errno) {
$ret = true; $ret = true;
} catch (PDOException $e) {
// TODO: handle exception
syslog(LOG_ERR, $e->getMessage());
} }
$stmt->close();
} }
return $ret; return $ret;
} }
@ -193,16 +202,18 @@
* @return array|bool Array of uUser users, false on error * @return array|bool Array of uUser users, false on error
*/ */
public static function getAll() { public static function getAll() {
$query = "SELECT id, login, password FROM `" . self::db()->table('users') . "` ORDER BY login"; try {
$query = "SELECT id, login, password FROM " . self::db()->table('users') . " ORDER BY login";
$result = self::db()->query($query); $result = self::db()->query($query);
if ($result === false) {
return false;
}
$userArr = []; $userArr = [];
while ($row = $result->fetch_assoc()) { while ($row = $result->fetch()) {
$userArr[] = self::rowToObject($row); $userArr[] = self::rowToObject($row);
} }
$result->close(); } catch (PDOException $e) {
// TODO: handle exception
syslog(LOG_ERR, $e->getMessage());
$userArr = false;
}
return $userArr; return $userArr;
} }

View File

@ -129,6 +129,63 @@
return $proto . str_replace("//", "/", $host . $path . "/"); 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) {
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) {
return self::requestValue($name, $default, INPUT_GET, FILTER_VALIDATE_BOOLEAN);
}
public static function postInt($name, $default = NULL) {
return self::requestInt($name, $default, INPUT_POST);
}
public static function getInt($name, $default = NULL) {
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 $val;
}
}
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;
} else {
return $default;
}
}
} }
?> ?>

View File

@ -24,9 +24,16 @@
require_once(ROOT_DIR . "/helpers/utils.php"); require_once(ROOT_DIR . "/helpers/utils.php");
require_once(ROOT_DIR . "/lang.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"); $auth->exitWithRedirect("login.php?auth_error=1");
} }
if (!$auth->isAuthenticated() && uConfig::$require_authentication) { if (!$auth->isAuthenticated() && uConfig::$require_authentication) {

View File

@ -21,7 +21,7 @@
require_once(ROOT_DIR . "/lang.php"); require_once(ROOT_DIR . "/lang.php");
require_once(ROOT_DIR . "/helpers/config.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);
?> ?>
<!DOCTYPE html> <!DOCTYPE html>

View File

@ -1,222 +0,0 @@
<?php
/* μlogger
*
* Copyright(C) 2017 Bartek Fabiszewski (www.fabiszewski.net)
*
* This is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/* 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();
}
?>

View File

@ -31,82 +31,43 @@ if (version_compare(PHP_VERSION, '5.4.0', '<')) {
define("ROOT_DIR", dirname(__DIR__)); define("ROOT_DIR", dirname(__DIR__));
require_once(ROOT_DIR . "/helpers/user.php"); require_once(ROOT_DIR . "/helpers/user.php");
require_once(ROOT_DIR . "/helpers/config.php"); require_once(ROOT_DIR . "/helpers/config.php");
require_once(ROOT_DIR . "/helpers/utils.php");
require_once(ROOT_DIR . "/lang.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); $prefix = preg_replace('/[^a-z0-9_]/i', '', uConfig::$dbprefix);
$tPositions = $prefix . "positions"; $tPositions = $prefix . "positions";
$tTracks = $prefix . "tracks"; $tTracks = $prefix . "tracks";
$tUsers = $prefix . "users"; $tUsers = $prefix . "users";
$dbDriver = null;
$messages = []; $messages = [];
switch ($command) { switch ($command) {
case "setup": 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; $error = false;
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try { try {
$mysqli = new mysqli(uConfig::$dbhost, uConfig::$dbuser, uConfig::$dbpass, uConfig::$dbname); $options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ];
} catch (mysqli_sql_exception $e ) { $pdo = new PDO(uConfig::$dbdsn, uConfig::$dbuser, uConfig::$dbpass, $options);
$dbDriver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
} catch (PDOException $e ) {
$messages[] = "<span class=\"warn\">{$langSetup["dbconnectfailed"]}</span>"; $messages[] = "<span class=\"warn\">{$langSetup["dbconnectfailed"]}</span>";
$messages[] = sprintf($langSetup["serversaid"], "<b>" . $e->getMessage() . "</b>"); $messages[] = sprintf($langSetup["serversaid"], "<b>" . $e->getMessage() . "</b>");
$messages[] = $langSetup["checkdbsettings"]; $messages[] = $langSetup["checkdbsettings"];
break; break;
} }
try { try {
$mysqli->set_charset('utf8'); $queries = getQueries($pdo);
foreach ($queries as $query) { foreach ($queries as $query) {
$mysqli->query($query); $pdo->query($query);
} }
} catch (mysqli_sql_exception $e) { } catch (PDOException $e) {
$messages[] = "<span class=\"warn\">{$langSetup["dbqueryfailed"]}</span>"; $messages[] = "<span class=\"warn\">{$langSetup["dbqueryfailed"]}</span>";
$messages[] = sprintf($langSetup["serversaid"], "<b>" . $e->getMessage() . "</b>"); $messages[] = sprintf($langSetup["serversaid"], "<b>" . $e->getMessage() . "</b>");
$error = true; $error = true;
} }
$mysqli->close(); $pdo = null;
if (!$error) { if (!$error) {
$messages[] = "<span class=\"ok\">{$langSetup["dbtablessuccess"]}</span>"; $messages[] = "<span class=\"ok\">{$langSetup["dbtablessuccess"]}</span>";
$messages[] = $langSetup["setupuser"]; $messages[] = $langSetup["setupuser"];
@ -121,8 +82,8 @@ switch ($command) {
break; break;
case "adduser": case "adduser":
$login = isset($_REQUEST['login']) ? $_REQUEST['login'] : NULL; $login = uUtils::postString('login');
$pass = isset($_REQUEST['pass']) ? $_REQUEST['pass'] : NULL; $pass = uUtils::postPass('pass');
if (uUser::add($login, $pass) !== false) { if (uUser::add($login, $pass) !== false) {
$messages[] = "<span class=\"ok\">{$langSetup["congratulations"]}</span>"; $messages[] = "<span class=\"ok\">{$langSetup["congratulations"]}</span>";
@ -157,18 +118,185 @@ switch ($command) {
$messages[] = "<form method=\"post\" action=\"setup.php\"><button>{$langSetup["restartbutton"]}</button></form>"; $messages[] = "<form method=\"post\" action=\"setup.php\"><button>{$langSetup["restartbutton"]}</button></form>";
break; break;
} }
if (empty(uConfig::$dbname) || empty(uConfig::$dbhost) || empty(uConfig::$dbuser)) { if (empty(uConfig::$dbdsn) || ($dbDriver != "sqlite" && empty(uConfig::$dbuser))) {
$messages[] = sprintf($langSetup["nodbsettings"], "\$dbname, \$dbhost, \$dbuser, \$dbpass"); if ($dbDriver == "sqlite") {
$required = "\$dbdsn";
} else {
$required = "\$dbdsn, \$dbuser, \$dbpass";
}
$messages[] = sprintf($langSetup["nodbsettings"], $required);
$messages[] = $langSetup["dorestart"]; $messages[] = $langSetup["dorestart"];
$messages[] = "<form method=\"post\" action=\"setup.php\"><button>{$langSetup["restartbutton"]}</button></form>"; $messages[] = "<form method=\"post\" action=\"setup.php\"><button>{$langSetup["restartbutton"]}</button></form>";
break; break;
} }
$messages[] = sprintf($langSetup["scriptdesc"], "'$tPositions', '$tTracks', '$tUsers'", "<b>" . uConfig::$dbname . "</b>"); $messages[] = sprintf($langSetup["scriptdesc"], "'$tPositions', '$tTracks', '$tUsers'", "<b>" . getDbname(uConfig::$dbdsn) . "</b>");
$messages[] = $langSetup["scriptdesc2"]; $messages[] = $langSetup["scriptdesc2"];
$messages[] = "<form method=\"post\" action=\"setup.php\"><input type=\"hidden\" name=\"command\" value=\"setup\"><button>{$langSetup["startbutton"]}</button></form>"; $messages[] = "<form method=\"post\" action=\"setup.php\"><input type=\"hidden\" name=\"command\" value=\"setup\"><button>{$langSetup["startbutton"]}</button></form>";
break; break;
} }
function getQueries($pdo) {
global $tPositions, $tUsers, $tTracks, $dbDriver;
$queries = [];
switch($dbDriver) {
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");
}
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";
}
?> ?>
<!DOCTYPE html> <!DOCTYPE html>

74
scripts/ulogger.pgsql Normal file
View File

@ -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');

View File

@ -5,6 +5,36 @@
CREATE DATABASE IF NOT EXISTS `ulogger` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE DATABASE IF NOT EXISTS `ulogger` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `ulogger`; 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`; DROP TABLE IF EXISTS `positions`;
CREATE TABLE `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, `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`user_id` int(11) NOT NULL, `user_id` int(11) NOT NULL,
`track_id` int(11) NOT NULL, `track_id` int(11) NOT NULL,
@ -25,77 +55,13 @@ CREATE TABLE `positions` (
`accuracy` int(11) DEFAULT NULL, `accuracy` int(11) DEFAULT NULL,
`provider` varchar(100) DEFAULT NULL, `provider` varchar(100) DEFAULT NULL,
`comment` varchar(255) 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; ) 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 -- This will add default user admin with password admin

68
scripts/ulogger.sqlite Normal file
View File

@ -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');

View File

@ -26,10 +26,10 @@
uUtils::exitWithError("Unauthorized"); uUtils::exitWithError("Unauthorized");
} }
$login = isset($_REQUEST['login']) ? trim($_REQUEST['login']) : NULL; $login = uUtils::postString('login');
$oldpass = isset($_REQUEST['oldpass']) ? $_REQUEST['oldpass'] : NULL; $oldpass = uUtils::postPass('oldpass');
$pass = isset($_REQUEST['pass']) ? $_REQUEST['pass'] : NULL; $pass = uUtils::postPass('pass');
// FIXME: stings need to be localized // FIXME: strings need to be localized
if (empty($pass)) { if (empty($pass)) {
uUtils::exitWithError("Empty password"); uUtils::exitWithError("Empty password");
} }

View File

@ -57,9 +57,9 @@ function toHMS($s) {
return (($d > 0) ? "$d d " : "") . sprintf("%02d:%02d:%02d", $h, $m, $s); return (($d > 0) ? "$d d " : "") . sprintf("%02d:%02d:%02d", $h, $m, $s);
} }
$type = isset($_REQUEST["type"]) ? $_REQUEST["type"] : "kml"; $type = uUtils::getString('type', 'kml');
$userId = (isset($_REQUEST["userid"]) && is_numeric($_REQUEST["userid"])) ? (int) $_REQUEST["userid"] : NULL; $userId = uUtils::getInt('userid');
$trackId = (isset($_REQUEST["trackid"]) && is_numeric($_REQUEST["trackid"])) ? (int) $_REQUEST["trackid"] : NULL; $trackId = uUtils::getInt('trackid');
if (!uConfig::$public_tracks && if (!uConfig::$public_tracks &&
(!$auth->isAuthenticated() || (!$auth->isAdmin() && $auth->user->id !== $userId))) { (!$auth->isAuthenticated() || (!$auth->isAdmin() && $auth->user->id !== $userId))) {

View File

@ -23,8 +23,8 @@ require_once(ROOT_DIR . "/helpers/utils.php");
$auth = new uAuth(); $auth = new uAuth();
$userId = (isset($_REQUEST["userid"]) && is_numeric($_REQUEST["userid"])) ? (int) $_REQUEST["userid"] : NULL; $userId = uUtils::getInt('userid');
$trackId = (isset($_REQUEST["trackid"]) && is_numeric($_REQUEST["trackid"])) ? (int) $_REQUEST["trackid"] : NULL; $trackId = uUtils::getInt('trackid');
$positionsArr = []; $positionsArr = [];
if ($userId) { if ($userId) {

View File

@ -22,7 +22,7 @@ require_once(ROOT_DIR . "/helpers/track.php");
$auth = new uAuth(); $auth = new uAuth();
$userId = (isset($_REQUEST["userid"]) && is_numeric($_REQUEST["userid"])) ? (int) $_REQUEST["userid"] : NULL; $userId = uUtils::getInt('userid');
$tracksArr = []; $tracksArr = [];
if ($userId) { if ($userId) {

View File

@ -24,9 +24,10 @@
$auth = new uAuth(); $auth = new uAuth();
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : NULL; $action = uUtils::postString('action');
$trackId = isset($_REQUEST['trackid']) ? trim($_REQUEST['trackid']) : NULL; $trackId = uUtils::postInt('trackid');
$trackName = isset($_REQUEST['trackname']) ? trim($_REQUEST['trackname']) : NULL; $trackName = uUtils::postString('trackname');
if (empty($action) || empty($trackId)) { if (empty($action) || empty($trackId)) {
uUtils::exitWithError($lang["servererror"]); uUtils::exitWithError($lang["servererror"]);
} }

View File

@ -23,9 +23,9 @@
$auth = new uAuth(); $auth = new uAuth();
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : NULL; $action = uUtils::postString('action');
$login = isset($_REQUEST['login']) ? trim($_REQUEST['login']) : NULL; $login = uUtils::postString('login');
$pass = isset($_REQUEST['pass']) ? $_REQUEST['pass'] : NULL; $pass = uUtils::postPass('pass');
if (!$auth->isAuthenticated() || !$auth->isAdmin() || $auth->user->login == $login || empty($action) || empty($login)) { if (!$auth->isAuthenticated() || !$auth->isAdmin() || $auth->user->login == $login || empty($action) || empty($login)) {
uUtils::exitWithError($lang["servererror"]); uUtils::exitWithError($lang["servererror"]);
} }

View File

@ -43,6 +43,8 @@ if (!isset($_FILES["gpx"])) {
$lastErr = error_get_last(); $lastErr = error_get_last();
if (!empty($lastErr)) { if (!empty($lastErr)) {
$message .= ": " . $lastErr["message"]; $message .= ": " . $lastErr["message"];
} else {
$message .= ": no uploaded file";
} }
uUtils::exitWithError($message); uUtils::exitWithError($message);
} }