From 6033bc12aaa5ff592a7a1fa4d14d35842bb40f16 Mon Sep 17 00:00:00 2001 From: Richard Underwood Date: Fri, 6 Jan 2017 13:59:44 +0000 Subject: [PATCH] Admin side of permissions done, still need to be enforced. --- includes/groups.inc.php | 15 ++- includes/misc.inc.php | 15 +++ includes/permissions.inc.php | 233 +++++++++++++++++++++++++++++++++++ index.php | 9 +- permissions.php | 71 ++++++++--- 5 files changed, 322 insertions(+), 21 deletions(-) create mode 100644 includes/permissions.inc.php diff --git a/includes/groups.inc.php b/includes/groups.inc.php index a62a743..5c02e52 100644 --- a/includes/groups.inc.php +++ b/includes/groups.inc.php @@ -28,7 +28,11 @@ function get_group_name($id) { $r = $q->execute(); $ret = $r->fetchArray(SQLITE3_NUM); - return $ret[0]; + if($ret) { + return $ret[0]; + } else { + return null; + } } function group_exists($name) { @@ -117,6 +121,15 @@ function get_user_id($user) { } } +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(); diff --git a/includes/misc.inc.php b/includes/misc.inc.php index 2e9d374..b8071fb 100644 --- a/includes/misc.inc.php +++ b/includes/misc.inc.php @@ -114,6 +114,21 @@ function get_usernames_filtered($term, $num = 10) { 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 = ?'); diff --git a/includes/permissions.inc.php b/includes/permissions.inc.php new file mode 100644 index 0000000..a0a7726 --- /dev/null +++ b/includes/permissions.inc.php @@ -0,0 +1,233 @@ + '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); + + +// move to misc? +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; + } + +} + +// move to misc? +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; + } +} + +// 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 - 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 - Return the calculated permissions for this user/zone +function permissions($zone,$userid) { + $perm=user_permissions($zone,$userid); + + if(!is_null($perm)) { + return $perm; + } else { + $perm=0; + + } +} + +?> diff --git a/index.php b/index.php index 1df3400..c2ff50c 100644 --- a/index.php +++ b/index.php @@ -371,7 +371,7 @@ $(document).ready(function () { }, account: { - title: 'Account', + title: 'Owner', width: '8%', display: displayContent('account'), options: function(data) { @@ -547,7 +547,7 @@ $(document).ready(function () { }, account: { - title: 'Account', + title: 'Owner', width: '8%', display: displayContent('account'), options: function(data) { @@ -851,6 +851,7 @@ $(document).ready(function () { permissions: { title: 'Permissions', options: { + '0' : 'No permissions', '1' : 'View Only', '3' : 'Update normal records', @@ -906,7 +907,7 @@ $(document).ready(function () { }, account: { - title: 'Account', + title: 'Owner', options: function(data) { return 'users.php?action=listoptions&e='+$epoch; }, @@ -975,7 +976,7 @@ $(document).ready(function () { inputClass: 'destname' }, account: { - title: 'Account', + title: 'Owner', options: function(data) { return 'users.php?action=listoptions&e='+$epoch; }, diff --git a/permissions.php b/permissions.php index 713e465..32d55ae 100644 --- a/permissions.php +++ b/permissions.php @@ -3,6 +3,7 @@ include_once('includes/config.inc.php'); include_once('includes/session.inc.php'); include_once('includes/misc.inc.php'); +include_once('includes/permissions.inc.php'); if (!is_csrf_safe()) { header('Status: 403'); @@ -10,7 +11,7 @@ if (!is_csrf_safe()) { jtable_respond(null, 'error', "Authentication required"); } -$zoneid = isset($_GET['zoneid']) ? intval($_GET['zoneid']) : ''; +$zoneid = isset($_GET['zoneid']) ? $_GET['zoneid'] : ''; if (!is_adminuser()) { header('Status: 403'); @@ -30,27 +31,45 @@ case "list": $permissions = get_zone_permissions($zoneid); jtable_respond($permissions); } else { - jtable_respond(null, 'error', 'Could not list zone permissions'); + jtable_respond(null, 'error', 'Zone id required'); } break; case "add": $type = isset($_POST['type']) ? $_POST['type'] : ''; $value = isset($_POST['value']) ? $_POST['value'] : ''; - $permissons = isset($_POST['permissions']) ? $_POST['permissions'] : ''; + $permissions = isset($_POST['permissions']) ? $_POST['permissions'] : ''; + $zone = isset($_GET['zoneid']) ? $_GET['zoneid'] : ''; if ($zoneid != '') { - 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'); + if($type == 'user') { + if (user_exists($value)) { + $userid=get_user_id($value); + if(!is_null(user_permissions($zone,$userid))) { + jtable_respond(null, 'error', "User already has permissions set for this zone"); + } elseif(!is_null($id=set_permissions($userid,null,$zone,$permissions))) { + $entry = array('id' => $id, 'type' => 'user', 'value' => $value, 'permissions' => $permissions); + jtable_respond($entry, 'single'); + } else { + jtable_respond(null, 'error', "Failed to set permissions"); + } } else { - jtable_respond(null, 'error', "Failed to add user to group"); + jtable_respond(null, 'error', "User doesn't exist"); } } else { - jtable_respond(null, 'error', "User doesn't exist"); + if (group_exists($value)) { + $groupid=get_group_id($value); + if(!is_null(group_permissions($zone,$groupid))) { + jtable_respond(null, 'error', "Group already has permissions set for this zone"); + } elseif(!is_null($id=set_permissions(null,$groupid,$zone,$permissions))) { + $entry = array('id' => $id, 'type' => 'group', 'value' => $value, 'permissions' => $permissions); + jtable_respond($entry, 'single'); + } else { + jtable_respond(null, 'error', "Failed to set permissions"); + } + } else { + jtable_respond(null, 'error', "Group doesn't exist"); + } } } else { jtable_respond(null, 'error', 'Zone not specified'); @@ -58,23 +77,43 @@ case "add": break; case "remove": + $id = isset($_POST['id']) ? $_POST['id'] : ''; if ($id != '') { - if(remove_group_member($id)) { + if(remove_permissions($id)) { jtable_respond(null, 'delete'); } else { - jtable_respond(null, 'error', "Failed to delete user from group"); + jtable_respond(null, 'error', "Failed to remove permissions"); } } else { jtable_respond(null, 'error', 'ID not specified'); } break; +case "update": + $id = isset($_POST['id']) ? $_POST['id'] : ''; + $permissions = isset($_POST['permissions']) ? intval($_POST['permissions']) : 0; + if ($id != '') { + if(update_permissions($id,$permissions)) { + $result = array('id' => $id, 'permissions' => $permissions); + jtable_respond($result, 'single'); + } else { + jtable_respond(null, 'error', 'Failed to set permissions'); + } + } else { + jtable_respond(null, 'error', 'ID not specified'); + } + case "autocomplete": - $term = isset($_GET['type']) ? $_GET['type'] : ''; + $type = isset($_GET['type']) ? $_GET['type'] : ''; $term = isset($_GET['term']) ? $_GET['term'] : ''; - $users=get_usernames_filtered($term); - print json_encode($users); + if($type == 'user') { + $users=get_usernames_filtered($term); + print json_encode($users); + } else { + $groups=get_groups_filtered($term); + print json_encode($groups); + } break; default: