mirror of
https://github.com/cwinfo/powerdns-admin.git
synced 2024-11-09 23:20:27 +00:00
Merge pull request #46 from ivanfilippov/new_ui
Update 'new_ui' branch on main repo
This commit is contained in:
commit
a4a48d6b01
17
README.md
17
README.md
@ -5,12 +5,15 @@ PowerDNS Web-GUI - Built by Flask
|
||||
- Multiple domain management
|
||||
- Local / LDAP user authentication
|
||||
- User management
|
||||
- User access management base on domain
|
||||
- User access management based on domain
|
||||
- User activity logging
|
||||
- Dashboard and pdns service statistics
|
||||
|
||||
## Setup
|
||||
|
||||
### PowerDNS Version Support:
|
||||
PowerDNS-Admin supports PowerDNS autoritative server versions **3.4.2** and higher but does **not** yet support PowerDNS 4.0.0
|
||||
|
||||
### pdns Service
|
||||
I assume that you have already installed powerdns service. Make sure that your `/etc/pdns/pdns.conf` has these contents
|
||||
```
|
||||
@ -30,7 +33,7 @@ MariaDB [(none)]> GRANT ALL PRIVILEGES ON powerdnsadmin.* TO powerdnsadmin@'%' I
|
||||
|
||||
### PowerDNS-Admin
|
||||
|
||||
In this installation guide, I am using CentOS 7 and run my python stuffs with *virtualenv*. If you don't have it, let install:
|
||||
In this installation guide, I am using CentOS 7 and run my python stuffs with *virtualenv*. If you don't have it, lets install it:
|
||||
```
|
||||
$ sudo yum install python-pip
|
||||
$ sudo pip install virtualenv
|
||||
@ -55,7 +58,7 @@ Web application configuration is stored in `config.py` file. Let's clone it from
|
||||
|
||||
Create database after having proper configs
|
||||
```
|
||||
(flask)% ./createdb.py
|
||||
(flask)% ./create_db.py
|
||||
```
|
||||
|
||||
|
||||
@ -64,5 +67,9 @@ Run the application and enjoy!
|
||||
(flask)$ ./run.py
|
||||
```
|
||||
|
||||
### Screenshot
|
||||
![Alt text](http://i.imgur.com/wA5qy2d.png)
|
||||
### Screenshots
|
||||
![login page](https://github.com/ngoduykhanh/PowerDNS-Admin/wiki/images/readme_screenshots/fullscreen-login.png?raw=true)
|
||||
![dashboard](https://github.com/ngoduykhanh/PowerDNS-Admin/wiki/images/readme_screenshots/fullscreen-dashboard.png?raw=true)
|
||||
![create domain page](https://github.com/ngoduykhanh/PowerDNS-Admin/wiki/images/readme_screenshots/fullscreen-domaincreate.png?raw=true)
|
||||
![manage domain page](https://github.com/ngoduykhanh/PowerDNS-Admin/wiki/images/readme_screenshots/fullscreen-domainmanage.png?raw=true)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
function applyChanges(data, url, showResult) {
|
||||
function applyChanges(data, url, showResult, refreshPage) {
|
||||
var success = false;
|
||||
$.ajax({
|
||||
type : "POST",
|
||||
@ -14,6 +14,9 @@ function applyChanges(data, url, showResult) {
|
||||
modal.find('.modal-body p').text("Applied changes successfully");
|
||||
modal.modal('show');
|
||||
}
|
||||
if (refreshPage) {
|
||||
location.reload(true);
|
||||
}
|
||||
},
|
||||
|
||||
error : function(jqXHR, status) {
|
||||
@ -91,7 +94,7 @@ function editRow(oTable, nRow) {
|
||||
jqTds[1].innerHTML = '<select class="form-control" id="record_type" name="record_type" value="' + aData[1] + '"' + '>' + record_types + '</select>';
|
||||
jqTds[2].innerHTML = '<select class="form-control" id="record_status" name="record_status" value="' + aData[2] + '"' + '><option value="false">Active</option><option value="true">Disabled</option></select>';
|
||||
jqTds[3].innerHTML = '<select class="form-control" id="record_ttl" name="record_ttl" value="' + aData[3] + '"' + '><option value="60">1 minute</option><option value="300">5 minutes</option><option value="1800">30 minutes</option><option value="3600">60 minutes</option><option value="86400">24 hours</option></select>';
|
||||
jqTds[4].innerHTML = '<input type="text" style="display:table-cell; width:100% !important" class="form-control input-small advance-data" value="' + aData[4].replace(/\"/g,""") + '">';
|
||||
jqTds[4].innerHTML = '<input type="text" style="display:table-cell; width:100% !important" id="current_edit_record_data" name="current_edit_record_data" class="form-control input-small advance-data" value="' + aData[4].replace(/\"/g,""") + '">';
|
||||
jqTds[5].innerHTML = '<button type="button" class="btn btn-flat btn-primary button_save">Save</button>';
|
||||
jqTds[6].innerHTML = '<button type="button" class="btn btn-flat btn-primary button_cancel">Cancel</button>';
|
||||
|
||||
|
91
app/templates/admin_createuser.html
Normal file
91
app/templates/admin_createuser.html
Normal file
@ -0,0 +1,91 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}<title>DNS Control Panel - Create User</title>{% endblock %}
|
||||
|
||||
{% block dashboard_stat %}
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<h1>
|
||||
User
|
||||
<small>Create new</small>
|
||||
</h1>
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{{ url_for('dashboard') }}"><i class="fa fa-dashboard"></i>Home</a></li>
|
||||
<li><a href="{{ url_for('dashboard') }}">Admin</a></li>
|
||||
<li class="active">Create user</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">Create new user</h3>
|
||||
</div>
|
||||
<!-- /.box-header -->
|
||||
<!-- form start -->
|
||||
<form role="form" method="post" action="{{ url_for('admin_createuser') }}">
|
||||
<div class="box-body">
|
||||
<div class="form-group has-feedback">
|
||||
<label class="control-label" for="firstname">First Name</label>
|
||||
<input type="text" class="form-control" placeholder="First Name"
|
||||
name="firstname" {% if user %}value={{ user.firstname }}{% endif %}> <span
|
||||
class="glyphicon glyphicon-user form-control-feedback"></span>
|
||||
</div>
|
||||
<div class="form-group has-feedback">
|
||||
<label class="control-label" for="lastname">Last Name</label>
|
||||
<input type="text" class="form-control" placeholder="Last name"
|
||||
name="lastname" {% if user %}value={{ user.lastname }}{% endif %}> <span
|
||||
class="glyphicon glyphicon-user form-control-feedback"></span>
|
||||
</div>
|
||||
<div class="form-group has-feedback {% if duplicate_email %}has-error{% endif %}">
|
||||
<label class="control-label" for="email">E-mail address</label>
|
||||
<input type="email" class="form-control" placeholder="Email"
|
||||
name="email" id="email" {% if user %}value={{ user.email }}{% endif %}> <span
|
||||
class="glyphicon glyphicon-envelope form-control-feedback"></span>
|
||||
{% if duplicate_email %}
|
||||
<span class="help-block">This e-mail address is already in use.</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<p class="login-box-msg">Enter the account details below</p>
|
||||
<div class="form-group has-feedback {% if duplicate_username %}has-error{% endif %}">
|
||||
<label class="control-label" for="username">Username</label>
|
||||
<input type="text" class="form-control" placeholder="Username"
|
||||
name="username" {% if user %}value={{ user.username }}{% endif %}> <span
|
||||
class="glyphicon glyphicon-user form-control-feedback"></span>
|
||||
{% if duplicate_username %}
|
||||
<span class="help-block">This username is already in use.</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="form-group has-feedback {% if blank_password %}has-error{% endif %}">
|
||||
<label class="control-label" for="username">Password</label>
|
||||
<input type="password" class="form-control" placeholder="Password"
|
||||
name="password"> <span
|
||||
class="glyphicon glyphicon-lock form-control-feedback"></span>
|
||||
{% if blank_password %}
|
||||
<span class="help-block">The password cannot be blank.</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-flat btn-primary">Create User</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 with creating a new user</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p>Fill in all the fields to the in the form to the left.</p>
|
||||
<p><strong>Newly created users do not have access to any domains.</strong> You will need to grant access to the user once it is created via the domain management buttons on the dashboard.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
@ -19,6 +19,13 @@
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">User Management</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<a href="{{ url_for('admin_createuser') }}">
|
||||
<button type="button" class="btn btn-flat btn-primary pull-left button_add_user">
|
||||
Add User <i class="fa fa-plus"></i>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<table id="tbl_users" class="table table-bordered table-striped">
|
||||
<thead>
|
||||
@ -97,9 +104,8 @@
|
||||
modal.find('.modal-body p').text(info);
|
||||
modal.find('#button_delete_confirm').click(function() {
|
||||
var postdata = {'action': 'delete_user', 'data': username}
|
||||
applyChanges(postdata, '/admin/manageuser');
|
||||
applyChanges(postdata, '/admin/manageuser', false, true);
|
||||
modal.modal('hide');
|
||||
location.reload();
|
||||
})
|
||||
modal.modal('show');
|
||||
|
||||
|
@ -73,65 +73,13 @@
|
||||
|
||||
$(".setting-toggle-button").click(function() {
|
||||
var setting = $(this).prop('id');
|
||||
applyChanges('','/admin/setting/' + setting + '/toggle')
|
||||
location.reload();
|
||||
applyChanges('','/admin/setting/' + setting + '/toggle', false, true)
|
||||
});
|
||||
|
||||
// TODO: allow editing of value field
|
||||
$(".setting-edit-button").click(function() {
|
||||
var setting = $(this).prop('id');
|
||||
applyChanges('','/admin/setting/' + setting + '/edit')
|
||||
location.reload();
|
||||
applyChanges('','/admin/setting/' + setting + '/edit', false, true)
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block modals %}
|
||||
<!-- Clear History Confirmation Box -->
|
||||
<div class="modal fade modal-warning" id="modal_clear_history">
|
||||
<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>Are you sure you want to remove all history?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-flat btn-default pull-left"
|
||||
data-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-flat btn-danger" onclick="applyChanges('', '/admin/history');location.reload();">Clear
|
||||
History</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.modal-content -->
|
||||
</div>
|
||||
<!-- /.modal-dialog -->
|
||||
</div>
|
||||
<div class="modal fade" id="modal_history_info">
|
||||
<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">History Details</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-flat btn-default pull-right"
|
||||
data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.modal-content -->
|
||||
</div>
|
||||
<!-- /.modal-dialog -->
|
||||
</div>
|
||||
<!-- /.modal -->
|
||||
{% endblock %}
|
||||
|
@ -57,6 +57,7 @@
|
||||
</a>
|
||||
|
||||
<div class="navbar-custom-menu">
|
||||
{% if current_user.id is defined %}
|
||||
<ul class="nav navbar-nav">
|
||||
<!-- User Account: style can be found in dropdown.less -->
|
||||
<li class="dropdown user user-menu">
|
||||
@ -71,18 +72,18 @@
|
||||
</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<!-- User image -->
|
||||
<li class="user-header">
|
||||
{% if current_user.avatar %}
|
||||
<img src="{{ url_for('user_avatar', filename=current_user.avatar) }}" class="img-circle" alt="User Image"/>
|
||||
{% else %}
|
||||
<img src="{{ url_for('static', filename='adminlte2/dist/img/avatar.png') }}" class="img-circle" alt="User Image"/>
|
||||
{% endif %}
|
||||
<p>
|
||||
{{ current_user.firstname }} {{ current_user.lastname }}
|
||||
<small>{{ current_user.role.name }}</small>
|
||||
</p>
|
||||
</li>
|
||||
<li class="user-header">
|
||||
{% if current_user.avatar %}
|
||||
<img src="{{ url_for('user_avatar', filename=current_user.avatar) }}" class="img-circle" alt="User Image"/>
|
||||
{% else %}
|
||||
<img src="{{ url_for('static', filename='adminlte2/dist/img/avatar.png') }}" class="img-circle" alt="User Image"/>
|
||||
{% endif %}
|
||||
<p>
|
||||
{{ current_user.firstname }} {{ current_user.lastname }}
|
||||
<small>{{ current_user.role.name }}</small>
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<!-- Menu Footer-->
|
||||
<li class="user-footer">
|
||||
<div class="pull-left">
|
||||
@ -95,6 +96,7 @@
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
@ -103,7 +105,7 @@
|
||||
<aside class="main-sidebar">
|
||||
<!-- sidebar: style can be found in sidebar.less -->
|
||||
<section class="sidebar">
|
||||
<!-- Sidebar user panel -->
|
||||
{% if current_user.id is defined %}
|
||||
<div class="user-panel">
|
||||
<div class="pull-left image">
|
||||
{% if current_user.avatar %}
|
||||
@ -117,7 +119,6 @@
|
||||
<a href="#"><i class="fa fa-circle text-success"></i> Logged In</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.search form -->
|
||||
<!-- sidebar menu: : style can be found in sidebar.less -->
|
||||
<ul class="sidebar-menu">
|
||||
<li class="header">USER ACTIONS</li>
|
||||
@ -130,6 +131,7 @@
|
||||
<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>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</section>
|
||||
<!-- /.sidebar -->
|
||||
</aside>
|
||||
@ -149,102 +151,8 @@
|
||||
</ol>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
<!-- Main content -->
|
||||
{% block content %}
|
||||
<section class="content">
|
||||
<!-- Small boxes (Stat box) -->
|
||||
<div class="row">
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<!-- small box -->
|
||||
<div class="small-box bg-aqua">
|
||||
<div class="inner">
|
||||
<h3>150</h3>
|
||||
<p>Domains</p>
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="ion ion-bag"></i>
|
||||
</div>
|
||||
<a href="#" class="small-box-footer">More info <i class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ./col -->
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<!-- small box -->
|
||||
<div class="small-box bg-green">
|
||||
<div class="inner">
|
||||
<h3>53<sup style="font-size: 20px">%</sup></h3>
|
||||
<p>Users</p>
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="ion ion-stats-bars"></i>
|
||||
</div>
|
||||
<a href="#" class="small-box-footer">More info <i class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ./col -->
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<!-- small box -->
|
||||
<div class="small-box bg-yellow">
|
||||
<div class="inner">
|
||||
<h3>44</h3>
|
||||
<p>Histories</p>
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="ion ion-person-add"></i>
|
||||
</div>
|
||||
<a href="#" class="small-box-footer">More info <i class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ./col -->
|
||||
<div class="col-lg-3 col-xs-6">
|
||||
<!-- small box -->
|
||||
<div class="small-box bg-red">
|
||||
<div class="inner">
|
||||
<h3>65</h3>
|
||||
<p>Uptime</p>
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="ion ion-pie-graph"></i>
|
||||
</div>
|
||||
<a href="#" class="small-box-footer">More info <i class="fa fa-arrow-circle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ./col -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
<!-- Main row -->
|
||||
<div class="row">
|
||||
<!-- Left col -->
|
||||
<section class="col-lg-7 connectedSortable">
|
||||
<!-- Custom tabs (Charts with tabs)-->
|
||||
<div class="nav-tabs-custom">
|
||||
<!-- Tabs within a box -->
|
||||
<ul class="nav nav-tabs pull-right">
|
||||
<li class="active"><a href="#revenue-chart" data-toggle="tab">Area</a></li>
|
||||
<li><a href="#sales-chart" data-toggle="tab">Donut</a></li>
|
||||
<li class="pull-left header"><i class="fa fa-inbox"></i> Sales</li>
|
||||
</ul>
|
||||
<div class="tab-content no-padding">
|
||||
<!-- Morris chart - Sales -->
|
||||
<div class="chart tab-pane active" id="revenue-chart" style="position: relative; height: 300px;"></div>
|
||||
<div class="chart tab-pane" id="sales-chart" style="position: relative; height: 300px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.nav-tabs-custom -->
|
||||
</section>
|
||||
<!-- /.Left col -->
|
||||
<!-- right col (We are only adding the ID to make the widgets sortable)-->
|
||||
<section class="col-lg-5 connectedSortable">
|
||||
|
||||
</section>
|
||||
<!-- right col -->
|
||||
</div>
|
||||
<!-- /.row (main row) -->
|
||||
|
||||
</section>
|
||||
{% endblock %}
|
||||
<!-- /.content -->
|
||||
</div>
|
||||
<!-- /.content-wrapper -->
|
||||
<footer class="main-footer">
|
||||
|
@ -246,6 +246,75 @@
|
||||
var domain = $(this).prop('id');
|
||||
applyChanges({'domain': domain}, '/domain/' + domain + '/update');
|
||||
});
|
||||
|
||||
{% if record_helper_setting %}
|
||||
//handle wacky record types
|
||||
$(document).on("focus", "#current_edit_record_data", function (e) {
|
||||
var record_type = $(this).parents("tr").find('#record_type').val();
|
||||
var record_data = $(this);
|
||||
if (record_type == "MX") {
|
||||
var modal = $("#modal_custom_record");
|
||||
if (record_data.val() == "") {
|
||||
var form = " <label for=\"mx_priority\">MX Priority</label> \
|
||||
<input type=\"text\" class=\"form-control\" name=\"mx_priority\" id=\"mx_priority\" placeholder=\"10\"> \
|
||||
<label for=\"mx_server\">MX Server</label> \
|
||||
<input type=\"text\" class=\"form-control\" name=\"mx_server\" id=\"mx_server\" placeholder=\"postfix.example.com\"> \
|
||||
";
|
||||
} else {
|
||||
var parts = record_data.val().split(" ");
|
||||
var form = " <label for=\"mx_priority\">MX Priority</label> \
|
||||
<input type=\"text\" class=\"form-control\" name=\"mx_priority\" id=\"mx_priority\" placeholder=\"10\" value=\"" + parts[0] + "\"> \
|
||||
<label for=\"mx_server\">MX Server</label> \
|
||||
<input type=\"text\" class=\"form-control\" name=\"mx_server\" id=\"mx_server\" placeholder=\"postfix.example.com\" value=\"" + parts[1] + "\"> \
|
||||
";
|
||||
}
|
||||
modal.find('.modal-body p').html(form);
|
||||
modal.find('#button_save').click(function() {
|
||||
mx_server = modal.find('#mx_server').val();
|
||||
mx_priority = modal.find('#mx_priority').val();
|
||||
data = mx_priority + " " + mx_server;
|
||||
record_data.val(data);
|
||||
modal.modal('hide');
|
||||
})
|
||||
modal.modal('show');
|
||||
} else if (record_type == "SRV") {
|
||||
var modal = $("#modal_custom_record");
|
||||
if (record_data.val() == "") {
|
||||
var form = " <label for=\"srv_priority\">SRV Priority</label> \
|
||||
<input type=\"text\" class=\"form-control\" name=\"srv_priority\" id=\"srv_priority\" placeholder=\"0\"> \
|
||||
<label for=\"srv_weight\">SRV Weight</label> \
|
||||
<input type=\"text\" class=\"form-control\" name=\"srv_weight\" id=\"srv_weight\" placeholder=\"10\"> \
|
||||
<label for=\"srv_port\">SRV Port</label> \
|
||||
<input type=\"text\" class=\"form-control\" name=\"srv_port\" id=\"srv_port\" placeholder=\"5060\"> \
|
||||
<label for=\"srv_target\">SRV Target</label> \
|
||||
<input type=\"text\" class=\"form-control\" name=\"srv_target\" id=\"srv_target\" placeholder=\"sip.example.com\"> \
|
||||
";
|
||||
} else {
|
||||
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> \
|
||||
<input type=\"text\" class=\"form-control\" name=\"srv_weight\" id=\"srv_weight\" placeholder=\"10\" value=\"" + parts[1] + "\"> \
|
||||
<label for=\"srv_port\">SRV Port</label> \
|
||||
<input type=\"text\" class=\"form-control\" name=\"srv_port\" id=\"srv_port\" placeholder=\"5060\" value=\"" + parts[2] + "\"> \
|
||||
<label for=\"srv_target\">SRV Target</label> \
|
||||
<input type=\"text\" class=\"form-control\" name=\"srv_target\" id=\"srv_target\" placeholder=\"sip.example.com\" value=\"" + parts[3] + "\"> \
|
||||
";
|
||||
}
|
||||
modal.find('.modal-body p').html(form);
|
||||
modal.find('#button_save').click(function() {
|
||||
srv_priority = modal.find('#srv_priority').val();
|
||||
srv_weight = modal.find('#srv_weight').val();
|
||||
srv_port = modal.find('#srv_port').val();
|
||||
srv_target = modal.find('#srv_target').val();
|
||||
data = srv_priority + " " + srv_weight + " " + srv_port + " " + srv_target;
|
||||
record_data.val(data);
|
||||
modal.modal('hide');
|
||||
})
|
||||
modal.modal('show');
|
||||
}
|
||||
});
|
||||
{% endif %}
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block modals %}
|
||||
@ -295,4 +364,25 @@
|
||||
</div>
|
||||
<!-- /.modal-dialog -->
|
||||
</div>
|
||||
<div class="modal fade modal-primary" id="modal_custom_record">
|
||||
<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">Custom Record</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-flat btn-primary" id="button_save">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.modal-content -->
|
||||
</div>
|
||||
<!-- /.modal-dialog -->
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
57
app/views.py
57
app/views.py
@ -22,6 +22,11 @@ def inject_fullscreen_layout_setting():
|
||||
fullscreen_layout_setting = Setting.query.filter(Setting.name == 'fullscreen_layout').first()
|
||||
return dict(fullscreen_layout_setting=strtobool(fullscreen_layout_setting.value))
|
||||
|
||||
@app.context_processor
|
||||
def inject_record_helper_setting():
|
||||
record_helper_setting = Setting.query.filter(Setting.name == 'record_helper').first()
|
||||
return dict(record_helper_setting=strtobool(record_helper_setting.value))
|
||||
|
||||
# START USER AUTHENTICATION HANDLER
|
||||
@app.before_request
|
||||
def before_request():
|
||||
@ -54,13 +59,29 @@ def admin_role_required(f):
|
||||
# END CUSTOMIZE DECORATOR
|
||||
|
||||
# START VIEWS
|
||||
@app.errorhandler(400)
|
||||
def http_bad_request(e):
|
||||
return redirect(url_for('error', code=400))
|
||||
|
||||
@app.errorhandler(401)
|
||||
def http_unauthorized(e):
|
||||
return redirect(url_for('error', code=401))
|
||||
|
||||
@app.errorhandler(404)
|
||||
def http_internal_server_error(e):
|
||||
return redirect(url_for('error', code=404))
|
||||
|
||||
@app.errorhandler(500)
|
||||
def http_page_not_found(e):
|
||||
return redirect(url_for('error', code=500))
|
||||
|
||||
@app.route('/error/<string:code>')
|
||||
def error(code, msg=None):
|
||||
supported_code = ('400', '401', '404', '500')
|
||||
if code in supported_code:
|
||||
return render_template('%s.html' % code, msg=msg), int(code)
|
||||
return render_template('errors/%s.html' % code, msg=msg), int(code)
|
||||
else:
|
||||
return render_template('404.html'), 404
|
||||
return render_template('errors/404.html'), 404
|
||||
|
||||
@app.route('/register', methods=['GET'])
|
||||
def register():
|
||||
@ -195,7 +216,7 @@ def domain_add():
|
||||
soa_edit_api = request.form.getlist('radio_type_soa_edit_api')[0]
|
||||
|
||||
if ' ' in domain_name or not domain_name or not domain_type:
|
||||
return render_template('400.html', msg="Please correct your input"), 400
|
||||
return render_template('errors/400.html', msg="Please correct your input"), 400
|
||||
|
||||
if domain_type == 'slave':
|
||||
if request.form.getlist('domain_master_address'):
|
||||
@ -211,7 +232,7 @@ def domain_add():
|
||||
history.add()
|
||||
return redirect(url_for('dashboard'))
|
||||
else:
|
||||
return render_template('400.html', msg=result['msg']), 400
|
||||
return render_template('errors/400.html', msg=result['msg']), 400
|
||||
except:
|
||||
return redirect(url_for('error', code=500))
|
||||
return render_template('domain_add.html')
|
||||
@ -368,13 +389,37 @@ def admin():
|
||||
|
||||
return render_template('admin.html', domains=domains, users=users, configs=configs, statistics=statistics, uptime=uptime, history_number=history_number)
|
||||
|
||||
@app.route('/admin/user/create', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@admin_role_required
|
||||
def admin_createuser():
|
||||
if request.method == 'GET':
|
||||
return render_template('admin_createuser.html')
|
||||
|
||||
if request.method == 'POST':
|
||||
fdata = request.form
|
||||
|
||||
user = User(username=fdata['username'], plain_text_password=fdata['password'], firstname=fdata['firstname'], lastname=fdata['lastname'], email=fdata['email'])
|
||||
|
||||
if fdata['password'] == "":
|
||||
return render_template('admin_createuser.html', user=user, blank_password=True)
|
||||
|
||||
result = user.create_local_user();
|
||||
|
||||
if result == 'Email already existed':
|
||||
return render_template('admin_createuser.html', user=user, duplicate_email=True)
|
||||
|
||||
if result == 'Username already existed':
|
||||
return render_template('admin_createuser.html', user=user, duplicate_username=True)
|
||||
|
||||
return redirect(url_for('admin_manageuser'))
|
||||
|
||||
@app.route('/admin/manageuser', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@admin_role_required
|
||||
def admin_manageuser():
|
||||
if request.method == 'GET':
|
||||
users = User.query.all()
|
||||
users = User.query.order_by(User.username).all()
|
||||
return render_template('admin_manageuser.html', users=users)
|
||||
|
||||
if request.method == 'POST':
|
||||
@ -460,7 +505,7 @@ def admin_settings_toggle(setting):
|
||||
if (result):
|
||||
return make_response(jsonify( { 'status': 'ok', 'msg': 'Toggled setting successfully.' } ), 200)
|
||||
else:
|
||||
return make_response(jsonify( { 'status': 'error', 'msg': 'Can toggle setting.' } ), 500)
|
||||
return make_response(jsonify( { 'status': 'error', 'msg': 'Unable to toggle setting.' } ), 500)
|
||||
|
||||
@app.route('/user/profile', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
|
@ -11,10 +11,12 @@ admin_role = Role('Administrator', 'Administrator')
|
||||
user_role = Role('User', 'User')
|
||||
maintenance_setting = Setting('maintenance', 'False')
|
||||
fullscreen_layout_setting = Setting('fullscreen_layout', 'True')
|
||||
record_helper_setting = Setting('record_helper_layout', 'True')
|
||||
db.session.add(admin_role)
|
||||
db.session.add(user_role)
|
||||
db.session.add(maintenance_setting)
|
||||
db.session.add(fullscreen_layout_setting)
|
||||
db.session.add(record_helper_setting)
|
||||
db.session.commit()
|
||||
if not os.path.exists(SQLALCHEMY_MIGRATE_REPO):
|
||||
api.create(SQLALCHEMY_MIGRATE_REPO, 'database repository')
|
||||
|
Loading…
Reference in New Issue
Block a user