Create DB config for pdns and authentication setting

This commit is contained in:
Khanh Ngo 2018-08-18 18:41:59 +07:00
parent 71b09b9bd1
commit 4b9349c83e
No known key found for this signature in database
GPG key ID: B9AE3BAF6D5A7B22
22 changed files with 664 additions and 124 deletions

View file

@ -39,7 +39,7 @@ def enable_github_oauth(GITHUB_ENABLE):
consumer_key=app.config['GITHUB_OAUTH_KEY'],
consumer_secret=app.config['GITHUB_OAUTH_SECRET'],
request_token_params={'scope': app.config['GITHUB_OAUTH_SCOPE']},
base_url=app.config['GITHUB_OAUTH_URL'],
base_url=app.config['GITHUB_OAUTH_URL'], # API URL
request_token_url=None,
access_token_method='POST',
access_token_url=app.config['GITHUB_OAUTH_TOKEN'],

View file

@ -1774,18 +1774,47 @@ class Setting(db.Model):
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(64))
value = db.Column(db.String(256))
view = db.Column(db.String(64))
# default settings (serves as list of known settings too):
# Note: booleans must be strings because of the way they are stored and used
defaults = {
'maintenance': 'False',
'fullscreen_layout': 'True',
'record_helper': 'True',
'login_ldap_first': 'True',
'maintenance': False,
'fullscreen_layout': True,
'record_helper': True,
'login_ldap_first': True,
'default_record_table_size': 15,
'default_domain_table_size': 10,
'auto_ptr': 'False',
'allow_quick_edit': 'True'
'auto_ptr': False,
'allow_quick_edit': True,
'pdns_api_url': '',
'pdns_api_key': '',
'pdns_version': '4.1.1',
'local_db_enabled': True,
'signup_enabled': True,
'ldap_enabled': False,
'ldap_type': 'ldap',
'ldap_uri': '',
'ldap_admin_username': '',
'ldap_admin_password': '',
'ldap_filter_basic': '',
'ldap_filter_username': '',
'ldap_sg_enabled': False,
'ldap_admin_group': False,
'ldap_user_group': False,
'github_oauth_enabled': False,
'github_oauth_key': '',
'github_oauth_secret': '',
'github_oauth_scope': 'email',
'github_oauth_api_url': 'https://api.github.com/user',
'github_oauth_token_url': 'https://github.com/login/oauth/access_token',
'github_oauth_authorize_url': 'https://github.com/login/oauth/authorize',
'google_oauth_enabled': False,
'google_oauth_client_id':'',
'google_oauth_client_secret':'',
'google_redirect_uri': '/user/authorized',
'google_token_url': 'https://accounts.google.com/o/oauth2/token',
'google_token_params': {'scope': 'email profile'},
'google_authorize_url':'https://accounts.google.com/o/oauth2/auth',
'google_base_url':'https://www.googleapis.com/oauth2/v1/',
}
def __init__(self, id=None, name=None, value=None):
@ -1804,7 +1833,7 @@ class Setting(db.Model):
if maintenance is None:
value = self.defaults['maintenance']
maintenance = Setting(name='maintenance', value=value)
maintenance = Setting(name='maintenance', value=str(value))
db.session.add(maintenance)
mode = str(mode)
@ -1825,7 +1854,7 @@ class Setting(db.Model):
if current_setting is None:
value = self.defaults[setting]
current_setting = Setting(name=setting, value=value)
current_setting = Setting(name=setting, value=str(value))
db.session.add(current_setting)
try:
@ -1864,12 +1893,20 @@ class Setting(db.Model):
if setting in self.defaults:
result = self.query.filter(Setting.name == setting).first()
if result is not None:
return result.value
return strtobool(result.value) if result.value in ['True', 'False'] else result.value
else:
return self.defaults[setting]
else:
logging.error('Unknown setting queried: {0}'.format(setting))
def get_view(self, view):
r = {}
settings = Setting.query.filter(Setting.view == view).all()
for setting in settings:
d = setting.__dict__
r[d['name']] = d['value']
return r
class DomainTemplate(db.Model):
__tablename__ = "domain_template"

View file

@ -1,4 +1,5 @@
{% extends "base.html" %}
{% set active_page = "admin_console" %}
{% block title %}<title>DNS Control Panel - Admin Console</title>{% endblock %}
{% block dashboard_stat %}

View file

@ -1,4 +1,5 @@
{% extends "base.html" %}
{% set active_page = "admin_accounts" %}
{% block title %}<title>DNS Control Panel - Edit Account</title>{% endblock %}
{% block dashboard_stat %}

View file

@ -1,4 +1,5 @@
{% extends "base.html" %}
{% set active_page = "admin_users" %}
{% block title %}<title>DNS Control Panel - Edit User</title>{% endblock %}
{% block dashboard_stat %}

View file

@ -1,4 +1,6 @@
{% extends "base.html" %} {% block title %}
{% extends "base.html" %}
{% set active_page = "admin_history" %}
{% block title %}
<title>DNS Control Panel - History</title>
{% endblock %} {% block dashboard_stat %}
<!-- Content Header (Page header) -->

View file

@ -1,4 +1,6 @@
{% extends "base.html" %} {% block title %}
{% extends "base.html" %}
{% set active_page = "admin_accounts" %}
{% block title %}
<title>DNS Control Panel - Account Management</title>
{% endblock %} {% block dashboard_stat %}
<section class="content-header">

View file

@ -1,4 +1,6 @@
{% extends "base.html" %} {% block title %}
{% extends "base.html" %}
{% set active_page = "admin_users" %}
{% block title %}
<title>DNS Control Panel - User Management</title>
{% endblock %} {% block dashboard_stat %}
<section class="content-header">

View file

@ -0,0 +1,271 @@
{% extends "base.html" %}
{% set active_page = "admin_settings" %}
{% block title %}
<title>DNS Control Panel - Authentication Settings</title>
{% endblock %} {% block dashboard_stat %}
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
Settings <small>PowerDNS-Admin settings</small>
</h1>
<ol class="breadcrumb">
<li><a href="{{ url_for('dashboard') }}"><i class="fa fa-dashboard"></i> Home</a></li>
<li><a href="#">Setting</a></li>
<li class="active">Authentication</li>
</ol>
</section>
{% endblock %}
{% block content %}
<section class="content">
<div class="row">
<div class="col-lg-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">Authentication Settings</h3>
</div>
<div class="box-body">
<!-- Custom Tabs -->
<div class="nav-tabs-custom" id="tabs">
<ul class="nav nav-tabs">
<li class="active"><a href="#tabs-general" data-toggle="tab">General</a></li>
<li class="active"><a href="#tabs-ldap" data-toggle="tab">LDAP</a></li>
<li><a href="#tabs-google" data-toggle="tab">Google OAuth</a></li>
<li><a href="#tabs-github" data-toggle="tab">Github OAuth</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tabs-general">
<form role="form" method="post">
<input type="hidden" value="general" name="config_tab" />
<div class="form-group">
<input type="checkbox" id="local_db_enabled" name="local_db_enabled" class="checkbox" {% if SETTING.get('local_db_enabled') %}checked{% endif %}>
<label for="local_db_enabled">Local DB Authentication</label>
</div>
<div class="form-group">
<input type="checkbox" id="signup_enabled" name="signup_enabled" class="checkbox" {% if SETTING.get('signup_enabled') %}checked{% endif %}>
<label for="signup_enabled">Allow users to sign up</label>
</div>
<div class="form-group">
<button type="submit" class="btn btn-flat btn-primary">Save</button>
</div>
</form>
</div>
<div class="tab-pane active" id="tabs-ldap">
<div class="row">
<div class="col-md-4">
<form role="form" method="post">
<input type="hidden" value="ldap" name="config_tab" />
<fieldset>
<legend>GENERAL</legend>
<div class="form-group">
<input type="checkbox" id="ldap_enabled" name="ldap_enabled" class="checkbox" {% if SETTING.get('ldap_enabled') %}checked{% endif %}>
<label for="ldap_enabled">Enable LDAP Authentication</label>
</div>
<div class="form-group">
<label>Type</label>
<div class="radio">
<label>
<input type="radio" name="ldap_type" id="ldap" value="ldap" {% if SETTING.get('ldap_type')=='ldap' %}checked{% endif %}> OpenLDAP
</label>
&nbsp;&nbsp;&nbsp;
<label>
<input type="radio" name="ldap_type" id="ad" value="ad" {% if SETTING.get('ldap_type')=='ad' %}checked{% endif %}> Active Directory
</label>
</div>
</div>
</fieldset>
<fieldset>
<legend>ADMINISTRATOR INFO</legend>
<div class="form-group">
<label for="ldap_uri">LDAP URI</label>
<input type="text" class="form-control" name="ldap_uri" id="ldap_uri" placeholder="e.g. ldaps://your-ldap-server:636" value="{{ SETTING.get('ldap_uri') }}">
</div>
<div class="form-group">
<label for="ldap_admin_username">LDAP admin username</label>
<input type="text" class="form-control" name="ldap_admin_username" id="ldap_admin_username" placeholder="e.g. cn=admin,dc=mydomain,dc=com" value="{{ SETTING.get('ldap_admin_username') }}">
</div>
<div class="form-group">
<label for="ldap_admin_password">LDAP admin password</label>
<input type="passowrd" class="form-control" name="ldap_admin_password" id="ldap_admin_password" placeholder="LDAP Admin password" value="{{ SETTING.get('ldap_admin_password') }}">
</div>
</fieldset>
<fieldset>
<legend>FILTERS</legend>
<div class="form-group">
<label for="ldap_filter_basic">Basic filter</label>
<input type="text" class="form-control" name="ldap_filter_basic" id="ldap_filter_basic" placeholder="e.g. (objectClass=inetorgperson)"value="{{ SETTING.get('ldap_filter_basic') }}">
</div>
<div class="form-group">
<label for="ldap_filter_username">Username field</label>
<input type="text" class="form-control" name="ldap_filter_username" id="ldap_filter_username" placeholder="e.g. uid" value="{{ SETTING.get('ldap_filter_username') }}">
</div>
</fieldset>
<fieldset>
<legend>GROUP SECURITY</legend>
<div class="form-group">
<label>Status</label>
<div class="radio">
<label>
<input type="radio" name="ldap_sg_enabled" id="ldap_sg_off" value="OFF" {% if not SETTING.get('ldap_sg_enabled') %}checked{% endif %}> OFF
</label>
&nbsp;&nbsp;&nbsp;
<label>
<input type="radio" name="ldap_sg_enabled" id="ldap_sg_on" value="ON" {% if SETTING.get('ldap_sg_enabled') %}checked{% endif %}> ON
</label>
</div>
</div>
<div class="form-group">
<label for="ldap_admin_group">Admin group</label>
<input type="text" class="form-control" name="ldap_admin_group" id="ldap_admin_group" placeholder="e.g. cn=sysops,dc=mydomain,dc=com" value="{{ SETTING.get('ldap_admin_group') }}">
</div>
<div class="form-group">
<label for="ldap_user_group">User group</label>
<input type="text" class="form-control" name="ldap_user_group" id="ldap_user_group" placeholder="e.g. cn=users,dc=mydomain,dc=com" value="{{ SETTING.get('ldap_user_group') }}">
</div>
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-flat btn-primary">Save</button>
</div>
</form>
</div>
<div class="col-md-8">
<legend>Help</legend>
<p>TBD</p>
</div>
</div>
</div>
<div class="tab-pane" id="tabs-google">
<div class="row">
<div class="col-md-4">
<form role="form" method="post">
<input type="hidden" value="google" name="config_tab" />
<fieldset>
<legend>GENERAL</legend>
<div class="form-group">
<input type="checkbox" id="google_oauth_enabled" name="google_oauth_enabled" class="checkbox" {% if SETTING.get('google_oauth_enabled') %}checked{% endif %}>
<label for="google_oauth_enabled">Enable Google OAuth</label>
</div>
<div class="form-group">
<label for="google_oauth_client_id">Client ID</label>
<input type="text" class="form-control" name="google_oauth_client_id" id="google_oauth_client_id" placeholder="Google OAuth client ID" value="{{ SETTING.get('google_oauth_client_id') }}">
</div>
<div class="form-group">
<label for="google_oauth_client_secret">Client secret</label>
<input type="text" class="form-control" name="google_oauth_client_secret" id="google_oauth_client_secret" placeholder="Google OAuth client secret" value="{{ SETTING.get('google_oauth_client_secret') }}">
</div>
</fieldset>
<fieldset>
<legend>ADVANCE</legend>
<div class="form-group">
<label for="google_redirect_uri">Redirect URI</label>
<input type="text" class="form-control" name="google_redirect_uri" id="google_redirect_uri" placeholder="e.g. /user/authorized" value="{{ SETTING.get('google_redirect_uri') }}">
</div>
<div class="form-group">
<label for="google_token_url">Token URL</label>
<input type="text" class="form-control" name="google_token_url" id="google_token_url" placeholder="e.g. https://accounts.google.com/o/oauth2/token" value="{{ SETTING.get('google_token_url') }}">
</div>
<div class="form-group">
<label for="google_token_params">Token params</label>
<input type="text" class="form-control" name="google_token_params" id="google_token_params" placeholder="e.g. {'scope': 'email profile'}" value="{{ SETTING.get('google_token_params') }}">
</div>
<div class="form-group">
<label for="google_authorize_url">Authorize URL</label>
<input type="text" class="form-control" name="google_authorize_url" id="google_authorize_url" placeholder="e.g. https://accounts.google.com/o/oauth2/auth" value="{{ SETTING.get('google_authorize_url') }}">
</div>
<div class="form-group">
<label for="google_base_url">Base URL</label>
<input type="text" class="form-control" name="google_base_url" id="google_base_url" placeholder="e.g. https://www.googleapis.com/oauth2/v1/" value="{{ SETTING.get('google_base_url') }}">
</div>
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-flat btn-primary">Save</button>
</div>
</form>
</div>
<div class="col-md-8">
<legend>Help</legend>
<p>TBD</p>
</div>
</div>
</div>
<div class="tab-pane" id="tabs-github">
<div class="row">
<div class="col-md-4">
<form role="form" method="post">
<input type="hidden" value="github" name="config_tab" />
<fieldset>
<legend>GENERAL</legend>
<div class="form-group">
<input type="checkbox" id="github_oauth_enabled" name="github_oauth_enabled" class="checkbox" {% if SETTING.get('github_oauth_enabled') %}checked{% endif %}>
<label for="github_oauth_enabled">Enable Github OAuth</label>
</div>
<div class="form-group">
<label for="github_oauth_key">Client key</label>
<input type="text" class="form-control" name="github_oauth_key" id="github_oauth_key" placeholder="Google OAuth client ID" value="{{ SETTING.get('github_oauth_key') }}">
</div>
<div class="form-group">
<label for="github_oauth_secret">Client secret</label>
<input type="text" class="form-control" name="github_oauth_secret" id="github_oauth_secret" placeholder="Google OAuth client secret" value="{{ SETTING.get('github_oauth_secret') }}">
</div>
</fieldset>
<fieldset>
<legend>ADVANCE</legend>
<div class="form-group">
<label for="github_oauth_scope">Scope</label>
<input type="text" class="form-control" name="github_oauth_scope" id="github_oauth_scope" placeholder="e.g. email" value="{{ SETTING.get('github_oauth_scope') }}">
</div>
<div class="form-group">
<label for="github_oauth_api_url">API URL</label>
<input type="text" class="form-control" name="github_oauth_api_url" id="github_oauth_api_url" placeholder="e.g. https://api.github.com/user" value="{{ SETTING.get('github_oauth_api_url') }}">
</div>
<div class="form-group">
<label for="github_oauth_token_url">Token URL</label>
<input type="text" class="form-control" name="github_oauth_token_url" id="github_oauth_token_url" placeholder="e.g. https://github.com/login/oauth/access_token" value="{{ SETTING.get('github_oauth_token_url') }}">
</div>
<div class="form-group">
<label for="github_oauth_authorize_url">Authorize URL</label>
<input type="text" class="form-control" name="github_oauth_authorize_url" id="github_oauth_authorize_url" placeholder="e.g. https://github.com/login/oauth/authorize" value="{{ SETTING.get('github_oauth_authorize_url') }}">
</div>
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-flat btn-primary">Save</button>
</div>
</form>
</div>
<div class="col-md-8">
<legend>Help</legend>
<p>TBD</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
{% endblock %}
{% block extrascripts %}
<!-- TODO: add password and password confirmation comparisson check -->
<script>
$(function() {
$('#tabs').tabs({
// add url anchor tags
activate: function(event, ui) {
window.location.hash = ui.newPanel.attr('id');
}
});
// re-set active tab (ui)
var activeTabIdx = $('#tabs').tabs('option','active');
$('#tabs li:eq('+activeTabIdx+')').tab('show')
});
// initialize pretty checkboxes
$('.checkbox').iCheck({
checkboxClass : 'icheckbox_square-blue',
increaseArea : '20%'
});
</script>
{% endblock %}

View file

@ -1,5 +1,7 @@
{% extends "base.html" %} {% block title %}
<title>DNS Control Panel - Settings</title>
{% extends "base.html" %}
{% set active_page = "admin_settings" %}
{% block title %}
<title>DNS Control Panel - Basic Settings</title>
{% endblock %} {% block dashboard_stat %}
<!-- Content Header (Page header) -->
<section class="content-header">
@ -7,9 +9,9 @@
Settings <small>PowerDNS-Admin settings</small>
</h1>
<ol class="breadcrumb">
<li><a href="{{ url_for('dashboard') }}"><i
class="fa fa-dashboard"></i> Home</a></li>
<li class="active">Settings</li>
<li><a href="{{ url_for('dashboard') }}"><i class="fa fa-dashboard"></i> Home</a></li>
<li><a href="#">Setting</a></li>
<li class="active">Basic</li>
</ol>
</section>
{% endblock %} {% block content %}
@ -18,7 +20,7 @@
<div class="col-xs-12">
<div class="box">
<div class="box-header">
<h3 class="box-title">Settings Management</h3>
<h3 class="box-title">Basic Settings</h3>
</div>
<div class="box-body">
<table id="tbl_settings" class="table table-bordered table-striped">
@ -30,21 +32,21 @@
</tr>
</thead>
<tbody>
{% for setting_name, setting_value in settings.items() %}
{% for setting in settings %}
<tr class="odd ">
<td>{{ setting_name }}</td>
{% if setting_value == "True" or setting_value == "False" %}
<td>{{ setting_value }}</td>
<td>{{ setting.name }}</td>
{% if setting.value == "True" or setting.value == "False" %}
<td>{{ setting.value }}</td>
{% else %}
<td><input name="value" id="value" value="{{ setting_value }}"></td>
<td><input name="value" id="value" value="{{ setting.value }}"></td>
{% endif %}
<td width="6%">
{% if setting_value == "True" or setting_value == "False" %}
<button type="button" class="btn btn-flat btn-warning setting-toggle-button" id="{{ setting_name }}">
{% if setting.value == "True" or setting.value == "False" %}
<button type="button" class="btn btn-flat btn-warning setting-toggle-button" id="{{ setting.name }}">
Toggle&nbsp;<i class="fa fa-info"></i>
</button>
{% else %}
<button type="button" class="btn btn-flat btn-warning setting-save-button" id="{{ setting_name }}">
<button type="button" class="btn btn-flat btn-warning setting-save-button" id="{{ setting.name }}">
Save&nbsp;<i class="fa fa-info"></i>
</button>
{% endif %}
@ -76,14 +78,14 @@
});
$(document.body).on('click', '.setting-toggle-button', function() {
var setting = $(this).prop('id');
applyChanges('', $SCRIPT_ROOT + '/admin/setting/' + setting + '/toggle', false, true)
applyChanges('', $SCRIPT_ROOT + '/admin/setting/basic/' + setting + '/toggle', false, true)
});
$(document.body).on('click', '.setting-save-button', function() {
var setting = $(this).prop('id');
var value = $(this).parents('tr').find('#value')[0].value;
var postdata = {'value': value};
applyChanges(postdata, $SCRIPT_ROOT + '/admin/setting/' + setting + '/edit', false, true)
applyChanges(postdata, $SCRIPT_ROOT + '/admin/setting/basic/' + setting + '/edit', false, true)
});
</script>
{% endblock %}

View file

@ -0,0 +1,75 @@
{% extends "base.html" %}
{% set active_page = "admin_settings" %}
{% block title %}
<title>DNS Control Panel - PDNS Settings</title>
{% endblock %} {% block dashboard_stat %}
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
Settings <small>PowerDNS-Admin settings</small>
</h1>
<ol class="breadcrumb">
<li><a href="{{ url_for('dashboard') }}"><i class="fa fa-dashboard"></i> Home</a></li>
<li><a href="#">Setting</a></li>
<li class="active">PDNS</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">PDNS Settings</h3>
</div>
<!-- /.box-header -->
<!-- form start -->
<form role="form" method="post" action="">
<input type="hidden" name="create" value="{{ create }}">
<div class="box-body">
{% if error %}
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<h4><i class="icon fa fa-ban"></i> Error!</h4>
{{ error }}
</div>
<span class="help-block">{{ error }}</span>
{% endif %}
<div class="form-group has-feedback">
<label class="control-label" for="pdns_api_url">PDNS API URL</label>
<input type="text" class="form-control" placeholder="PowerDNS API url" name="pdns_api_url" value="{{ pdns_api_url }}">
<span class="form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<label class="control-label" for="pdns_api_key">PDNS API KEY</label>
<input type="text" class="form-control" placeholder="PowerDNS API key" name="pdns_api_key" value="{{ pdns_api_key }}">
<span class="form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<label class="control-label" for="pdns_version">PDNS VERSION</label>
<input type="text" class="form-control" placeholder="PowerDNS version" name="pdns_version" value="{{ pdns_version }}">
<span class="form-control-feedback"></span>
</div>
</div>
<div class="box-footer">
<button type="submit" class="btn btn-flat btn-primary">Update</button>
</div>
</form>
</div>
</div>
<div class="col-md-8">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">Help</h3>
</div>
<div class="box-body">
<p>Fill in all the fields to the in the form to the left.</p>
</div>
</div>
</div>
</div>
</section>
{% endblock %}
{% block extrascripts %}
{% endblock %}

View file

@ -21,7 +21,7 @@
<![endif]-->
{% endblock %}
</head>
<body class="hold-transition skin-blue sidebar-mini {% if not fullscreen_layout_setting %}layout-boxed{% endif %}">
<body class="hold-transition skin-blue sidebar-mini {% if not SETTING.get('fullscreen_layout') %}layout-boxed{% endif %}">
<div class="wrapper">
{% block pageheader %}
<header class="main-header">
@ -105,17 +105,44 @@
<!-- sidebar menu: : style can be found in sidebar.less -->
<ul class="sidebar-menu" data-widget="tree">
<li class="header">USER ACTIONS</li>
<li><a href="{{ url_for('dashboard') }}"><i class="fa fa-dashboard"></i> <span>Dashboard</span></a></li>
<li class="{{ 'active' if active_page == 'dashboard' else '' }}">
<a href="{{ url_for('dashboard') }}"><i class="fa fa-dashboard"></i> Dashboard</a>
</li>
{% if current_user.role.name == 'Administrator' %}
<li><a href="{{ url_for('domain_add') }}"><i class="fa fa-plus"></i> <span>New Domain</span></a></li>
<li class="{{ 'active' if active_page == 'new_domain' else '' }}">
<a href="{{ url_for('domain_add') }}"><i class="fa fa-plus"></i> New Domain</a>
</li>
<li class="header">ADMINISTRATION</li>
<li><a href="{{ url_for('admin') }}"><i class="fa fa-wrench"></i> <span>Admin Console</span></a></li>
<li><a href="{{ url_for('templates') }}"><i class="fa fa-clone"></i> <span>Domain Templates</span></a></li>
<li><a href="{{ url_for('admin_manageuser') }}"><i class="fa fa-users"></i> <span>Users</span></a></li>
<li><a href="{{ url_for('admin_manageaccount') }}"><i class="fa fa-industry"></i> <span>Accounts</span></a></li>
<li><a href="{{ url_for('admin_history') }}"><i class="fa fa-calendar"></i> <span>History</span></a></li>
<li><a href="{{ url_for('admin_settings') }}"><i class="fa fa-cog"></i> <span>Settings</span></a></li>
<li class="{{ 'active' if active_page == 'admin_console' else '' }}">
<a href="{{ url_for('admin') }}"><i class="fa fa-wrench"></i> Admin Console</a>
</li>
<li class="{{ 'active' if active_page == 'admin_domain_template' else '' }}">
<a href="{{ url_for('templates') }}"><i class="fa fa-clone"></i> Domain Templates</a>
</li>
<li class="{{ 'active' if active_page == 'admin_users' else '' }}">
<a href="{{ url_for('admin_manageuser') }}"><i class="fa fa-users"></i> Users</a>
</li>
<li class="{{ 'active' if active_page == 'admin_accounts' else '' }}">
<a href="{{ url_for('admin_manageaccount') }}"><i class="fa fa-industry"></i> Accounts</a>
</li>
<li class="{{ 'active' if active_page == 'admin_history' else '' }}">
<a href="{{ url_for('admin_history') }}"><i class="fa fa-calendar"></i> History</a>
</li>
<li class="{{ 'treeview active' if active_page == 'admin_settings' else 'treeview' }}">
<a href="#">
<i class="fa fa-cog"></i> Settings
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu" {% if active_page == 'admin_settings' %}style="display: block;"{% endif %}>
<li><a href="{{ url_for('admin_setting_basic') }}"><i class="fa fa-circle-o"></i></i> Basic</a></li>
<li><a href="{{ url_for('admin_setting_pdns') }}"><i class="fa fa-circle-o"></i> PDNS</a></li>
<li><a href="{{ url_for('admin_setting_authentication') }}"><i class="fa fa-circle-o"></i> Authentication</a></li>
</ul>
</li>
{% endif %}
</ul>
{% endif %}
</section>
<!-- /.sidebar -->
@ -146,7 +173,7 @@
</div>
<!-- ./wrapper -->
<script type="text/javascript">
$SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
$SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
</script>
{% block scripts %}
{% assets "js_main" -%}

View file

@ -1,4 +1,5 @@
{% extends "base.html" %}
{% set active_page = "dashboard" %}
{% block title %}<title>DNS Control Panel - HOME</title>{% endblock %}
{% block dashboard_stat %}
@ -188,14 +189,14 @@
"ajax" : "{{ url_for('dashboard_domains') }}",
"info" : false,
"autoWidth" : false,
{% if default_domain_table_size_setting in ['10','25','50','100'] %}
{% if SETTING.get('default_domain_table_size') in ['10','25','50','100'] %}
"lengthMenu": [ [10, 25, 50, 100, -1],
[10, 25, 50, 100, "All"]],
{% else %}
"lengthMenu": [ [10, 25, 50, 100, {{ default_domain_table_size_setting }}, -1],
[10, 25, 50, 100, {{ default_domain_table_size_setting }}, "All"]],
"lengthMenu": [ [10, 25, 50, 100, {{ SETTING.get('default_domain_table_size') }}, -1],
[10, 25, 50, 100, {{ SETTING.get('default_domain_table_size') }}, "All"]],
{% endif %}
"pageLength": {{ default_domain_table_size_setting }}
"pageLength": {{ SETTING.get('default_domain_table_size') }}
});
$(document.body).on('click', '.history-info-button', function() {
var modal = $("#modal_history_info");

View file

@ -118,14 +118,14 @@
"ordering" : true,
"info" : true,
"autoWidth" : false,
{% if default_record_table_size_setting in ['5','15','20'] %}
{% if SETTING.get('default_record_table_size') in ['5','15','20'] %}
"lengthMenu": [ [5, 15, 20, -1],
[5, 15, 20, "All"]],
{% else %}
"lengthMenu": [ [5, 15, 20, {{ default_record_table_size_setting }}, -1],
[5, 15, 20, {{ default_record_table_size_setting }}, "All"]],
"lengthMenu": [ [5, 15, 20, {{ SETTING.get('default_record_table_size') }}, -1],
[5, 15, 20, {{ SETTING.get('default_record_table_size') }}, "All"]],
{% endif %}
"pageLength": {{ default_record_table_size_setting }},
"pageLength": {{ SETTING.get('default_record_table_size') }},
"language": {
"lengthMenu": " _MENU_ records"
},
@ -267,7 +267,7 @@
applyChanges({'domain': domain}, $SCRIPT_ROOT + '/domain/' + domain + '/update');
});
{% if record_helper_setting %}
{% if SETTING.get('record_helper_setting') %}
//handle wacky record types
$(document.body).on("focus", "#current_edit_record_data", function (e) {
var record_type = $(this).parents("tr").find('#record_type').val();

View file

@ -1,4 +1,5 @@
{% extends "base.html" %}
{% set active_page = "new_domain" %}
{% block title %}<title>DNS Control Panel - Add Domain</title>{% endblock %}
{% block dashboard_stat %}
@ -45,7 +46,7 @@
</label>
&nbsp;&nbsp;&nbsp;
<label>
<input type="radio" name="radio_type"id="radio_type_master" value="master"> Master
<input type="radio" name="radio_type" id="radio_type_master" value="master"> Master
</label>
&nbsp;&nbsp;&nbsp;
<label>

View file

@ -105,9 +105,9 @@
</div>
<div class="box-body">
<p><input type="checkbox" id="{{ domain.name }}" class="auto_ptr_toggle"
{% for setting in domain.settings %}{% if setting.setting=='auto_ptr' and setting.value=='True' %}checked{% endif %}{% endfor %} {% if auto_ptr_setting %}disabled="True"{% endif %}>
{% for setting in domain.settings %}{% if setting.setting=='auto_ptr' and setting.value=='True' %}checked{% endif %}{% endfor %} {% if SETTING.get('auto_ptr') %}disabled="True"{% endif %}>
&nbsp;Allow automatic reverse pointer creation on record updates?{% if
auto_ptr_setting %}</br><code>Auto-ptr is enabled globally on the PDA system!</code>{% endif %}</p>
SETTING.get('auto_ptr') %}</br><code>Auto-ptr is enabled globally on the PDA system!</code>{% endif %}</p>
</div>
</div>

View file

@ -55,7 +55,7 @@
<div class="form-group">
<select class="form-control" name="auth_method">
<option value="LOCAL">LOCAL Authentication</option>
{% if login_ldap_first_setting %}
{% if SETTING.get('login_ldap_first') %}
<option value="LDAP" selected="selected">LDAP Authentication</option>
{% else %}
<option value="LDAP">LDAP Authentication</option>

View file

@ -1,4 +1,5 @@
{% extends "base.html" %}
{% set active_page = "admin_domain_template" %}
{% block title %}<title>DNS Control Panel - Templates</title>{% endblock %}
{% block dashboard_stat %}

View file

@ -1,4 +1,5 @@
{% extends "base.html" %}
{% set active_page = "admin_domain_template" %}
{% block title %}<title>DNS Control Panel - Create Template</title>{% endblock %}
{% block dashboard_stat %}

View file

@ -1,4 +1,5 @@
{% extends "base.html" %}
{% set active_page = "admin_domain_template" %}
{% block title %}<title>DNS Control Panel - Edit Template</title>{% endblock %}
{% block dashboard_stat %}
@ -102,14 +103,14 @@
"ordering" : true,
"info" : true,
"autoWidth" : false,
{% if default_record_table_size_setting in ['5','15','20'] %}
{% if SETTING.get('default_record_table_size') in ['5','15','20'] %}
"lengthMenu": [ [5, 15, 20, -1],
[5, 15, 20, "All"]],
{% else %}
"lengthMenu": [ [5, 15, 20, {{ default_record_table_size_setting }}, -1],
[5, 15, 20, {{ default_record_table_size_setting }}, "All"]],
"lengthMenu": [ [5, 15, 20, {{ SETTING.get('default_record_table_size') }}, -1],
[5, 15, 20, {{ SETTING.get('default_record_table_size') }}, "All"]],
{% endif %}
"pageLength": {{ default_record_table_size_setting }},
"pageLength": {{ SETTING.get('default_record_table_size') }},
"language": {
"lengthMenu": " _MENU_ records"
},
@ -223,7 +224,7 @@
nNew = false;
});
{% if record_helper_setting %}
{% if SETTING.get('record_helper') %}
//handle wacky record types
$(document.body).on("focus", "#current_edit_record_data", function (e) {
var record_type = $(this).parents("tr").find('#record_type').val();

View file

@ -44,53 +44,23 @@ else:
@app.context_processor
def inject_fullscreen_layout_setting():
setting_value = Setting().get('fullscreen_layout')
return dict(fullscreen_layout_setting=strtobool(setting_value))
@app.context_processor
def inject_record_helper_setting():
setting_value = Setting().get('record_helper')
return dict(record_helper_setting=strtobool(setting_value))
@app.context_processor
def inject_login_ldap_first_setting():
setting_value = Setting().get('login_ldap_first')
return dict(login_ldap_first_setting=strtobool(setting_value))
@app.context_processor
def inject_default_record_table_size_setting():
setting_value = Setting().get('default_record_table_size')
return dict(default_record_table_size_setting=setting_value)
@app.context_processor
def inject_default_domain_table_size_setting():
setting_value = Setting().get('default_domain_table_size')
return dict(default_domain_table_size_setting=setting_value)
@app.context_processor
def inject_auto_ptr_setting():
setting_value = Setting().get('auto_ptr')
return dict(auto_ptr_setting=strtobool(setting_value))
def inject_setting():
setting = Setting()
return dict(SETTING=setting)
# START USER AUTHENTICATION HANDLER
@app.before_request
def before_request():
# check site maintenance mode first
maintenance = Setting().get('maintenance')
if strtobool(maintenance):
return render_template('maintenance.html')
# check if user is anonymous
g.user = current_user
login_manager.anonymous_user = Anonymous
# check site maintenance mode
maintenance = Setting().get('maintenance')
if maintenance and g.user.role.name != 'Administrator':
return render_template('maintenance.html')
@login_manager.user_loader
def load_user(id):
@ -621,7 +591,7 @@ def domain(domain_name):
# can not get any record, API server might be down
return redirect(url_for('error', code=500))
quick_edit = strtobool(Setting().get('allow_quick_edit'))
quick_edit = Setting().get('allow_quick_edit')
records = []
#TODO: This should be done in the "model" instead of "view"
@ -1374,39 +1344,19 @@ def admin_history():
return render_template('admin_history.html', histories=histories)
@app.route('/admin/settings', methods=['GET'])
@app.route('/admin/setting/basic', methods=['GET'])
@login_required
@admin_role_required
def admin_settings():
def admin_setting_basic():
if request.method == 'GET':
# start with a copy of the setting defaults (ignore maintenance setting)
settings = Setting.defaults.copy()
settings.pop('maintenance', None)
# update settings info with any customizations
for s in settings:
value = Setting().get(s)
if value is not None:
settings[s] = value
return render_template('admin_settings.html', settings=settings)
settings = Setting.query.filter(Setting.view=='basic').all()
return render_template('admin_setting_basic.html', settings=settings)
@app.route('/admin/setting/<path:setting>/toggle', methods=['POST'])
@app.route('/admin/setting/basic/<path:setting>/edit', methods=['POST'])
@login_required
@admin_role_required
def admin_settings_toggle(setting):
result = Setting().toggle(setting)
if (result):
return make_response(jsonify( { 'status': 'ok', 'msg': 'Toggled setting successfully.' } ), 200)
else:
return make_response(jsonify( { 'status': 'error', 'msg': 'Unable to toggle setting.' } ), 500)
@app.route('/admin/setting/<path:setting>/edit', methods=['POST'])
@login_required
@admin_role_required
def admin_settings_edit(setting):
def admin_setting_basic_edit(setting):
jdata = request.json
new_value = jdata['value']
result = Setting().set(setting, new_value)
@ -1417,6 +1367,87 @@ def admin_settings_edit(setting):
return make_response(jsonify( { 'status': 'error', 'msg': 'Unable to toggle setting.' } ), 500)
@app.route('/admin/setting/basic/<path:setting>/toggle', methods=['POST'])
@login_required
@admin_role_required
def admin_setting_basic_toggle(setting):
result = Setting().toggle(setting)
if (result):
return make_response(jsonify( { 'status': 'ok', 'msg': 'Toggled setting successfully.' } ), 200)
else:
return make_response(jsonify( { 'status': 'error', 'msg': 'Unable to toggle setting.' } ), 500)
@app.route('/admin/setting/pdns', methods=['GET', 'POST'])
@login_required
@admin_role_required
def admin_setting_pdns():
if request.method == 'GET':
pdns_api_url = Setting().get('pdns_api_url')
pdns_api_key = Setting().get('pdns_api_key')
pdns_version = Setting().get('pdns_version')
return render_template('admin_setting_pdns.html', pdns_api_url=pdns_api_url, pdns_api_key=pdns_api_key, pdns_version=pdns_version)
elif request.method == 'POST':
pdns_api_url = request.form.get('pdns_api_url')
pdns_api_key = request.form.get('pdns_api_key')
pdns_version = request.form.get('pdns_version')
Setting().set('pdns_api_url', pdns_api_url)
Setting().set('pdns_api_key', pdns_api_key)
Setting().set('pdns_version', pdns_version)
return render_template('admin_setting_pdns.html', pdns_api_url=pdns_api_url, pdns_api_key=pdns_api_key, pdns_version=pdns_version)
@app.route('/admin/setting/authentication', methods=['GET', 'POST'])
@login_required
@admin_role_required
def admin_setting_authentication():
if request.method == 'GET':
return render_template('admin_setting_authentication.html')
elif request.method == 'POST':
conf_type = request.form.get('config_tab')
if conf_type == 'general':
local_db_enabled = True if request.form.get('local_db_enabled') else False
signup_enabled = True if request.form.get('signup_enabled', ) else False
Setting().set('local_db_enabled', local_db_enabled)
Setting().set('signup_enabled', signup_enabled)
elif conf_type == 'ldap':
Setting().set('ldap_enabled', True if request.form.get('ldap_enabled') else False)
Setting().set('ldap_type', request.form.get('ldap_type'))
Setting().set('ldap_uri', request.form.get('ldap_uri'))
Setting().set('ldap_admin_username', request.form.get('ldap_admin_username'))
Setting().set('ldap_admin_password', request.form.get('ldap_admin_password'))
Setting().set('ldap_filter_basic', request.form.get('ldap_filter_basic'))
Setting().set('ldap_filter_username', request.form.get('ldap_filter_username'))
Setting().set('ldap_sg_enabled', True if request.form.get('ldap_sg_enabled')=='ON' else False)
Setting().set('ldap_admin_group', request.form.get('ldap_admin_group'))
Setting().set('ldap_user_group', request.form.get('ldap_user_group'))
elif conf_type == 'google':
Setting().set('google_oauth_enabled', True if request.form.get('google_oauth_enabled') else False)
Setting().set('google_oauth_client_id', request.form.get('google_oauth_client_id'))
Setting().set('google_oauth_client_secret', request.form.get('google_oauth_client_secret'))
Setting().set('google_redirect_uri', request.form.get('google_redirect_uri'))
Setting().set('google_token_url', request.form.get('google_token_url'))
Setting().set('google_token_params', request.form.get('google_token_params'))
Setting().set('google_authorize_url', request.form.get('google_authorize_url'))
Setting().set('google_base_url', request.form.get('google_base_url'))
elif conf_type == 'github':
Setting().set('github_oauth_enabled', True if request.form.get('github_oauth_enabled') else False)
Setting().set('github_oauth_key', request.form.get('github_oauth_key'))
Setting().set('github_oauth_secret', request.form.get('github_oauth_secret'))
Setting().set('github_oauth_scope', request.form.get('github_oauth_scope'))
Setting().set('github_oauth_api_url', request.form.get('github_oauth_api_url'))
Setting().set('github_oauth_token_url', request.form.get('github_oauth_token_url'))
Setting().set('github_oauth_authorize_url', request.form.get('github_oauth_authorize_url'))
else:
return abort(400)
setting = Setting().get_view('authentication')
return render_template('admin_setting_authentication.html', setting=setting)
@app.route('/user/profile', methods=['GET', 'POST'])
@login_required
def user_profile():

View file

@ -0,0 +1,83 @@
"""Add view column to setting table
Revision ID: 59729e468045
Revises: 787bdba9e147
Create Date: 2018-08-17 16:17:31.058782
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '59729e468045'
down_revision = '787bdba9e147'
branch_labels = None
depends_on = None
def update_data():
setting_table = sa.sql.table('setting',
sa.sql.column('id', sa.Integer),
sa.sql.column('name', sa.String),
sa.sql.column('value', sa.String),
sa.sql.column('view', sa.String)
)
# just update previous records which have id <= 7
op.execute(
setting_table.update().where(setting_table.c.id <= 7).values({'view': 'basic'})
)
# add more new settings
op.bulk_insert(setting_table,
[
{'id': 8, 'name': 'pdns_api_url', 'value': '', 'view': 'pdns'},
{'id': 9, 'name': 'pdns_api_key', 'value': '', 'view': 'pdns'},
{'id': 10, 'name': 'pdns_version', 'value': '4.1.1', 'view': 'pdns'},
{'id': 11, 'name': 'local_db_enabled', 'value': 'True', 'view': 'authentication'},
{'id': 12, 'name': 'signup_enabled', 'value': 'True', 'view': 'authentication'},
{'id': 13, 'name': 'ldap_enabled', 'value': 'False', 'view': 'authentication'},
{'id': 14, 'name': 'ldap_type', 'value': 'ldap', 'view': 'authentication'},
{'id': 15, 'name': 'ldap_uri', 'value': '', 'view': 'authentication'},
{'id': 16, 'name': 'ldap_admin_username', 'value': '', 'view': 'authentication'},
{'id': 17, 'name': 'ldap_admin_password', 'value': '', 'view': 'authentication'},
{'id': 18, 'name': 'ldap_filter_basic', 'value': '', 'view': 'authentication'},
{'id': 19, 'name': 'ldap_filter_username', 'value': '', 'view': 'authentication'},
{'id': 20, 'name': 'ldap_sg_enabled', 'value': 'False', 'view': 'authentication'},
{'id': 21, 'name': 'ldap_admin_group', 'value': '', 'view': 'authentication'},
{'id': 22, 'name': 'ldap_user_group', 'value': '', 'view': 'authentication'},
{'id': 23, 'name': 'github_oauth_enabled', 'value': 'False', 'view': 'authentication'},
{'id': 24, 'name': 'github_oauth_key', 'value': '', 'view': 'authentication'},
{'id': 25, 'name': 'github_oauth_secret', 'value': '', 'view': 'authentication'},
{'id': 26, 'name': 'github_oauth_scope', 'value': 'email', 'view': 'authentication'},
{'id': 27, 'name': 'github_oauth_api_url', 'value': 'https://api.github.com/user', 'view': 'authentication'},
{'id': 28, 'name': 'github_oauth_token_url', 'value': 'https://github.com/login/oauth/access_token', 'view': 'authentication'},
{'id': 29, 'name': 'github_oauth_authorize_url', 'value': 'https://github.com/login/oauth/authorize', 'view': 'authentication'},
{'id': 30, 'name': 'google_oauth_enabled', 'value': 'False', 'view': 'authentication'},
{'id': 31, 'name': 'google_oauth_client_id', 'value': '', 'view': 'authentication'},
{'id': 32, 'name': 'google_oauth_client_secret', 'value': '', 'view': 'authentication'},
{'id': 33, 'name': 'google_redirect_uri', 'value': '/user/authorized', 'view': 'authentication'},
{'id': 34, 'name': 'google_token_url', 'value': 'https://accounts.google.com/o/oauth2/token', 'view': 'authentication'},
{'id': 35, 'name': 'google_token_params', 'value': "{'scope': 'email profile'}", 'view': 'authentication'},
{'id': 36, 'name': 'google_authorize_url', 'value': 'https://accounts.google.com/o/oauth2/auth', 'view': 'authentication'},
{'id': 37, 'name': 'google_base_url', 'value': 'https://www.googleapis.com/oauth2/v1/', 'view': 'authentication'},
]
)
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('setting', sa.Column('view', sa.String(length=64), nullable=True))
# ### end Alembic commands ###
# update data for new schema
update_data()
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('setting', 'view')
# delete added records in previous version
op.execute("DELETE FROM setting WHERE id > 7")
# ### end Alembic commands ###