Userlists
pull/161/head
Pavel Loginov 2019-10-18 20:23:35 +03:00
parent 16cc10d862
commit 73d4c61bb3
20 changed files with 234 additions and 153 deletions

View File

@ -8,6 +8,7 @@ from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/'))
template = env.get_template('add.html')
form = cgi.FieldStorage()
serv = form.getvalue('serv')
if form.getvalue('add'):
c = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
@ -43,10 +44,8 @@ template = template.render(title = "Add",
print(template)
if form.getvalue('mode') is not None:
hap_configs_dir = funct.get_config_var('configs', 'haproxy_save_configs_dir')
cert_path = sql.get_setting('cert_path')
haproxy_dir = sql.get_setting('haproxy_dir')
serv = form.getvalue('serv')
port = form.getvalue('port')
bind = ""
ip = ""
@ -177,29 +176,61 @@ if form.getvalue('mode') is not None:
waf += " http-request deny if { var(txn.modsec.code) -m int gt 0 }\n"
config_add = "\n" + name + "\n" + bind + mode + maxconn + balance + options_split + filter + compression_s + cache_s + waf + backend + servers_split + "\n" + cache_set
cfg = hap_configs_dir + serv + "-" + funct.get_data('config') + ".cfg"
if form.getvalue('new_userlist') is not None:
name = "userlist "+form.getvalue('new_userlist')+ "\n"
funct.get_config(serv, cfg)
try:
with open(cfg, "a") as conf:
conf.write(config_add)
except IOError:
print("Can't read import config file")
funct.logging(serv, "add.py add new %s" % name)
print('<div class="line3">')
MASTERS = sql.is_master(serv)
for master in MASTERS:
if master[0] != None:
funct.upload_and_restart(master[0], cfg)
stderr = funct.upload_and_restart(serv, cfg, just_save="save")
if stderr:
print('<div class="alert alert-danger">%s</div>' % stderr)
else:
print('<meta http-equiv="refresh" content="0; url=add.py?add=%s&conf=%s&serv=%s">' % (name, config_add, serv))
new_userlist_groups = ""
if form.getvalue('userlist-group') is not None:
groups = form.getlist('userlist-group')
for group in groups:
new_userlist_groups += " group "+group+ "\n"
new_users_list = ""
if form.getvalue('userlist-user') is not None:
users = form.getlist('userlist-user')
passwords = form.getlist('userlist-password')
userlist_user_group = form.getlist('userlist-user-group')
i = 0
print(userlist_user_group)
for user in users:
try:
group = ' groups '+userlist_user_group[i]
except:
group = ''
new_users_list += " user "+user+" insecure-password " + passwords[i] +group+ "\n"
i += 1
print('</div>')
config_add = "\n" + name + new_userlist_groups + new_users_list
try:
if config_add:
hap_configs_dir = funct.get_config_var('configs', 'haproxy_save_configs_dir')
cfg = hap_configs_dir + serv + "-" + funct.get_data('config') + ".cfg"
funct.get_config(serv, cfg)
try:
with open(cfg, "a") as conf:
conf.write(config_add)
except IOError:
print("Can't read import config file")
funct.logging(serv, "add.py add new %s" % name)
print('<div class="line3">')
MASTERS = sql.is_master(serv)
for master in MASTERS:
if master[0] != None:
funct.upload_and_restart(master[0], cfg)
stderr = funct.upload_and_restart(serv, cfg, just_save="save")
if stderr:
print('<div class="alert alert-danger">%s</div>' % stderr)
else:
print('<meta http-equiv="refresh" content="0; url=add.py?add=%s&conf=%s&serv=%s">' % (name, config_add, serv))
print('</div>')
except:
pass

View File

@ -1,55 +0,0 @@
#!/usr/bin/env python3
import os
import sql
import http, cgi
import funct
import sql
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/'))
template = env.get_template('lists.html')
print('Content-type: text/html\n')
funct.check_login()
form = cgi.FieldStorage()
funct.page_for_admin(level = 2)
try:
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
user = sql.get_user_name_by_uuid(user_id.value)
user_group = sql.get_user_group_by_uuid(user_id.value)
servers = sql.get_dick_permit(virt=1)
token = sql.get_token(user_id.value)
servbackend = form.getvalue('servbackend')
serv = form.getvalue('serv')
if servbackend is None:
servbackend = ""
except:
pass
dir = os.path.dirname(os.getcwd())+"/"+sql.get_setting('lists_path')
white_dir = os.path.dirname(os.getcwd())+"/"+sql.get_setting('lists_path')+"/"+user_group+"/white"
black_dir = os.path.dirname(os.getcwd())+"/"+sql.get_setting('lists_path')+"/"+user_group+"/black"
if not os.path.exists(dir):
os.makedirs(dir)
if not os.path.exists(dir+"/"+user_group):
os.makedirs(dir+"/"+user_group)
if not os.path.exists(white_dir):
os.makedirs(white_dir)
if not os.path.exists(black_dir):
os.makedirs(black_dir)
white_lists = funct.get_files(dir=white_dir, format="lst")
black_lists = funct.get_files(dir=black_dir, format="lst")
template = template.render(h2 = 1,
title = "Lists",
role = sql.get_user_role_by_uuid(user_id.value),
user = user,
white_lists = white_lists,
black_lists = black_lists,
group = user_group,
versions = funct.versions(),
token = token)
print(template)

View File

@ -244,9 +244,20 @@ def get_sections(config):
return_config = list()
with open(config, 'r') as f:
for line in f:
if line.startswith('listen') or line.startswith('frontend') or line.startswith('backend') or line.startswith('cache') or line.startswith('defaults') or line.startswith('global'):
line = line.strip()
return_config.append(line)
if (
line.startswith('listen') or
line.startswith('frontend') or
line.startswith('backend') or
line.startswith('cache') or
line.startswith('defaults') or
line.startswith('global') or
line.startswith('#HideBlockEnd') or
line.startswith('#HideBlockStart') or
line.startswith('peers') or
line.startswith('userlist')
):
line = line.strip()
return_config.append(line)
return return_config
@ -265,10 +276,21 @@ def get_section_from_config(config, section):
continue
if record:
if line.startswith('listen') or line.startswith('frontend') or line.startswith('backend') or line.startswith('cache') or line.startswith('defaults') or line.startswith('global') or line.startswith('#HideBlockEnd') or line.startswith('#HideBlockStart'):
record = False
end_line = index
end_line = end_line - 1
if (
line.startswith('listen') or
line.startswith('frontend') or
line.startswith('backend') or
line.startswith('cache') or
line.startswith('defaults') or
line.startswith('global') or
line.startswith('#HideBlockEnd') or
line.startswith('#HideBlockStart') or
line.startswith('peers') or
line.startswith('userlist')
):
record = False
end_line = index
end_line = end_line - 1
else:
return_config += line

View File

@ -1,6 +1,5 @@
#!/usr/bin/env python3
import funct, sql
import create_db
import os, http.cookies
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/'))
@ -28,10 +27,8 @@ commands = [ "ls -l %s |awk '{ print $6\" \"$7\" \"$8}'" % haproxy_config_path ]
servers_with_status1 = []
out1 = ""
for s in servers:
# print(s[2])
servers_with_status = list()
cmd = 'echo "show info" |nc %s %s -w 1 |grep -e "Ver\|Uptime:\|Process_num"' % (s[2], haproxy_sock_port)
# print(cmd )
out = funct.subprocess_execute(cmd)
servers_with_status.append(s[0])
servers_with_status.append(s[1])

View File

@ -2,7 +2,7 @@
CONF=/etc/keepalived/keepalived.conf
if [ -f $CONF ];then
echo -e 'error: Keepalived already installed. You can edit config <a href="/app/keepalivedconfig.py" title="Edit Keepalived config">here</a><br /><br />'
echo -e 'info: Keepalived already installed. You can edit config <a href="/app/keepalivedconfig.py" title="Edit Keepalived config">here</a><br /><br />'
exit 1
fi

View File

@ -2,7 +2,6 @@
for ARGUMENT in "$@"
do
KEY=$(echo $ARGUMENT | cut -f1 -d=)
VALUE=$(echo $ARGUMENT | cut -f2 -d=)
@ -12,8 +11,6 @@ do
HAPROXY_PATH) HAPROXY_PATH=${VALUE} ;;
*)
esac
done
VERSION=$(echo $VERSION | awk -F"-" '{print $1}')
VERSION_MAJ=$(echo $VERSION | awk -F"." '{print $1"."$2}')
@ -94,7 +91,6 @@ if [ $? -eq 1 ]; then
fi
wget -O /tmp/modsecurity.conf https://github.com/SpiderLabs/ModSecurity/raw/v2/master/modsecurity.conf-recommended
sudo bash -c cat << EOF >> /tmp/modsecurity.conf
Include $HAPROXY_PATH/waf/rules/modsecurity_crs_10_ignore_static.conf
Include $HAPROXY_PATH/waf/rules/modsecurity_crs_10_setup.conf

View File

@ -5,7 +5,7 @@ import http.cookies
import funct
import sql
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/'), autoescape=True)
env = Environment(loader=FileSystemLoader('templates/'), autoescape=True,extensions=['jinja2.ext.loopcontrols'])
template = env.get_template('sections.html')
print('Content-type: text/html\n')
@ -81,11 +81,6 @@ if serv is not None and form.getvalue('config') is not None:
funct.diff_config(oldcfg, cfg)
#if save:
# c = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
# c["restart"] = form.getvalue('serv')
# print(c)
os.system("/bin/rm -f " + hap_configs_dir + "*.old")

View File

@ -19,7 +19,7 @@ def out_error(e):
else:
error = e.args[0]
print('Content-type: text/html\n')
print('<span class="alert alert-danger" id="error">An error occurred: ' + error + ' <a title="Close" id="errorMess"><b>X</b></a></span>')
print('<span class="alert alert-danger" style="height: 20px;margin-bottom: 20px;" id="error">An error occurred: ' + error + ' <a title="Close" id="errorMess"><b>X</b></a></span>')
def add_user(user, email, password, role, group, activeuser):
con, cur = create_db.get_cur()
@ -1683,10 +1683,10 @@ if form.getvalue('newtoption'):
if form.getvalue('updateoption') is not None:
option = form.getvalue('updateoption')
id = form.getvalue('id')
print('Content-type: text/html\n')
id = form.getvalue('id')
check_token()
if option is None or id is None:
print('Content-type: text/html\n')
print(error_mess)
else:
update_options(option, id)

View File

@ -18,6 +18,7 @@ h3 {
<li><a href="#ssl">SSL certificates</a></li>
<li><a href="#option">Options</a></li>
<li><a href="#add-servers">Servers</a></li>
<li><a href="#userlist">Userlist</a></li>
{% if user %}
<a href=/app/login.py?logout=logout title="Logout, user name: {{ user }}" class="login"> Logout</a>
{% else %}
@ -308,7 +309,7 @@ h3 {
</span>
<div id="options-listen-show-div" style="display: none;">
<div class="tooltip">
<span style="padding-right: 10px;" class="form-control">Start typing options: </span>
<span style="padding-right: 10px;">Start typing options: </span>
<input type="text" id="options" class="form-control">
<span style="padding-left: 10px;">
or press down. <a href="http://cbonte.github.io/haproxy-dconv/1.7/configuration.html" target="_blanck" style="color: #23527c" title="HAproxy docs">Read more about options</a>
@ -790,8 +791,8 @@ h3 {
<td class="padding10 first-collumn">
{{ option.0 }}
</td>
<td class="padding10 first-collumn" style="width: 100%;">
<input type="text" id="option-body-{{ option.0 }}" value="{{ option.1 }}" size="100" class="form-control">
<td class="padding10 first-collumn" style="width: 77%;">
<input type="text" id="option-body-{{ option.0 }}" value="{{ option.1 }}" size="60" class="form-control">
</td>
<td>
<a class="delete" onclick="confirmDeleteOption({{ option.0 }})" title="Delete option {{option.1}}" style="cursor: pointer;"></a>
@ -812,8 +813,8 @@ h3 {
<td class="padding10 first-collumn">
Enter option for save:
</td>
<td>
<input type="text" name="new-option" id="new-option" class="form-control" size="100">
<td style="width: 77%;">
<input type="text" name="new-option" id="new-option" class="form-control" size="60">
</td>
<td>
<a class="add-admin" id="add-option-new" title="Add new option" style="cursor: pointer;"></a>
@ -845,8 +846,8 @@ h3 {
<td class="padding10 first-collumn">
<input type="text" id="servers-ip-{{ s.0 }}" value="{{ s.1 }}" size="15" class="form-control">
</td>
<td class="padding10 first-collumn" style="width: 100%;">
<input type="text" id="servers-desc-{{ s.0 }}" value="{{ s.2 }}" size="60" class="form-control">
<td class="padding10 first-collumn" style="width: 77%;">
<input type="text" id="servers-desc-{{ s.0 }}" value="{{ s.2 }}" size="50" class="form-control">
</td>
<td>
<a class="delete" onclick="confirmDeleteSavedServer({{ s.0 }})" title="Delete server {{s.1}}" style="cursor: pointer;"></a>
@ -867,8 +868,8 @@ h3 {
<td class="padding10 first-collumn">
<input type="text" name="new-saved-servers" id="new-saved-servers" class="form-control" size="15">
</td>
<td style="width: 100%;">
<input type="text" name="new-saved-servers-description" id="new-saved-servers-description" class="form-control" size="60">
<td style="width: 77%;">
<input type="text" name="new-saved-servers-description" id="new-saved-servers-description" class="form-control" size="50">
</td>
<td>
<a class="add-admin" id="add-saved-server-new" title="Add new server" style="cursor: pointer;"></a>
@ -886,6 +887,76 @@ h3 {
</a>
</div>
</div>
<div id="userlist">
<form name="add-userlist" action="/app/add.py">
<table>
<caption><h3>Add Userlist</h3></caption>
<tr>
<td class="addName">Select server: </td>
<td class="addOption">
<select required name="serv" id="serv3">
<option disabled selected>Choose server</option>
{% for select in selects %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endfor %}
</select>
<div class="tooltip tooltipTop"><b>Note:</b> If you reconfigure Master server, Slave will reconfigured automatically</div>
</td>
<td rowspan="4" class="add-note addName alert-info">
It is possible to control access to frontend/backend/listen sections or to
http stats by allowing only authenticated and authorized users. To do this,
it is required to create at least one userlist and to define users.
</td>
</tr>
<tr>
<td class="addName">Userlist name:</td>
<td class="addOption">
<input type="text" name="new_userlist" id="new_userlist" required title="Userlist name" placeholder="basic-auth-list" class="form-control">
</td>
</tr>
<tr>
<td class="addName">Groups:</td>
<td class="addOption">
<span id="userlist-groups">
<input name="userlist-group" title="User`s group" placeholder="group_name" class="form-control">
</span>
<span>
<a class="add-server" id="add-userlist-group" title="Add extra group" style="cursor: pointer;"></a>
</span>
<div class="tooltip tooltipTop">It is also possible to attach users to this group by using a comma separated list of names preceded by "users" keyword.</div>
</td>
</tr>
<tr>
<td class="addName">User:</td>
<td class="addOption">
<span id="userlist-users">
<input name="userlist-user" required title="User name" placeholder="user_name" class="form-control">
<input name="userlist-password" required title="User password. By default it insecure-password" placeholder="password" class="form-control">
<input name="userlist-user-group" title="User`s group" placeholder="user`s group" class="form-control">
</span>
<span>
<a class="add-server" id="add-userlist-user" title="Add extra user" style="cursor: pointer;"></a>
</span>
<div class="tooltip tooltipTop">It is also possible to attach groups to this user by using a comma separated list of groups.</div>
</td>
</tr>
<tr>
<td class="addButton">
<button type="submit" value="" name="" class="btn btn-default">Add Userlist</button>
</td>
</tr>
</table>
</form>
<div class="add-note addName alert-info" style="width: inherit; margin-right: 15px;">
In this section you can create userlists. And after use them in the "Add" sections
<br />
<br />
How to use userlists you can read
<a href="https://haproxy-wi.org/description.py?description=userlist" title="How to use userlists" target="_blank">
<b>here</b>
</a>
</div>
</div>
<div id="dialog-confirm-delete" title="Are you sure you want to delete?" style="display: none;">
<p><span class="ui-icon ui-icon-alert" style="float:left; margin:3px 12px 20px 0;"></span>Deleting all data will be lost?</p>

View File

@ -105,6 +105,16 @@
</span><div>
{% continue %}
{% endif %}
{% if line.startswith('userlist') %}
</div><span class="param"> {{ line }}
{% if role %}
<span class="accordion-link">
<a href="/app/sections.py?serv={{serv}}&section={{ line }}">Edit</a>
</span>
{% endif %}
</span><div>
{% continue %}
{% endif %}
{% if "acl" in line or "option" in line or "server" in line %}
{% if "timeout" not in line and "default-server" not in line and "#use_backend" not in line and "#" not in line%}
<span class="paramInSec">

View File

@ -1,10 +1,10 @@
{% for option in options %}
<tr style="width: 50%;" id="option-table-{{option.0}}" class="newoption update">
<tr style="width: 50%;" id="option-{{option.0}}" class="newoption update">
<td class="padding10 first-collumn">
{{ option.0 }}
</td>
<td class="first-collumn" style="width: 100%;">
<input type="text" id="option-body-{{option.0}}" class="form-control" value="{{option.1}}" size="100">
<td class="first-collumn" style="width: 77%;">
<input type="text" id="option-body-{{option.0}}" class="form-control" value="{{option.1}}" size="60">
</td>
<td>

View File

@ -3,8 +3,8 @@
<td class="padding10 first-collumn">
<input type="text" id="servers-ip-{{s.0}}" class="form-control" value="{{s.1}}" size="15">
</td>
<td class="first-collumn" style="width: 100%;">
<input type="text" id="servers-desc-{{s.0}}" class="form-control" value="{{s.2}}" size="60">
<td class="first-collumn" style="width: 77%;">
<input type="text" id="servers-desc-{{s.0}}" class="form-control" value="{{s.2}}" size="50">
</td>
<td>
<a class="delete" onclick="confirmDeleteSavedServer({{s.0}})" style="cursor: pointer;"></a>

View File

@ -66,14 +66,15 @@
<li><a href=/app/hapservers.py title="Working with Haproxy Configs" class="overview-link head-submenu">Overview</a> </li>
<li><a href=/app/config.py title="Working with HAProxy configs" class="edit head-submenu">Configs</a></li>
{% if role <= 2 %}
<li><a href=/app/add.py#proxy title="Add proxy" class="add head-submenu" id="add1">Add proxy</a></li>
<li><a href=/app/versions.py title="Actions with configs versions" class="version head-submenu">Versions</a></li>
<li><a href=/app/add.py#ssl title="Upload SSL cert" class="cert head-submenu" id="add4">SSL</a></li>
<li><a href=/app/add.py#option title="Save custom options" class="option head-submenu" id="add5">Options</a></li>
<li><a href=/app/add.py#add-servers title="Save servers" class="runtime head-submenu" id="add6">Servers</a></li>
<li><a href=/app/lists.py title="Manage black and white lists" class="lists head-submenu">Lists</a> </li>
<li><a href=/app/waf.py title="Web application firewall" class="waf head-submenu">WAF</a> </li>
<li><a href=/app/ihap.py title="Installation HAProxy" class="hap head-submenu">Installation</a> </li>
<li><a href="/app/add.py#proxy" title="Add proxy" class="add head-submenu" id="add1">Add proxy</a></li>
<li><a href="/app/versions.py" title="Actions with configs versions" class="version head-submenu">Versions</a></li>
<li><a href="/app/add.py#ssl" title="Upload SSL cert" class="cert head-submenu" id="add4">SSL</a></li>
<li><a href="/app/add.py#option" title="Save custom options" class="option head-submenu" id="add5">Options</a></li>
<li><a href="/app/add.py#add-servers" title="Save servers" class="runtime head-submenu" id="add6">Servers</a></li>
<li><a href="/app/add.py#userlist" title="Add userlist" class="add-userlist head-submenu" id="add7">User list</a></li>
<li><a href="/app/lists.py" title="Manage black and white lists" class="lists head-submenu">Lists</a> </li>
<li><a href="/app/waf.py" title="Web application firewall" class="waf head-submenu">WAF</a> </li>
<li><a href="/app/ihap.py" title="Installation HAProxy" class="hap head-submenu">Installation</a> </li>
{% endif %}
</ul>
</li>
@ -102,7 +103,6 @@
<li><a href=/app/users.py#users title="Actions with users" class="users head-submenu">Users</a></li>
<li><a href=/app/users.py#groups title="Actions with groups" class="group head-submenu">Groups</a></li>
<li><a href=/app/users.py#servers title="Actions with servers" class="runtime head-submenu">Servers</a></li>
<!-- <li><a href=/app/users.py#roles title="Users roles" class="role head-submenu">Roles</a></li> -->
<li><a href=/app/users.py#ssh title="Manage SSH credentials" class="admin head-submenu">SSH credentials</a></li>
<li><a href=/app/settings.py title="HAproxy-WI settings" class="settings head-submenu">Settings</a></li>
<li><a href=/app/viewlogs.py title="View internal logs" class="logs head-submenu">Internal logs</a></li>

View File

@ -3,13 +3,13 @@
<script src="/inc/users.js"></script>
<table class="overview">
<tr class="overviewHead">
<td class="padding10 first-collumn" style="width: 350px;">Version</td>
<td class="padding10 first-collumn">Server</td>
<td style="width: 150px;">SYN flood protect</td>
<td class="padding10 first-collumn" style="width: 35%;">Version</td>
<td class="padding10 first-collumn" style="width: 35%;">Server</td>
<td>SYN flood protect</td>
<td></td>
</tr>
<tr>
<td class="padding10 first-collumn" style="width: 350px;">
<td class="padding10 first-collumn" style="width: 20%;">
<select id="hapver" name="hapver" required>
<option disabled>Choose HAProxy version</option>
<option value="2.0.4-1">2.0.4-1</option>

View File

@ -63,11 +63,6 @@ if serv is not None and form.getvalue('config') is not None:
funct.upload_and_restart(master[0], configver, just_save=save)
stderr = funct.upload_and_restart(serv, configver, just_save=save)
if save:
c = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
c["restart"] = form.getvalue('serv')
print(c)
output_from_parsed_template = template.render(h2 = 1, title = "Working with versions HAProxy configs",

View File

@ -660,15 +660,6 @@ $( function() {
});
$( "#tabs" ).tabs( "option", "active", 0 );
} );
// $( "#add2" ).on( "click", function() {
// $('.menu li ul li').each(function () {
// $(this).find('a').css('padding-left', '20px')
// $(this).find('a').css('border-left', '0px solid #5D9CEB');
// $(this).children("#add2").css('padding-left', '30px');
// $(this).children("#add2").css('border-left', '4px solid #5D9CEB');
// });
// $( "#tabs" ).tabs( "option", "active", 1 );
// } );
$( "#add4" ).on( "click", function() {
$('.menu li ul li').each(function () {
$(this).find('a').css('padding-left', '20px')
@ -696,6 +687,15 @@ $( function() {
});
$( "#tabs" ).tabs( "option", "active", 6 );
} );
$( "#add7" ).on( "click", function() {
$('.menu li ul li').each(function () {
$(this).find('a').css('padding-left', '20px')
$(this).find('a').css('border-left', '0px solid #5D9CEB');
$(this).children("#add7").css('padding-left', '30px');
$(this).children("#add7").css('border-left', '4px solid #5D9CEB');
});
$( "#tabs" ).tabs( "option", "active", 7 );
} );
}
$( "#path-cert-listen" ).autocomplete({
@ -824,13 +824,21 @@ $( function() {
}
} );
});
var add_server_var = '<br /><input name="servers" title="Backend port" size=14 placeholder="xxx.xxx.xxx.xxx" class="form-control">: <input name="server_port" title="Backend port" size=1 placeholder="yyy" class="form-control">'
var add_server_var = '<br /><input name="servers" title="Backend IP" size=14 placeholder="xxx.xxx.xxx.xxx" class="form-control">: <input name="server_port" title="Backend port" size=1 placeholder="yyy" class="form-control">'
$('#add-server-input').click(function() {
$('#servers').append(add_server_var);
});
$('#add-server-input2').click(function() {
$('#servers2').append(add_server_var);
});
var add_userlist_var = '<br /><input name="userlist-user" title="User name" placeholder="user_name" class="form-control"> <input name="userlist-password" required title="User password. By default it insecure-password" placeholder="password" class="form-control"> <input name="userlist-user-group" title="User`s group" placeholder="user`s group" class="form-control">'
$('#add-userlist-user').click(function() {
$('#userlist-users').append(add_userlist_var);
});
var add_userlist_group_var = '<br /><input name="userlist-group" title="User`s group" placeholder="group_name" class="form-control">'
$('#add-userlist-group').click(function() {
$('#userlist-groups').append(add_userlist_group_var);
});
$('.advance-show').click(function() {
$('.advance-show').fadeOut();
$('.advance').fadeIn();

View File

@ -164,6 +164,11 @@
font-family: "Font Awesome 5 Solid";
content: "\f00c";
}
.add-userlist::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f0c0";
}
.add-server::before {
display: none;
font-family: "Font Awesome 5 Solid";

View File

@ -556,8 +556,8 @@ $( function() {
$( "#hide_menu" ).click(function() {
$(".top-menu").hide( "drop", "fast" );
$(".container").css("max-width", "98%");
$(".footer").css("max-width", "98%");
$(".container").css("max-width", "100%");
$(".footer").css("max-width", "97%");
$(".container").css("margin-left", "1%");
$(".footer").css("margin-left", "1%");
$(".show_menu").show();
@ -583,7 +583,7 @@ $( function() {
}
if (hideMenu == "hide") {
$(".top-menu").hide();
$(".container").css("max-width", "98%");
$(".container").css("max-width", "97%");
$(".container").css("margin-left", "1%");
$(".show_menu").show();
}

View File

@ -21,7 +21,6 @@ h2 {
color: #fff;
margin-top: 0px;
margin-bottom: 0px;
width: 98.9%;
}
h3 {
margin-top: -0;
@ -30,7 +29,6 @@ h3 {
padding: 0.3em;
font-size: 1.6em;
border-bottom: 1px solid #ddd;
width: 100.43%;
}
form {
margin: 0;
@ -83,12 +81,10 @@ pre {
min-width: 40%;
background-color: #fff;
margin-left: 207px;
margin-right: 20px;
padding-bottom: 10px;
}
.footer {
min-height: 50px;
/* top: calc(99vh - 40px); */
right: 0;
left: 0;
max-width: 91%;
@ -98,7 +94,6 @@ pre {
margin-right: 20px;
border-top: 1px solid #ddd;
clear: both;
/* position: fixed; */
}
#version {
float: left;
@ -835,6 +830,9 @@ label {
.wrong-login {
margin-right: -150px;
}
}
@media (max-width: 1280px) {
}
@media (max-width: 1080px) {
#logo_span {
@ -887,6 +885,12 @@ label {
.wrong-login {
margin-right: -260px;
}
.overview {
width: 90% !important;
}
.overview h3 {
width: 46.4% !important;
}
}
@media (max-width: 667px) {
#logo_span {

View File

@ -50,6 +50,8 @@ $( function() {
data = data.replace(/\s+/g,' ');
if (data.indexOf('error') != '-1' || data.indexOf('alert') != '-1' || data.indexOf('Failed') != '-1') {
$("#ajax").html('<div class="alert alert-danger">'+data+'</data>');
} else if (data.indexOf('info') != '-1' ){
$("#ajax").html('<div class="alert alert-info">'+data+'</data>');
} else if (data.indexOf('success') != '-1' ){
$('.alert-danger').remove();
$("#ajax").html('<div class="alert alert-success">All is ready!</data>');