Added user interface functions for adding remote permissions

This commit is contained in:
Lukas Metzger 2016-02-05 17:14:49 +01:00
parent a37a616967
commit 31b1a8d55f
5 changed files with 545 additions and 6 deletions

137
api/edit-remote.php Normal file
View file

@ -0,0 +1,137 @@
<?php
/*
* Copyright 2016 Lukas Metzger <developer@lukas-metzger.com>.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
require_once '../config/config-default.php';
require_once '../lib/database.php';
require_once '../lib/session.php';
$input = json_decode(file_get_contents('php://input'));
if(!isset($input->csrfToken) || $input->csrfToken !== $_SESSION['csrfToken']) {
echo "Permission denied!";
exit();
}
//Permission check
if(isset($input->record)) {
$permquery = $db->prepare("SELECT * FROM records JOIN permissions ON records.domain_id=permissions.domain WHERE user=? AND records.id=?");
$permquery->bind_param("ii", $_SESSION['id'], $input->record);
$permquery->execute();
$permquery->store_result();
if($permquery->num_rows() < 1 && $_SESSION['type'] != "admin") {
echo "Permission denied!";
exit();
}
} else {
echo "Permission denied!";
exit();
}
//Action for getting permission
if(isset($input->action) && $input->action == "getPermissions") {
$sql = "SELECT id, description, type FROM remote WHERE record=?";
$stmt = $db->prepare($sql);
$stmt->bind_param("i",$input->record);
$stmt->execute();
$result = $stmt->get_result();
$retval = Array();
while($obj = $result->fetch_object()) {
$retval[] = $obj;
}
}
//Action for adding password
if(isset($input->action) && $input->action == "addPassword") {
$passwordHash = password_hash($input->password, PASSWORD_DEFAULT);
$sql = "INSERT INTO remote(record,description,type,security) VALUES (?,?,'password',?)";
$stmt = $db->prepare($sql);
$stmt->bind_param("iss",$input->record, $input->description, $passwordHash);
$stmt->execute();
}
//Action for adding key
if(isset($input->action) && $input->action == "addKey") {
$sql = "INSERT INTO remote(record,description,type,security) VALUES (?,?,'key',?)";
$stmt = $db->prepare($sql);
$stmt->bind_param("iss",$input->record, $input->description, $input->key);
$stmt->execute();
}
//Action for updating password
if(isset($input->action) && $input->action == "changePassword") {
if(isset($input->password)) {
$passwordHash = password_hash($input->password, PASSWORD_DEFAULT);
$sql = "UPDATE remote SET description=?,security=? WHERE id=?";
$stmt = $db->prepare($sql);
$stmt->bind_param("ssi",$input->description, $passwordHash, $input->permission);
$stmt->execute();
} else {
$sql = "UPDATE remote SET description=? WHERE id=?";
$stmt = $db->prepare($sql);
$stmt->bind_param("ssi",$input->description, $input->permission);
$stmt->execute();
}
}
//Action for updating key
if(isset($input->action) && $input->action == "changeKey") {
$sql = "UPDATE remote SET description=?,security=? WHERE id=?";
$stmt = $db->prepare($sql);
$stmt->bind_param("ssi",$input->description, $input->key, $input->permission);
$stmt->execute();
}
//Action for getting key
if(isset($input->action) && $input->action == "getKey") {
$sql = "SELECT security FROM remote WHERE id=? AND type='key'";
$stmt = $db->prepare($sql);
$stmt->bind_param("i",$input->permission);
$stmt->execute();
$stmt->bind_result($key);
$stmt->fetch();
$retval = Array();
$retval['key'] = $key;
}
//Action for deleting permission
if(isset($input->action) && $input->action == "deletePermission") {
$sql = "DELETE FROM remote WHERE id=?";
$stmt = $db->prepare($sql);
$stmt->bind_param("i",$input->permission);
$stmt->execute();
}
if(isset($retval)) {
echo json_encode($retval);
} else {
echo "{}";
}

View file

@ -155,7 +155,7 @@ limitations under the License.
<td><input id="addContent" type="text" class="form-control input-sm" data-regex="^.+$"></td>
<td><input id="addPrio" type="text" class="form-control input-sm" size="1" data-regex="^[0-9]+$"></td>
<td><input id="addTtl" type="text" class="form-control input-sm" size="3" data-regex="^[0-9]+$"></td>
<td colspan="2"><button id="addButton" class="btn btn-success btn-sm">&nbsp;Add&nbsp;</button></td>
<td colspan="3"><button id="addButton" class="btn btn-success btn-sm">&nbsp;Add&nbsp;</button></td>
</tfoot>
</table>
</div>

122
edit-remote.php Normal file
View file

@ -0,0 +1,122 @@
<!DOCTYPE html>
<!--
Copyright 2016 Lukas Metzger <developer@lukas-metzger.com>.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<?php
require_once 'lib/headers.php';
require_once 'lib/session.php';
?>
<html>
<head>
<title>PDNS Manager - Remotes</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="include/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="include/bootstrap/css/bootstrap-theme.min.css" rel="stylesheet">
<link href="include/select2/select2.min.css" rel="stylesheet">
<link href="include/select2/select2-bootstrap.min.css" rel="stylesheet">
<link href="include/custom.css" rel="stylesheet">
<script src="include/jquery.js"></script>
<script src="include/bootstrap/js/bootstrap.min.js"></script>
<script src="include/select2/select2.min.js"></script>
<script src="js/edit-remote.js"></script>
</head>
<body>
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container">
<div class="navbar-brand">
PDNS Manager
</div>
<ul class="nav navbar-nav">
<li><a href="domains.php">Domains</a></li>
<?php if($_SESSION['type'] == "admin") echo '<li><a href="users.php">Users</a></li>'; ?>
<li><a href="password.php">Password</a></li>
<li><a href="logout.php">Logout</a></li>
</ul>
</div>
</nav>
<div class="container">
<row>
<h2 id="heading">Remote access</h2>
</row>
<row>
<div class="col-md-4">
<table id="permissions" class="table table-hover">
<thead>
<tr>
<td><strong>ID</strong></td>
<td><strong>Description</strong></td>
<td><strong>Type</strong></td>
<td></td>
<td></td>
</tr>
</thead>
<tbody>
</tbody>
</table>
<row>
<button id="button-add-password" class="btn btn-success">Add password</button>
<button id="button-add-key" class="btn btn-success">Add key</button>
</row>
</div>
<div class="col-md-4 col-md-offset-1" id="info-dialogs">
<row id="data-password" class="defaulthidden">
<form>
<div class="form-group">
<label for="data-password-description" class="control-label">Description</label>
<input type="text" class="form-control" id="data-password-description" placeholder="Description" autocomplete="off">
</div>
<div class="form-group">
<label for="data-password-password" class="control-label">Password</label>
<input type="password" class="form-control" id="data-password-password" placeholder="Password" autocomplete="off">
</div>
<div class="form-group">
<label for="data-password-password2" class="control-label">Password repeated</label>
<input type="password" class="form-control" id="data-password-password2" placeholder="Password repeated" autocomplete="off">
</div>
<button id="data-password-confirm" class="btn btn-primary">Add</button>
<button id="data-password-cancel" class="btn btn-default">Cancel</button>
</form>
</row>
<row id="data-key" class="defaulthidden">
<form>
<div class="form-group">
<label for="data-key-description" class="control-label">Description</label>
<input type="text" class="form-control" id="data-key-description" placeholder="Description" autocomplete="off">
</div>
<div class="form-group">
<label for="data-key-key" class="control-label">RSA Public Key</label>
<textarea class="form-control" id="data-key-key" placeholder="Enter RSA Public Key" autocomplete="off" cols="100" rows="10"></textarea>
</div>
<button id="data-key-confirm" class="btn btn-primary">Add</button>
<button id="data-key-cancel" class="btn btn-default">Cancel</button>
</form>
</row>
</div>
</row>
</div>
<?php echo '<span class="hidden" id="csrfToken">' . $_SESSION['csrfToken'] . '</span>'; ?>
</body>
</html>

View file

@ -115,12 +115,14 @@ function recreateTable(data) {
.append('<td>' + item.priority + '</td>')
.append('<td>' + item.ttl + '</td>')
.append('<td><span class="glyphicon glyphicon-pencil cursor-pointer"></span></td>')
.append('<td><span class="glyphicon glyphicon-trash cursor-pointer"></span></td>');
.append('<td><span class="glyphicon glyphicon-trash cursor-pointer"></span></td>')
.append('<td><span class="glyphicon glyphicon-share cursor-pointer"></span></td>');
});
$('#table-records>tbody>tr>td>span.glyphicon-trash').click(trashClicked);
$('#table-records>tbody>tr>td>span.glyphicon-pencil').click(editClicked);
$('#table-records>tbody>tr>td>span.glyphicon-share').click(remoteClicked);
}
function requestRecordData() {
@ -253,8 +255,9 @@ function editClicked() {
tableCells.eq(6).remove();
tableCells.eq(7).remove();
tableCells.eq(8).remove();
$(tableRow).append('<td colspan="2"><button class="btn btn-primary btn-sm">Save</button></td>');
$(tableRow).append('<td colspan="3"><button class="btn btn-primary btn-sm">Save</button></td>');
$(tableRow).find('button').click(saveRecord);
@ -287,9 +290,11 @@ function saveRecord() {
tableRow.children('td').eq(6).remove();
tableRow.append('<td><span class="glyphicon glyphicon-pencil cursor-pointer"></span></td>')
.append('<td><span class="glyphicon glyphicon-trash cursor-pointer"></span></td>');
.append('<td><span class="glyphicon glyphicon-trash cursor-pointer"></span></td>')
.append('<td><span class="glyphicon glyphicon-share cursor-pointer"></span></td>');
tableRow.find('span.glyphicon-trash').click(trashClicked);
tableRow.find('span.glyphicon-pencil').click(editClicked);
tableRow.find('span.glyphicon-pencil').click(editClicked);
tableRow.find('span.glyphicon-share').click(remoteClicked);
enableFilter(true);
@ -331,10 +336,12 @@ function addRecord() {
.append('<td>' + data.prio + '</td>')
.append('<td>' + data.ttl + '</td>')
.append('<td><span class="glyphicon glyphicon-pencil cursor-pointer"></span></td>')
.append('<td><span class="glyphicon glyphicon-trash cursor-pointer"></span></td>');
.append('<td><span class="glyphicon glyphicon-trash cursor-pointer"></span></td>')
.append('<td><span class="glyphicon glyphicon-share cursor-pointer"></span></td>');
$('#table-records>tbody>tr').last().find('span.glyphicon-pencil').click(editClicked);
$('#table-records>tbody>tr').last().find('span.glyphicon-trash').click(trashClicked);
$('#table-records>tbody>tr').last().find('span.glyphicon-share').click(remoteClicked);
requestSerial();
$('#addName').val("");
@ -417,4 +424,9 @@ function validateLine() {
});
return errors <= 0;
}
function remoteClicked() {
var recordId = $(this).parent().siblings().eq(0).text();
location.assign("edit-remote.php#" + recordId);
}

268
js/edit-remote.js Normal file
View file

@ -0,0 +1,268 @@
/*
* Copyright 2016 Lukas Metzger <developer@lukas-metzger.com>.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
$(document).ready(function() {
$('#data-password-password2').bind("paste keyup change", function() {
if($('#data-password-password').val() != $('#data-password-password2').val()) {
$(this).parent().addClass("has-error");
} else {
$(this).parent().removeClass("has-error");
}
});
$('#button-add-password').click(function() {
resetFields();
$('#data-password').show();
$('#data-key').hide();
$('#data-password-confirm').unbind().click(addPassword);
});
$('#button-add-key').click(function() {
resetFields();
$('#data-key').show();
$('#data-password').hide();
$('#data-key-confirm').unbind().click(addKey);
});
$('#data-password-cancel').click(function() {
$('#data-password').hide();
});
$('#data-key-cancel').click(function() {
$('#data-key').hide();
});
requestPermissions();
});
function regexValidate() {
var regex = new RegExp($(this).attr('data-regex'));
if(!regex.test($(this).val())) {
$(this).parent().addClass("has-error");
} else {
$(this).parent().removeClass("has-error");
}
}
function createTable(data) {
$('#permissions tbody').empty();
$.each(data, function(index,item) {
$('<tr></tr>').appendTo('#permissions tbody')
.append('<td>' + item.id + '</td>')
.append('<td>' + item.description + '</td>')
.append('<td>' + item.type + '</td>')
.append('<td><span class="glyphicon glyphicon-pencil cursor-pointer"></span></td>')
.append('<td><span class="glyphicon glyphicon-trash cursor-pointer"></span></td>');
});
$('#permissions tbody span.glyphicon-trash').click(deletePermission);
$('#permissions tbody span.glyphicon-pencil').click(prepareEdit);
}
function requestPermissions() {
var data = {
action: "getPermissions",
csrfToken: $('#csrfToken').text(),
record: location.hash.substring(1)
};
$.post(
"api/edit-remote.php",
JSON.stringify(data),
function(data) {
createTable(data);
},
"json"
);
}
function resetFields() {
$('#info-dialogs input').val("");
$('#info-dialogs textarea').val("");
$('#info-dialogs .form-group').removeClass("has-error");
$('#data-password-password').attr("placeholder", "Password");
$('#data-password-password2').attr("placeholder", "Password repeated");
$('#data-password-confirm').text("Add");
$('#data-key-confirm').text("Add");
}
function addPassword() {
if($('#data-password-password').val() != $('#data-password-password2').val() || $('#data-password-password').val().length <= 0) {
$('#data-password-password2').parent().addClass("has-error");
return;
}
var data = {
csrfToken: $('#csrfToken').text(),
action: "addPassword",
description: $('#data-password-description').val(),
password: $('#data-password-password').val(),
record: location.hash.substring(1)
};
$.post(
"api/edit-remote.php",
JSON.stringify(data),
function(data) {
$('#data-password').hide();
requestPermissions();
},
"json"
);
}
function addKey() {
if($('#data-key-key').val().length <= 0) {
$('#data-key-key').parent().addClass("has-error");
return;
}
var data = {
csrfToken: $('#csrfToken').text(),
action: "addKey",
description: $('#data-key-description').val(),
key: $('#data-key-key').val(),
record: location.hash.substring(1)
};
$.post(
"api/edit-remote.php",
JSON.stringify(data),
function(data) {
$('#data-key').hide();
requestPermissions();
},
"json"
);
}
function deletePermission() {
var data = {
csrfToken: $('#csrfToken').text(),
action: "deletePermission",
permission: $(this).parent().siblings().eq(0).text(),
record: location.hash.substring(1)
};
$.post(
"api/edit-remote.php",
JSON.stringify(data),
function(data) {
requestPermissions();
},
"json"
);
}
function prepareEdit() {
var type = $(this).parent().siblings().eq(2).text();
if(type === "password") {
resetFields();
$('#data-password').show();
$('#data-key').hide();
$('#data-password-confirm').unbind().click(changePassword);
$('#data-password-password').attr("placeholder", "(Unchanged)");
$('#data-password-password2').attr("placeholder", "(Unchanged)");
$('#data-password-confirm').text("Change");
$('#data-password-description').val($(this).parent().siblings().eq(1).text());
$('#data-password-confirm').data("permission-id", $(this).parent().siblings().eq(0).text());
} else if(type === "key") {
resetFields();
$('#data-key').show();
$('#data-password').hide();
$('#data-key-confirm').unbind().click(changeKey);
$('#data-key-confirm').text("Change");
$('#data-key-description').val($(this).parent().siblings().eq(1).text());
$('#data-key-confirm').data("permission-id", $(this).parent().siblings().eq(0).text());
var data = {
csrfToken: $('#csrfToken').text(),
action: "getKey",
permission: $(this).parent().siblings().eq(0).text(),
record: location.hash.substring(1)
};
$.post(
"api/edit-remote.php",
JSON.stringify(data),
function(data) {
$('#data-key-key').val(data.key);
},
"json"
);
}
}
function changePassword() {
if($('#data-password-password').val() != $('#data-password-password2').val()) {
$('#data-password-password2').parent().addClass("has-error");
return;
}
var data = {
csrfToken: $('#csrfToken').text(),
action: "changePassword",
description: $('#data-password-description').val(),
record: location.hash.substring(1),
permission: $('#data-password-confirm').data("permission-id")
};
if($('#data-password-password').val().length >= 0) {
data.password = $('#data-password-password').val();
}
$.post(
"api/edit-remote.php",
JSON.stringify(data),
function(data) {
$('#data-password').hide();
requestPermissions();
},
"json"
);
}
function changeKey() {
if($('#data-key-key').val().length <= 0) {
$('#data-key-key').parent().addClass("has-error");
return;
}
var data = {
csrfToken: $('#csrfToken').text(),
action: "changeKey",
description: $('#data-key-description').val(),
key: $('#data-key-key').val(),
record: location.hash.substring(1),
permission: $('#data-key-confirm').data("permission-id")
};
$.post(
"api/edit-remote.php",
JSON.stringify(data),
function(data) {
$('#data-key').hide();
requestPermissions();
},
"json"
);
}