diff --git a/groups.php b/groups.php new file mode 100644 index 0000000..33df583 --- /dev/null +++ b/groups.php @@ -0,0 +1,134 @@ + $group['name'] . " - " . $group['desc'], + 'Value' => $group['name']); + } + jtable_respond($retgroups, 'options'); + break; + +case "create": + $name = isset($_POST['name']) ? $_POST['name'] : ''; + $desc = isset($_POST['desc']) ? $_POST['desc'] : ''; + + if (!valid_group($name)) { + jtable_respond(null, 'error', "Please only use ^[a-z0-9@_.-]+$ for group names"); + } + + if (group_exists($name)) { + jtable_respond(null, 'error', 'Group already exists'); + } + + if (add_group($name, $desc)) { + $result = array('name' => $name, 'desc' => $desc); + jtable_respond($result, 'single'); + } else { + jtable_respond(null, 'error', 'Could not create group'); + } + break; + +case "update": + $id = isset($_POST['id']) ? intval($_POST['id']) : ''; + $name = isset($_POST['name']) ? $_POST['name'] : ''; + $desc = isset($_POST['desc']) ? $_POST['desc'] : ''; + + if ($id != '' and update_group($id, $name, $desc)) { + $result = array('name' => $name, 'desc' => $desc); + jtable_respond($result, 'single'); + } else { + jtable_respond(null, 'error', 'Could not update group'); + } + break; + +case "delete": + $id = isset($_POST['id']) ? intval($_POST['id']) : ''; + + if ($id != '' and delete_group($id) !== FALSE) { + jtable_respond(null, 'delete'); + } else { + jtable_respond(null, 'error', 'Could not delete group'); + } + break; + +case "listmembers": + $groupid = isset($_GET['groupid']) ? intval($_GET['groupid']) : ''; + + if ($groupid != '') { + $groups = get_group_members($groupid); + jtable_respond($groups); + } else { + jtable_respond(null, 'error', 'Could not list group members'); + } + break; + +case "addmember": + $groupid = isset($_GET['groupid']) ? intval($_GET['groupid']) : ''; + $user = isset($_POST['user']) ? $_POST['user'] : ''; + + if ($groupid != '') { + if (user_exists($user)) { + if(is_group_member($groupid,$user)) { + jtable_respond(null, 'error', "User already a member of the group"); + } elseif(!is_null($id=add_group_member($groupid,$user))) { + $entry = array('id' => $id,'user' => $user); + jtable_respond($entry, 'single'); + } else { + jtable_respond(null, 'error', "Failed to add user to group"); + } + } else { + jtable_respond(null, 'error', "User doesn't exist"); + } + } else { + jtable_respond(null, 'error', 'Group not specified'); + } + break; + +case "removemember": + $id = isset($_POST['id']) ? $_POST['id'] : ''; + + if ($id != '') { + if(remove_group_member($id)) { + jtable_respond(null, 'delete'); + } else { + jtable_respond(null, 'error', "Failed to delete user from group"); + } + } else { + jtable_respond(null, 'error', 'ID not specified'); + } + break; + +default: + jtable_respond(null, 'error', 'Invalid action'); + break; +} diff --git a/includes/config.inc.php-dist b/includes/config.inc.php-dist index 8991b81..ed7d11e 100644 --- a/includes/config.inc.php-dist +++ b/includes/config.inc.php-dist @@ -10,6 +10,12 @@ $logging = TRUE; $allowclearlogs = TRUE; # Allow clearing of log entries $allowrotatelogs = FALSE;# Allow rotation to text file on server +$restrictediting = TRUE; # Restrict editing of record types +$restrictedtypes = array( + 'SOA' => 1, + 'NS' => 1 +); + # Log directory - if allowrotatelogs is set, this is where the logs will # be written. It must be writeable by the web server user. $logsdirectory = "../etc"; diff --git a/includes/database.inc.php b/includes/database.inc.php new file mode 100644 index 0000000..cfb9ff3 --- /dev/null +++ b/includes/database.inc.php @@ -0,0 +1,60 @@ +exec($createsql); + $salt = bin2hex(openssl_random_pseudo_bytes(16)); + $db->exec("INSERT INTO users (emailaddress, password, isadmin) VALUES ('admin', '".crypt("admin", '$6$'.$salt)."', 1)"); + + return $db; +} + +function open_db() { + global $authdb, $db, $db_version; + + if (!isset($db)) { + $db = new SQLite3($authdb, SQLITE3_OPEN_READWRITE); + $db->exec('PRAGMA foreign_keys = 1'); + } + + $version = intval($db->querySingle('SELECT value FROM metadata WHERE name = "version"')); + + switch($version) { + case 0: + $sql = file_get_contents('includes/upgrade-0-1.sql'); + $db->exec($sql); + writelog("Upgraded schema to version 1","system"); + // continue + case 1: // never existed + $sql = file_get_contents('includes/upgrade-1-2.sql'); + $db->exec($sql); + writelog("Upgraded schema to version 2","system"); + // continue + case $db_version: + break; + } + + return $db; +} + +function get_db() { + global $authdb, $db; + + if (!isset($db)) { + open_db(); + } + + return $db; +} + +?> diff --git a/includes/groups.inc.php b/includes/groups.inc.php new file mode 100644 index 0000000..b2c2b8c --- /dev/null +++ b/includes/groups.inc.php @@ -0,0 +1,176 @@ +query('SELECT id, name, desc FROM groups ORDER BY name'); + $ret = array(); + while ($row = $r->fetchArray(SQLITE3_ASSOC)) { + array_push($ret, $row); + } + + return $ret; +} + +function get_group_info($name) { + $db = get_db(); + $q = $db->prepare('SELECT * FROM groups WHERE name = ?'); + $q->bindValue(1, $name); + $result = $q->execute(); + $groupinfo = $result->fetchArray(SQLITE3_ASSOC); + + return $groupinfo; +} + +function get_group_name($id) { + $db = get_db(); + $q = $db->prepare('SELECT name FROM groups WHERE id = ?'); + $q->bindValue(1, $id, SQLITE3_INTEGER); + $r = $q->execute(); + $ret = $r->fetchArray(SQLITE3_NUM); + + if($ret) { + return $ret[0]; + } else { + return null; + } +} + +function group_exists($name) { + return (bool) get_group_info($name); +} + +function add_group($name, $desc) { + $db = get_db(); + $q = $db->prepare('INSERT INTO groups (name, desc) VALUES (?, ?)'); + $q->bindValue(1, $name, SQLITE3_TEXT); + $q->bindValue(2, $desc, SQLITE3_TEXT); + $ret = $q->execute(); + + writelog("Added group $name ($desc)."); + return $ret; +} + +function update_group($id, $name, $desc) { + $db = get_db(); + + $q = $db->prepare('SELECT * FROM groups WHERE id = ?'); + $q->bindValue(1, $id, SQLITE3_INTEGER); + $result = $q->execute(); + $groupinfo = $result->fetchArray(SQLITE3_ASSOC); + $q->close(); + $oldname = $groupinfo['name']; + + $q = $db->prepare('UPDATE groups SET name = ?, desc = ? WHERE id = ?'); + $q->bindValue(1, $name, SQLITE3_TEXT); + $q->bindValue(2, $desc, SQLITE3_TEXT); + $q->bindValue(3, $id, SQLITE3_INTEGER); + writelog("Updating group $oldname to: $name ($desc) "); + $ret = $q->execute(); + + return $ret; +} + +function delete_group($id) { + $db = get_db(); + + $q = $db->prepare('SELECT * FROM groups WHERE id = ?'); + $q->bindValue(1, $id, SQLITE3_INTEGER); + $result = $q->execute(); + $groupinfo = $result->fetchArray(SQLITE3_ASSOC); + $q->close(); + + if($groupinfo) { + $q = $db->prepare('DELETE FROM groups WHERE id = ?'); + $q->bindValue(1, $id, SQLITE3_INTEGER); + $ret = $q->execute(); + + writelog("Deleted group " . $groupinfo['name'] . "."); + return $ret; + } else { + return false; + } +} + +function valid_group($name) { + return ( bool ) preg_match( "/^[a-z0-9@_.-]+$/i" , $name ); +} + +function get_group_members($id) { + $db = get_db(); + + $q = $db->prepare('SELECT groupmembers.id,users.emailaddress AS user FROM groupmembers,users WHERE "group" = ? AND groupmembers.user = users.id'); + $q->bindValue(1, $id, SQLITE3_INTEGER); + $result = $q->execute(); + + $ret = array(); + + while ($row = $result->fetchArray(SQLITE3_ASSOC)) { + array_push($ret, $row); + } + + return $ret; +} + +function get_group_id($group) { + $info=get_group_info($group); + if($info) { + return $info['id']; + } else { + return null; + } +} + +function is_group_member($id,$user) { + $db = get_db(); + + $q = $db->prepare('SELECT id FROM groupmembers WHERE "group" = ? AND user = ?'); + $q->bindValue(1, $id, SQLITE3_INTEGER); + $q->bindValue(2, get_user_id($user), SQLITE3_INTEGER); + $r = $q->execute(); + $ret = $r->fetchArray(SQLITE3_NUM); + return (bool) $ret; +} + +function add_group_member($id,$user) { + $db = get_db(); + + $userid=get_user_id($user); + + $q = $db->prepare('INSERT INTO groupmembers ("group", user) VALUES (?, ?)'); + $q->bindValue(1, $id, SQLITE3_INTEGER); + $q->bindValue(2, $userid, SQLITE3_INTEGER); + $ret = $q->execute(); + + if($ret) { + writelog("Added user $user to group " . get_group_name($id) . "."); + return $db->lastInsertRowID(); + } else { + writelog("Failed to add user $user to group " . get_group_name($id) . "."); + return null; + } +} + +function remove_group_member($id) { + $db = get_db(); + + $q = $db->prepare('SELECT groups.name,users.emailaddress FROM groupmembers,users,groups WHERE groupmembers.id=? AND groupmembers.user=users.id AND groupmembers."group"=groups.id'); + $q->bindValue(1, $id, SQLITE3_INTEGER); + $r = $q->execute(); + $ret = $r->fetchArray(SQLITE3_NUM); + $group=$ret[0]; + $user=$ret[1]; + $q->close(); + + $q = $db->prepare('DELETE FROM groupmembers WHERE id=?'); + $q->bindValue(1, $id, SQLITE3_INTEGER); + $ret = $q->execute(); + + if($ret) { + writelog("Removed user $user from group $group."); + } else { + writelog("Failed to remove user $user from group $group."); + } + return $ret; +} + +?> diff --git a/includes/misc.inc.php b/includes/misc.inc.php index 274b638..7093f42 100644 --- a/includes/misc.inc.php +++ b/includes/misc.inc.php @@ -1,6 +1,7 @@ exec($createsql); - $salt = bin2hex(openssl_random_pseudo_bytes(16)); - $db->exec("INSERT INTO users (emailaddress, password, isadmin) VALUES ('admin', '".crypt("admin", '$6$'.$salt)."', 1)"); +if(class_exists('SQLite3')) { + if (isset($authdb) && !file_exists($authdb)) { + init_db(); + } else { + open_db(); + } } function string_starts_with($string, $prefix) @@ -84,17 +84,6 @@ function string_ends_with($string, $suffix) return (substr($string, -$length) === $suffix); } -function get_db() { - global $authdb, $db; - - if (!isset($db)) { - $db = new SQLite3($authdb, SQLITE3_OPEN_READWRITE); - $db->exec('PRAGMA foreign_keys = 1'); - } - - return $db; -} - function get_all_users() { $db = get_db(); $r = $db->query('SELECT id, emailaddress, isadmin FROM users ORDER BY emailaddress'); @@ -106,6 +95,40 @@ function get_all_users() { return $ret; } +/* Fetches a list of usernames from the DB for autocomplete. + * Restricts list by $term which can appear anywhere in the username + * Restricts results to $num responses + */ +function get_usernames_filtered($term, $num = 10) { + $db = get_db(); + $q = $db->prepare("SELECT emailaddress FROM users WHERE emailaddress LIKE ? ORDER BY emailaddress LIMIT 0, ?"); + $q->bindValue(1, "%" . $term . "%", SQLITE3_TEXT); + $q->bindValue(2, $num, SQLITE3_INTEGER); + $r = $q->execute(); + + $ret = array(); + while ($row = $r->fetchArray(SQLITE3_NUM)) { + array_push($ret, $row[0]); + } + + return $ret; +} + +function get_groups_filtered($term, $num = 10) { + $db = get_db(); + $q = $db->prepare("SELECT name FROM groups WHERE name LIKE ? ORDER BY name LIMIT 0, ?"); + $q->bindValue(1, "%" . $term . "%", SQLITE3_TEXT); + $q->bindValue(2, $num, SQLITE3_INTEGER); + $r = $q->execute(); + + $ret = array(); + while ($row = $r->fetchArray(SQLITE3_NUM)) { + array_push($ret, $row[0]); + } + + return $ret; +} + function get_user_info($u) { $db = get_db(); $q = $db->prepare('SELECT * FROM users WHERE emailaddress = ?'); @@ -216,6 +239,10 @@ function valid_user($name) { } function jtable_respond($records, $method = 'multiple', $msg = 'Undefined errormessage') { + if($records == null) { + $records=array(); + } + $jTableResult = array(); if ($method == 'error') { $jTableResult['Result'] = "ERROR"; @@ -355,13 +382,6 @@ function writelog($line, $user=False) { try { $db = get_db(); - $q = $db->prepare('CREATE TABLE IF NOT EXISTS logs ( - id INTEGER PRIMARY KEY, - user TEXT NOT NULL, - log TEXT NOT NULL, - timestamp DATETIME DEFAULT CURRENT_TIMESTAMP);'); - $ret = $q->execute(); - $q = $db->prepare('INSERT INTO logs (user, log) VALUES (:user, :log)'); $q->bindValue(':user', $user, SQLITE3_TEXT); $q->bindValue(':log', $line, SQLITE3_TEXT); @@ -455,4 +475,53 @@ if (!function_exists('hash_pbkdf2')) { } } +// get user id from name +function get_user_id($user) { + $info=get_user_info($user); + if($info) { + return $info['id']; + } else { + return null; + } +} + +// get zone id from name +function get_zone_id($zone) { + $db = get_db(); + + $q = $db->prepare('SELECT id FROM zones WHERE zone=?'); + $q->bindValue(1, $zone, SQLITE3_TEXT); + $r = $q->execute(); + $ret = $r->fetchArray(SQLITE3_NUM); + + if($ret) { + return $ret[0]; + } else { + return null; + } + +} + +// get user name from id +function get_user_name($userid) { + $db = get_db(); + + $q = $db->prepare('SELECT emailAddress FROM users WHERE id = ?'); + $q->bindValue(1, $userid, SQLITE3_INTEGER); + $r = $q->execute(); + $ret = $r->fetchArray(SQLITE3_NUM); + + if($ret) { + return $ret[0]; + } else { + return null; + } +} + + +// Include functions for group management +include_once('groups.inc.php'); +// Include functions for permissions management +include_once('permissions.inc.php'); + ?> diff --git a/includes/permissions.inc.php b/includes/permissions.inc.php new file mode 100644 index 0000000..c007e98 --- /dev/null +++ b/includes/permissions.inc.php @@ -0,0 +1,253 @@ + 'No permissions', + '1' => 'View Only', + '3' => 'Update normal records', + '7' => 'Update all records', + '15' => 'Admin' +); + +define('PERM_VIEW',0x01); +define('PERM_UPDATE',0x02); +define('PERM_UPDATESPECIAL',0x04); +define('PERM_ADMIN',0x08); + +define('PERM_ALL',0xffff); + + +// Interface function - Return an array of permissions for the zone +function get_zone_permissions($zone) { + $db = get_db(); + + $q = $db->prepare('SELECT p.id,p.user,u.emailAddress AS uname,p."group",g.name AS gname, p.permissions FROM permissions p LEFT JOIN users u ON p.user=u.id LEFT JOIN groups g ON p."group"=g.id LEFT JOIN zones z ON p.zone=z.id WHERE z.zone=?'); + $q->bindValue(1, $zone, SQLITE3_TEXT); + $result = $q->execute(); + + $ret = array(); + + while ($row = $result->fetchArray(SQLITE3_ASSOC)) { + $row2 = array(); + $row2['id']=$row['id']; + if($row['user']>0) { + $row2['type']='user'; + $row2['value']=$row['uname']; + } else { + $row2['type']='group'; + $row2['value']=$row['gname']; + } + $row2['permissions']=$row['permissions']; + array_push($ret, $row2); + } + + return $ret; +} + +// Interface function - Set permissions for a zone - either userid or groupid should be null +function set_permissions($userid,$groupid,$zone,$permissions) { + global $permissionmap; + + $db = get_db(); + + $q = $db->prepare('INSERT INTO permissions (zone,user,"group",permissions) VALUES (?,?,?,?)'); + $q->bindValue(1, get_zone_id($zone), SQLITE3_INTEGER); + $q->bindValue(2, $userid, SQLITE3_INTEGER); + $q->bindValue(3, $groupid, SQLITE3_INTEGER); + $q->bindValue(4, $permissions, SQLITE3_INTEGER); + + $ret = $q->execute(); + + if(!is_null($userid)) { + $who="user " . get_user_name($userid); + } else { + $who="group " . get_group_name($groupid); + } + + if($ret) { + writelog("Added '$permissionmap[$permissions]' permissions for $who from zone $zone."); + return $db->lastInsertRowID(); + } else { + writelog("Failed to add permissions to zone $zone for $who."); + return null; + } +} + +// Interface function - Copy permissions from one zone to another - used for cloning, so assumes no existing permissions on the domain + +function copy_permissions($srczone,$dstzone) { + $db = get_db(); + + $q = $db->prepare('SELECT p.user,p."group",p.permissions FROM permissions p, zones z WHERE p.zone=z.id AND z.zone=?'); + $q->bindValue(1, $srczone, SQLITE3_TEXT); + $result = $q->execute(); + + while ($row = $result->fetchArray(SQLITE3_ASSOC)) { + set_permissions($row['user'],$row['group'],$dstzone,$row['permissions']); + } + + return null; +} + +// Interface function - Update permissions for a zone +function update_permissions($id,$permissions) { + global $permissionmap; + + $db = get_db(); + + $q = $db->prepare('SELECT p.permissions, u.emailAddress, g.name, z.zone FROM permissions p LEFT JOIN users u ON p.user=u.id LEFT JOIN groups g ON p."group"=g.id LEFT JOIN zones z ON p.zone=z.id WHERE p.id=?'); + $q->bindValue(1, $id, SQLITE3_INTEGER); + $r = $q->execute(); + $ret = $r->fetchArray(SQLITE3_NUM); + if($ret[1]!='') { + $who="user " . $ret[1]; + } else { + $who="group " . $ret[2]; + } + $before=$ret[0]; + $zone=$ret[3]; + $q->close(); + + $q = $db->prepare('UPDATE permissions SET permissions=? WHERE id=?'); + $q->bindValue(1, $permissions, SQLITE3_INTEGER); + $q->bindValue(2, $id, SQLITE3_INTEGER); + + $ret = $q->execute(); + + if($ret) { + writelog("Permissions changed on zone $zone for $who from '$permissionmap[$before]' to '$permissionmap[$permissions]'."); + return $db->lastInsertRowID(); + } else { + writelog("Failed to set permissions on zone $zone for $who (permissions id $id)."); + return null; + } +} + +// Interface function - Remove permissions from a zone +function remove_permissions($id) { + global $permissionmap; + + $db = get_db(); + + $q = $db->prepare('SELECT p.permissions, u.emailAddress, g.name, z.zone FROM permissions p LEFT JOIN users u ON p.user=u.id LEFT JOIN groups g ON p."group"=g.id LEFT JOIN zones z ON p.zone=z.id WHERE p.id=?'); + $q->bindValue(1, $id, SQLITE3_INTEGER); + $r = $q->execute(); + $ret = $r->fetchArray(SQLITE3_NUM); + if($ret[1]!='') { + $who="user " . $ret[1]; + } else { + $who="group " . $ret[2]; + } + $before=$ret[0]; + $zone=$ret[3]; + $q->close(); + + $q = $db->prepare('DELETE FROM permissions WHERE id=?'); + $q->bindValue(1, $id, SQLITE3_INTEGER); + $ret = $q->execute(); + + if($ret) { + writelog("Removed '$permissionmap[$before]' permissions for $who from zone $zone"); + } else { + writelog("Failed to remove permissions for $who from zone $zone (permissions id $id)."); + } + return $ret; +} + +// Utility function - Return the permissions set on the zone for this user *not including any group membership* +function user_permissions($zone,$userid) { + $db = get_db(); + + $q = $db->prepare('SELECT p.permissions FROM permissions p LEFT JOIN zones z ON p.zone=z.id WHERE p.user=? AND z.zone=?'); + $q->bindValue(1, $userid, SQLITE3_INTEGER); + $q->bindValue(2, $zone, SQLITE3_TEXT); + $r = $q->execute(); + if($r) { + $ret = $r->fetchArray(SQLITE3_NUM); + return $ret[0]; + } else { + return null; + } +} + +// Utility function - Return the permissions set on the zone for this group +function group_permissions($zone,$groupid) { + $db = get_db(); + + $q = $db->prepare('SELECT p.permissions FROM permissions p LEFT JOIN zones z ON p.zone=z.id WHERE p."group"=? AND z.zone=?'); + $q->bindValue(1, $groupid, SQLITE3_INTEGER); + $q->bindValue(2, $zone, SQLITE3_TEXT); + $r = $q->execute(); + if($r) { + $ret = $r->fetchArray(SQLITE3_NUM); + return $ret[0]; + } else { + return null; + } +} + +// utility function - get the owner of the domain. Move to misc? +function zone_owner($zone) { + $db = get_db(); + + $q = $db->prepare('SELECT owner FROM zones WHERE zones.zone=?'); + $q->bindValue(1,$zone,SQLITE3_TEXT); + $r = $q->execute(); + if($r) { + $ret = $r->fetchArray(SQLITE3_NUM); + return $ret[0]; + } else { + return null; + } +} + +// Utility function - Return the calculated permissions for this user/zone +function permissions($zone,$userid) { + if(is_adminuser() || ($userid == zone_owner($zone))) { + return PERM_ALL; + } + + $perm=user_permissions($zone,$userid); + if(!is_null($perm)) { + return $perm; + } else { + $perm=0; + $zoneid=get_zone_id($zone); + $db = get_db(); + + $q = $db->prepare('SELECT p.permissions FROM groupmembers gm LEFT JOIN permissions p ON p."group"=gm."group" WHERE zone=? AND p."group">0 AND gm.user=?'); + $q->bindValue(1, $zoneid, SQLITE3_INTEGER); + $q->bindValue(2, $userid, SQLITE3_INTEGER); + $r = $q->execute(); + + while ($row = $r->fetchArray(SQLITE3_NUM)) { + $perm=$perm|$row[0]; + } + return $perm; + } +} + +// Utility function - check a permission for current user +function check_permissions($zone,$permmask) { + return (bool) (permissions($zone,get_user_id(get_sess_user()))&$permmask); +} + + +?> diff --git a/includes/scheme.sql b/includes/scheme.sql index 9bdbd56..78c5a1b 100644 --- a/includes/scheme.sql +++ b/includes/scheme.sql @@ -12,3 +12,39 @@ CREATE TABLE zones ( owner INTEGER NOT NULL, UNIQUE(zone), FOREIGN KEY(owner) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE ); + +CREATE TABLE logs ( + id INTEGER PRIMARY KEY, + user TEXT NOT NULL, + log TEXT NOT NULL, + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP); + +CREATE TABLE groups ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name VARCHAR UNIQUE NOT NULL, + desc VARCHAR); + +CREATE TABLE groupmembers ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + "group" INTEGER NOT NULL, + user INTEGER NOT NULL, + UNIQUE("group",user), + FOREIGN KEY("group") REFERENCES groups(id) ON DELETE CASCADE, + FOREIGN KEY(user) REFERENCES users(id) ON DELETE CASCADE); + +CREATE TABLE permissions ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + zone INTEGER NOT NULL, + user INTEGER, + "group" INTEGER, + permissions INTEGER, + UNIQUE(zone,user,"group"), + FOREIGN KEY(zone) REFERENCES zones(id) ON DELETE CASCADE, + FOREIGN KEY(user) REFERENCES users(id) ON DELETE CASCADE, + FOREIGN KEY("group") REFERENCES groups(id) ON DELETE CASCADE); + +CREATE TABLE metadata ( + name VARCHAR PRIMARY KEY, + value VARCHAR NOT NULL); + +INSERT INTO metadata (name, value) VALUES ("version","2"); diff --git a/includes/upgrade-0-1.sql b/includes/upgrade-0-1.sql new file mode 100644 index 0000000..56796e0 --- /dev/null +++ b/includes/upgrade-0-1.sql @@ -0,0 +1,5 @@ +CREATE TABLE IF NOT EXISTS logs ( + id INTEGER PRIMARY KEY, + user TEXT NOT NULL, + log TEXT NOT NULL, + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP); diff --git a/includes/upgrade-1-2.sql b/includes/upgrade-1-2.sql new file mode 100644 index 0000000..f884fc2 --- /dev/null +++ b/includes/upgrade-1-2.sql @@ -0,0 +1,29 @@ +CREATE TABLE groups ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name VARCHAR UNIQUE NOT NULL, + desc VARCHAR); + +CREATE TABLE groupmembers ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + "group" INTEGER NOT NULL, + user INTEGER NOT NULL, + UNIQUE("group",user), + FOREIGN KEY("group") REFERENCES groups(id) ON DELETE CASCADE, + FOREIGN KEY(user) REFERENCES users(id) ON DELETE CASCADE); + +CREATE TABLE permissions ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + zone INTEGER NOT NULL, + user INTEGER, + "group" INTEGER, + permissions INTEGER, + UNIQUE(zone,user,"group"), + FOREIGN KEY(zone) REFERENCES zones(id) ON DELETE CASCADE, + FOREIGN KEY(user) REFERENCES users(id) ON DELETE CASCADE, + FOREIGN KEY("group") REFERENCES groups(id) ON DELETE CASCADE); + +CREATE TABLE metadata ( + name VARCHAR PRIMARY KEY, + value VARCHAR NOT NULL); + +INSERT INTO metadata (name, value) VALUES ("version","2"); diff --git a/index.php b/index.php index b0e6fd4..0b4d5df 100644 --- a/index.php +++ b/index.php @@ -48,6 +48,8 @@ if (is_logged_in() and isset($_POST['formname']) and $_POST['formname'] === "cha + + @@ -162,7 +164,7 @@ if ($blocklogin === TRUE) {