Added working implementation for edit-master.php, validity checks are required

This commit is contained in:
Lukas Metzger 2016-01-23 17:05:13 +01:00
parent 59a3ed22e3
commit 17e3cf908d
4 changed files with 421 additions and 48 deletions

View file

@ -20,6 +20,7 @@ require_once '../config/config-default.php';
require_once '../lib/database.php';
require_once '../lib/session.php';
require_once '../lib/soa-mail.php';
require_once '../lib/update-serial.php';
$input = json_decode(file_get_contents('php://input'));
@ -151,4 +152,130 @@ if(isset($input->action) && $input->action == "getSoa") {
}
echo json_encode($retval);
//Action for getting SOA
if(isset($input->action) && $input->action == "getSerial") {
$domainId = (int)$input->domain;
$stmt = $db->prepare("SELECT content FROM records WHERE type='SOA' AND domain_id=?");
$stmt->bind_param("i", $domainId);
$stmt->execute();
$stmt->bind_result($content);
$stmt->fetch();
$content = explode(" ", $content);
$retval = Array();
$retval['serial'] = $content[2];
}
//Action for saving SOA
if(isset($input->action) && $input->action == "saveSoa") {
$domainId = (int)$input->domain;
$db->autocommit(false);
$db->begin_transaction();
$stmt = $db->prepare("SELECT content FROM records WHERE type='SOA' AND domain_id=?");
$stmt->bind_param("i", $domainId);
$stmt->execute();
$stmt->bind_result($content);
$stmt->fetch();
$stmt->close();
$content = explode(" ", $content);
$serial = $content[2];
$newsoa = $input->primary . " ";
$newsoa .= mail_to_soa($input->email) . " ";
$newsoa .= $serial . " ";
$newsoa .= $input->refresh . " ";
$newsoa .= $input->retry . " ";
$newsoa .= $input->expire . " ";
$newsoa .= $input->ttl;
$stmt = $db->prepare("UPDATE records SET content=? WHERE type='SOA' AND domain_id=?");
$stmt->bind_param("si", $newsoa, $domainId);
$stmt->execute();
$db->commit();
$retval = Array();
update_serial($db, $domainId);
}
//Action for saving Record
if(isset($input->action) && $input->action == "saveRecord") {
$domainId = $input->domain;
$stmt = $db->prepare("UPDATE records SET name=?,type=?,content=?,ttl=?,prio=? WHERE id=? AND domain_id=?");
$stmt->bind_param("sssiiii",
$input->name, $input->type,
$input->content, $input->ttl,
$input->prio,
$input->id, $domainId
);
$stmt->execute();
update_serial($db, $domainId);
}
//Action for adding Record
if(isset($input->action) && $input->action == "addRecord") {
$domainId = $input->domain;
$stmt = $db->prepare("INSERT INTO records (domain_id, name, type, content, prio, ttl) VALUES (?,?,?,?,?,?)");
$stmt->bind_param("isssii",
$domainId, $input->name,
$input->type, $input->content,
$input->prio, $input->ttl
);
$stmt->execute();
$stmt->close();
$stmt = $db->prepare("SELECT LAST_INSERT_ID()");
$stmt->execute();
$stmt->bind_result($newId);
$stmt->fetch();
$stmt->close();
$retval = Array();
$retval['newId'] = $newId;
update_serial($db, $domainId);
}
//Action for removing Record
if(isset($input->action) && $input->action == "removeRecord") {
$domainId = $input->domain;
$recordId = $input->id;
$stmt = $db->prepare("DELETE FROM records WHERE id=? AND domain_id=?");
$stmt->bind_param("ii", $recordId, $domainId);
$stmt->execute();
$stmt->close();
update_serial($db, $domainId);
}
//Action for getting domain name
if(isset($input->action) && $input->action == "getDomainName") {
$domainId = $input->domain;
$stmt = $db->prepare("SELECT name FROM domains WHERE id=?");
$stmt->bind_param("i", $domainId);
$stmt->execute();
$stmt->bind_result($domainName);
$stmt->fetch();
$stmt->close();
$retval = Array();
$retval['name'] = $domainName;
}
if (isset($retval)) {
echo json_encode($retval);
} else {
echo "{}";
}

View file

@ -51,7 +51,7 @@ limitations under the License.
<div class="container">
<row>
<h2 id="domain-name">example.com</h2>
<h2 id="domain-name"></h2>
</row>
<div id="soa" class="container">
@ -125,45 +125,7 @@ limitations under the License.
<div class="form-group">
<strong>Type</strong>
<span class="glyphicon glyphicon-sort cursor-pointer"></span>
<select class="form-control no-shadow" id="searchType" multiple>
<option value="A" >A</option>
<option value="AAAA" >AAAA</option>
<option value="AFSDB" >AFSDB</option>
<option value="CERT" >CERT</option>
<option value="CNAME" >CNAME</option>
<option value="DHCID" >DHCID</option>
<option value="DLV" >DLV</option>
<option value="DNSKEY" >DNSKEY</option>
<option value="DS" >DS</option>
<option value="EUI48" >EUI48</option>
<option value="EUI64" >EUI64</option>
<option value="HINFO" >HINFO</option>
<option value="IPSECKEY" >IPSECKEY</option>
<option value="KEY" >KEY</option>
<option value="KX" >KX</option>
<option value="LOC" >LOC</option>
<option value="MINFO" >MINFO</option>
<option value="MR" >MR</option>
<option value="MX" >MX</option>
<option value="NAPTR" >NAPTR</option>
<option value="NS" >NS</option>
<option value="NSEC" >NSEC</option>
<option value="NSEC3" >NSEC3</option>
<option value="NSEC3PARAM" >NSEC3PARAM</option>
<option value="OPT" >OPT</option>
<option value="PTR" >PTR</option>
<option value="RKEY" >RKEY</option>
<option value="RP" >RP</option>
<option value="RRSIG" >RRSIG</option>
<option value="SOA" >SOA</option>
<option value="SPF" >SPF</option>
<option value="SRV" >SRV</option>
<option value="SSHFP" >SSHFP</option>
<option value="TLSA" >TLSA</option>
<option value="TSIG" >TSIG</option>
<option value="TXT" >TXT</option>
<option value="WKS" >WKS</option>
</select>
<select class="form-control no-shadow" id="searchType" multiple></select>
</div>
</form>
</td>
@ -182,7 +144,15 @@ limitations under the License.
</thead>
<tbody>
</tbody>
<tfoot>
<td></td>
<td><input id="addName" type="text" class="form-control input-sm"></td>
<td><select id="addType" class="form-control" style="width: 70%;"></select></td>
<td><input id="addContent" type="text" class="form-control input-sm"></td>
<td><input id="addPrio" type="text" class="form-control input-sm" size="1"></td>
<td><input id="addTtl" type="text" class="form-control input-sm" size="3"></td>
<td colspan="2"><button id="addButton" class="btn btn-success btn-sm">&nbsp;Add&nbsp;</button></td>
</tfoot>
</table>
</div>
</div>

View file

@ -17,7 +17,18 @@
var sort = {
field: "",
order: 1
}
};
var domainName = "";
var recordTypes = [
"A","AAAA","AFSDB","CERT","CNAME","DHCID",
"DLV","DNSKEY","DS","EUI48","EUI64","HINFO",
"IPSECKEY","KEY","KX","LOC","MINFO","MR",
"MX","NAPTR","NS","NSEC","NSEC3","NSEC3PARAM",
"OPT","PTR","RKEY","RP","RRSIG","SOA","SPF",
"SRV","SSHFP","TLSA","TSIG","TXT","WKS"
];
$(document).ready(function() {
@ -42,7 +53,12 @@ $(document).ready(function() {
});
$('#searchType').select2({
placeholder: "Filter..."
placeholder: "Filter...",
data: recordTypes
});
$('#addType').select2({
data: recordTypes
});
$('#table-records>thead>tr>td span.glyphicon').click(function() {
@ -70,10 +86,13 @@ $(document).ready(function() {
$('#searchType').change(function() {
requestRecordData();
});
$('#addButton').click(addRecord);
requestRecordData();
requestSoaData();
requestSerial();
requestDomainName();
});
function validateSoaData() {
@ -101,10 +120,13 @@ function recreateTable(data) {
.append('<td>' + item.content + '</td>')
.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-pencil cursor-pointer"></span></td>')
.append('<td><span class="glyphicon glyphicon-trash cursor-pointer"></span></td>');
});
$('#table-records>tbody>tr>td>span.glyphicon-trash').click(trashClicked);
$('#table-records>tbody>tr>td>span.glyphicon-pencil').click(editClicked);
}
function requestRecordData() {
@ -158,6 +180,22 @@ function requestSoaData() {
$('#soa-retry').val(data.retry);
$('#soa-expire').val(data.expire);
$('#soa-ttl').val(data.ttl);
},
"json"
);
}
function requestSerial() {
var data = {
action: "getSerial"
};
data.domain = location.hash.substring(1);
$.post(
"api/edit-master.php",
JSON.stringify(data),
function(data) {
$('#soa-serial').val(data.serial);
},
"json"
@ -165,5 +203,184 @@ function requestSoaData() {
}
function saveSoaData() {
var data = {
action: "saveSoa"
};
data.domain = location.hash.substring(1);
data.primary = $('#soa-primary').val();
data.email = $('#soa-mail').val();
data.refresh = $('#soa-refresh').val();
data.retry = $('#soa-retry').val();
data.expire = $('#soa-expire').val();
data.ttl = $('#soa-ttl').val();
$.post(
"api/edit-master.php",
JSON.stringify(data),
function() {
requestSerial();
},
"json"
);
}
function editClicked() {
var tableCells = $(this).parent().parent().children('td');
var tableRow = $(this).parent().parent();
var valueName = tableCells.eq(1).text();
tableCells.eq(1).empty();
$('<input type="text" class="form-control input-sm">').appendTo(tableCells.eq(1)).val(valueName);
var valueType = tableCells.eq(2).text();
tableCells.eq(2).empty();
$('<select class="form-control" style="width: 70%;"></select>').appendTo(tableCells.eq(2)).select2({
data: recordTypes
}).val(valueType).trigger("change");
var valueContent = tableCells.eq(3).text();
tableCells.eq(3).empty();
$('<input type="text" class="form-control input-sm">').appendTo(tableCells.eq(3)).val(valueContent);
var valuePrio = tableCells.eq(4).text();
tableCells.eq(4).empty();
$('<input type="text" class="form-control input-sm" size="1">').appendTo(tableCells.eq(4)).val(valuePrio);
var valueTtl = tableCells.eq(5).text();
tableCells.eq(5).empty();
$('<input type="text" class="form-control input-sm" size="3">').appendTo(tableCells.eq(5)).val(valueTtl);
tableCells.eq(6).remove();
tableCells.eq(7).remove();
$(tableRow).append('<td colspan="2"><button class="btn btn-primary btn-sm">Save</button></td>');
$(tableRow).find('button').click(saveRecord);
enableFilter(false);
}
function saveRecord() {
var tableRow = $(this).parent().parent();
var data = {
id: tableRow.children('td').eq(0).text(),
name: tableRow.children('td').eq(1).children('input').val(),
type: tableRow.children('td').eq(2).children('select').val(),
content: tableRow.children('td').eq(3).children('input').val(),
prio: tableRow.children('td').eq(4).children('input').val(),
ttl: tableRow.children('td').eq(5).children('input').val(),
action: "saveRecord",
domain: location.hash.substring(1)
};
tableRow.children('td').eq(0).empty().text(data.id);
tableRow.children('td').eq(1).empty().text(data.name);
tableRow.children('td').eq(2).empty().text(data.type);
tableRow.children('td').eq(3).empty().text(data.content);
tableRow.children('td').eq(4).empty().text(data.prio);
tableRow.children('td').eq(5).empty().text(data.ttl);
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>');
tableRow.find('span.glyphicon-trash').click(trashClicked);
tableRow.find('span.glyphicon-pencil').click(editClicked);
enableFilter(true);
$.post(
"api/edit-master.php",
JSON.stringify(data),
function() {
requestSerial();
},
"json"
);
}
function addRecord() {
var data = {
name: $('#addName').val(),
type: $('#addType').val(),
content: $('#addContent').val(),
prio: $('#addPrio').val(),
ttl: $('#addTtl').val(),
action: "addRecord",
domain: location.hash.substring(1)
};
$.post(
"api/edit-master.php",
JSON.stringify(data),
function(dataRecv) {
$('<tr></tr>').appendTo('#table-records>tbody')
.append('<td>' + dataRecv.newId + '</td>')
.append('<td>' + data.name + '</td>')
.append('<td>' + data.type + '</td>')
.append('<td>' + data.content + '</td>')
.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>')
.find('span.glyphicon-trash').click(trashClicked)
.find('span.glyphicon-pencil').click(editClicked);
requestSerial();
},
"json"
);
}
function trashClicked() {
var data = {
id: $(this).parent().parent().children().eq(0).text(),
domain: location.hash.substring(1),
action: "removeRecord"
};
var lineAffected = $(this).parent().parent();
$.post(
"api/edit-master.php",
JSON.stringify(data),
function() {
lineAffected.remove();
requestSerial();
},
"json"
);
}
function requestDomainName() {
var data = {
action: "getDomainName",
domain: location.hash.substring(1)
};
$.post(
"api/edit-master.php",
JSON.stringify(data),
function(data) {
$('#domain-name').text(data.name);
domainName = data.name;
},
"json"
);
}
function enableFilter(enable) {
if(enable) {
$('#searchName').prop("disabled", false);
$('#searchType').prop("disabled", false);
$('#searchContent').prop("disabled", false);
} else {
$('#searchName').prop("disabled", true);
$('#searchType').prop("disabled", true);
$('#searchContent').prop("disabled", true);
}
}

59
lib/update-serial.php Normal file
View file

@ -0,0 +1,59 @@
<?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.
*/
function update_serial($db, $domainId) {
$db->autocommit(false);
$db->begin_transaction();
$stmt = $db->prepare("SELECT content FROM records WHERE type='SOA' AND domain_id=?");
$stmt->bind_param("i", $domainId);
$stmt->execute();
$stmt->bind_result($content);
$stmt->fetch();
$stmt->close();
$content = explode(" ", $content);
$serial = $content[2];
$currentSerialDate = (int)($serial / 100);
$currentSerialSequence = $serial % 100;
$currentDate = (int)date("Ymd");
if($currentDate != $currentSerialDate) {
$newSerial = $currentDate . "00";
} else {
$newSerialSequence = ($currentSerialSequence+1)%100 . "";
$newSerialSequence = str_pad($newSerialSequence, 2, "0", STR_PAD_LEFT);
$newSerial = $currentDate . "" . $newSerialSequence;
}
$content[2] = $newSerial;
$newsoa = implode(" ", $content);
$stmt = $db->prepare("UPDATE records SET content=? WHERE type='SOA' AND domain_id=?");
$stmt->bind_param("si", $newsoa, $domainId);
$stmt->execute();
$db->commit();
}