Move isAdmin flag to database

This commit is contained in:
Bartek Fabiszewski 2020-02-17 18:51:27 +01:00
parent f0516b4f14
commit aa9d507d12
14 changed files with 98 additions and 102 deletions

View File

@ -38,14 +38,14 @@ if [ "$ULOGGER_DB_DRIVER" = "pgsql" ]; then
su postgres -c "psql -c \"GRANT ALL PRIVILEGES ON DATABASE ulogger TO ulogger\""
su postgres -c "psql -d ulogger -c \"GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO ulogger\""
su postgres -c "psql -d ulogger -c \"GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO ulogger\""
su postgres -c "psql -d ulogger -c \"INSERT INTO users (login, password) VALUES ('admin', '\\\$2y\\\$10\\\$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq')\""
su postgres -c "psql -d ulogger -c \"INSERT INTO users (login, password, admin) VALUES ('${ULOGGER_ADMIN_USER}', '\\\$2y\\\$10\\\$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq', TRUE)\""
su postgres -c "pg_ctl -w stop"
sed -i "s/^\$dbdsn = .*$/\$dbdsn = \"pgsql:host=localhost;port=5432;dbname=ulogger\";/" /var/www/html/config.php
elif [ "$ULOGGER_DB_DRIVER" = "sqlite" ]; then
mkdir -p /data/sqlite
chown -R nobody:nobody /data
sqlite3 -init /var/www/html/scripts/ulogger.sqlite /data/sqlite/ulogger.db .exit
sqlite3 -line /data/ulogger.db "INSERT INTO users (login, password) VALUES ('admin', '\$2y\$10\$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq')"
sqlite3 -line /data/ulogger.db "INSERT INTO users (login, password, admin) VALUES ('${ULOGGER_ADMIN_USER}', '\$2y\$10\$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq', 1)"
sed -i "s/^\$dbdsn = .*$/\$dbdsn = \"sqlite:\/data\/sqlite\/ulogger.db\";/" /var/www/html/config.php
else
mkdir -p /run/mysqld
@ -54,12 +54,12 @@ else
mysqld_safe --datadir=/data &
mysqladmin --silent --wait=30 ping
mysqladmin -u root password "${DB_ROOT_PASS}"
mysql -u root -p"${DB_ROOT_PASS}" < /var/www/html/scripts/ulogger.sql
mysql -u root -p"${DB_ROOT_PASS}" < /var/www/html/scripts/ulogger.mysql
mysql -u root -p"${DB_ROOT_PASS}" -e "CREATE USER 'ulogger'@'localhost' IDENTIFIED BY '${DB_USER_PASS}'"
mysql -u root -p"${DB_ROOT_PASS}" -e "GRANT ALL PRIVILEGES ON ulogger.* TO 'ulogger'@'localhost'"
mysql -u root -p"${DB_ROOT_PASS}" -e "CREATE USER 'ulogger'@'%' IDENTIFIED BY '${DB_USER_PASS}'"
mysql -u root -p"${DB_ROOT_PASS}" -e "GRANT ALL PRIVILEGES ON ulogger.* TO 'ulogger'@'%'"
mysql -u root -p"${DB_ROOT_PASS}" -e "INSERT INTO users (login, password) VALUES ('admin', '\$2y\$10\$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq')" ulogger
mysql -u root -p"${DB_ROOT_PASS}" -e "INSERT INTO users (login, password, admin) VALUES ('${ULOGGER_ADMIN_USER}', '\$2y\$10\$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq', TRUE)" ulogger
mysqladmin -u root -p"${DB_ROOT_PASS}" shutdown
sed -i "s/^\$dbdsn = .*$/\$dbdsn = \"mysql:host=localhost;port=3306;dbname=ulogger;charset=utf8\";/" /var/www/html/config.php
fi

View File

@ -1,7 +1,6 @@
#!/bin/sh
# set config variables
sed -i "s/^\$admin_user = .*$/\$admin_user = \"${ULOGGER_ADMIN_USER}\";/" /var/www/html/config.php
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

View File

@ -1,6 +1,6 @@
<?xml version="1.0" ?>
<dataset>
<users id="1" login="admin" password="$2y$10$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq" />
<users id="1" login="admin" password="$2y$10$7OvZrKgonVZM9lkzrTbiou.CVhO3HjPk5y0W9L68fVwPs/osBRIMq" admin="1" />
<tracks />
<positions />
</dataset>

View File

@ -1,5 +1,4 @@
<?php
use PHPUnit\Framework\TestCase;
if (!defined("ROOT_DIR")) { define("ROOT_DIR", __DIR__ . "/../.."); }
@ -8,11 +7,11 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase
/**
* @var PDO $pdo
*/
static private $pdo = null;
static private $pdo;
/**
* @var PHPUnit_Extensions_Database_DB_IDatabaseConnection $conn
*/
private $conn = null;
private $conn;
static private $driver = "mysql";
protected $testUser = "testUser";
@ -28,7 +27,7 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase
protected $testTrackName = "test track";
protected $testTrackComment = "test track comment";
protected $testTimestamp = 1502974402;
protected $testLat = 0;
protected $testLat = 0.0;
protected $testLon = 10.604001083;
protected $testAltitude = 10.01;
protected $testSpeed = 10.01;
@ -93,17 +92,17 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase
}
protected function resetAutoincrement($users = 1, $tracks = 1, $positions = 1) {
if (self::$driver == "pgsql") {
self::$pdo->query("ALTER SEQUENCE users_id_seq RESTART WITH $users");
self::$pdo->query("ALTER SEQUENCE tracks_id_seq RESTART WITH $tracks");
self::$pdo->query("ALTER SEQUENCE positions_id_seq RESTART WITH $positions");
} else if (self::$driver == "sqlite") {
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");
} else if (self::$driver === "sqlite") {
$retry = 1;
do {
try {
self::$pdo->query("DELETE FROM sqlite_sequence WHERE NAME = 'users'");
self::$pdo->query("DELETE FROM sqlite_sequence WHERE NAME = 'tracks'");
self::$pdo->query("DELETE FROM sqlite_sequence WHERE NAME = 'positions'");
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'");
$retry = 0;
} catch (Exception $e) {
// sqlite raises error when db schema changes in another connection.
@ -175,12 +174,13 @@ abstract class BaseDatabaseTestCase extends PHPUnit_Extensions_Database_TestCase
*
* @param string $user User login
* @param string $pass User password
* @param bool $isAdmin User is admin
* @return int|bool User id or false on error
*/
protected function addTestUser($user = NULL, $pass = NULL) {
protected function addTestUser($user = NULL, $pass = NULL, $isAdmin = false) {
if (is_null($user)) { $user = $this->testUser; }
if (is_null($pass)) { $pass = $this->testPass; }
$id = $this->pdoInsert('users', [ 'login' => $user, 'password' => $pass ]);
$id = $this->pdoInsert('users', [ 'login' => $user, 'password' => $pass, 'admin' => (int) $isAdmin ]);
if ($id !== false) {
return (int) $id;
}

View File

@ -1,5 +1,4 @@
<?php
use PHPUnit\Framework\TestCase;
require_once(__DIR__ . "/../../helpers/auth.php");
require_once(__DIR__ . "/../lib/UloggerDatabaseTestCase.php");
@ -22,10 +21,10 @@ class AuthTest extends UloggerDatabaseTestCase {
$auth = new uAuth();
$auth->checkLogin($this->testUser, $this->testPass);
$this->assertTrue($auth->isAuthenticated(), "Not authenticated");
$this->assertTrue($auth->user instanceof uUser, "User variable not set");
$this->assertInstanceOf(uUser::class, $auth->user, "User variable not set");
$this->assertEquals($this->testUser, $auth->user->login, "Wrong login");
$this->assertEquals($_SESSION["user"]->login, $auth->user->login, "Wrong login");
$this->assertTrue($_SESSION["user"] instanceof uUser, "User not set in session");
$this->assertInstanceOf(uUser::class, $_SESSION["user"], "User not set in session");
}
/**
@ -38,7 +37,7 @@ class AuthTest extends UloggerDatabaseTestCase {
$auth = new uAuth();
$auth->checkLogin($this->testUser, "badPass");
$this->assertFalse($auth->isAuthenticated(), "Should not be authenticated");
$this->assertTrue(is_null($auth->user), "User not null");
$this->assertInternalType('null', $auth->user, "User not null");
}
/**
@ -51,7 +50,7 @@ class AuthTest extends UloggerDatabaseTestCase {
$auth = new uAuth();
$auth->checkLogin("", $this->testPass);
$this->assertFalse($auth->isAuthenticated(), "Should not be authenticated");
$this->assertTrue(is_null($auth->user), "User not null");
$this->assertInternalType('null', $auth->user, "User not null");
}
/**
@ -63,7 +62,7 @@ class AuthTest extends UloggerDatabaseTestCase {
$auth = new uAuth();
$this->assertFalse($auth->isAuthenticated(), "Should not be authenticated");
$this->assertTrue(is_null($auth->user), "User not null");
$this->assertInternalType('null', $auth->user, "User not null");
}
/**
@ -109,7 +108,7 @@ class AuthTest extends UloggerDatabaseTestCase {
/**
* @runInSeparateProcess
*/
public function testNotIsAdmin() {
public function testIsNotAdmin() {
$this->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT));
$this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count");
@ -123,15 +122,13 @@ class AuthTest extends UloggerDatabaseTestCase {
* @runInSeparateProcess
*/
public function testIsAdmin() {
$this->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT));
$this->addTestUser($this->testUser, password_hash($this->testPass, PASSWORD_DEFAULT), true);
$this->assertEquals(1, $this->getConnection()->getRowCount('users'), "Wrong row count");
uConfig::$admin_user = $this->testUser;
@$auth = new uAuth();
$auth->checkLogin($this->testUser, $this->testPass);
$this->assertTrue($auth->isAuthenticated(), "Should be authenticated");
$this->assertTrue($auth->isAdmin(), "Should not be admin");
$this->assertTrue($auth->isAdmin(), "Should be admin");
}
}

View File

@ -1,5 +1,4 @@
<?php
use PHPUnit\Framework\TestCase;
require_once(__DIR__ . "/../lib/UloggerDatabaseTestCase.php");
require_once(__DIR__ . "/../../helpers/user.php");
@ -57,17 +56,20 @@ class UserTest extends UloggerDatabaseTestCase {
$this->assertEquals(2, $this->getConnection()->getRowCount('users'), "Wrong row count");
$userArr = uUser::getAll();
$this->assertEquals(2, count($userArr), "Wrong array size");
$this->assertTrue($userArr[0] instanceof uUser, "Wrong array member");
$this->assertCount(2, $userArr, "Wrong array size");
$this->assertInstanceOf(uUser::class, $userArr[0], "Wrong array member");
}
public function testIsAdmin() {
$this->addTestUser($this->testUser, NULL, true);
$user = new uUser($this->testUser);
$this->assertTrue($user->isAdmin, "User should be admin");
}
public function testIsNotAdmin() {
$this->addTestUser($this->testUser);
$user = new uUser($this->testUser);
$this->assertFalse($user->isAdmin, "User should not be admin");
uConfig::$admin_user = $this->testUser;
$user = new uUser($this->testUser);
$this->assertTrue($user->isAdmin, "User should be admin");
}
public function testIsValid() {

View File

@ -42,6 +42,13 @@ Together with a dedicated [μlogger mobile client](https://github.com/bfabiszews
- You may also want to set your new user as an [admin in config file](https://github.com/bfabiszewski/ulogger-server/blob/v0.2/config.default.php#L67).
- Folders `.docker/` and `.tests/` as well as composer files are needed only for development. May be safely removed.
## Upgrade to version 1.x
- TODO: convert following notes to migration script
- 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`
- modify admin user entry in `users` table: set `admin` to `true`
## 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.
- Optional configuration options with ENV variables, for list see [Dockerfile](https://github.com/bfabiszewski/ulogger-server/blob/master/Dockerfile). The variables correspond to main μlogger configuration parameteres.

View File

@ -55,13 +55,6 @@ $require_authentication = 1;
// (0 = no, 1 = yes)
$public_tracks = 0;
// admin user, who
// - can add new users
// - can edit all tracks, users
// - has access to all users locations
// none if empty
$admin_user = "";
// miniumum required length of user password
$pass_lenmin = 12;

View File

@ -30,69 +30,69 @@
/**
* @var string Version number
*/
static $version = "1.0-beta";
public static $version = "1.0-beta";
/**
* @var string Default map drawing framework
*/
static $mapapi = "openlayers";
public static $mapapi = "openlayers";
/**
* @var string|null Google maps key
*/
static $gkey = null;
public static $gkey;
/**
* @var array Openlayers additional map layers
*/
static $ol_layers = [];
public static $ol_layers = [];
/**
* @var float Default latitude for initial map
*/
static $init_latitude = 52.23;
public static $init_latitude = 52.23;
/**
* @var float Default longitude for initial map
*/
static $init_longitude = 21.01;
public static $init_longitude = 21.01;
/**
* @var string Database dsn
*/
static $dbdsn = "";
public static $dbdsn = "";
/**
* @var string Database user
*/
static $dbuser = "";
public static $dbuser = "";
/**
* @var string Database pass
*/
static $dbpass = "";
public static $dbpass = "";
/**
* @var string Optional table names prefix, eg. "ulogger_"
*/
static $dbprefix = "";
public static $dbprefix = "";
/**
* @var bool Require login/password authentication
*/
static $require_authentication = true;
public static $require_authentication = true;
/**
* @var bool All users tracks are visible to authenticated user
*/
static $public_tracks = false;
public static $public_tracks = false;
/**
* @var string Admin user who has access to all users locations
* none if empty
*/
static $admin_user = "";
public static $admin_user = "";
/**
* @var int Miniumum required length of user password
*/
static $pass_lenmin = 12;
public static $pass_lenmin = 12;
/**
* @var int Required strength of user password
@ -101,35 +101,35 @@
* 2 = require mixed case and numbers
* 3 = require mixed case, numbers and non-alphanumeric characters
*/
static $pass_strength = 2;
public static $pass_strength = 2;
/**
* @var int Default interval in seconds for live auto reload
*/
static $interval = 10;
public static $interval = 10;
/**
* @var string Default language code
*/
static $lang = "en";
public static $lang = "en";
/**
* @var string Default units
*/
static $units = "metric";
public static $units = "metric";
/**
* @var int Stroke weight
*/
static $strokeWeight = 2;
public static $strokeWeight = 2;
/**
* @var string Stroke color
*/
static $strokeColor = '#ff0000';
public static $strokeColor = '#ff0000';
/**
* @var int Stroke opacity
*/
static $strokeOpacity = 1;
public static $strokeOpacity = 1;
private static $fileLoaded = false;
@ -138,7 +138,7 @@
/**
* Static initializer
*/
static public function init() {
public static function init() {
if (!self::$initialized) {
self::setFromFile();
self::setFromCookies();

View File

@ -42,15 +42,15 @@
public function __construct($login = NULL) {
if (!empty($login)) {
try {
$query = "SELECT id, login, password FROM " . self::db()->table('users') . " WHERE login = ? LIMIT 1";
$query = "SELECT id, login, password, admin FROM " . self::db()->table('users') . " WHERE login = ? LIMIT 1";
$stmt = self::db()->prepare($query);
$stmt->execute([ $login ]);
$stmt->bindColumn('id', $this->id, PDO::PARAM_INT);
$stmt->bindColumn('login', $this->login);
$stmt->bindColumn('password', $this->hash);
$stmt->bindColumn('admin', $this->isAdmin, PDO::PARAM_BOOL);
if ($stmt->fetch(PDO::FETCH_BOUND)) {
$this->isValid = true;
$this->isAdmin = self::isAdmin($this->login);
}
} catch (PDOException $e) {
// TODO: handle exception
@ -73,17 +73,18 @@
*
* @param string $login Login
* @param string $pass Password
* @param bool $isAdmin Is admin
* @return int|bool New user id, false on error
*/
public static function add($login, $pass) {
public static function add($login, $pass, $isAdmin = false) {
$userid = false;
if (!empty($login) && !empty($pass) && self::validPassStrength($pass)) {
$hash = password_hash($pass, PASSWORD_DEFAULT);
$table = self::db()->table('users');
try {
$query = "INSERT INTO $table (login, password) VALUES (?, ?)";
$query = "INSERT INTO $table (login, password, admin) VALUES (?, ?, ?)";
$stmt = self::db()->prepare($query);
$stmt->execute([ $login, $hash ]);
$stmt->execute([ $login, $hash, (int) $isAdmin ]);
$userid = (int) self::db()->lastInsertId("${table}_id_seq");
} catch (PDOException $e) {
// TODO: handle exception
@ -199,7 +200,7 @@
*/
public static function getAll() {
try {
$query = "SELECT id, login, password FROM " . self::db()->table('users') . " ORDER BY login";
$query = "SELECT id, login, password, admin FROM " . self::db()->table('users') . " ORDER BY login";
$result = self::db()->query($query);
$userArr = [];
while ($row = $result->fetch()) {
@ -224,19 +225,9 @@
$user->id = $row['id'];
$user->login = $row['login'];
$user->hash = $row['password'];
$user->isAdmin = self::isAdmin($row['login']);
$user->isAdmin = (bool) $row['admin'];
$user->isValid = true;
return $user;
}
/**
* Is given login admin user
*
* @param string $login Login
* @return bool True if admin, false otherwise
*/
private static function isAdmin($login) {
return (!empty(uConfig::$admin_user) && uConfig::$admin_user == $login);
}
}
?>

View File

@ -24,6 +24,7 @@ $enabled = false;
/* -------------------------------------------- */
/* no user modifications should be needed below */
/** @noinspection ConstantCanBeUsedInspection */
if (version_compare(PHP_VERSION, "5.4.0", "<")) {
die("Sorry, ulogger will not work with PHP version lower than 5.4 (you have " . PHP_VERSION . ")");
}
@ -63,7 +64,7 @@ switch ($command) {
$queries = getQueries($pdo->getAttribute(PDO::ATTR_DRIVER_NAME));
$pdo->beginTransaction();
foreach ($queries as $query) {
$pdo->query($query);
$pdo->exec($query);
}
$pdo->commit();
} catch (PDOException $e) {
@ -90,7 +91,7 @@ switch ($command) {
$login = uUtils::postString("login");
$pass = uUtils::postPass("pass");
if (uUser::add($login, $pass) !== false) {
if (uUser::add($login, $pass, true) !== false) {
$messages[] = "<span class=\"ok\">{$langSetup["congratulations"]}</span>";
$messages[] = $langSetup["setupcomplete"];
$messages[] = "<span class=\"warn\">{$langSetup["disablewarn"]}</span><br>";
@ -123,7 +124,7 @@ switch ($command) {
$messages[] = "<form method=\"post\" action=\"setup.php\"><button>{$langSetup["restartbutton"]}</button></form>";
break;
}
if (ini_get("session.auto_start") == "1") {
if (ini_get("session.auto_start") === "1") {
$messages[] = sprintf($langSetup["optionwarn"], "session.auto_start", "0 (off)");
$messages[] = $langSetup["dorestart"];
$messages[] = "<form method=\"post\" action=\"setup.php\"><button>{$langSetup["restartbutton"]}</button></form>";
@ -182,7 +183,8 @@ function getQueries($dbDriver) {
$queries[] = "CREATE TABLE `$tUsers` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`login` varchar(15) CHARACTER SET latin1 NOT NULL UNIQUE,
`password` varchar(255) CHARACTER SET latin1 NOT NULL DEFAULT ''
`password` varchar(255) CHARACTER SET latin1 NOT NULL DEFAULT '',
`admin` boolean NOT NULL DEFAULT FALSE
) ENGINE=InnoDB DEFAULT CHARSET=utf8";
@ -224,7 +226,8 @@ function getQueries($dbDriver) {
$queries[] = "CREATE TABLE $tUsers (
id SERIAL PRIMARY KEY,
login VARCHAR(15) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL DEFAULT ''
password VARCHAR(255) NOT NULL DEFAULT '',
admin BOOLEAN NOT NULL DEFAULT FALSE
)";
$queries[] = "CREATE TABLE $tTracks (
@ -265,7 +268,8 @@ function getQueries($dbDriver) {
$queries[] = "CREATE TABLE `$tUsers` (
`id` integer PRIMARY KEY AUTOINCREMENT,
`login` varchar(15) NOT NULL UNIQUE,
`password` varchar(255) NOT NULL DEFAULT ''
`password` varchar(255) NOT NULL DEFAULT '',
`admin` integer NOT NULL DEFAULT 0
)";
$queries[] = "CREATE TABLE `$tTracks` (
`id` integer PRIMARY KEY AUTOINCREMENT,
@ -309,8 +313,7 @@ function getQueries($dbDriver) {
*/
function getPdo() {
$options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION];
$pdo = new PDO(uConfig::$dbdsn, uConfig::$dbuser, uConfig::$dbpass, $options);
return $pdo;
return new PDO(uConfig::$dbdsn, uConfig::$dbuser, uConfig::$dbpass, $options);
}
?>
@ -355,6 +358,7 @@ function getPdo() {
color: #00e700;
}
</style>
<!--suppress ES6ConvertVarToLetConst -->
<script>
var lang = <?= json_encode($lang) ?>;
var pass_regex = <?= uConfig::passRegex() ?>;

View File

@ -16,7 +16,8 @@ DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`login` varchar(15) CHARACTER SET latin1 NOT NULL UNIQUE,
`password` varchar(255) CHARACTER SET latin1 NOT NULL DEFAULT ''
`password` varchar(255) CHARACTER SET latin1 NOT NULL DEFAULT '',
`admin` boolean NOT NULL DEFAULT FALSE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------

View File

@ -16,7 +16,8 @@ DROP TABLE IF EXISTS users;
CREATE TABLE users (
id serial PRIMARY KEY,
login varchar(15) NOT NULL UNIQUE,
password varchar(255) NOT NULL DEFAULT ''
password varchar(255) NOT NULL DEFAULT '',
admin boolean NOT NULL DEFAULT FALSE
);
-- --------------------------------------------------------

View File

@ -13,7 +13,8 @@ DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` integer PRIMARY KEY AUTOINCREMENT,
`login` varchar(15) NOT NULL UNIQUE,
`password` varchar(255) NOT NULL DEFAULT ''
`password` varchar(255) NOT NULL DEFAULT '',
`admin` integer NOT NULL DEFAULT 0
);
-- --------------------------------------------------------