mirror of
https://github.com/cwinfo/powerdns-admin.git
synced 2024-11-08 22:50:26 +00:00
allow users to remove domain (#952)
This commit is contained in:
parent
1f34dbf810
commit
bf83662108
@ -93,6 +93,23 @@ def can_configure_dnssec(f):
|
|||||||
|
|
||||||
return decorated_function
|
return decorated_function
|
||||||
|
|
||||||
|
def can_remove_domain(f):
|
||||||
|
"""
|
||||||
|
Grant access if:
|
||||||
|
- user is in Operator role or higher, or
|
||||||
|
- allow_user_remove_domain is on
|
||||||
|
"""
|
||||||
|
@wraps(f)
|
||||||
|
def decorated_function(*args, **kwargs):
|
||||||
|
if current_user.role.name not in [
|
||||||
|
'Administrator', 'Operator'
|
||||||
|
] and not Setting().get('allow_user_remove_domain'):
|
||||||
|
abort(403)
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
|
||||||
|
return decorated_function
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def can_create_domain(f):
|
def can_create_domain(f):
|
||||||
"""
|
"""
|
||||||
|
@ -26,6 +26,7 @@ class Setting(db.Model):
|
|||||||
'pretty_ipv6_ptr': False,
|
'pretty_ipv6_ptr': False,
|
||||||
'dnssec_admins_only': False,
|
'dnssec_admins_only': False,
|
||||||
'allow_user_create_domain': False,
|
'allow_user_create_domain': False,
|
||||||
|
'allow_user_remove_domain': False,
|
||||||
'allow_user_view_history': False,
|
'allow_user_view_history': False,
|
||||||
'bg_domain_updates': False,
|
'bg_domain_updates': False,
|
||||||
'site_name': 'PowerDNS-Admin',
|
'site_name': 'PowerDNS-Admin',
|
||||||
|
@ -642,7 +642,7 @@ def setting_basic():
|
|||||||
'login_ldap_first', 'default_record_table_size',
|
'login_ldap_first', 'default_record_table_size',
|
||||||
'default_domain_table_size', 'auto_ptr', 'record_quick_edit',
|
'default_domain_table_size', 'auto_ptr', 'record_quick_edit',
|
||||||
'pretty_ipv6_ptr', 'dnssec_admins_only',
|
'pretty_ipv6_ptr', 'dnssec_admins_only',
|
||||||
'allow_user_create_domain', 'allow_user_view_history', 'bg_domain_updates', 'site_name',
|
'allow_user_create_domain', 'allow_user_remove_domain', 'allow_user_view_history', 'bg_domain_updates', 'site_name',
|
||||||
'session_timeout', 'warn_session_timeout', 'ttl_options',
|
'session_timeout', 'warn_session_timeout', 'ttl_options',
|
||||||
'pdns_api_timeout', 'verify_ssl_connections', 'verify_user_email', 'otp_field_enabled', 'custom_css'
|
'pdns_api_timeout', 'verify_ssl_connections', 'verify_user_email', 'otp_field_enabled', 'custom_css'
|
||||||
]
|
]
|
||||||
|
@ -10,7 +10,7 @@ from flask_login import login_required, current_user, login_manager
|
|||||||
|
|
||||||
from ..lib.utils import pretty_domain_name
|
from ..lib.utils import pretty_domain_name
|
||||||
from ..lib.utils import pretty_json
|
from ..lib.utils import pretty_json
|
||||||
from ..decorators import can_create_domain, operator_role_required, can_access_domain, can_configure_dnssec
|
from ..decorators import can_create_domain, operator_role_required, can_access_domain, can_configure_dnssec, can_remove_domain
|
||||||
from ..models.user import User, Anonymous
|
from ..models.user import User, Anonymous
|
||||||
from ..models.account import Account
|
from ..models.account import Account
|
||||||
from ..models.setting import Setting
|
from ..models.setting import Setting
|
||||||
@ -21,6 +21,9 @@ from ..models.record_entry import RecordEntry
|
|||||||
from ..models.domain_template import DomainTemplate
|
from ..models.domain_template import DomainTemplate
|
||||||
from ..models.domain_template_record import DomainTemplateRecord
|
from ..models.domain_template_record import DomainTemplateRecord
|
||||||
from ..models.domain_setting import DomainSetting
|
from ..models.domain_setting import DomainSetting
|
||||||
|
from ..models.base import db
|
||||||
|
from ..models.domain_user import DomainUser
|
||||||
|
from ..models.account_user import AccountUser
|
||||||
|
|
||||||
domain_bp = Blueprint('domain',
|
domain_bp = Blueprint('domain',
|
||||||
__name__,
|
__name__,
|
||||||
@ -131,6 +134,60 @@ def domain(domain_name):
|
|||||||
ttl_options=ttl_options)
|
ttl_options=ttl_options)
|
||||||
|
|
||||||
|
|
||||||
|
@domain_bp.route('/remove', methods=['GET', 'POST'])
|
||||||
|
@login_required
|
||||||
|
@can_remove_domain
|
||||||
|
def remove():
|
||||||
|
# domains is a list of all the domains a User may access
|
||||||
|
# Admins may access all
|
||||||
|
# Regular users only if they are associated with the domain
|
||||||
|
if current_user.role.name in ['Administrator', 'Operator']:
|
||||||
|
domains = Domain.query.order_by(Domain.name).all()
|
||||||
|
else:
|
||||||
|
# Get query for domain to which the user has access permission.
|
||||||
|
# This includes direct domain permission AND permission through
|
||||||
|
# account membership
|
||||||
|
domains = db.session.query(Domain) \
|
||||||
|
.outerjoin(DomainUser, Domain.id == DomainUser.domain_id) \
|
||||||
|
.outerjoin(Account, Domain.account_id == Account.id) \
|
||||||
|
.outerjoin(AccountUser, Account.id == AccountUser.account_id) \
|
||||||
|
.filter(
|
||||||
|
db.or_(
|
||||||
|
DomainUser.user_id == current_user.id,
|
||||||
|
AccountUser.user_id == current_user.id
|
||||||
|
)).order_by(Domain.name)
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
# TODO Change name from 'domainid' to something else, its confusing
|
||||||
|
domain_name = request.form['domainid']
|
||||||
|
|
||||||
|
# Get domain from Database, might be None
|
||||||
|
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||||
|
|
||||||
|
# Check if the domain is in domains before removal
|
||||||
|
if domain not in domains:
|
||||||
|
abort(403)
|
||||||
|
|
||||||
|
# Delete
|
||||||
|
d = Domain()
|
||||||
|
result = d.delete(domain_name)
|
||||||
|
|
||||||
|
if result['status'] == 'error':
|
||||||
|
abort(500)
|
||||||
|
|
||||||
|
history = History(msg='Delete domain {0}'.format(
|
||||||
|
pretty_domain_name(domain_name)),
|
||||||
|
created_by=current_user.username)
|
||||||
|
history.add()
|
||||||
|
|
||||||
|
return redirect(url_for('dashboard.dashboard'))
|
||||||
|
|
||||||
|
else:
|
||||||
|
# On GET return the domains we got earlier
|
||||||
|
return render_template('domain_remove.html',
|
||||||
|
domainss=domains)
|
||||||
|
|
||||||
|
|
||||||
@domain_bp.route('/add', methods=['GET', 'POST'])
|
@domain_bp.route('/add', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
@can_create_domain
|
@can_create_domain
|
||||||
|
@ -117,6 +117,11 @@
|
|||||||
<a href="{{ url_for('domain.add') }}"><i class="fa fa-plus"></i> <span>New Domain</span></a>
|
<a href="{{ url_for('domain.add') }}"><i class="fa fa-plus"></i> <span>New Domain</span></a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if SETTING.get('allow_user_remove_domain') or current_user.role.name in ['Administrator', 'Operator'] %}
|
||||||
|
<li class="{{ 'active' if active_page == 'remove_domain' else '' }}">
|
||||||
|
<a href="{{ url_for('domain.remove') }}"><i class="fa fa-trash-o"></i> <span>Remove Domain</span></a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
{% if current_user.role.name in ['Administrator', 'Operator'] %}
|
{% if current_user.role.name in ['Administrator', 'Operator'] %}
|
||||||
<li class="header">ADMINISTRATION</li>
|
<li class="header">ADMINISTRATION</li>
|
||||||
<li class="{{ 'active' if active_page == 'admin_console' else '' }}">
|
<li class="{{ 'active' if active_page == 'admin_console' else '' }}">
|
||||||
|
129
powerdnsadmin/templates/domain_remove.html
Normal file
129
powerdnsadmin/templates/domain_remove.html
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% set active_page = "remove_domain" %}
|
||||||
|
{% block title %}<title>Remove Domain - {{ SITE_NAME }}</title>{% endblock %}
|
||||||
|
|
||||||
|
{% block dashboard_stat %}
|
||||||
|
<!-- Content Header (Page header) -->
|
||||||
|
<section class="content-header">
|
||||||
|
<h1>
|
||||||
|
Domain
|
||||||
|
<small>Remove existing</small>
|
||||||
|
</h1>
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li><a href="{{ url_for('dashboard.dashboard') }}"><i class="fa fa-dashboard"></i>Home</a></li>
|
||||||
|
<li><a href="{{ url_for('dashboard.dashboard') }}">Domain</a></li>
|
||||||
|
<li class="active">Remove Domain</li>
|
||||||
|
</ol>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<section class="content">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="box box-primary">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">Remove domain</h3>
|
||||||
|
</div>
|
||||||
|
<!-- /.box-header -->
|
||||||
|
<!-- form start -->
|
||||||
|
<form role="form" method="post" action="{{ url_for('domain.remove') }}">
|
||||||
|
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<div class="box-body">
|
||||||
|
<select id=domainid class="form-control" style="width:15em;">
|
||||||
|
<option value="0">- Select Domain -</option>
|
||||||
|
{% for domain in domainss %}
|
||||||
|
<option value="{{ domain.id }}">{{ domain.name }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select><br />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /.box-body -->
|
||||||
|
|
||||||
|
<div class="box-footer">
|
||||||
|
<button type="button" class="btn btn-flat btn-danger button_delete">Remove</button>
|
||||||
|
<button type="button" class="btn btn-flat btn-default"
|
||||||
|
onclick="window.location.href='{{ url_for('dashboard.dashboard') }}'">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<!-- /.box -->
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="box box-primary">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">Help with removing a new domain</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
<dl class="dl-horizontal">
|
||||||
|
<dt>Domain name</dt>
|
||||||
|
<dd>Select domain you wish to remove from DNS.</dd>
|
||||||
|
</dl>
|
||||||
|
<p>Find more details at <a href="https://docs.powerdns.com/md/">https://docs.powerdns.com/md/</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
|
{% block extrascripts %}
|
||||||
|
<script>
|
||||||
|
// handle delete button
|
||||||
|
$(document.body).on("click", ".button_delete", function(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
if ( $("#domainid").val() == 0 ){
|
||||||
|
var modal = $("#modal_error");
|
||||||
|
modal.find('.modal-body p').text("Please select domain to remove.");
|
||||||
|
modal.modal('show');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var modal = $("#modal_delete");
|
||||||
|
var domain = $("#domainid option:selected").text();
|
||||||
|
var info = "Are you sure you want to delete " + domain + "?";
|
||||||
|
modal.find('.modal-body p').text(info);
|
||||||
|
modal.find('#button_delete_confirm').click(function () {
|
||||||
|
$.post($SCRIPT_ROOT + '/domain/remove' , {
|
||||||
|
'_csrf_token': '{{ csrf_token() }}',
|
||||||
|
'domainid': domain,
|
||||||
|
}, function () {
|
||||||
|
window.location.href = '{{ url_for('dashboard.dashboard') }}';
|
||||||
|
});
|
||||||
|
modal.modal('hide');
|
||||||
|
})
|
||||||
|
modal.modal('show');
|
||||||
|
|
||||||
|
$("#button_delete_cancel").unbind().one('click', function(e) {
|
||||||
|
modal.modal('hide');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block modals %}
|
||||||
|
<div class="modal fade modal-warning" id="modal_delete">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal"
|
||||||
|
aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
<h4 class="modal-title">Confirmation</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p></p>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-flat btn-default pull-left" id="button_delete_cancel"
|
||||||
|
data-dismiss="modal">Close</button>
|
||||||
|
<button type="button" class="btn btn-flat btn-danger" id="button_delete_confirm">Delete</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /.modal-content -->
|
||||||
|
</div>
|
||||||
|
<!-- /.modal-dialog -->
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue
Block a user