mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2025-04-22 03:06:55 +00:00
Merge c1c1d67bc9
into 0293e04311
This commit is contained in:
commit
bf939ae3b9
@ -45,7 +45,7 @@ def authorized_personnel_only(viewfunc):
|
|||||||
|
|
||||||
# Authorized to access an API view?
|
# Authorized to access an API view?
|
||||||
if "admin" in privs:
|
if "admin" in privs:
|
||||||
# Call view func.
|
# Call view func.
|
||||||
return viewfunc(*args, **kwargs)
|
return viewfunc(*args, **kwargs)
|
||||||
elif not error:
|
elif not error:
|
||||||
error = "You are not an administrator."
|
error = "You are not an administrator."
|
||||||
@ -283,7 +283,7 @@ def dns_set_record(qname, rtype="A"):
|
|||||||
# make this action set (replace all records for this
|
# make this action set (replace all records for this
|
||||||
# qname-rtype pair) rather than add (add a new record).
|
# qname-rtype pair) rather than add (add a new record).
|
||||||
action = "set"
|
action = "set"
|
||||||
|
|
||||||
elif request.method == "DELETE":
|
elif request.method == "DELETE":
|
||||||
if value == '':
|
if value == '':
|
||||||
# Delete all records for this qname-type pair.
|
# Delete all records for this qname-type pair.
|
||||||
@ -402,6 +402,20 @@ def backup_status():
|
|||||||
from backup import backup_status
|
from backup import backup_status
|
||||||
return json_response(backup_status(env))
|
return json_response(backup_status(env))
|
||||||
|
|
||||||
|
@app.route('/system/privacy/enable', methods=["POST"])
|
||||||
|
@authorized_personnel_only
|
||||||
|
def privacy_status_enable():
|
||||||
|
env.update({'PRIVACY' : 'True'})
|
||||||
|
utils.save_environment(env)
|
||||||
|
return "Ok"
|
||||||
|
|
||||||
|
@app.route('/system/privacy/disable', methods=["POST"])
|
||||||
|
@authorized_personnel_only
|
||||||
|
def privacy_status_disable():
|
||||||
|
env.update({'PRIVACY' : 'False'})
|
||||||
|
utils.save_environment(env)
|
||||||
|
return "Ok"
|
||||||
|
|
||||||
# MUNIN
|
# MUNIN
|
||||||
|
|
||||||
@app.route('/munin/')
|
@app.route('/munin/')
|
||||||
@ -432,4 +446,3 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
# Start the application server. Listens on 127.0.0.1 (IPv4 only).
|
# Start the application server. Listens on 127.0.0.1 (IPv4 only).
|
||||||
app.run(port=10222)
|
app.run(port=10222)
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ def run_checks(rounded_values, env, output, pool):
|
|||||||
# (ignore errors; if bind9/rndc isn't running we'd already report
|
# (ignore errors; if bind9/rndc isn't running we'd already report
|
||||||
# that in run_services checks.)
|
# that in run_services checks.)
|
||||||
shell('check_call', ["/usr/sbin/rndc", "flush"], trap=True)
|
shell('check_call', ["/usr/sbin/rndc", "flush"], trap=True)
|
||||||
|
|
||||||
run_system_checks(rounded_values, env, output)
|
run_system_checks(rounded_values, env, output)
|
||||||
|
|
||||||
# perform other checks asynchronously
|
# perform other checks asynchronously
|
||||||
@ -149,6 +149,7 @@ def check_service(i, service, env):
|
|||||||
def run_system_checks(rounded_values, env, output):
|
def run_system_checks(rounded_values, env, output):
|
||||||
check_ssh_password(env, output)
|
check_ssh_password(env, output)
|
||||||
check_software_updates(env, output)
|
check_software_updates(env, output)
|
||||||
|
check_miab_version(env, output)
|
||||||
check_system_aliases(env, output)
|
check_system_aliases(env, output)
|
||||||
check_free_disk_space(rounded_values, env, output)
|
check_free_disk_space(rounded_values, env, output)
|
||||||
|
|
||||||
@ -264,10 +265,10 @@ def run_domain_checks_on_domain(domain, rounded_time, env, dns_domains, dns_zone
|
|||||||
|
|
||||||
if domain == env["PRIMARY_HOSTNAME"]:
|
if domain == env["PRIMARY_HOSTNAME"]:
|
||||||
check_primary_hostname_dns(domain, env, output, dns_domains, dns_zonefiles)
|
check_primary_hostname_dns(domain, env, output, dns_domains, dns_zonefiles)
|
||||||
|
|
||||||
if domain in dns_domains:
|
if domain in dns_domains:
|
||||||
check_dns_zone(domain, env, output, dns_zonefiles)
|
check_dns_zone(domain, env, output, dns_zonefiles)
|
||||||
|
|
||||||
if domain in mail_domains:
|
if domain in mail_domains:
|
||||||
check_mail_domain(domain, env, output)
|
check_mail_domain(domain, env, output)
|
||||||
|
|
||||||
@ -644,7 +645,7 @@ def check_certificate(domain, ssl_certificate, ssl_private_key, warn_if_expiring
|
|||||||
return "*." + idna.encode(dns_name[2:]).decode('ascii')
|
return "*." + idna.encode(dns_name[2:]).decode('ascii')
|
||||||
else:
|
else:
|
||||||
return idna.encode(dns_name).decode('ascii')
|
return idna.encode(dns_name).decode('ascii')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sans = cert.extensions.get_extension_for_oid(OID_SUBJECT_ALTERNATIVE_NAME).value.get_values_for_type(DNSName)
|
sans = cert.extensions.get_extension_for_oid(OID_SUBJECT_ALTERNATIVE_NAME).value.get_values_for_type(DNSName)
|
||||||
for san in sans:
|
for san in sans:
|
||||||
@ -805,11 +806,11 @@ def list_apt_updates(apt_update=True):
|
|||||||
return pkgs
|
return pkgs
|
||||||
|
|
||||||
def what_version_is_this(env):
|
def what_version_is_this(env):
|
||||||
# This function runs `git describe` on the Mail-in-a-Box installation directory.
|
# This function runs `git describe --abbrev=0` on the Mail-in-a-Box installation directory.
|
||||||
# Git may not be installed and Mail-in-a-Box may not have been cloned from github,
|
# Git may not be installed and Mail-in-a-Box may not have been cloned from github,
|
||||||
# so this function may raise all sorts of exceptions.
|
# so this function may raise all sorts of exceptions.
|
||||||
miab_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
miab_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
tag = shell("check_output", ["/usr/bin/git", "describe"], env={"GIT_DIR": os.path.join(miab_dir, '.git')}).strip()
|
tag = shell("check_output", ["/usr/bin/git", "describe", "--abbrev=0"], env={"GIT_DIR": os.path.join(miab_dir, '.git')}).strip()
|
||||||
return tag
|
return tag
|
||||||
|
|
||||||
def get_latest_miab_version():
|
def get_latest_miab_version():
|
||||||
@ -818,6 +819,14 @@ def get_latest_miab_version():
|
|||||||
import urllib.request
|
import urllib.request
|
||||||
return re.search(b'TAG=(.*)', urllib.request.urlopen("https://mailinabox.email/bootstrap.sh?ping=1").read()).group(1).decode("utf8")
|
return re.search(b'TAG=(.*)', urllib.request.urlopen("https://mailinabox.email/bootstrap.sh?ping=1").read()).group(1).decode("utf8")
|
||||||
|
|
||||||
|
def check_miab_version(env, output):
|
||||||
|
if env['PRIVACY'] == 'True':
|
||||||
|
output.print_warning("Mail-in-a-Box version check disabled.")
|
||||||
|
elif what_version_is_this(env) != get_latest_miab_version():
|
||||||
|
output.print_error("Mail-in-a-Box is outdated. To find the latest version and for upgrade instructions, see https://mailinabox.email/. ")
|
||||||
|
else:
|
||||||
|
output.print_ok("Mail-in-a-Box is up to date. You are running version %s." % what_version_is_this(env))
|
||||||
|
|
||||||
def run_and_output_changes(env, pool, send_via_email):
|
def run_and_output_changes(env, pool, send_via_email):
|
||||||
import json
|
import json
|
||||||
from difflib import SequenceMatcher
|
from difflib import SequenceMatcher
|
||||||
@ -884,7 +893,7 @@ def run_and_output_changes(env, pool, send_via_email):
|
|||||||
if category not in cur_status:
|
if category not in cur_status:
|
||||||
out.add_heading(category)
|
out.add_heading(category)
|
||||||
out.print_warning("This section was removed.")
|
out.print_warning("This section was removed.")
|
||||||
|
|
||||||
if send_via_email:
|
if send_via_email:
|
||||||
# If there were changes, send off an email.
|
# If there were changes, send off an email.
|
||||||
buf = out.buf.getvalue()
|
buf = out.buf.getvalue()
|
||||||
@ -896,7 +905,7 @@ def run_and_output_changes(env, pool, send_via_email):
|
|||||||
msg['To'] = "administrator@%s" % env['PRIMARY_HOSTNAME']
|
msg['To'] = "administrator@%s" % env['PRIMARY_HOSTNAME']
|
||||||
msg['Subject'] = "[%s] Status Checks Change Notice" % env['PRIMARY_HOSTNAME']
|
msg['Subject'] = "[%s] Status Checks Change Notice" % env['PRIMARY_HOSTNAME']
|
||||||
msg.set_payload(buf, "UTF-8")
|
msg.set_payload(buf, "UTF-8")
|
||||||
|
|
||||||
# send to administrator@
|
# send to administrator@
|
||||||
import smtplib
|
import smtplib
|
||||||
mailserver = smtplib.SMTP('localhost', 25)
|
mailserver = smtplib.SMTP('localhost', 25)
|
||||||
@ -906,7 +915,7 @@ def run_and_output_changes(env, pool, send_via_email):
|
|||||||
"administrator@%s" % env['PRIMARY_HOSTNAME'], # RCPT TO
|
"administrator@%s" % env['PRIMARY_HOSTNAME'], # RCPT TO
|
||||||
msg.as_string())
|
msg.as_string())
|
||||||
mailserver.quit()
|
mailserver.quit()
|
||||||
|
|
||||||
# Store the current status checks output for next time.
|
# Store the current status checks output for next time.
|
||||||
os.makedirs(os.path.dirname(cache_fn), exist_ok=True)
|
os.makedirs(os.path.dirname(cache_fn), exist_ok=True)
|
||||||
with open(cache_fn, "w") as f:
|
with open(cache_fn, "w") as f:
|
||||||
|
@ -114,7 +114,6 @@
|
|||||||
</li>
|
</li>
|
||||||
<li><a href="#sync_guide" onclick="return show_panel(this);">Contacts/Calendar</a></li>
|
<li><a href="#sync_guide" onclick="return show_panel(this);">Contacts/Calendar</a></li>
|
||||||
<li><a href="#web" onclick="return show_panel(this);">Web</a></li>
|
<li><a href="#web" onclick="return show_panel(this);">Web</a></li>
|
||||||
<li><a href="#version" onclick="return show_panel(this);">Version</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="nav navbar-nav navbar-right">
|
<ul class="nav navbar-nav navbar-right">
|
||||||
<li><a href="#" onclick="do_logout(); return false;" style="color: white">Log out?</a></li>
|
<li><a href="#" onclick="do_logout(); return false;" style="color: white">Log out?</a></li>
|
||||||
@ -168,10 +167,6 @@
|
|||||||
{% include "ssl.html" %}
|
{% include "ssl.html" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="panel_version" class="admin_panel">
|
|
||||||
{% include "version.html" %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
@ -215,8 +210,8 @@ $(function() {
|
|||||||
$('#global_modal').on('shown.bs.modal', function (e) {
|
$('#global_modal').on('shown.bs.modal', function (e) {
|
||||||
// set focus to first input in the global modal's body
|
// set focus to first input in the global modal's body
|
||||||
var input = $('#global_modal .modal-body input');
|
var input = $('#global_modal .modal-body input');
|
||||||
if (input.length > 0) $(input[0]).focus();
|
if (input.length > 0) $(input[0]).focus();
|
||||||
})
|
})
|
||||||
$('#global_modal .btn-danger').click(function() {
|
$('#global_modal .btn-danger').click(function() {
|
||||||
// Don't take action now. Wait for the modal to be totally hidden
|
// Don't take action now. Wait for the modal to be totally hidden
|
||||||
// so that we don't attempt to show another modal while this one
|
// so that we don't attempt to show another modal while this one
|
||||||
@ -231,7 +226,7 @@ $(function() {
|
|||||||
if (global_modal_state == null) global_modal_state = 1; // cancel if the user hit ESC or clicked outside of the modal
|
if (global_modal_state == null) global_modal_state = 1; // cancel if the user hit ESC or clicked outside of the modal
|
||||||
if (global_modal_funcs && global_modal_funcs[global_modal_state])
|
if (global_modal_funcs && global_modal_funcs[global_modal_state])
|
||||||
global_modal_funcs[global_modal_state]();
|
global_modal_funcs[global_modal_state]();
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
function show_modal_error(title, message, callback) {
|
function show_modal_error(title, message, callback) {
|
||||||
@ -294,7 +289,7 @@ function ajax(options) {
|
|||||||
};
|
};
|
||||||
options.error = function(jqxhr) {
|
options.error = function(jqxhr) {
|
||||||
hide_loading_indicator();
|
hide_loading_indicator();
|
||||||
if (!old_error)
|
if (!old_error)
|
||||||
show_modal_error("Error", "Something went wrong, sorry.")
|
show_modal_error("Error", "Something went wrong, sorry.")
|
||||||
else
|
else
|
||||||
old_error(jqxhr.responseText, jqxhr);
|
old_error(jqxhr.responseText, jqxhr);
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<table id="system-checks" class="table" style="max-width: 60em">
|
<table id="system-checks" class="table" style="max-width: 60em">
|
||||||
<thead>
|
<thead>
|
||||||
</thead>
|
</thead>
|
||||||
@ -43,6 +42,10 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<h4>Privacy Setting</h4>
|
||||||
|
<p>By deactivating the adavanced privacy feature your Mail-in-a-Box will contact a remote server to check if a new version got released.</p>
|
||||||
|
<p>Advanced Privacy <a onclick="enable_privacy()" href="">On</a> | <a onclick="disable_privacy()" href="">Off</a></p>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function show_system_status() {
|
function show_system_status() {
|
||||||
$('#system-checks tbody').html("<tr><td colspan='2' class='text-muted'>Loading...</td></tr>")
|
$('#system-checks tbody').html("<tr><td colspan='2' class='text-muted'>Loading...</td></tr>")
|
||||||
@ -83,4 +86,16 @@ function show_system_status() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
function enable_privacy() {
|
||||||
|
api(
|
||||||
|
"/system/privacy/enable",
|
||||||
|
"Post",
|
||||||
|
{ });
|
||||||
|
}
|
||||||
|
function disable_privacy() {
|
||||||
|
api(
|
||||||
|
"/system/privacy/disable",
|
||||||
|
"Post",
|
||||||
|
{ });
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
<style>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<h2>Mail-in-a-Box Version</h2>
|
|
||||||
|
|
||||||
<p>You are running Mail-in-a-Box version <span id="miab-version" style="font-weight: bold">...</span>.</p>
|
|
||||||
|
|
||||||
<p>The latest version of Mail-in-a-Box is <button id="miab-get-latest-upstream" onclick="check_latest_version()">Check</button>.</p>
|
|
||||||
|
|
||||||
<p>To find the latest version and for upgrade instructions, see <a href="https://mailinabox.email/">https://mailinabox.email/</a>, <a href="https://github.com/mail-in-a-box/mailinabox/blob/master/CHANGELOG.md">release notes</a>, and <a href="https://mailinabox.email/maintenance.html#updating-mail-in-a-box">upgrade instructions</a>.</p>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function show_version() {
|
|
||||||
$('#miab-version').text('loading...');
|
|
||||||
api(
|
|
||||||
"/system/version",
|
|
||||||
"GET",
|
|
||||||
{
|
|
||||||
},
|
|
||||||
function(version) {
|
|
||||||
$('#miab-version').text(version);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function check_latest_version() {
|
|
||||||
$('#miab-get-latest-upstream').text('loading...');
|
|
||||||
api(
|
|
||||||
"/system/latest-upstream-version",
|
|
||||||
"POST",
|
|
||||||
{
|
|
||||||
},
|
|
||||||
function(version) {
|
|
||||||
$('#miab-get-latest-upstream').text(version);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
@ -88,6 +88,7 @@ PUBLIC_IPV6=$PUBLIC_IPV6
|
|||||||
PRIVATE_IP=$PRIVATE_IP
|
PRIVATE_IP=$PRIVATE_IP
|
||||||
PRIVATE_IPV6=$PRIVATE_IPV6
|
PRIVATE_IPV6=$PRIVATE_IPV6
|
||||||
CSR_COUNTRY=$CSR_COUNTRY
|
CSR_COUNTRY=$CSR_COUNTRY
|
||||||
|
PRIVACY=True
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Start service configuration.
|
# Start service configuration.
|
||||||
|
Loading…
Reference in New Issue
Block a user