mirror of
https://github.com/cwinfo/powerdns-admin.git
synced 2024-11-09 23:20:27 +00:00
Merge pull request #27 from ProviderNL/dnssec
Dnssec function thanks @JeroenBo
This commit is contained in:
commit
77c3af2e81
2
.gitignore
vendored
2
.gitignore
vendored
@ -31,3 +31,5 @@ db_repository/*
|
||||
upload/avatar/*
|
||||
tmp/*
|
||||
.ropeproject
|
||||
.sonarlint/*
|
||||
pdns.db
|
||||
|
@ -302,10 +302,10 @@ class User(db.Model):
|
||||
We will create a local user (in DB) in order to manage user
|
||||
profile such as name, roles,...
|
||||
"""
|
||||
|
||||
|
||||
# Set an invalid password hash for non local users
|
||||
self.password = '*'
|
||||
|
||||
|
||||
db.session.add(self)
|
||||
db.session.commit()
|
||||
|
||||
@ -678,7 +678,7 @@ class Domain(db.Model):
|
||||
|
||||
def create_reverse_domain(self, domain_name, domain_reverse_name):
|
||||
"""
|
||||
Check the existing reverse lookup domain,
|
||||
Check the existing reverse lookup domain,
|
||||
if not exists create a new one automatically
|
||||
"""
|
||||
domain_obj = Domain.query.filter(Domain.name == domain_name).first()
|
||||
@ -823,6 +823,49 @@ class Domain(db.Model):
|
||||
else:
|
||||
return {'status': 'error', 'msg': 'This domain doesnot exist'}
|
||||
|
||||
def enable_domain_dnssec(self, domain_name):
|
||||
"""
|
||||
Enable domain DNSSEC
|
||||
"""
|
||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||
if domain:
|
||||
headers = {}
|
||||
headers['X-API-Key'] = PDNS_API_KEY
|
||||
post_data = {
|
||||
"keytype": "ksk",
|
||||
"active": True
|
||||
}
|
||||
try:
|
||||
jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s/cryptokeys' % domain.name), headers=headers, method='POST',data=post_data)
|
||||
if 'error' in jdata:
|
||||
return {'status': 'error', 'msg': 'DNSSEC is not enabled for this domain', 'jdata' : jdata}
|
||||
else:
|
||||
return {'status': 'ok'}
|
||||
except:
|
||||
return {'status': 'error', 'msg': 'There was something wrong, please contact administrator'}
|
||||
else:
|
||||
return {'status': 'error', 'msg': 'This domain doesnot exist'}
|
||||
|
||||
def delete_dnssec_key(self, domain_name, key_id):
|
||||
"""
|
||||
Remove keys DNSSEC
|
||||
"""
|
||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||
if domain:
|
||||
headers = {}
|
||||
headers['X-API-Key'] = PDNS_API_KEY
|
||||
url = '/servers/localhost/zones/%s/cryptokeys/%s' % (domain.name, key_id)
|
||||
|
||||
try:
|
||||
jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + url), headers=headers, method='DELETE')
|
||||
if 'error' in jdata:
|
||||
return {'status': 'error', 'msg': 'DNSSEC is not disabled for this domain', 'jdata' : jdata}
|
||||
else:
|
||||
return {'status': 'ok'}
|
||||
except:
|
||||
return {'status': 'error', 'msg': 'There was something wrong, please contact administrator','id': key_id, 'url': url}
|
||||
else:
|
||||
return {'status': 'error', 'msg': 'This domain doesnot exist'}
|
||||
|
||||
class DomainUser(db.Model):
|
||||
__tablename__ = 'domain_user'
|
||||
@ -977,7 +1020,7 @@ class Record(object):
|
||||
if r_type == 'PTR': # only ptr
|
||||
if ':' in r['record_name']: # dirty ipv6 check
|
||||
r_name = r['record_name']
|
||||
|
||||
|
||||
record = {
|
||||
"name": r_name,
|
||||
"type": r_type,
|
||||
@ -986,7 +1029,7 @@ class Record(object):
|
||||
"ttl": int(r['record_ttl']) if r['record_ttl'] else 3600,
|
||||
}
|
||||
records.append(record)
|
||||
|
||||
|
||||
deleted_records, new_records = self.compare(domain, records)
|
||||
|
||||
records = []
|
||||
@ -998,7 +1041,7 @@ class Record(object):
|
||||
if r_type == 'PTR': # only ptr
|
||||
if ':' in r['name']: # dirty ipv6 check
|
||||
r_name = dns.reversename.from_address(r['name']).to_text()
|
||||
|
||||
|
||||
record = {
|
||||
"name": r_name,
|
||||
"type": r_type,
|
||||
@ -1059,12 +1102,12 @@ class Record(object):
|
||||
r_name = key[0]
|
||||
r_type = key[1]
|
||||
r_changetype = key[2]
|
||||
|
||||
|
||||
if PRETTY_IPV6_PTR: # only if activated
|
||||
if r_type == 'PTR': # only ptr
|
||||
if ':' in r_name: # dirty ipv6 check
|
||||
r_name = dns.reversename.from_address(r_name).to_text()
|
||||
|
||||
|
||||
new_record = {
|
||||
"name": r_name,
|
||||
"type": r_type,
|
||||
|
@ -1,3 +1,5 @@
|
||||
var dnssecKeyList = []
|
||||
|
||||
function applyChanges(data, url, showResult, refreshPage) {
|
||||
var success = false;
|
||||
$.ajax({
|
||||
@ -116,7 +118,22 @@ function SelectElement(elementID, valueToSelect)
|
||||
element.value = valueToSelect;
|
||||
}
|
||||
|
||||
function getdnssec(url){
|
||||
function enable_dns_sec(url) {
|
||||
$.getJSON(url, function(data) {
|
||||
var modal = $("#modal_dnssec_info");
|
||||
|
||||
if (data['status'] == 'error'){
|
||||
modal.find('.modal-body p').text(data['msg']);
|
||||
}
|
||||
else {
|
||||
modal.modal('hide');
|
||||
//location.reload();
|
||||
window.location.reload(true);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function getdnssec(url,domain){
|
||||
|
||||
$.getJSON(url, function(data) {
|
||||
var modal = $("#modal_dnssec_info");
|
||||
@ -127,23 +144,36 @@ function getdnssec(url){
|
||||
else {
|
||||
dnssec_msg = '';
|
||||
var dnssec = data['dnssec'];
|
||||
for (var i = 0; i < dnssec.length; i++) {
|
||||
if (dnssec[i]['active']){
|
||||
dnssec_msg += '<form>'+
|
||||
'<h3><strong>'+dnssec[i]['keytype']+'</strong></h3>'+
|
||||
'<strong>DNSKEY</strong>'+
|
||||
'<input class="form-control" autocomplete="off" type="text" readonly="true" value="'+dnssec[i]['dnskey']+'">'+
|
||||
'</form>'+
|
||||
'<br/>';
|
||||
if(dnssec[i]['ds']){
|
||||
var dsList = dnssec[i]['ds'];
|
||||
dnssec_msg += '<strong>DS</strong>';
|
||||
for (var j = 0; j < dsList.length; j++){
|
||||
dnssec_msg += '<input class="form-control" autocomplete="off" type="text" readonly="true" value="'+dsList[j]+'">';
|
||||
}
|
||||
}
|
||||
dnssec_msg += '</form>';
|
||||
|
||||
if (dnssec.length == 0 && parseFloat(PDNS_VERSION) > 4.1) {
|
||||
dnssec_msg = '<h3>Enable DNSSEC?';
|
||||
modal.find('.modal-body p').html(dnssec_msg);
|
||||
dnssec_footer = '<button type="button" class="btn btn-flat btn-success button_dnssec_enable pull-left" id="'+domain+'">Enable</button><button type="button" class="btn btn-flat btn-default pull-right" data-dismiss="modal">Cancel</button>';
|
||||
modal.find('.modal-footer ').html(dnssec_footer);
|
||||
}
|
||||
else {
|
||||
if (parseFloat(PDNS_VERSION) > 4.1) {
|
||||
dnssec_footer = '<button type="button" class="btn btn-flat btn-danger button_dnssec_disable pull-left" id="'+domain+'">Disable DNSSEC</button><button type="button" class="btn btn-flat btn-default pull-right" data-dismiss="modal">Close</button>';
|
||||
modal.find('.modal-footer ').html(dnssec_footer);
|
||||
}
|
||||
for (var i = 0; i < dnssec.length; i++) {
|
||||
if (dnssec[i]['active']){
|
||||
dnssec_msg += '<form>'+
|
||||
'<h3><strong>'+dnssec[i]['keytype']+'</strong></h3>'+
|
||||
'<strong>DNSKEY</strong>'+
|
||||
'<input class="form-control" autocomplete="off" type="text" readonly="true" value="'+dnssec[i]['dnskey']+'">'+
|
||||
'</form>'+
|
||||
'<br/>';
|
||||
if(dnssec[i]['ds']){
|
||||
var dsList = dnssec[i]['ds'];
|
||||
dnssec_msg += '<strong>DS</strong>';
|
||||
for (var j = 0; j < dsList.length; j++){
|
||||
dnssec_msg += '<input class="form-control" autocomplete="off" type="text" readonly="true" value="'+dsList[j]+'">';
|
||||
}
|
||||
}
|
||||
dnssec_msg += '</form>';
|
||||
}
|
||||
}
|
||||
}
|
||||
modal.find('.modal-body p').html(dnssec_msg);
|
||||
}
|
||||
|
@ -83,7 +83,7 @@
|
||||
<small>{{ current_user.role.name }}</small>
|
||||
</p>
|
||||
</li>
|
||||
|
||||
|
||||
<!-- Menu Footer-->
|
||||
<li class="user-footer">
|
||||
<div class="pull-left">
|
||||
|
@ -158,6 +158,7 @@
|
||||
<button type="button" class="btn btn-flat dnssec btn-success button_dnssec" id="{{ domain.name }}" style="width:100%;">
|
||||
<i class="fa fa-lock"></i> Enabled
|
||||
</button>
|
||||
|
||||
{% else %}
|
||||
<button type="button" class="btn btn-flat dnssec button_dnssec" id="{{ domain.name }}" style="width:100%;">
|
||||
<i class="fa fa-unlock-alt"></i> Disabled
|
||||
@ -206,6 +207,7 @@
|
||||
{% endblock %}
|
||||
{% block extrascripts %}
|
||||
<script>
|
||||
PDNS_VERSION = '{{ pdns_version }}'
|
||||
// set up history data table
|
||||
$("#tbl_history").DataTable({
|
||||
"paging" : false,
|
||||
@ -214,7 +216,7 @@
|
||||
"ordering" : false,
|
||||
"info" : false,
|
||||
"autoWidth" : false
|
||||
});
|
||||
});
|
||||
// set up domain list
|
||||
$("#tbl_domain_list").DataTable({
|
||||
"paging" : true,
|
||||
@ -240,7 +242,19 @@
|
||||
});
|
||||
$(document.body).on("click", ".button_dnssec", function() {
|
||||
var domain = $(this).prop('id');
|
||||
getdnssec($SCRIPT_ROOT + '/domain/' + domain + '/dnssec');
|
||||
getdnssec($SCRIPT_ROOT + '/domain/' + domain + '/dnssec',domain);
|
||||
});
|
||||
|
||||
$(document.body).on("click", ".button_dnssec_enable", function() {
|
||||
var domain = $(this).prop('id');
|
||||
enable_dns_sec($SCRIPT_ROOT + '/domain/' + domain + '/dnssec/enable');
|
||||
|
||||
});
|
||||
|
||||
$(document.body).on("click", ".button_dnssec_disable", function() {
|
||||
var domain = $(this).prop('id');
|
||||
enable_dns_sec($SCRIPT_ROOT + '/domain/' + domain + '/dnssec/disable');
|
||||
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
@ -88,7 +88,7 @@
|
||||
</td>
|
||||
<td width="6%">
|
||||
<button type="button" class="btn btn-flat btn-warning""> <i class="fa fa-exclamation-circle"></i> </button>
|
||||
</td>
|
||||
</td>
|
||||
{% endif %}
|
||||
</td>
|
||||
<!-- hidden column that we can sort on -->
|
||||
@ -109,6 +109,7 @@
|
||||
{% endblock %}
|
||||
{% block extrascripts %}
|
||||
<script>
|
||||
PDNS_VERSION = '{{ pdns_version }}'
|
||||
// superglobals
|
||||
window.records_allow_edit = {{ editable_records|tojson }};
|
||||
window.nEditing = null;
|
||||
@ -148,7 +149,7 @@
|
||||
],
|
||||
"orderFixed": [[7, 'asc']]
|
||||
});
|
||||
|
||||
|
||||
// handle delete button
|
||||
$(document.body).on("click", ".button_delete", function(e) {
|
||||
e.stopPropagation();
|
||||
@ -156,25 +157,25 @@
|
||||
var table = $("#tbl_records").DataTable();
|
||||
var record = $(this).prop('id');
|
||||
var nRow = $(this).parents('tr')[0];
|
||||
var info = "Are you sure you want to delete " + record + "?";
|
||||
var info = "Are you sure you want to delete " + record + "?";
|
||||
modal.find('.modal-body p').text(info);
|
||||
modal.find('#button_delete_confirm').click(function() {
|
||||
table.row(nRow).remove().draw();
|
||||
modal.modal('hide');
|
||||
})
|
||||
modal.modal('show');
|
||||
|
||||
|
||||
});
|
||||
// handle edit button
|
||||
$(document.body).on("click", ".button_edit, .row_record", function(e) {
|
||||
e.stopPropagation();
|
||||
if ($(this).is('tr')) {
|
||||
var nRow = $(this)[0];
|
||||
var nRow = $(this)[0];
|
||||
} else {
|
||||
var nRow = $(this).parents('tr')[0];
|
||||
}
|
||||
var table = $("#tbl_records").DataTable();
|
||||
|
||||
|
||||
if (nEditing == nRow) {
|
||||
/* click on row already being edited, do nothing */
|
||||
} else if (nEditing !== null && nEditing != nRow && nNew == false) {
|
||||
@ -194,13 +195,13 @@
|
||||
nEditing = nRow;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// handle apply changes button
|
||||
$(document.body).on("click",".button_apply_changes", function() {
|
||||
var modal = $("#modal_apply_changes");
|
||||
var table = $("#tbl_records").DataTable();
|
||||
var domain = $(this).prop('id');
|
||||
var info = "Are you sure you want to apply your changes?";
|
||||
var info = "Are you sure you want to apply your changes?";
|
||||
modal.find('.modal-body p').text(info);
|
||||
modal.find('#button_apply_confirm').click(function() {
|
||||
var data = getTableData(table);
|
||||
@ -208,9 +209,9 @@
|
||||
modal.modal('hide');
|
||||
})
|
||||
modal.modal('show');
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
// handle add record button
|
||||
$(document.body).on("click", ".button_add_record", function (e) {
|
||||
if (nNew || nEditing) {
|
||||
@ -221,7 +222,7 @@
|
||||
}
|
||||
// clear search first
|
||||
$("#tbl_records").DataTable().search('').columns().search('').draw();
|
||||
|
||||
|
||||
// add new row
|
||||
var default_type = records_allow_edit[0]
|
||||
var nRow = jQuery('#tbl_records').dataTable().fnAddData(['', default_type, 'Active', 3600, '', '', '', '0']);
|
||||
@ -230,7 +231,7 @@
|
||||
nEditing = nRow;
|
||||
nNew = true;
|
||||
});
|
||||
|
||||
|
||||
//handle cancel button
|
||||
$(document.body).on("click", ".button_cancel", function (e) {
|
||||
e.stopPropagation();
|
||||
@ -244,7 +245,7 @@
|
||||
nEditing = null;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//handle save button
|
||||
$(document.body).on("click", ".button_save", function (e) {
|
||||
e.stopPropagation();
|
||||
@ -253,13 +254,13 @@
|
||||
nEditing = null;
|
||||
nNew = false;
|
||||
});
|
||||
|
||||
|
||||
//handle update_from_master button
|
||||
$(document.body).on("click", ".button_update_from_master", function (e) {
|
||||
var domain = $(this).prop('id');
|
||||
applyChanges({'domain': domain}, $SCRIPT_ROOT + '/domain/' + domain + '/update');
|
||||
});
|
||||
|
||||
|
||||
{% if record_helper_setting %}
|
||||
//handle wacky record types
|
||||
$(document.body).on("focus", "#current_edit_record_data", function (e) {
|
||||
@ -276,7 +277,7 @@
|
||||
<input type=\"text\" class=\"form-control\" name=\"caa_value\" id=\"caa_value\" placeholder=\"eg. letsencrypt.org\"> \
|
||||
";
|
||||
} else {
|
||||
var parts = record_data.val().split(" ");
|
||||
var parts = record_data.val().split(" ");
|
||||
var form = " <label for=\"caa_flag\">CAA Flag</label> \
|
||||
<input type=\"text\" class=\"form-control\" name=\"caa_flag\" id=\"caa_flag\" placeholder=\"0\" value=\"" + parts[0] + "\"> \
|
||||
<label for=\"caa_tag\">CAA Tag</label> \
|
||||
@ -333,7 +334,7 @@
|
||||
<input type=\"text\" class=\"form-control\" name=\"srv_target\" id=\"srv_target\" placeholder=\"sip.example.com\"> \
|
||||
";
|
||||
} else {
|
||||
var parts = record_data.val().split(" ");
|
||||
var parts = record_data.val().split(" ");
|
||||
var form = " <label for=\"srv_priority\">SRV Priority</label> \
|
||||
<input type=\"text\" class=\"form-control\" name=\"srv_priority\" id=\"srv_priority\" placeholder=\"0\" value=\"" + parts[0] + "\"> \
|
||||
<label for=\"srv_weight\">SRV Weight</label> \
|
||||
@ -374,7 +375,7 @@
|
||||
<input type=\"text\" class=\"form-control\" name=\"soa_minimumttl\" id=\"soa_minimumttl\" placeholder=\"300\"> \
|
||||
";
|
||||
} else {
|
||||
var parts = record_data.val().split(" ");
|
||||
var parts = record_data.val().split(" ");
|
||||
var form = " <label for=\"soa_primaryns\">Primary Name Server</label> \
|
||||
<input type=\"text\" class=\"form-control\" name=\"soa_primaryns\" id=\"soa_primaryns\" value=\"" + parts[0] + "\"> \
|
||||
<label for=\"soa_adminemail\">Primary Contact</label> \
|
||||
@ -392,7 +393,7 @@
|
||||
";
|
||||
}
|
||||
modal.find('.modal-body p').html(form);
|
||||
modal.find('#button_save').click(function() {
|
||||
modal.find('#button_save').click(function() {
|
||||
soa_primaryns = modal.find('#soa_primaryns').val();
|
||||
soa_adminemail = modal.find('#soa_adminemail').val();
|
||||
soa_serial = modal.find('#soa_serial').val();
|
||||
@ -400,7 +401,7 @@
|
||||
soa_failedzonerefresh = modal.find('#soa_failedzonerefresh').val();
|
||||
soa_zoneexpiry = modal.find('#soa_zoneexpiry').val();
|
||||
soa_minimumttl = modal.find('#soa_minimumttl').val();
|
||||
|
||||
|
||||
data = soa_primaryns + " " + soa_adminemail + " " + soa_serial + " " + soa_zonerefresh + " " + soa_failedzonerefresh + " " + soa_zoneexpiry + " " + soa_minimumttl;
|
||||
record_data.val(data);
|
||||
modal.modal('hide');
|
||||
|
29
app/views.py
29
app/views.py
@ -439,7 +439,7 @@ def dashboard():
|
||||
uptime = filter(lambda uptime: uptime['name'] == 'uptime', statistics)[0]['value']
|
||||
else:
|
||||
uptime = 0
|
||||
return render_template('dashboard.html', domains=domains, domain_count=domain_count, users=users, history_number=history_number, uptime=uptime, histories=history)
|
||||
return render_template('dashboard.html', domains=domains, domain_count=domain_count, users=users, history_number=history_number, uptime=uptime, histories=history,pdns_version=app.config['PDNS_VERSION'])
|
||||
|
||||
|
||||
@app.route('/domain/<path:domain_name>', methods=['GET', 'POST'])
|
||||
@ -479,7 +479,7 @@ def domain(domain_name):
|
||||
editable_records = app.config['FORWARD_RECORDS_ALLOW_EDIT']
|
||||
else:
|
||||
editable_records = app.config['REVERSE_RECORDS_ALLOW_EDIT']
|
||||
return render_template('domain.html', domain=domain, records=records, editable_records=editable_records)
|
||||
return render_template('domain.html', domain=domain, records=records, editable_records=editable_records,pdns_version=app.config['PDNS_VERSION'])
|
||||
|
||||
|
||||
@app.route('/admin/domain/add', methods=['GET', 'POST'])
|
||||
@ -644,6 +644,31 @@ def domain_dnssec(domain_name):
|
||||
dnssec = domain.get_domain_dnssec(domain_name)
|
||||
return make_response(jsonify(dnssec), 200)
|
||||
|
||||
@app.route('/domain/<string:domain_name>/dnssec/enable', methods=['GET'])
|
||||
@login_required
|
||||
def domain_dnssec_enable(domain_name):
|
||||
if not current_user.can_access_domain(domain_name):
|
||||
return make_response(jsonify({'status': 'error', 'msg': 'You do not have access to that domain'}), 403)
|
||||
|
||||
domain = Domain()
|
||||
dnssec = domain.enable_domain_dnssec(domain_name)
|
||||
return make_response(jsonify(dnssec), 200)
|
||||
|
||||
@app.route('/domain/<string:domain_name>/dnssec/disable', methods=['GET'])
|
||||
@login_required
|
||||
def domain_dnssec_disable(domain_name):
|
||||
if not current_user.can_access_domain(domain_name):
|
||||
return make_response(jsonify({'status': 'error', 'msg': 'You do not have access to that domain'}), 403)
|
||||
|
||||
domain = Domain()
|
||||
dnssec = domain.get_domain_dnssec(domain_name)
|
||||
|
||||
for key in dnssec['dnssec']:
|
||||
response = domain.delete_dnssec_key(domain_name,key['id']);
|
||||
|
||||
return make_response(jsonify( { 'status': 'ok', 'msg': 'DNSSEC removed.' } ))
|
||||
|
||||
|
||||
@app.route('/domain/<string:domain_name>/managesetting', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@admin_role_required
|
||||
|
Loading…
Reference in New Issue
Block a user