Admin side of permissions done, still need to be enforced.

This commit is contained in:
Richard Underwood 2017-01-06 13:59:44 +00:00
parent 4eb40af5b7
commit 6033bc12aa
5 changed files with 322 additions and 21 deletions

View file

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

View file

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

View file

@ -0,0 +1,233 @@
<?php
/*
* Permissions.
*
* Set on either users or groups.
* User permissions override any permissions on groups (as are more specific)
* Group permissions are additive
* "Account" renamed as "Owner" in interface, and will always have full permissions.
*
* Bitmask:
* 0x01 - View
* 0x02 - Update non-special records
* 0x04 - Update special records
* 0x08 - Admin (e.g. change permissions)
*
* The interface will use combinations of these shown in the permissionsmap below.
*
*/
$permissionmap=array(
'0' => '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;
}
}
?>

View file

@ -371,7 +371,7 @@ $(document).ready(function () {
},
<?php if (is_adminuser()) { ?>
account: {
title: 'Account',
title: 'Owner',
width: '8%',
display: displayContent('account'),
options: function(data) {
@ -547,7 +547,7 @@ $(document).ready(function () {
},
<?php if (is_adminuser()) { ?>
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',
<?php if($restrictediting) { ?>
'3' : 'Update normal records',
@ -906,7 +907,7 @@ $(document).ready(function () {
},
<?php if (is_adminuser()) { ?>
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;
},

View file

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