Store config in database

This commit is contained in:
Bartek Fabiszewski 2020-02-19 18:42:44 +01:00
parent 9506835472
commit ab261741a4
30 changed files with 816 additions and 366 deletions

View File

@ -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"

View File

@ -3,4 +3,6 @@
<users id="1" login="admin" password="$2y$10$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq" admin="1" />
<tracks />
<positions />
<config map_api="openlayers" />
<ol_layers />
</dataset>

View File

@ -3,4 +3,6 @@
<users />
<tracks />
<positions />
<config map_api="openlayers" />
<ol_layers />
</dataset>

View File

@ -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.

View File

@ -1,13 +1,109 @@
<?php
use PHPUnit\Framework\TestCase;
if (!defined("ROOT_DIR")) { define("ROOT_DIR", __DIR__ . "/../.."); }
require_once(__DIR__ . "/../../helpers/config.php");
require_once(__DIR__ . "/../lib/UloggerDatabaseTestCase.php");
class ConfigTest extends TestCase {
class ConfigTest extends UloggerDatabaseTestCase {
private $mapApi;
private $latitude;
private $longitude;
private $googleKey;
private $requireAuth;
private $publicTracks;
private $passLenMin;
private $passStrength;
private $interval;
private $lang;
private $units;
private $strokeWeight;
private $strokeColor;
private $strokeOpacity;
private $testLayer;
private $testUrl;
private $testPriority;
public function setUp() {
parent::setUp();
$this->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\"");

View File

@ -1,7 +1,5 @@
<?php
use Psr\Http\Message\ResponseInterface;
require_once(__DIR__ . "/../lib/UloggerAPITestCase.php");
if (!defined("ROOT_DIR")) { define("ROOT_DIR", __DIR__ . "/../.."); }
require_once(ROOT_DIR . "/helpers/config.php");
@ -503,7 +501,7 @@ class InternalAPITest extends UloggerAPITestCase {
"form_params" => [
"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");
}

View File

@ -38,8 +38,8 @@ class SetupTest extends UloggerAPITestCase {
$body = (string) $response->getBody();
$this->assertContains("<span class=\"ok\">", $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");
}

View File

@ -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

View File

@ -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.

View File

@ -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 = "";
?>

View File

@ -17,218 +17,272 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
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));
}
}
?>

View File

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

View File

@ -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;
}

40
helpers/layer.php Normal file
View File

@ -0,0 +1,40 @@
<?php
/**
* μ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 <http://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@ -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) {

View File

@ -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 @@
<div>
<label for="api"><?= $lang['api'] ?></label>
<select id="api" name="api" data-bind="mapApi">
<option value="gmaps"<?= (uConfig::$mapapi === 'gmaps') ? ' selected' : '' ?>>Google Maps</option>
<option value="openlayers"<?= (uConfig::$mapapi === 'openlayers') ? ' selected' : '' ?>>OpenLayers</option>
<option value="gmaps"<?= (uConfig::$mapApi === 'gmaps') ? ' selected' : '' ?>>Google Maps</option>
<option value="openlayers"<?= (uConfig::$mapApi === 'openlayers') ? ' selected' : '' ?>>OpenLayers</option>
</select>
</div>

View File

@ -17,6 +17,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
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<string, string>} 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();
}
}

28
js/src/layer.js Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}
}

View File

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

View File

@ -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) {

View File

@ -49,7 +49,7 @@
<br>
<input type="submit" value="<?= $lang["login"] ?>">
<input type="hidden" name="action" value="auth">
<?php if (!uConfig::$require_authentication): ?>
<?php if (!uConfig::$requireAuthentication): ?>
<div id="cancel"><a href="<?= BASE_URL ?>"><?= $lang["cancel"] ?></a></div>
<?php endif; ?>
</form>

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

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

View File

@ -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;
}

View File

@ -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();
}
}

View File

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

View File

@ -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 ];