diff --git a/.docker/run.sh b/.docker/run.sh index 3b79acc..69a94a3 100644 --- a/.docker/run.sh +++ b/.docker/run.sh @@ -1,14 +1,5 @@ #!/bin/sh -# set config variables -sed -i "s/^\$pass_strength = .*$/\$pass_strength = ${ULOGGER_PASS_STRENGTH};/" /var/www/html/config.php -sed -i "s/^\$pass_lenmin = .*$/\$pass_lenmin = ${ULOGGER_PASS_LENMIN};/" /var/www/html/config.php -sed -i "s/^\$require_authentication = .*$/\$require_authentication = ${ULOGGER_REQUIRE_AUTHENTICATION};/" /var/www/html/config.php -sed -i "s/^\$public_tracks = .*$/\$public_tracks = ${ULOGGER_PUBLIC_TRACKS};/" /var/www/html/config.php -sed -i "s/^\$gkey = .*$/\$gkey = \"${ULOGGER_GKEY}\";/" /var/www/html/config.php -sed -i "s/^\$lang = .*$/\$lang = \"${ULOGGER_LANG}\";/" /var/www/html/config.php -sed -i "s/^\$units = .*$/\$units = \"${ULOGGER_UNITS}\";/" /var/www/html/config.php - if [ "${ULOGGER_ENABLE_SETUP}" = "1" ]; then sed -i "s/\$enabled = false;/\$enabled = true;/" /var/www/html/scripts/setup.php; echo "ulogger setup script enabled" diff --git a/.tests/fixtures/fixture_admin.xml b/.tests/fixtures/fixture_admin.xml index c34a854..362bc23 100644 --- a/.tests/fixtures/fixture_admin.xml +++ b/.tests/fixtures/fixture_admin.xml @@ -3,4 +3,6 @@ + + diff --git a/.tests/fixtures/fixture_empty.xml b/.tests/fixtures/fixture_empty.xml index 4a92520..0f69f1a 100644 --- a/.tests/fixtures/fixture_empty.xml +++ b/.tests/fixtures/fixture_empty.xml @@ -3,4 +3,6 @@ + + diff --git a/.tests/lib/BaseDatabaseTestCase.php b/.tests/lib/BaseDatabaseTestCase.php index c347ccd..1c38d02 100644 --- a/.tests/lib/BaseDatabaseTestCase.php +++ b/.tests/lib/BaseDatabaseTestCase.php @@ -91,11 +91,12 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase return $this->createFlatXMLDataSet(__DIR__ . '/../fixtures/fixture_empty.xml'); } - protected function resetAutoincrement($users = 1, $tracks = 1, $positions = 1) { + protected function resetAutoincrement($users = 1, $tracks = 1, $positions = 1, $layers = 1) { if (self::$driver === "pgsql") { self::$pdo->exec("ALTER SEQUENCE users_id_seq RESTART WITH $users"); self::$pdo->exec("ALTER SEQUENCE tracks_id_seq RESTART WITH $tracks"); self::$pdo->exec("ALTER SEQUENCE positions_id_seq RESTART WITH $positions"); + self::$pdo->exec("ALTER SEQUENCE ol_layers_id_seq RESTART WITH $layers"); } else if (self::$driver === "sqlite") { $retry = 1; do { @@ -103,6 +104,7 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase self::$pdo->exec("DELETE FROM sqlite_sequence WHERE NAME = 'users'"); self::$pdo->exec("DELETE FROM sqlite_sequence WHERE NAME = 'tracks'"); self::$pdo->exec("DELETE FROM sqlite_sequence WHERE NAME = 'positions'"); + self::$pdo->exec("DELETE FROM sqlite_sequence WHERE NAME = 'ol_layers'"); $retry = 0; } catch (Exception $e) { // sqlite raises error when db schema changes in another connection. diff --git a/.tests/tests/ConfigTest.php b/.tests/tests/ConfigTest.php index 806cde7..07779f5 100644 --- a/.tests/tests/ConfigTest.php +++ b/.tests/tests/ConfigTest.php @@ -1,13 +1,109 @@ initConfigValues(); + } + + protected function getDataSet() { + $this->initConfigValues(); + $this->resetAutoincrement(); + $dataset = [ + "config" => [ + [ + "map_api" => $this->mapApi, + "latitude" => $this->latitude, + "longitude" => $this->longitude, + "google_key" => $this->googleKey, + "require_auth" => (int) $this->requireAuth, + "public_tracks" => (int) $this->publicTracks, + "pass_lenmin" => $this->passLenMin, + "pass_strength" => $this->passStrength, + "interval_seconds" => $this->interval, + "lang" => $this->lang, + "units" => $this->units, + "stroke_weight" => $this->strokeWeight, + "stroke_color" => hexdec(str_replace('#', '', $this->strokeColor)), + "stroke_opacity" => $this->strokeOpacity * 100 + ] + ], + "ol_layers" => [ + [ + "id" => 1, "name" => $this->testLayer, "url" => $this->testUrl, "priority" => $this->testPriority + ] + ]]; + return $this->createArrayDataSet($dataset); + } + + public function testSetFromDatabase() { + uConfig::setFromDatabase(); + $this->assertEquals($this->mapApi, uConfig::$mapApi); + $this->assertEquals($this->latitude, uConfig::$initLatitude); + $this->assertEquals($this->longitude, uConfig::$initLongitude); + $this->assertEquals($this->googleKey, uConfig::$googleKey); + $this->assertEquals($this->requireAuth, uConfig::$requireAuthentication); + $this->assertEquals($this->publicTracks, uConfig::$publicTracks); + $this->assertEquals($this->passLenMin, uConfig::$passLenMin); + $this->assertEquals($this->passStrength, uConfig::$passStrength); + $this->assertEquals($this->interval, uConfig::$interval); + $this->assertEquals($this->lang, uConfig::$lang); + $this->assertEquals($this->units, uConfig::$units); + $this->assertEquals($this->strokeWeight, uConfig::$strokeWeight); + $this->assertEquals($this->strokeColor, uConfig::$strokeColor); + $this->assertEquals($this->strokeOpacity, uConfig::$strokeOpacity); + + $this->assertEquals($this->testLayer, uConfig::$olLayers[0]->name); + $this->assertEquals($this->testUrl, uConfig::$olLayers[0]->url); + $this->assertEquals($this->testPriority, uConfig::$olLayers[0]->priority); + } + + private function initConfigValues() { + $this->mapApi = 'testApi'; + $this->latitude = 33.33; + $this->longitude = 22.22; + $this->googleKey = 'testKey'; + $this->requireAuth = true; + $this->publicTracks = true; + $this->passLenMin = 3; + $this->passStrength = 3; + $this->interval = 66; + $this->lang = 'pl'; + $this->units = 'nautical'; + $this->strokeWeight = 55; + $this->strokeColor = '#afafaf'; + $this->strokeOpacity = 0.44; + $this->testLayer = 'testLayer'; + $this->testUrl = 'testUrl'; + $this->testPriority = 5; + } public function testPassRegex() { - uConfig::$pass_lenmin = 0; - uConfig::$pass_strength = 0; + uConfig::$passLenMin = 0; + uConfig::$passStrength = 0; $password0 = "password"; $password1 = "PASSword"; $password2 = "PASSword1234"; @@ -19,21 +115,21 @@ class ConfigTest extends TestCase { $this->assertRegExp($regex, $password2, "Regex: \"$regex\", password: \"$password2\""); $this->assertRegExp($regex, $password3, "Regex: \"$regex\", password: \"$password3\""); - uConfig::$pass_strength = 1; + uConfig::$passStrength = 1; $regex = uConfig::passRegex(); $this->assertNotRegExp($regex, $password0, "Regex: \"$regex\", password: \"$password0\""); $this->assertRegExp($regex, $password1, "Regex: \"$regex\", password: \"$password1\""); $this->assertRegExp($regex, $password2, "Regex: \"$regex\", password: \"$password2\""); $this->assertRegExp($regex, $password3, "Regex: \"$regex\", password: \"$password3\""); - uConfig::$pass_strength = 2; + uConfig::$passStrength = 2; $regex = uConfig::passRegex(); $this->assertNotRegExp($regex, $password0, "Regex: \"$regex\", password: \"$password0\""); $this->assertNotRegExp($regex, $password1, "Regex: \"$regex\", password: \"$password1\""); $this->assertRegExp($regex, $password2, "Regex: \"$regex\", password: \"$password2\""); $this->assertRegExp($regex, $password3, "Regex: \"$regex\", password: \"$password3\""); - uConfig::$pass_strength = 3; + uConfig::$passStrength = 3; $regex = uConfig::passRegex(); $this->assertNotRegExp($regex, $password0, "Regex: \"$regex\", password: \"$password0\""); $this->assertNotRegExp($regex, $password1, "Regex: \"$regex\", password: \"$password1\""); @@ -42,18 +138,18 @@ class ConfigTest extends TestCase { $password_len5 = "12345"; $password_len10 = "1234567890"; - uConfig::$pass_lenmin = 5; - uConfig::$pass_strength = 0; + uConfig::$passLenMin = 5; + uConfig::$passStrength = 0; $regex = uConfig::passRegex(); $this->assertRegExp($regex, $password_len5, "Regex: \"$regex\", password: \"$password_len5\""); $this->assertRegExp($regex, $password_len10, "Regex: \"$regex\", password: \"$password_len10\""); - uConfig::$pass_lenmin = 7; + uConfig::$passLenMin = 7; $regex = uConfig::passRegex(); $this->assertNotRegExp($regex, $password_len5, "Regex: \"$regex\", password: \"$password_len5\""); $this->assertRegExp($regex, $password_len10, "Regex: \"$regex\", password: \"$password_len10\""); - uConfig::$pass_lenmin = 12; + uConfig::$passLenMin = 12; $regex = uConfig::passRegex(); $this->assertNotRegExp($regex, $password_len5, "Regex: \"$regex\", password: \"$password_len5\""); $this->assertNotRegExp($regex, $password_len10, "Regex: \"$regex\", password: \"$password_len10\""); diff --git a/.tests/tests/InternalAPITest.php b/.tests/tests/InternalAPITest.php index 8a68d80..6f49c8a 100644 --- a/.tests/tests/InternalAPITest.php +++ b/.tests/tests/InternalAPITest.php @@ -1,7 +1,5 @@ [ "login" => $this->testAdminUser, "oldpass" => "badpass", - "pass" => "newpass", + "pass" => "Newpass1234567890", ], ]; $response = $this->http->post("/utils/changepass.php", $options); @@ -522,7 +520,7 @@ class InternalAPITest extends UloggerAPITestCase { "http_errors" => false, "form_params" => [ "login" => $this->testAdminUser, - "pass" => "newpass", + "pass" => "Newpass1234567890", ], ]; $response = $this->http->post("/utils/changepass.php", $options); @@ -537,7 +535,7 @@ class InternalAPITest extends UloggerAPITestCase { public function testChangePassSelfAdmin() { $this->assertTrue($this->authenticate(), "Authentication failed"); - $newPass = "newpass"; + $newPass = "Newpass1234567890"; $options = [ "http_errors" => false, @@ -559,7 +557,7 @@ class InternalAPITest extends UloggerAPITestCase { $userId = $this->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT)); $this->assertTrue($this->authenticate($this->testUser, $this->testPass), "Authentication failed"); - $newPass = "newpass"; + $newPass = "Newpass1234567890"; $options = [ "http_errors" => false, @@ -581,7 +579,7 @@ class InternalAPITest extends UloggerAPITestCase { $this->assertTrue($this->authenticate(), "Authentication failed"); $userId = $this->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT)); - $newPass = "newpass"; + $newPass = "Newpass1234567890"; $options = [ "http_errors" => false, @@ -599,11 +597,11 @@ class InternalAPITest extends UloggerAPITestCase { } public function testChangePassOtherUser() { - $userId = $this->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT)); - $userId2 = $this->addTestUser($this->testUser2, password_hash($this->testPass, PASSWORD_DEFAULT)); + $this->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT)); + $this->addTestUser($this->testUser2, password_hash($this->testPass, PASSWORD_DEFAULT)); $this->assertTrue($this->authenticate($this->testUser, $this->testPass), "Authentication failed"); - $newPass = "newpass"; + $newPass = "Newpass1234567890"; $options = [ "http_errors" => false, @@ -736,7 +734,7 @@ class InternalAPITest extends UloggerAPITestCase { $this->assertEquals(2, $this->getConnection()->getRowCount("users"), "Wrong row count"); $trackId = $this->addTestTrack($userId); - $trackId2 = $this->addTestTrack($userId); + $this->addTestTrack($userId); $this->assertEquals(2, $this->getConnection()->getRowCount("tracks"), "Wrong row count"); @@ -947,7 +945,6 @@ class InternalAPITest extends UloggerAPITestCase { } public function testHandleUserUpdateEmptyPass() { - $lang = (new uLang("en"))->getStrings(); $this->assertTrue($this->authenticate(), "Authentication failed"); $this->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT)); $this->assertEquals(2, $this->getConnection()->getRowCount("users"), "Wrong row count"); @@ -958,10 +955,7 @@ class InternalAPITest extends UloggerAPITestCase { ]; $response = $this->http->post("/utils/handleuser.php", $options); $this->assertEquals(200, $response->getStatusCode(), "Unexpected status code"); - $json = json_decode($response->getBody()); - $this->assertNotNull($json, "JSON object is null"); - $this->assertEquals(1, (int) $json->error, "Wrong error status"); - $this->assertEquals((string) $json->message, $lang["servererror"], "Wrong error message"); + $this->assertEquals(2, $this->getConnection()->getRowCount("users"), "Wrong row count"); $this->assertTrue(password_verify($this->testPass, $this->pdoGetColumn("SELECT password FROM users WHERE login = '$this->testUser'")), "Wrong actual password hash"); } diff --git a/.tests/tests/SetupTest.php b/.tests/tests/SetupTest.php index 88be791..8c7dc0e 100644 --- a/.tests/tests/SetupTest.php +++ b/.tests/tests/SetupTest.php @@ -38,8 +38,8 @@ class SetupTest extends UloggerAPITestCase { $body = (string) $response->getBody(); $this->assertContains("", $body); $this->assertEquals(2, $this->getConnection()->getRowCount("users"), "Wrong row count"); - $expected = [ "id" => 2, "login" => $this->testUser ]; - $actual = $this->getConnection()->createQueryTable("users", "SELECT id, login FROM users WHERE id = 2"); + $expected = [ "id" => 2, "login" => $this->testUser, "admin" => 1 ]; + $actual = $this->getConnection()->createQueryTable("users", "SELECT id, login, admin FROM users WHERE id = 2"); $this->assertTableContains($expected, $actual, "Wrong actual table data"); $this->assertTrue(password_verify($this->testPass, $this->pdoGetColumn("SELECT password FROM users WHERE id = 2")), "Wrong actual password hash"); } diff --git a/Dockerfile b/Dockerfile index 47ee91f..92804b9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,13 +8,6 @@ ARG DB_USER_PASS=secret2 ARG DB_DRIVER=mysql ENV ULOGGER_ADMIN_USER admin -ENV ULOGGER_PASS_STRENGTH 0 -ENV ULOGGER_PASS_LENMIN 5 -ENV ULOGGER_REQUIRE_AUTHENTICATION 1 -ENV ULOGGER_PUBLIC_TRACKS 0 -ENV ULOGGER_GKEY "" -ENV ULOGGER_LANG en -ENV ULOGGER_UNITS metric ENV ULOGGER_DB_DRIVER ${DB_DRIVER} ENV ULOGGER_ENABLE_SETUP 0 diff --git a/README.md b/README.md index e1e14a9..f6bdb27 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,9 @@ Together with a dedicated [μlogger mobile client](https://github.com/bfabiszews - Database changes: - `ALTER TABLE positions CHANGE image_id image VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL` - `ALTER TABLE users ADD admin BOOLEAN NOT NULL DEFAULT FALSE AFTER password` + - new tables for config values: `config` and `ol_layers`, see SQL files in scripts folder, eg. [mysql](https://github.com/bfabiszewski/ulogger-server/blob/master/scripts/ulogger.mysql) - modify admin user entry in `users` table: set `admin` to `true` +- Config file changes: only database setup is defined in config file, see [config.default.php](https://github.com/bfabiszewski/ulogger-server/blob/master/config.default.php) for valid values ## Docker - Run `docker run --name ulogger -p 8080:80 -d bfabiszewski/ulogger` and access `http://localhost:8080` in your browser. Log in with `admin`:`admin` credentials and change default password. diff --git a/config.default.php b/config.default.php index 62427a1..6c3cc4a 100644 --- a/config.default.php +++ b/config.default.php @@ -20,72 +20,22 @@ // This is default configuration file. // Copy it to config.php and customize -// default map drawing framework -//$mapapi = "gmaps"; // google maps -$mapapi = "openlayers"; // openlayers - -// openlayers additional map layers in XYZ format -// name => url -$ol_layers['OpenCycleMap'] = 'https://{a-c}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png'; // ?apikey=[API_KEY] -$ol_layers['OpenTopoMap'] = 'https://{a-c}.tile.opentopomap.org/{z}/{x}/{y}.png'; -$ol_layers['ESRI'] = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'; -$ol_layers['UMP'] = 'http://{1-3}.tiles.ump.waw.pl/ump_tiles/{z}/{x}/{y}.png'; -$ol_layers['Osmapa.pl'] = 'http://{a-c}.tile.openstreetmap.pl/osmapa.pl/{z}/{x}/{y}.png'; - - -// default coordinates for initial map -$init_latitude = 52.23; -$init_longitude = 21.01; - -// you may set your google maps api key -$gkey = ""; - // Database config -$dbdsn = ""; // DSN eg. "mysql:host=localhost;port=3307;dbname=testdb;charset=utf8" -$dbuser = ""; // database user -$dbpass = ""; // database pass -$dbprefix = ""; // optional table names prefix, eg. "ulogger_" -// other -// require login/password authentication -// (0 = no, 1 = yes) -$require_authentication = 1; +// PDO data source name, eg.: +// mysql:host=localhost;port=3307;dbname=ulogger;charset=utf8 +// mysql:unix_socket=/tmp/mysql.sock;dbname=ulogger;charset=utf8 +// pgsql:host=localhost;port=5432;dbname=ulogger +// sqlite:/tmp/ulogger.db +$dbdsn = ""; -// all users tracks are visible to authenticated user -// (0 = no, 1 = yes) -$public_tracks = 0; +// Database user name +$dbuser = ""; -// miniumum required length of user password -$pass_lenmin = 12; +// Database user password +$dbpass = ""; -// required strength of user password -// 0 = no requirements, -// 1 = require mixed case letters (lower and upper), -// 2 = require mixed case and numbers, -// 3 = require mixed case, numbers and non-alphanumeric characters -$pass_strength = 2; - -// Default interval in seconds for live auto reload -$interval = 10; - -// Default language -// (en, pl, de, hu, fr, it) -$lang = "en"; -//$lang = "pl"; -//$lang = "de"; -//$lang = "hu"; -//$lang = "fr"; -//$lang = "it"; - -// units -// (metric, imperial, nautical) -$units = "metric"; -//$units = "imperial"; -//$units = "nautical"; - -// track line stroke -$strokeWeight = 2; -$strokeColor = '#FF0000'; -$strokeOpacity = 1.0; +// Optional table names prefix, eg. "ulogger_" +$dbprefix = ""; ?> diff --git a/helpers/config.php b/helpers/config.php index 8f4015b..8c12abd 100644 --- a/helpers/config.php +++ b/helpers/config.php @@ -17,218 +17,272 @@ * along with this program; if not, see . */ +require_once(ROOT_DIR . "/helpers/db.php"); +require_once(ROOT_DIR . "/helpers/layer.php"); - /** - * Initialize on file include - */ - uConfig::init(); +/** + * Initialize on file include + */ +uConfig::init(); - /** - * Handles config values - */ - class uConfig { - /** - * @var string Version number - */ - public static $version = "1.0-beta"; +/** + * Handles config values + */ +class uConfig { + /** + * @var string Version number + */ + public static $version = "1.0-beta"; - /** - * @var string Default map drawing framework - */ - public static $mapapi = "openlayers"; + /** + * @var string Default map drawing framework + */ + public static $mapApi = "openlayers"; - /** - * @var string|null Google maps key - */ - public static $gkey; + /** + * @var string|null Google maps key + */ + public static $googleKey; - /** - * @var array Openlayers additional map layers - */ - public static $ol_layers = []; + /** + * @var uLayer[] Openlayers extra map layers + */ + public static $olLayers = []; - /** - * @var float Default latitude for initial map - */ - public static $init_latitude = 52.23; - /** - * @var float Default longitude for initial map - */ - public static $init_longitude = 21.01; + /** + * @var float Default latitude for initial map + */ + public static $initLatitude = 52.23; + /** + * @var float Default longitude for initial map + */ + public static $initLongitude = 21.01; - /** - * @var string Database dsn - */ - public static $dbdsn = ""; - /** - * @var string Database user - */ - public static $dbuser = ""; - /** - * @var string Database pass - */ - public static $dbpass = ""; - /** - * @var string Optional table names prefix, eg. "ulogger_" - */ - public static $dbprefix = ""; + /** + * @var string Database DSN + */ + public static $dbdsn = ""; + /** + * @var string Database user + */ + public static $dbuser = ""; + /** + * @var string Database pass + */ + public static $dbpass = ""; + /** + * @var string Optional table names prefix, eg. "ulogger_" + */ + public static $dbprefix = ""; - /** - * @var bool Require login/password authentication - */ - public static $require_authentication = true; + /** + * @var bool Require login/password authentication + */ + public static $requireAuthentication = true; - /** - * @var bool All users tracks are visible to authenticated user - */ - public static $public_tracks = false; + /** + * @var bool All users tracks are visible to authenticated user + */ + public static $publicTracks = false; - /** - * @var string Admin user who has access to all users locations - * none if empty - */ - public static $admin_user = ""; + /** + * @var int Miniumum required length of user password + */ + public static $passLenMin = 10; - /** - * @var int Miniumum required length of user password - */ - public static $pass_lenmin = 12; + /** + * @var int Required strength of user password + * 0 = no requirements, + * 1 = require mixed case letters (lower and upper), + * 2 = require mixed case and numbers + * 3 = require mixed case, numbers and non-alphanumeric characters + */ + public static $passStrength = 2; - /** - * @var int Required strength of user password - * 0 = no requirements, - * 1 = require mixed case letters (lower and upper), - * 2 = require mixed case and numbers - * 3 = require mixed case, numbers and non-alphanumeric characters - */ - public static $pass_strength = 2; + /** + * @var int Default interval in seconds for live auto reload + */ + public static $interval = 10; - /** - * @var int Default interval in seconds for live auto reload - */ - public static $interval = 10; + /** + * @var string Default language code + */ + public static $lang = "en"; - /** - * @var string Default language code - */ - public static $lang = "en"; + /** + * @var string Default units + */ + public static $units = "metric"; - /** - * @var string Default units - */ - public static $units = "metric"; + /** + * @var int Stroke weight + */ + public static $strokeWeight = 2; + /** + * @var string Stroke color + */ + public static $strokeColor = '#ff0000'; + /** + * @var int Stroke opacity + */ + public static $strokeOpacity = 1; - /** - * @var int Stroke weight - */ - public static $strokeWeight = 2; - /** - * @var string Stroke color - */ - public static $strokeColor = '#ff0000'; - /** - * @var int Stroke opacity - */ - public static $strokeOpacity = 1; + private static $fileLoaded = false; + private static $initialized = false; - private static $fileLoaded = false; - - private static $initialized = false; - - /** - * Static initializer - */ - public static function init() { - if (!self::$initialized) { - self::setFromFile(); - self::setFromCookies(); - self::$initialized = true; - } - } - - /** - * Read config values from "/config.php" file - */ - private static function setFromFile() { - $configFile = ROOT_DIR . "/config.php"; - if (self::$fileLoaded || !file_exists($configFile)) { - return; - } - self::$fileLoaded = true; - include_once($configFile); - - if (isset($mapapi)) { self::$mapapi = $mapapi; } - if (isset($gkey) && !empty($gkey)) { self::$gkey = $gkey; } - if (isset($ol_layers)) { self::$ol_layers = $ol_layers; } - if (isset($init_latitude)) { self::$init_latitude = $init_latitude; } - if (isset($init_longitude)) { self::$init_longitude = $init_longitude; } - if (isset($dbdsn)) { self::$dbdsn = $dbdsn; } - if (isset($dbuser)) { self::$dbuser = $dbuser; } - if (isset($dbpass)) { self::$dbpass = $dbpass; } - if (isset($dbprefix)) { self::$dbprefix = $dbprefix; } - if (isset($require_authentication)) { self::$require_authentication = (bool) $require_authentication; } - if (isset($public_tracks)) { self::$public_tracks = (bool) $public_tracks; } - if (isset($admin_user)) { self::$admin_user = $admin_user; } - if (isset($pass_lenmin)) { self::$pass_lenmin = (int) $pass_lenmin; } - if (isset($pass_strength)) { self::$pass_strength = (int) $pass_strength; } - if (isset($interval)) { self::$interval = (int) $interval; } - if (isset($lang)) { self::$lang = $lang; } - if (isset($units)) { self::$units = $units; } - if (isset($strokeWeight)) { self::$strokeWeight = $strokeWeight; } - if (isset($strokeColor)) { self::$strokeColor = $strokeColor; } - if (isset($strokeOpacity)) { self::$strokeOpacity = $strokeOpacity; } - - if (!self::$require_authentication) { - // tracks must be public if we don't require authentication - self::$public_tracks = true; - } - } - - /** - * Read config values stored in cookies - */ - private static function setFromCookies() { - if (isset($_COOKIE["ulogger_api"])) { self::$mapapi = $_COOKIE["ulogger_api"]; } - if (isset($_COOKIE["ulogger_lang"])) { self::$lang = $_COOKIE["ulogger_lang"]; } - if (isset($_COOKIE["ulogger_units"])) { self::$units = $_COOKIE["ulogger_units"]; } - if (isset($_COOKIE["ulogger_interval"])) { self::$interval = $_COOKIE["ulogger_interval"]; } - } - - /** - * Is config loaded from file? - * - * @return True if loaded, false otherwise - */ - public static function isFileLoaded() { - return self::$fileLoaded; - } - - /** - * Regex to test if password matches strength and length requirements. - * Valid for both php and javascript - */ - public static function passRegex() { - $regex = ""; - if (self::$pass_strength > 0) { - // lower and upper case - $regex .= "(?=.*[a-z])(?=.*[A-Z])"; - } - if (self::$pass_strength > 1) { - // digits - $regex .= "(?=.*[0-9])"; - } - if (self::$pass_strength > 2) { - // not latin, not digits - $regex .= "(?=.*[^a-zA-Z0-9])"; - } - if (self::$pass_lenmin > 0) { - $regex .= "(?=.{" . self::$pass_lenmin . ",})"; - } - if (empty($regex)) { - $regex = ".*"; - } - return "/" . $regex . "/"; + /** + * Static initializer + */ + public static function init() { + if (!self::$initialized) { + self::setFromFile(); + self::setFromDatabase(); + self::setFromCookies(); + self::$initialized = true; } } + /** + * Get db instance + * + * @return uDb instance + */ + private static function db() { + return uDb::getInstance(); + } + + /** + * Read config values from database + */ + public static function setFromDatabase() { + try { + $query = "SELECT map_api, latitude, longitude, google_key, require_auth, public_tracks, + pass_lenmin, pass_strength, interval_seconds, lang, units, + stroke_weight, stroke_color, stroke_opacity + FROM " . self::db()->table('config') . " LIMIT 1"; + $result = self::db()->query($query); + $row = $result->fetch(); + if ($row) { + if (!empty($row['map_api'])) { self::$mapApi = $row['map_api']; } + if (is_numeric($row['latitude'])) { self::$initLatitude = $row['latitude']; } + if (is_numeric($row['longitude'])) { self::$initLongitude = $row['longitude']; } + if (!empty($row['google_key'])) { self::$googleKey = $row['google_key']; } + if (is_numeric($row['require_auth']) || is_bool($row['require_auth'])) { self::$requireAuthentication = (bool) $row['require_auth']; } + if (is_numeric($row['public_tracks']) || is_bool($row['public_tracks'])) { self::$publicTracks = (bool) $row['public_tracks']; } + if (is_numeric($row['pass_lenmin'])) { self::$passLenMin = $row['pass_lenmin']; } + if (is_numeric($row['pass_strength'])) { self::$passStrength = $row['pass_strength']; } + if (is_numeric($row['interval_seconds'])) { self::$interval = $row['interval_seconds']; } + if (!empty($row['lang'])) { self::$lang = $row['lang']; } + if (!empty($row['units'])) { self::$units = $row['units']; } + if (is_numeric($row['stroke_weight'])) { self::$strokeWeight = $row['stroke_weight']; } + if (is_numeric($row['stroke_color'])) { self::$strokeColor = self::getColorAsHex($row['stroke_color']); } + if (is_numeric($row['stroke_opacity'])) { self::$strokeOpacity = $row['stroke_opacity'] / 100; } + } + self::setLayersFromDatabase(); + if (!self::$requireAuthentication) { + // tracks must be public if we don't require authentication + self::$publicTracks = true; + } + } catch (PDOException $e) { + // TODO: handle exception + syslog(LOG_ERR, $e->getMessage()); + return; + } + } + + /** + * Read config values from database + * @throws PDOException + */ + private static function setLayersFromDatabase() { + self::$olLayers = []; + $query = "SELECT id, name, url, priority FROM " . self::db()->table('ol_layers'); + $result = self::db()->query($query); + while ($row = $result->fetch()) { + self::$olLayers[] = new uLayer($row['id'], $row['name'], $row['url'], $row['priority']); + } + } + + /** + * Read config values from "/config.php" file + * @noinspection IssetArgumentExistenceInspection + * @noinspection DuplicatedCode + * @noinspection PhpIncludeInspection + */ + private static function setFromFile() { + $configFile = ROOT_DIR . "/config.php"; + if (self::$fileLoaded || !file_exists($configFile)) { return; } + self::$fileLoaded = true; + include_once($configFile); + + if (isset($dbdsn)) { self::$dbdsn = $dbdsn; } + if (isset($dbuser)) { self::$dbuser = $dbuser; } + if (isset($dbpass)) { self::$dbpass = $dbpass; } + if (isset($dbprefix)) { self::$dbprefix = $dbprefix; } + } + + /** + * Read config values stored in cookies + */ + private static function setFromCookies() { + if (isset($_COOKIE["ulogger_api"])) { self::$mapApi = $_COOKIE["ulogger_api"]; } + if (isset($_COOKIE["ulogger_lang"])) { self::$lang = $_COOKIE["ulogger_lang"]; } + if (isset($_COOKIE["ulogger_units"])) { self::$units = $_COOKIE["ulogger_units"]; } + if (isset($_COOKIE["ulogger_interval"])) { self::$interval = $_COOKIE["ulogger_interval"]; } + } + + /** + * Is config loaded from file? + * + * @return bool True if loaded, false otherwise + */ + public static function isFileLoaded() { + return self::$fileLoaded; + } + + /** + * Regex to test if password matches strength and length requirements. + * Valid for both php and javascript + * @return string + */ + public static function passRegex() { + $regex = ""; + if (self::$passStrength > 0) { + // lower and upper case + $regex .= "(?=.*[a-z])(?=.*[A-Z])"; + } + if (self::$passStrength > 1) { + // digits + $regex .= "(?=.*[0-9])"; + } + if (self::$passStrength > 2) { + // not latin, not digits + $regex .= "(?=.*[^a-zA-Z0-9])"; + } + if (self::$passLenMin > 0) { + $regex .= "(?=.{" . self::$passLenMin . ",})"; + } + if (empty($regex)) { + $regex = ".*"; + } + return "/" . $regex . "/"; + } + + /** + * @param int $color Color value as integer + * @return string Color hex string + */ + private static function getColorAsHex($color) { + return '#' . sprintf('%03x', $color); + } + + /** + * @param string $color Color hex string + * @return int Color value as integer + */ + private static function getColorAsInt($color) { + return hexdec(str_replace('#', '', $color)); + } +} + ?> diff --git a/helpers/db.php b/helpers/db.php index de6392c..71bc962 100644 --- a/helpers/db.php +++ b/helpers/db.php @@ -77,6 +77,8 @@ self::$tables['positions'] = $prefix . "positions"; self::$tables['tracks'] = $prefix . "tracks"; self::$tables['users'] = $prefix . "users"; + self::$tables['config'] = $prefix . "config"; + self::$tables['ol_layers'] = $prefix . "ol_layers"; } /** @@ -146,8 +148,8 @@ * @param string $charset */ private function setCharset($charset) { - if (self::$driver == "pgsql" || self::$driver == "mysql") { - $this->query("SET NAMES '$charset'"); + if (self::$driver === "pgsql" || self::$driver === "mysql") { + $this->exec("SET NAMES '$charset'"); } } @@ -156,7 +158,7 @@ * @param string $dsn * @return string Empty string if not found */ - static public function getDbName($dsn) { + public static function getDbName($dsn) { $name = ""; if (strpos($dsn, ":") !== false) { list($scheme, $dsnWithoutScheme) = explode(":", $dsn, 2); diff --git a/helpers/lang.php b/helpers/lang.php index b3cbeca..f9a276b 100644 --- a/helpers/lang.php +++ b/helpers/lang.php @@ -49,14 +49,14 @@ * * @var array */ - private $strings = []; + private $strings; /** * Setup script strings * Array of key => translation pairs * * @var array */ - private $setupStrings = []; + private $setupStrings; /** * Constructor @@ -71,13 +71,14 @@ // override with translated strings if needed // missing strings will be displayed in English - if ($language != "en" && array_key_exists($language, self::$languages)) { + if ($language !== "en" && array_key_exists($language, self::$languages)) { require(ROOT_DIR . "/lang/$language.php"); } // choose password messages based on config - $lang['passrules'] = isset($lang["passrules_" . uConfig::$pass_strength]) ? $lang["passrules_" . uConfig::$pass_strength] : ""; - $lang['passlenmin'] = sprintf($lang["passlenmin"], uConfig::$pass_lenmin); + $passRules = "passrules_" . uConfig::$passStrength; + $lang['passrules'] = isset($lang[$passRules]) ? $lang[$passRules] : ""; + $lang['passlenmin'] = sprintf($lang["passlenmin"], uConfig::$passLenMin); $this->strings = $lang; $this->setupStrings = $langSetup; } diff --git a/helpers/layer.php b/helpers/layer.php new file mode 100644 index 0000000..437b9e5 --- /dev/null +++ b/helpers/layer.php @@ -0,0 +1,40 @@ +. + */ + +class uLayer { + public $id; + public $name; + public $url; + public $priority; + + /** + * uLayer constructor. + * @param int $id + * @param string $name + * @param string $url + * @param int $priority + */ + public function __construct($id, $name, $url, $priority) { + $this->id = $id; + $this->name = $name; + $this->url = $url; + $this->priority = $priority; + } +} \ No newline at end of file diff --git a/helpers/user.php b/helpers/user.php index 0fa6f08..5e09c7f 100644 --- a/helpers/user.php +++ b/helpers/user.php @@ -137,7 +137,7 @@ try { $query = "UPDATE " . self::db()->table('users') . " SET admin = ? WHERE login = ?"; $stmt = self::db()->prepare($query); - $stmt->execute([ $isAdmin, $this->login ]); + $stmt->execute([ (int) $isAdmin, $this->login ]); $ret = true; $this->isAdmin = $isAdmin; } catch (PDOException $e) { diff --git a/index.php b/index.php index e4fd8d5..f05dd67 100644 --- a/index.php +++ b/index.php @@ -39,7 +39,7 @@ if ($action === 'auth' && !$auth->isAuthenticated()) { $auth->exitWithRedirect('login.php?auth_error=1'); } - if (uConfig::$require_authentication && !$auth->isAuthenticated()) { + if (uConfig::$requireAuthentication && !$auth->isAuthenticated()) { $auth->exitWithRedirect('login.php'); } @@ -91,8 +91,8 @@
diff --git a/js/src/config.js b/js/src/config.js index 0c00701..cdb68a8 100644 --- a/js/src/config.js +++ b/js/src/config.js @@ -17,6 +17,7 @@ * along with this program; if not, see . */ +import uLayer from './layer.js'; import uObserve from './observe.js'; /** @@ -25,7 +26,7 @@ import uObserve from './observe.js'; * @property {string} units * @property {string} mapApi * @property {?string} gkey - * @property {Object} olLayers + * @property {uLayer[]} olLayers * @property {number} initLatitude * @property {number} initLongitude * @property {RegExp} passRegex @@ -51,7 +52,7 @@ export default class uConfig { this.lang = 'en'; this.mapApi = 'openlayers'; this.gkey = null; - this.olLayers = {}; + this.olLayers = []; this.initLatitude = 52.23; this.initLongitude = 21.01; this.passRegex = new RegExp('(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{12,})'); @@ -93,6 +94,15 @@ export default class uConfig { this.unitDay = 'unitday'; } + /** + * @param {Array} layers + */ + loadLayers(layers) { + for (const layer of layers) { + this.olLayers.push(new uLayer(layer.id, layer.name, layer.url, layer.priority)); + } + } + /** * Load config values from data object * @param {Object} data @@ -100,14 +110,15 @@ export default class uConfig { load(data) { if (data) { for (const property in data) { - if (data.hasOwnProperty(property) && this.hasOwnProperty(property)) { + if (property === 'olLayers') { + this.loadLayers(data[property]); + } else if (property === 'passRegex') { + const re = data[property]; + this[property] = new RegExp(re.substr(1, re.length - 2)); + } else if (data.hasOwnProperty(property) && this.hasOwnProperty(property)) { this[property] = data[property]; } } - if (data.passRegex) { - const re = data.passRegex; - this.passRegex = new RegExp(re.substr(1, re.length - 2)); - } this.initUnits(); } } diff --git a/js/src/layer.js b/js/src/layer.js new file mode 100644 index 0000000..8866221 --- /dev/null +++ b/js/src/layer.js @@ -0,0 +1,28 @@ +/* + * μlogger + * + * Copyright(C) 2020 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 . + */ + +export default class uLayer { + // eslint-disable-next-line max-params + constructor(id, name, url, priority) { + this.id = id; + this.name = name; + this.url = url; + this.priority = priority; + } +} diff --git a/js/src/mapapi/api_openlayers.js b/js/src/mapapi/api_openlayers.js index e53389d..f24a7c6 100644 --- a/js/src/mapapi/api_openlayers.js +++ b/js/src/mapapi/api_openlayers.js @@ -158,17 +158,19 @@ export default class OpenLayersApi { this.selectedLayer = osm; // add extra tile layers - for (const layerName in config.olLayers) { - if (config.olLayers.hasOwnProperty(layerName)) { - const layerUrl = config.olLayers[layerName]; - const ol_layer = new ol.layer.TileLayer({ - name: layerName, - visible: false, - source: new ol.source.XYZ({ - url: layerUrl - }) - }); - this.map.addLayer(ol_layer); + for (const layer of config.olLayers) { + const ol_layer = new ol.layer.TileLayer({ + name: layer.name, + visible: false, + source: new ol.source.XYZ({ + url: layer.url + }) + }); + this.map.addLayer(ol_layer); + if (layer.priority) { + this.selectedLayer.setVisible(false); + this.selectedLayer = ol_layer; + this.selectedLayer.setVisible(true); } } diff --git a/js/src/utils.js b/js/src/utils.js index 6dfe77d..12005f5 100644 --- a/js/src/utils.js +++ b/js/src/utils.js @@ -131,7 +131,7 @@ export default class uUtils { /** * Convert hex string and opacity to an rgba string * @param {string} hex - * @param {number} opacity + * @param {number=} opacity * @returns {string} */ static hexToRGBA(hex, opacity) { diff --git a/login.php b/login.php index 5f18933..6cd16eb 100644 --- a/login.php +++ b/login.php @@ -49,7 +49,7 @@
"> - +
diff --git a/scripts/setup.php b/scripts/setup.php index ad2063f..1089a7e 100644 --- a/scripts/setup.php +++ b/scripts/setup.php @@ -45,6 +45,8 @@ $prefix = preg_replace("/[^a-z0-9_]/i", "", uConfig::$dbprefix); $tPositions = $prefix . "positions"; $tTracks = $prefix . "tracks"; $tUsers = $prefix . "users"; +$tConfig = $prefix . "config"; +$tLayers = $prefix . "ol_layers"; $messages = []; @@ -171,7 +173,7 @@ switch ($command) { * @return array */ function getQueries($dbDriver) { - global $tPositions, $tUsers, $tTracks; + global $tPositions, $tUsers, $tTracks, $tConfig, $tLayers; $queries = []; switch ($dbDriver) { @@ -179,6 +181,8 @@ function getQueries($dbDriver) { $queries[] = "DROP TABLE IF EXISTS `$tPositions`"; $queries[] = "DROP TABLE IF EXISTS `$tTracks`"; $queries[] = "DROP TABLE IF EXISTS `$tUsers`"; + $queries[] = "DROP TABLE IF EXISTS `$tConfig`"; + $queries[] = "DROP TABLE IF EXISTS `$tLayers`"; $queries[] = "CREATE TABLE `$tUsers` ( `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -216,54 +220,128 @@ function getQueries($dbDriver) { FOREIGN KEY(`user_id`) REFERENCES `$tUsers`(`id`), FOREIGN KEY(`track_id`) REFERENCES `$tTracks`(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; + + $queries[] = "CREATE TABLE `$tConfig` ( + `map_api` varchar(50) NOT NULL DEFAULT 'openlayers', + `latitude` double NOT NULL DEFAULT '52.23', + `longitude` double NOT NULL DEFAULT '21.01', + `google_key` varchar(50) DEFAULT NULL, + `require_auth` boolean NOT NULL DEFAULT TRUE, + `public_tracks` boolean NOT NULL DEFAULT FALSE, + `pass_lenmin` int(11) NOT NULL DEFAULT '10', + `pass_strength` tinyint(1) NOT NULL DEFAULT '2', + `interval_seconds` int(11) NOT NULL DEFAULT '10', + `lang` varchar(10) NOT NULL DEFAULT 'en', + `units` varchar(10) NOT NULL DEFAULT 'metric', + `stroke_weight` int(11) NOT NULL DEFAULT '2', + `stroke_color` int(11) NOT NULL DEFAULT '16711680', + `stroke_opacity` int(11) NOT NULL DEFAULT '100' + ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; + + $queries[] = "INSERT INTO `$tConfig` () VALUES ();"; + + $queries[] = "CREATE TABLE `$tLayers` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `name` varchar(50) NOT NULL, + `url` varchar(255) NOT NULL, + `priority` int(11) NOT NULL DEFAULT '0' + ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; + + $queries[] = "INSERT INTO `$tLayers` (`id`, `name`, `url`, `priority`) VALUES + (1, 'OpenCycleMap', 'https://{a-c}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', 0), + (2, 'OpenTopoMap', 'https://{a-c}.tile.opentopomap.org/{z}/{x}/{y}.png', 0), + (3, 'OpenSeaMap', 'https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', 0), + (4, 'ESRI', 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', 0), + (5, 'UMP', 'http://{1-3}.tiles.ump.waw.pl/ump_tiles/{z}/{x}/{y}.png', 0), + (6, 'Osmapa.pl', 'http://{a-c}.tile.openstreetmap.pl/osmapa.pl/{z}/{x}/{y}.png', 0)"; + break; case "pgsql": $queries[] = "DROP TABLE IF EXISTS $tPositions"; $queries[] = "DROP TABLE IF EXISTS $tTracks"; $queries[] = "DROP TABLE IF EXISTS $tUsers"; + $queries[] = "DROP TABLE IF EXISTS $tConfig"; + $queries[] = "DROP TABLE IF EXISTS $tLayers"; $queries[] = "CREATE TABLE $tUsers ( - id SERIAL PRIMARY KEY, - login VARCHAR(15) NOT NULL UNIQUE, - password VARCHAR(255) NOT NULL DEFAULT '', - admin BOOLEAN NOT NULL DEFAULT FALSE + id serial PRIMARY KEY, + login varchar(15) NOT NULL UNIQUE, + password varchar(255) NOT NULL DEFAULT '', + admin boolean NOT NULL DEFAULT FALSE )"; $queries[] = "CREATE TABLE $tTracks ( - id SERIAL PRIMARY KEY, - user_id INT NOT NULL, - name VARCHAR(255) DEFAULT NULL, - comment VARCHAR(1024) DEFAULT NULL, + 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)"; $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 VARCHAR(100) DEFAULT NULL, + 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 varchar(100) 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)"; + + $queries[] = "CREATE TABLE $tConfig ( + map_api varchar(50) NOT NULL DEFAULT 'openlayers', + latitude double precision NOT NULL DEFAULT '52.23', + longitude double precision NOT NULL DEFAULT '21.01', + google_key varchar(50) DEFAULT NULL, + require_auth boolean NOT NULL DEFAULT TRUE, + public_tracks boolean NOT NULL DEFAULT FALSE, + pass_lenmin int NOT NULL DEFAULT '10', + pass_strength smallint NOT NULL DEFAULT '2', + interval_seconds int NOT NULL DEFAULT '10', + lang varchar(10) NOT NULL DEFAULT 'en', + units varchar(10) NOT NULL DEFAULT 'metric', + stroke_weight int NOT NULL DEFAULT '2', + stroke_color int NOT NULL DEFAULT '16711680', + stroke_opacity int NOT NULL DEFAULT '100' + )"; + + $queries[] = "INSERT INTO $tConfig DEFAULT VALUES"; + + $queries[] = "CREATE TABLE $tLayers ( + id serial PRIMARY KEY, + name varchar(50) NOT NULL, + url varchar(255) NOT NULL, + priority int NOT NULL DEFAULT '0' + )"; + + $queries[] = "INSERT INTO $tLayers (id, name, url, priority) VALUES + (1, 'OpenCycleMap', 'https://{a-c}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', 0), + (2, 'OpenTopoMap', 'https://{a-c}.tile.opentopomap.org/{z}/{x}/{y}.png', 0), + (3, 'OpenSeaMap', 'https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', 0), + (4, 'ESRI', 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', 0), + (5, 'UMP', 'http://{1-3}.tiles.ump.waw.pl/ump_tiles/{z}/{x}/{y}.png', 0), + (6, 'Osmapa.pl', 'http://{a-c}.tile.openstreetmap.pl/osmapa.pl/{z}/{x}/{y}.png', 0)"; + break; case "sqlite": $queries[] = "DROP TABLE IF EXISTS `$tPositions`"; $queries[] = "DROP TABLE IF EXISTS `$tTracks`"; $queries[] = "DROP TABLE IF EXISTS `$tUsers`"; + $queries[] = "DROP TABLE IF EXISTS `$tConfig`"; + $queries[] = "DROP TABLE IF EXISTS `$tLayers`"; $queries[] = "CREATE TABLE `$tUsers` ( `id` integer PRIMARY KEY AUTOINCREMENT, @@ -299,6 +377,41 @@ function getQueries($dbDriver) { )"; $queries[] = "CREATE INDEX `idx_ptrack_id` ON `$tPositions`(`track_id`)"; $queries[] = "CREATE INDEX `idx_puser_id` ON `$tPositions`(`user_id`)"; + + $queries[] = "CREATE TABLE `$tConfig` ( + `map_api` varchar(50) NOT NULL DEFAULT 'openlayers', + `latitude` double NOT NULL DEFAULT '52.23', + `longitude` double NOT NULL DEFAULT '21.01', + `google_key` varchar(50) DEFAULT NULL, + `require_auth` integer NOT NULL DEFAULT 1, + `public_tracks` integer NOT NULL DEFAULT 0, + `pass_lenmin` integer NOT NULL DEFAULT '10', + `pass_strength` integer NOT NULL DEFAULT '2', + `interval_seconds` integer NOT NULL DEFAULT '10', + `lang` varchar(10) NOT NULL DEFAULT 'en', + `units` varchar(10) NOT NULL DEFAULT 'metric', + `stroke_weight` integer NOT NULL DEFAULT '2', + `stroke_color` integer NOT NULL DEFAULT '16711680', + `stroke_opacity` integer NOT NULL DEFAULT '100' + )"; + + $queries[] = "INSERT INTO `$tConfig` DEFAULT VALUES"; + + $queries[] = "CREATE TABLE `$tLayers` ( + `id` integer PRIMARY KEY AUTOINCREMENT, + `name` varchar(50) NOT NULL, + `url` varchar(255) NOT NULL, + `priority` integer NOT NULL DEFAULT '0' + )"; + + $queries[] = "INSERT INTO `$tLayers` (`id`, `name`, `url`, `priority`) VALUES + (1, 'OpenCycleMap', 'https://{a-c}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', 0), + (2, 'OpenTopoMap', 'https://{a-c}.tile.opentopomap.org/{z}/{x}/{y}.png', 0), + (3, 'OpenSeaMap', 'https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', 0), + (4, 'ESRI', 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', 0), + (5, 'UMP', 'http://{1-3}.tiles.ump.waw.pl/ump_tiles/{z}/{x}/{y}.png', 0), + (6, 'Osmapa.pl', 'http://{a-c}.tile.openstreetmap.pl/osmapa.pl/{z}/{x}/{y}.png', 0)"; + break; default: diff --git a/scripts/ulogger.mysql b/scripts/ulogger.mysql index ac92fe1..1ed970a 100644 --- a/scripts/ulogger.mysql +++ b/scripts/ulogger.mysql @@ -63,6 +63,61 @@ CREATE TABLE `positions` ( FOREIGN KEY(`track_id`) REFERENCES `tracks`(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +-- -------------------------------------------------------- + +-- +-- Table structure for table `config` +-- + +DROP TABLE IF EXISTS `config`; +CREATE TABLE `config` ( + `map_api` varchar(50) NOT NULL DEFAULT 'openlayers', + `latitude` double NOT NULL DEFAULT '52.23', + `longitude` double NOT NULL DEFAULT '21.01', + `google_key` varchar(50) DEFAULT NULL, + `require_auth` boolean NOT NULL DEFAULT TRUE, + `public_tracks` boolean NOT NULL DEFAULT FALSE, + `pass_lenmin` int(11) NOT NULL DEFAULT '10', + `pass_strength` tinyint(1) NOT NULL DEFAULT '2', + `interval_seconds` int(11) NOT NULL DEFAULT '10', + `lang` varchar(10) NOT NULL DEFAULT 'en', + `units` varchar(10) NOT NULL DEFAULT 'metric', + `stroke_weight` int(11) NOT NULL DEFAULT '2', + `stroke_color` int(11) NOT NULL DEFAULT '16711680', + `stroke_opacity` int(11) NOT NULL DEFAULT '100' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Data for table `config` +-- + +INSERT INTO `config` () VALUES (); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ol_layers` +-- + +DROP TABLE IF EXISTS `ol_layers`; +CREATE TABLE `ol_layers` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `name` varchar(50) NOT NULL, + `url` varchar(255) NOT NULL, + `priority` int(11) NOT NULL DEFAULT '0' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Data for table `ol_layers` +-- + +INSERT INTO `ol_layers` (`id`, `name`, `url`, `priority`) VALUES +(1, 'OpenCycleMap', 'https://{a-c}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', 0), +(2, 'OpenTopoMap', 'https://{a-c}.tile.opentopomap.org/{z}/{x}/{y}.png', 0), +(3, 'OpenSeaMap', 'https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', 0), +(4, 'ESRI', 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', 0), +(5, 'UMP', 'http://{1-3}.tiles.ump.waw.pl/ump_tiles/{z}/{x}/{y}.png', 0), +(6, 'Osmapa.pl', 'http://{a-c}.tile.openstreetmap.pl/osmapa.pl/{z}/{x}/{y}.png', 0); -- -- This will add default user admin with password admin diff --git a/scripts/ulogger.pgsql b/scripts/ulogger.pgsql index 9a0bdc1..3c5c0b3 100644 --- a/scripts/ulogger.pgsql +++ b/scripts/ulogger.pgsql @@ -65,6 +65,62 @@ CREATE TABLE positions ( CREATE INDEX idx_ptrack_id ON positions(track_id); CREATE INDEX idx_puser_id ON positions(user_id); +-- -------------------------------------------------------- + +-- +-- Table structure for table `config` +-- + +DROP TABLE IF EXISTS config; +CREATE TABLE config ( + map_api varchar(50) NOT NULL DEFAULT 'openlayers', + latitude double precision NOT NULL DEFAULT '52.23', + longitude double precision NOT NULL DEFAULT '21.01', + google_key varchar(50) DEFAULT NULL, + require_auth boolean NOT NULL DEFAULT TRUE, + public_tracks boolean NOT NULL DEFAULT FALSE, + pass_lenmin int NOT NULL DEFAULT '10', + pass_strength smallint NOT NULL DEFAULT '2', + interval_seconds int NOT NULL DEFAULT '10', + lang varchar(10) NOT NULL DEFAULT 'en', + units varchar(10) NOT NULL DEFAULT 'metric', + stroke_weight int NOT NULL DEFAULT '2', + stroke_color int NOT NULL DEFAULT '16711680', + stroke_opacity int NOT NULL DEFAULT '100' +); + +-- +-- Data for table `config` +-- + +INSERT INTO config DEFAULT VALUES; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ol_layers` +-- + +DROP TABLE IF EXISTS ol_layers; + +CREATE TABLE ol_layers ( + id serial PRIMARY KEY, + name varchar(50) NOT NULL, + url varchar(255) NOT NULL, + priority int NOT NULL DEFAULT '0' +); + +-- +-- Data for table ol_layers +-- + +INSERT INTO ol_layers (id, name, url, priority) VALUES +(1, 'OpenCycleMap', 'https://{a-c}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', 0), +(2, 'OpenTopoMap', 'https://{a-c}.tile.opentopomap.org/{z}/{x}/{y}.png', 0), +(3, 'OpenSeaMap', 'https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', 0), +(4, 'ESRI', 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', 0), +(5, 'UMP', 'http://{1-3}.tiles.ump.waw.pl/ump_tiles/{z}/{x}/{y}.png', 0), +(6, 'Osmapa.pl', 'http://{a-c}.tile.openstreetmap.pl/osmapa.pl/{z}/{x}/{y}.png', 0); -- -- This will add default user admin with password admin diff --git a/scripts/ulogger.sqlite b/scripts/ulogger.sqlite index c738da8..804d737 100644 --- a/scripts/ulogger.sqlite +++ b/scripts/ulogger.sqlite @@ -60,6 +60,62 @@ CREATE TABLE `positions` ( CREATE INDEX `idx_ptrack_id` ON `positions`(`track_id`); CREATE INDEX `idx_puser_id` ON `positions`(`user_id`); +-- -------------------------------------------------------- + +-- +-- Table structure for table `config` +-- + +DROP TABLE IF EXISTS `config`; +CREATE TABLE `config` ( + `map_api` varchar(50) NOT NULL DEFAULT 'openlayers', + `latitude` double NOT NULL DEFAULT '52.23', + `longitude` double NOT NULL DEFAULT '21.01', + `google_key` varchar(50) DEFAULT NULL, + `require_auth` integer NOT NULL DEFAULT 1, + `public_tracks` integer NOT NULL DEFAULT 0, + `pass_lenmin` integer NOT NULL DEFAULT '10', + `pass_strength` integer NOT NULL DEFAULT '2', + `interval_seconds` integer NOT NULL DEFAULT '10', + `lang` varchar(10) NOT NULL DEFAULT 'en', + `units` varchar(10) NOT NULL DEFAULT 'metric', + `stroke_weight` integer NOT NULL DEFAULT '2', + `stroke_color` integer NOT NULL DEFAULT '16711680', + `stroke_opacity` integer NOT NULL DEFAULT '100' +); + +-- +-- Data for table `config` +-- + +INSERT INTO `config` DEFAULT VALUES; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `ol_layers` +-- + +DROP TABLE IF EXISTS `ol_layers`; +CREATE TABLE `ol_layers` ( + `id` integer PRIMARY KEY AUTOINCREMENT, + `name` varchar(50) NOT NULL, + `url` varchar(255) NOT NULL, + `priority` integer NOT NULL DEFAULT '0' +); + +-- +-- Data for table `ol_layers` +-- + +INSERT INTO `ol_layers` (`id`, `name`, `url`, `priority`) VALUES +(1, 'OpenCycleMap', 'https://{a-c}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', 0), +(2, 'OpenTopoMap', 'https://{a-c}.tile.opentopomap.org/{z}/{x}/{y}.png', 0), +(3, 'OpenSeaMap', 'https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', 0), +(4, 'ESRI', 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', 0), +(5, 'UMP', 'http://{1-3}.tiles.ump.waw.pl/ump_tiles/{z}/{x}/{y}.png', 0), +(6, 'Osmapa.pl', 'http://{a-c}.tile.openstreetmap.pl/osmapa.pl/{z}/{x}/{y}.png', 0); + -- -- This will add default user admin with password admin -- The password should be changed immediatelly after installation diff --git a/utils/export.php b/utils/export.php index da87687..9e78fb8 100644 --- a/utils/export.php +++ b/utils/export.php @@ -62,7 +62,7 @@ $type = uUtils::getString('type', 'kml'); $userId = uUtils::getInt('userid'); $trackId = uUtils::getInt('trackid'); -if (!uConfig::$public_tracks && +if (!uConfig::$publicTracks && (!$auth->isAuthenticated() || (!$auth->isAdmin() && $auth->user->id !== $userId))) { // unauthorized exit(); diff --git a/utils/getinit.php b/utils/getinit.php index 7d6eb4b..7f81cbe 100644 --- a/utils/getinit.php +++ b/utils/getinit.php @@ -38,17 +38,17 @@ $resultConfig = [ "interval" => uConfig::$interval, "units" => uConfig::$units, "lang" => uConfig::$lang, - "mapApi" => uConfig::$mapapi, - "gkey" => uConfig::$gkey, - "initLatitude" => uConfig::$init_latitude, - "initLongitude" => uConfig::$init_longitude, + "mapApi" => uConfig::$mapApi, + "gkey" => uConfig::$googleKey, + "initLatitude" => uConfig::$initLatitude, + "initLongitude" => uConfig::$initLongitude, "passRegex" => uConfig::passRegex(), "strokeWeight" => uConfig::$strokeWeight, "strokeColor" => uConfig::$strokeColor, "strokeOpacity" => uConfig::$strokeOpacity, "olLayers" => [] ]; -foreach (uConfig::$ol_layers as $key => $val) { +foreach (uConfig::$olLayers as $key => $val) { $resultConfig["olLayers"][$key] = $val; } diff --git a/utils/getpositions.php b/utils/getpositions.php index b418f54..e9d256a 100644 --- a/utils/getpositions.php +++ b/utils/getpositions.php @@ -30,7 +30,7 @@ $last = uUtils::getBool('last'); $positionsArr = []; if ($userId) { - if (uConfig::$public_tracks || + if (uConfig::$publicTracks || ($auth->isAuthenticated() && ($auth->isAdmin() || $auth->user->id === $userId))) { if ($trackId) { // get all track data @@ -44,7 +44,7 @@ if ($userId) { } } } else if ($last) { - if (uConfig::$public_tracks || ($auth->isAuthenticated() && ($auth->isAdmin()))) { + if (uConfig::$publicTracks || ($auth->isAuthenticated() && ($auth->isAdmin()))) { $positionsArr = uPosition::getLastAllUsers(); } } diff --git a/utils/gettracks.php b/utils/gettracks.php index fa91600..a197ade 100644 --- a/utils/gettracks.php +++ b/utils/gettracks.php @@ -26,7 +26,7 @@ $userId = uUtils::getInt('userid'); $tracksArr = []; if ($userId) { - if (uConfig::$public_tracks || + if (uConfig::$publicTracks || ($auth->isAuthenticated() && ($auth->isAdmin() || $auth->user->id === $userId))) { $tracksArr = uTrack::getAll($userId); } diff --git a/utils/getusers.php b/utils/getusers.php index 30ab17c..25bcc96 100644 --- a/utils/getusers.php +++ b/utils/getusers.php @@ -24,7 +24,7 @@ require_once(ROOT_DIR . "/helpers/track.php"); $auth = new uAuth(); $usersArr = []; -if (uConfig::$public_tracks || $auth->isAdmin()) { +if (uConfig::$publicTracks || $auth->isAdmin()) { $usersArr = uUser::getAll(); } else if ($auth->isAuthenticated()) { $usersArr = [ $auth->user ];