mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2025-01-23 12:37:05 +00:00
Fixed UP031 (printf-string-formatting): Use format specifiers instead of percent format
This commit is contained in:
parent
e93009704e
commit
b1e094afe5
@ -719,7 +719,7 @@ def munin_cgi(filename):
|
||||
|
||||
query_str = request.query_string.decode("utf-8", 'ignore')
|
||||
|
||||
env = {'PATH_INFO': '/%s/' % filename, 'REQUEST_METHOD': 'GET', 'QUERY_STRING': query_str}
|
||||
env = {'PATH_INFO': '/{}/'.format(filename), 'REQUEST_METHOD': 'GET', 'QUERY_STRING': query_str}
|
||||
code, binout = utils.shell('check_output',
|
||||
COMMAND.split(" ", 5),
|
||||
# Using a maxsplit of 5 keeps the last arguments together
|
||||
|
@ -187,7 +187,7 @@ def build_zone(domain, domain_properties, additional_records, env, is_zone=True)
|
||||
# is managed outside of the box.
|
||||
if is_zone:
|
||||
# Obligatory NS record to ns1.PRIMARY_HOSTNAME.
|
||||
records.append((None, "NS", "ns1.%s." % env["PRIMARY_HOSTNAME"], False))
|
||||
records.append((None, "NS", "ns1.{}.".format(env["PRIMARY_HOSTNAME"]), False))
|
||||
|
||||
# NS record to ns2.PRIMARY_HOSTNAME or whatever the user overrides.
|
||||
# User may provide one or more additional nameservers
|
||||
@ -254,16 +254,16 @@ def build_zone(domain, domain_properties, additional_records, env, is_zone=True)
|
||||
# was set. So set has_rec_base to a clone of the current set of DNS settings, and don't update
|
||||
# during this process.
|
||||
has_rec_base = list(records)
|
||||
a_expl = "Required. May have a different value. Sets the IP address that %s resolves to for web hosting and other services besides mail. The A record must be present but its value does not affect mail delivery." % domain
|
||||
a_expl = "Required. May have a different value. Sets the IP address that {} resolves to for web hosting and other services besides mail. The A record must be present but its value does not affect mail delivery.".format(domain)
|
||||
if domain_properties[domain]["auto"]:
|
||||
if domain.startswith(("ns1.", "ns2.")): a_expl = False # omit from 'External DNS' page since this only applies if box is its own DNS server
|
||||
if domain.startswith("www."): a_expl = "Optional. Sets the IP address that %s resolves to so that the box can provide a redirect to the parent domain." % domain
|
||||
if domain.startswith("www."): a_expl = "Optional. Sets the IP address that {} resolves to so that the box can provide a redirect to the parent domain.".format(domain)
|
||||
if domain.startswith("mta-sts."): a_expl = "Optional. MTA-STS Policy Host serving /.well-known/mta-sts.txt."
|
||||
if domain.startswith("autoconfig."): a_expl = "Provides email configuration autodiscovery support for Thunderbird Autoconfig."
|
||||
if domain.startswith("autodiscover."): a_expl = "Provides email configuration autodiscovery support for Z-Push ActiveSync Autodiscover."
|
||||
defaults = [
|
||||
(None, "A", env["PUBLIC_IP"], a_expl),
|
||||
(None, "AAAA", env.get('PUBLIC_IPV6'), "Optional. Sets the IPv6 address that %s resolves to, e.g. for web hosting. (It is not necessary for receiving mail on this domain.)" % domain),
|
||||
(None, "AAAA", env.get('PUBLIC_IPV6'), "Optional. Sets the IPv6 address that {} resolves to, e.g. for web hosting. (It is not necessary for receiving mail on this domain.)".format(domain)),
|
||||
]
|
||||
for qname, rtype, value, explanation in defaults:
|
||||
if value is None or value.strip() == "": continue # skip IPV6 if not set
|
||||
@ -281,13 +281,13 @@ def build_zone(domain, domain_properties, additional_records, env, is_zone=True)
|
||||
if domain_properties[domain]["mail"]:
|
||||
# The MX record says where email for the domain should be delivered: Here!
|
||||
if not has_rec(None, "MX", prefix="10 "):
|
||||
records.append((None, "MX", "10 %s." % env["PRIMARY_HOSTNAME"], "Required. Specifies the hostname (and priority) of the machine that handles @%s mail." % domain))
|
||||
records.append((None, "MX", "10 {}.".format(env["PRIMARY_HOSTNAME"]), "Required. Specifies the hostname (and priority) of the machine that handles @{} mail.".format(domain)))
|
||||
|
||||
# SPF record: Permit the box ('mx', see above) to send mail on behalf of
|
||||
# the domain, and no one else.
|
||||
# Skip if the user has set a custom SPF record.
|
||||
if not has_rec(None, "TXT", prefix="v=spf1 "):
|
||||
records.append((None, "TXT", 'v=spf1 mx -all', "Recommended. Specifies that only the box is permitted to send @%s mail." % domain))
|
||||
records.append((None, "TXT", 'v=spf1 mx -all', "Recommended. Specifies that only the box is permitted to send @{} mail.".format(domain)))
|
||||
|
||||
# Append the DKIM TXT record to the zone as generated by OpenDKIM.
|
||||
# Skip if the user has set a DKIM record already.
|
||||
@ -296,12 +296,12 @@ def build_zone(domain, domain_properties, additional_records, env, is_zone=True)
|
||||
m = re.match(r'(\S+)\s+IN\s+TXT\s+\( ((?:"[^"]+"\s+)+)\)', orf.read(), re.S)
|
||||
val = "".join(re.findall(r'"([^"]+)"', m.group(2)))
|
||||
if not has_rec(m.group(1), "TXT", prefix="v=DKIM1; "):
|
||||
records.append((m.group(1), "TXT", val, "Recommended. Provides a way for recipients to verify that this machine sent @%s mail." % domain))
|
||||
records.append((m.group(1), "TXT", val, "Recommended. Provides a way for recipients to verify that this machine sent @{} mail.".format(domain)))
|
||||
|
||||
# Append a DMARC record.
|
||||
# Skip if the user has set a DMARC record already.
|
||||
if not has_rec("_dmarc", "TXT", prefix="v=DMARC1; "):
|
||||
records.append(("_dmarc", "TXT", 'v=DMARC1; p=quarantine;', "Recommended. Specifies that mail that does not originate from the box but claims to be from @%s or which does not have a valid DKIM signature is suspect and should be quarantined by the recipient's mail system." % domain))
|
||||
records.append(("_dmarc", "TXT", 'v=DMARC1; p=quarantine;', "Recommended. Specifies that mail that does not originate from the box but claims to be from @{} or which does not have a valid DKIM signature is suspect and should be quarantined by the recipient's mail system.".format(domain)))
|
||||
|
||||
if domain_properties[domain]["user"]:
|
||||
# Add CardDAV/CalDAV SRV records on the non-primary hostname that points to the primary hostname
|
||||
@ -364,9 +364,9 @@ def build_zone(domain, domain_properties, additional_records, env, is_zone=True)
|
||||
# Mark this domain as not sending mail with hard-fail SPF and DMARC records.
|
||||
d = (qname+"." if qname else "") + domain
|
||||
if not has_rec(qname, "TXT", prefix="v=spf1 "):
|
||||
records.append((qname, "TXT", 'v=spf1 -all', "Recommended. Prevents use of this domain name for outbound mail by specifying that no servers are valid sources for mail from @%s. If you do send email from this domain name you should either override this record such that the SPF rule does allow the originating server, or, take the recommended approach and have the box handle mail for this domain (simply add any receiving alias at this domain name to make this machine treat the domain name as one of its mail domains)." % d))
|
||||
records.append((qname, "TXT", 'v=spf1 -all', "Recommended. Prevents use of this domain name for outbound mail by specifying that no servers are valid sources for mail from @{}. If you do send email from this domain name you should either override this record such that the SPF rule does allow the originating server, or, take the recommended approach and have the box handle mail for this domain (simply add any receiving alias at this domain name to make this machine treat the domain name as one of its mail domains).".format(d)))
|
||||
if not has_rec("_dmarc" + ("."+qname if qname else ""), "TXT", prefix="v=DMARC1; "):
|
||||
records.append(("_dmarc" + ("."+qname if qname else ""), "TXT", 'v=DMARC1; p=reject;', "Recommended. Prevents use of this domain name for outbound mail by specifying that the SPF rule should be honoured for mail from @%s." % d))
|
||||
records.append(("_dmarc" + ("."+qname if qname else ""), "TXT", 'v=DMARC1; p=reject;', "Recommended. Prevents use of this domain name for outbound mail by specifying that the SPF rule should be honoured for mail from @{}.".format(d)))
|
||||
|
||||
# And with a null MX record (https://explained-from-first-principles.com/email/#null-mx-record)
|
||||
if not has_rec(qname, "MX"):
|
||||
@ -592,7 +592,7 @@ def get_dns_zonefile(zone, env):
|
||||
if zone == domain:
|
||||
break
|
||||
else:
|
||||
raise ValueError("%s is not a domain name that corresponds to a zone." % zone)
|
||||
raise ValueError("{} is not a domain name that corresponds to a zone.".format(zone))
|
||||
|
||||
nsd_zonefile = "/etc/nsd/zones/" + fn
|
||||
with open(nsd_zonefile, encoding="utf-8") as f:
|
||||
@ -617,8 +617,8 @@ zone:
|
||||
# and, if not a subnet, notifies to them.
|
||||
for ipaddr in get_secondary_dns(additional_records, mode="xfr"):
|
||||
if "/" not in ipaddr:
|
||||
nsdconf += "\n\tnotify: %s NOKEY" % (ipaddr)
|
||||
nsdconf += "\n\tprovide-xfr: %s NOKEY\n" % (ipaddr)
|
||||
nsdconf += "\n\tnotify: {} NOKEY".format(ipaddr)
|
||||
nsdconf += "\n\tprovide-xfr: {} NOKEY\n".format(ipaddr)
|
||||
|
||||
# Check if the file is changing. If it isn't changing,
|
||||
# return False to flag that no change was made.
|
||||
@ -898,7 +898,7 @@ def set_custom_dns_record(qname, rtype, value, action, env):
|
||||
else:
|
||||
# No match.
|
||||
if qname != "_secondary_nameserver":
|
||||
raise ValueError("%s is not a domain name or a subdomain of a domain name managed by this box." % qname)
|
||||
raise ValueError("{} is not a domain name or a subdomain of a domain name managed by this box.".format(qname))
|
||||
|
||||
# validate rtype
|
||||
rtype = rtype.upper()
|
||||
@ -928,7 +928,7 @@ def set_custom_dns_record(qname, rtype, value, action, env):
|
||||
# anything goes
|
||||
pass
|
||||
else:
|
||||
raise ValueError("Unknown record type '%s'." % rtype)
|
||||
raise ValueError("Unknown record type '{}'.".format(rtype))
|
||||
|
||||
# load existing config
|
||||
config = list(get_custom_dns_config(env))
|
||||
@ -1039,7 +1039,7 @@ def set_secondary_dns(hostnames, env):
|
||||
try:
|
||||
resolver.resolve(item, "AAAA")
|
||||
except (dns.resolver.NoNameservers, dns.resolver.NXDOMAIN, dns.resolver.NoAnswer, dns.resolver.Timeout):
|
||||
raise ValueError("Could not resolve the IP address of %s." % item)
|
||||
raise ValueError("Could not resolve the IP address of {}.".format(item))
|
||||
else:
|
||||
# Validate IP address.
|
||||
try:
|
||||
@ -1048,7 +1048,7 @@ def set_secondary_dns(hostnames, env):
|
||||
else:
|
||||
ipaddress.ip_address(item[4:]) # raises a ValueError if there's a problem
|
||||
except ValueError:
|
||||
raise ValueError("'%s' is not an IPv4 or IPv6 address or subnet." % item[4:])
|
||||
raise ValueError("'{}' is not an IPv4 or IPv6 address or subnet.".format(item[4:]))
|
||||
|
||||
# Set.
|
||||
set_custom_dns_record("_secondary_nameserver", "A", " ".join(hostnames), "set", env)
|
||||
|
@ -302,7 +302,7 @@ def scan_mail_log(env):
|
||||
for date, sender, message in user_data["blocked"]:
|
||||
if len(sender) > 64:
|
||||
sender = sender[:32] + "…" + sender[-32:]
|
||||
user_rejects.extend((f'{date} - {sender} ', ' %s' % message))
|
||||
user_rejects.extend((f'{date} - {sender} ', ' {}'.format(message)))
|
||||
rejects.append(user_rejects)
|
||||
|
||||
print_user_table(
|
||||
@ -608,7 +608,7 @@ def valid_date(string):
|
||||
try:
|
||||
date = dateutil.parser.parse(string)
|
||||
except ValueError:
|
||||
raise argparse.ArgumentTypeError("Unrecognized date and/or time '%s'" % string)
|
||||
raise argparse.ArgumentTypeError("Unrecognized date and/or time '{}'".format(string))
|
||||
return date
|
||||
|
||||
|
||||
@ -670,7 +670,7 @@ def print_user_table(users, data=None, sub_data=None, activity=None, latest=None
|
||||
col_str = f"{d[row]!s:<20}"
|
||||
col_left[col] = True
|
||||
else:
|
||||
temp = "{:>%s}" % max(5, len(l) + 1, len(str(d[row])) + 1)
|
||||
temp = "{{:>{}}}".format(max(5, len(l) + 1, len(str(d[row])) + 1))
|
||||
col_str = temp.format(str(d[row]))
|
||||
col_widths[col] = max(col_widths[col], len(col_str))
|
||||
line += col_str
|
||||
@ -707,10 +707,10 @@ def print_user_table(users, data=None, sub_data=None, activity=None, latest=None
|
||||
if sub_data is not None:
|
||||
for l, d in sub_data:
|
||||
if d[row]:
|
||||
lines.extend(('┬', '│ %s' % l, '├─%s─' % (len(l) * '─'), '│'))
|
||||
lines.extend(('┬', '│ {}'.format(l), '├─%s─' % (len(l) * '─'), '│'))
|
||||
max_len = 0
|
||||
for v in list(d[row]):
|
||||
lines.append("│ %s" % v)
|
||||
lines.append("│ {}".format(v))
|
||||
max_len = max(max_len, len(v))
|
||||
lines.append("└" + (max_len + 1) * "─")
|
||||
|
||||
|
@ -322,7 +322,7 @@ def set_mail_password(email, pw, env):
|
||||
conn, c = open_database(env, with_connection=True)
|
||||
c.execute("UPDATE users SET password=? WHERE email=?", (pw, email))
|
||||
if c.rowcount != 1:
|
||||
return ("That's not a user (%s)." % email, 400)
|
||||
return ("That's not a user ({}).".format(email), 400)
|
||||
conn.commit()
|
||||
return "OK"
|
||||
|
||||
@ -341,7 +341,7 @@ def get_mail_password(email, env):
|
||||
c.execute('SELECT password FROM users WHERE email=?', (email,))
|
||||
rows = c.fetchall()
|
||||
if len(rows) != 1:
|
||||
raise ValueError("That's not a user (%s)." % email)
|
||||
raise ValueError("That's not a user ({}).".format(email))
|
||||
return rows[0][0]
|
||||
|
||||
def remove_mail_user(email, env):
|
||||
@ -349,7 +349,7 @@ def remove_mail_user(email, env):
|
||||
conn, c = open_database(env, with_connection=True)
|
||||
c.execute("DELETE FROM users WHERE email=?", (email,))
|
||||
if c.rowcount != 1:
|
||||
return ("That's not a user (%s)." % email, 400)
|
||||
return ("That's not a user ({}).".format(email), 400)
|
||||
conn.commit()
|
||||
|
||||
# Update things in case any domains are removed.
|
||||
@ -365,12 +365,12 @@ def get_mail_user_privileges(email, env, empty_on_error=False):
|
||||
rows = c.fetchall()
|
||||
if len(rows) != 1:
|
||||
if empty_on_error: return []
|
||||
return ("That's not a user (%s)." % email, 400)
|
||||
return ("That's not a user ({}).".format(email), 400)
|
||||
return parse_privs(rows[0][0])
|
||||
|
||||
def validate_privilege(priv):
|
||||
if "\n" in priv or priv.strip() == "":
|
||||
return ("That's not a valid privilege (%s)." % priv, 400)
|
||||
return ("That's not a valid privilege ({}).".format(priv), 400)
|
||||
return None
|
||||
|
||||
def add_remove_mail_user_privilege(email, priv, action, env):
|
||||
@ -413,7 +413,7 @@ def add_mail_alias(address, forwards_to, permitted_senders, env, update_if_exist
|
||||
if address == "":
|
||||
return ("No email address provided.", 400)
|
||||
if not validate_email(address, mode='alias'):
|
||||
return ("Invalid email address (%s)." % address, 400)
|
||||
return ("Invalid email address ({}).".format(address), 400)
|
||||
|
||||
# validate forwards_to
|
||||
validated_forwards_to = []
|
||||
@ -442,7 +442,7 @@ def add_mail_alias(address, forwards_to, permitted_senders, env, update_if_exist
|
||||
# Strip any +tag from email alias and check privileges
|
||||
privileged_email = re.sub(r"(?=\+)[^@]*(?=@)",'',email)
|
||||
if not validate_email(email):
|
||||
return ("Invalid receiver email address (%s)." % email, 400)
|
||||
return ("Invalid receiver email address ({}).".format(email), 400)
|
||||
if is_dcv_source and not is_dcv_address(email) and "admin" not in get_mail_user_privileges(privileged_email, env, empty_on_error=True):
|
||||
# Make domain control validation hijacking a little harder to mess up by
|
||||
# requiring aliases for email addresses typically used in DCV to forward
|
||||
@ -462,7 +462,7 @@ def add_mail_alias(address, forwards_to, permitted_senders, env, update_if_exist
|
||||
login = login.strip()
|
||||
if login == "": continue
|
||||
if login not in valid_logins:
|
||||
return ("Invalid permitted sender: %s is not a user on this system." % login, 400)
|
||||
return ("Invalid permitted sender: {} is not a user on this system.".format(login), 400)
|
||||
validated_permitted_senders.append(login)
|
||||
|
||||
# Make sure the alias has either a forwards_to or a permitted_sender.
|
||||
@ -481,7 +481,7 @@ def add_mail_alias(address, forwards_to, permitted_senders, env, update_if_exist
|
||||
return_status = "alias added"
|
||||
except sqlite3.IntegrityError:
|
||||
if not update_if_exists:
|
||||
return ("Alias already exists (%s)." % address, 400)
|
||||
return ("Alias already exists ({}).".format(address), 400)
|
||||
else:
|
||||
c.execute("UPDATE aliases SET destination = ?, permitted_senders = ? WHERE source = ?", (forwards_to, permitted_senders, address))
|
||||
return_status = "alias updated"
|
||||
@ -501,7 +501,7 @@ def remove_mail_alias(address, env, do_kick=True):
|
||||
conn, c = open_database(env, with_connection=True)
|
||||
c.execute("DELETE FROM aliases WHERE source=?", (address,))
|
||||
if c.rowcount != 1:
|
||||
return ("That's not an alias (%s)." % address, 400)
|
||||
return ("That's not an alias ({}).".format(address), 400)
|
||||
conn.commit()
|
||||
|
||||
if do_kick:
|
||||
|
@ -518,7 +518,7 @@ def check_certificate(domain, ssl_certificate, ssl_private_key, warn_if_expiring
|
||||
cert = load_pem(ssl_cert_chain[0])
|
||||
if not isinstance(cert, Certificate): raise ValueError("This is not a certificate file.")
|
||||
except ValueError as e:
|
||||
return ("There is a problem with the certificate file: %s" % str(e), None)
|
||||
return ("There is a problem with the certificate file: {}".format(str(e)), None)
|
||||
|
||||
# First check that the domain name is one of the names allowed by
|
||||
# the certificate.
|
||||
@ -530,8 +530,7 @@ def check_certificate(domain, ssl_certificate, ssl_private_key, warn_if_expiring
|
||||
# should work in normal cases).
|
||||
wildcard_domain = re.sub(r"^[^\.]+", "*", domain)
|
||||
if domain not in certificate_names and wildcard_domain not in certificate_names:
|
||||
return ("The certificate is for the wrong domain name. It is for %s."
|
||||
% ", ".join(sorted(certificate_names)), None)
|
||||
return ("The certificate is for the wrong domain name. It is for {}.".format(", ".join(sorted(certificate_names))), None)
|
||||
|
||||
# Second, check that the certificate matches the private key.
|
||||
if ssl_private_key is not None:
|
||||
@ -544,10 +543,10 @@ def check_certificate(domain, ssl_certificate, ssl_private_key, warn_if_expiring
|
||||
if (not isinstance(priv_key, rsa.RSAPrivateKey)
|
||||
and not isinstance(priv_key, dsa.DSAPrivateKey)
|
||||
and not isinstance(priv_key, ec.EllipticCurvePrivateKey)):
|
||||
return ("The private key file %s is not a private key file." % ssl_private_key, None)
|
||||
return ("The private key file {} is not a private key file.".format(ssl_private_key), None)
|
||||
|
||||
if priv_key.public_key().public_numbers() != cert.public_key().public_numbers():
|
||||
return ("The certificate does not correspond to the private key at %s." % ssl_private_key, None)
|
||||
return ("The certificate does not correspond to the private key at {}.".format(ssl_private_key), None)
|
||||
|
||||
# We could also use the openssl command line tool to get the modulus
|
||||
# listed in each file. The output of each command below looks like "Modulus=XXXXX".
|
||||
@ -593,7 +592,7 @@ def check_certificate(domain, ssl_certificate, ssl_private_key, warn_if_expiring
|
||||
|
||||
elif retcode != 0:
|
||||
if "unable to get local issuer certificate" in verifyoutput:
|
||||
return ("The certificate is missing an intermediate chain or the intermediate chain is incorrect or incomplete. (%s)" % verifyoutput, None)
|
||||
return ("The certificate is missing an intermediate chain or the intermediate chain is incorrect or incomplete. ({})".format(verifyoutput), None)
|
||||
|
||||
# There is some unknown problem. Return the `openssl verify` raw output.
|
||||
return ("There is a problem with the certificate.", verifyoutput.strip())
|
||||
@ -610,7 +609,7 @@ def check_certificate(domain, ssl_certificate, ssl_private_key, warn_if_expiring
|
||||
expiry_info = "The certificate expires in %d days on %s." % (ndays, cert_expiration_date.date().isoformat())
|
||||
else:
|
||||
# We'll renew it with Lets Encrypt.
|
||||
expiry_info = "The certificate expires on %s." % cert_expiration_date.date().isoformat()
|
||||
expiry_info = "The certificate expires on {}.".format(cert_expiration_date.date().isoformat())
|
||||
|
||||
if warn_if_expiring_soon and ndays <= warn_if_expiring_soon:
|
||||
# Warn on day 10 to give 4 days for us to automatically renew the
|
||||
|
@ -248,7 +248,7 @@ def check_free_disk_space(rounded_values, env, output):
|
||||
def check_free_memory(rounded_values, env, output):
|
||||
# Check free memory.
|
||||
percent_free = 100 - psutil.virtual_memory().percent
|
||||
memory_msg = "System memory is %s%% free." % str(round(percent_free))
|
||||
memory_msg = "System memory is {}% free.".format(str(round(percent_free)))
|
||||
if percent_free >= 20:
|
||||
if rounded_values: memory_msg = "System free memory is at least 20%."
|
||||
output.print_ok(memory_msg)
|
||||
@ -478,7 +478,7 @@ def check_primary_hostname_dns(domain, env, output, dns_domains, dns_zonefiles):
|
||||
tlsa25 = query_dns(tlsa_qname, "TLSA", nxdomain=None)
|
||||
tlsa25_expected = build_tlsa_record(env)
|
||||
if tlsa25 == tlsa25_expected:
|
||||
output.print_ok("""The DANE TLSA record for incoming mail is correct (%s).""" % tlsa_qname,)
|
||||
output.print_ok("""The DANE TLSA record for incoming mail is correct ({}).""".format(tlsa_qname),)
|
||||
elif tlsa25 is None:
|
||||
if has_dnssec:
|
||||
# Omit a warning about it not being set if DNSSEC isn't enabled,
|
||||
@ -497,9 +497,9 @@ def check_alias_exists(alias_name, alias, env, output):
|
||||
if mail_aliases[alias]:
|
||||
output.print_ok(f"{alias_name} exists as a mail alias. [{alias} ↦ {mail_aliases[alias]}]")
|
||||
else:
|
||||
output.print_error("""You must set the destination of the mail alias for %s to direct email to you or another administrator.""" % alias)
|
||||
output.print_error("""You must set the destination of the mail alias for {} to direct email to you or another administrator.""".format(alias))
|
||||
else:
|
||||
output.print_error("""You must add a mail alias for %s which directs email to you or another administrator.""" % alias)
|
||||
output.print_error("""You must add a mail alias for {} which directs email to you or another administrator.""".format(alias))
|
||||
|
||||
def check_dns_zone(domain, env, output, dns_zonefiles):
|
||||
# If a DS record is set at the registrar, check DNSSEC first because it will affect the NS query.
|
||||
@ -527,7 +527,7 @@ def check_dns_zone(domain, env, output, dns_zonefiles):
|
||||
probably_external_dns = False
|
||||
|
||||
if existing_ns.lower() == correct_ns.lower():
|
||||
output.print_ok("Nameservers are set correctly at registrar. [%s]" % correct_ns)
|
||||
output.print_ok("Nameservers are set correctly at registrar. [{}]".format(correct_ns))
|
||||
elif ip == correct_ip:
|
||||
# The domain resolves correctly, so maybe the user is using External DNS.
|
||||
output.print_warning(f"""The nameservers set on this domain at your domain name registrar should be {correct_ns}. They are currently {existing_ns}.
|
||||
@ -546,7 +546,7 @@ def check_dns_zone(domain, env, output, dns_zonefiles):
|
||||
# We must first resolve the nameserver to an IP address so we can query it.
|
||||
ns_ips = query_dns(ns, "A")
|
||||
if not ns_ips or ns_ips in {'[Not Set]', '[timeout]'}:
|
||||
output.print_error("Secondary nameserver %s is not valid (it doesn't resolve to an IP address)." % ns)
|
||||
output.print_error("Secondary nameserver {} is not valid (it doesn't resolve to an IP address).".format(ns))
|
||||
continue
|
||||
# Choose the first IP if nameserver returns multiple
|
||||
ns_ip = ns_ips.split('; ')[0]
|
||||
@ -587,7 +587,7 @@ def check_dns_zone_suggestions(domain, env, output, dns_zonefiles, domains_with_
|
||||
if domain in domains_with_a_records:
|
||||
output.print_warning("""Web has been disabled for this domain because you have set a custom DNS record.""")
|
||||
if "www." + domain in domains_with_a_records:
|
||||
output.print_warning("""A redirect from 'www.%s' has been disabled for this domain because you have set a custom DNS record on the www subdomain.""" % domain)
|
||||
output.print_warning("""A redirect from 'www.{}' has been disabled for this domain because you have set a custom DNS record on the www subdomain.""".format(domain))
|
||||
|
||||
# Since DNSSEC is optional, if a DS record is NOT set at the registrar suggest it.
|
||||
# (If it was set, we did the check earlier.)
|
||||
@ -616,7 +616,7 @@ def check_dnssec(domain, env, output, dns_zonefiles, is_checking_primary=False):
|
||||
# Some registrars may want the public key so they can compute the digest. The DS
|
||||
# record that we suggest using is for the KSK (and that's how the DS records were generated).
|
||||
# We'll also give the nice name for the key algorithm.
|
||||
dnssec_keys = load_env_vars_from_file(os.path.join(env['STORAGE_ROOT'], 'dns/dnssec/%s.conf' % alg_name_map[ds_alg]))
|
||||
dnssec_keys = load_env_vars_from_file(os.path.join(env['STORAGE_ROOT'], 'dns/dnssec/{}.conf'.format(alg_name_map[ds_alg])))
|
||||
with open(os.path.join(env['STORAGE_ROOT'], 'dns/dnssec/' + dnssec_keys['KSK'] + '.key'), encoding="utf-8") as f:
|
||||
dnsssec_pubkey = f.read().split("\t")[3].split(" ")[3]
|
||||
|
||||
@ -662,7 +662,7 @@ def check_dnssec(domain, env, output, dns_zonefiles, is_checking_primary=False):
|
||||
for this domain is valid.""")
|
||||
else:
|
||||
if is_checking_primary:
|
||||
output.print_error("""The DNSSEC 'DS' record for %s is incorrect. See further details below.""" % domain)
|
||||
output.print_error("""The DNSSEC 'DS' record for {} is incorrect. See further details below.""".format(domain))
|
||||
return
|
||||
output.print_error("""This domain's DNSSEC DS record is incorrect. The chain of trust is broken between the public DNS system
|
||||
and this machine's DNS server. It may take several hours for public DNS to update after a change. If you did not recently
|
||||
@ -774,7 +774,7 @@ def check_mail_domain(domain, env, output):
|
||||
elif dbl == "[Not Set]":
|
||||
output.print_warning(f"Could not connect to dbl.spamhaus.org. Could not determine whether the domain {domain} is blacklisted. Please try again later.")
|
||||
elif dbl == "127.255.255.252":
|
||||
output.print_warning("Incorrect spamhaus query: %s. Could not determine whether the domain %s is blacklisted." % (domain+'.dbl.spamhaus.org', domain))
|
||||
output.print_warning("Incorrect spamhaus query: {}. Could not determine whether the domain {} is blacklisted.".format(domain+'.dbl.spamhaus.org', domain))
|
||||
elif dbl == "127.255.255.254":
|
||||
output.print_warning("Mail-in-a-Box is configured to use a public DNS server. This is not supported by spamhaus. Could not determine whether the domain {} is blacklisted.".format(domain))
|
||||
elif dbl == "127.255.255.255":
|
||||
@ -960,14 +960,14 @@ def check_miab_version(env, output):
|
||||
this_ver = "Unknown"
|
||||
|
||||
if config.get("privacy", True):
|
||||
output.print_warning("You are running version Mail-in-a-Box %s. Mail-in-a-Box version check disabled by privacy setting." % this_ver)
|
||||
output.print_warning("You are running version Mail-in-a-Box {}. Mail-in-a-Box version check disabled by privacy setting.".format(this_ver))
|
||||
else:
|
||||
latest_ver = get_latest_miab_version()
|
||||
|
||||
if this_ver == latest_ver:
|
||||
output.print_ok("Mail-in-a-Box is up to date. You are running version %s." % this_ver)
|
||||
output.print_ok("Mail-in-a-Box is up to date. You are running version {}.".format(this_ver))
|
||||
elif latest_ver is None:
|
||||
output.print_error("Latest Mail-in-a-Box version could not be determined. You are running version %s." % this_ver)
|
||||
output.print_error("Latest Mail-in-a-Box version could not be determined. You are running version {}.".format(this_ver))
|
||||
else:
|
||||
output.print_error(f"A new version of Mail-in-a-Box is available. You are running version {this_ver}. The latest version is {latest_ver}. For upgrade instructions, see https://mailinabox.email. ")
|
||||
|
||||
|
@ -180,8 +180,8 @@ def make_domain_config(domain, templates, ssl_certificates, env):
|
||||
web_sockets = True
|
||||
url = re.sub("#(.*)$", "", url)
|
||||
|
||||
nginx_conf_extra += "\tlocation %s {" % path
|
||||
nginx_conf_extra += "\n\t\tproxy_pass %s;" % url
|
||||
nginx_conf_extra += "\tlocation {} {{".format(path)
|
||||
nginx_conf_extra += "\n\t\tproxy_pass {};".format(url)
|
||||
if proxy_redirect_off:
|
||||
nginx_conf_extra += "\n\t\tproxy_redirect off;"
|
||||
if pass_http_host_header:
|
||||
@ -198,8 +198,8 @@ def make_domain_config(domain, templates, ssl_certificates, env):
|
||||
nginx_conf_extra += "\n\t\tproxy_set_header X-Real-IP $remote_addr;"
|
||||
nginx_conf_extra += "\n\t}\n"
|
||||
for path, alias in yaml.get("aliases", {}).items():
|
||||
nginx_conf_extra += "\tlocation %s {" % path
|
||||
nginx_conf_extra += "\n\t\talias %s;" % alias
|
||||
nginx_conf_extra += "\tlocation {} {{".format(path)
|
||||
nginx_conf_extra += "\n\t\talias {};".format(alias)
|
||||
nginx_conf_extra += "\n\t}\n"
|
||||
for path, url in yaml.get("redirects", {}).items():
|
||||
nginx_conf_extra += f"\trewrite {path} {url} permanent;\n"
|
||||
@ -216,7 +216,7 @@ def make_domain_config(domain, templates, ssl_certificates, env):
|
||||
# Add in any user customizations in the includes/ folder.
|
||||
nginx_conf_custom_include = os.path.join(env["STORAGE_ROOT"], "www", safe_domain_name(domain) + ".conf")
|
||||
if os.path.exists(nginx_conf_custom_include):
|
||||
nginx_conf_extra += "\tinclude %s;\n" % (nginx_conf_custom_include)
|
||||
nginx_conf_extra += "\tinclude {};\n".format(nginx_conf_custom_include)
|
||||
# PUT IT ALL TOGETHER
|
||||
|
||||
# Combine the pieces. Iteratively place each template into the "# ADDITIONAL DIRECTIVES HERE" placeholder
|
||||
|
@ -164,7 +164,7 @@ def migration_12(env):
|
||||
try:
|
||||
table = table[0]
|
||||
c = conn.cursor()
|
||||
dropcmd = "DROP TABLE %s" % table
|
||||
dropcmd = "DROP TABLE {}".format(table)
|
||||
c.execute(dropcmd)
|
||||
except:
|
||||
print("Failed to drop table", table)
|
||||
|
@ -142,7 +142,7 @@ def http_test(url, expected_status, postdata=None, qsargs=None, auth=None):
|
||||
# return response status code
|
||||
if r.status_code != expected_status:
|
||||
r.raise_for_status() # anything but 200
|
||||
raise OSError("Got unexpected status code %s." % r.status_code)
|
||||
raise OSError("Got unexpected status code {}.".format(r.status_code))
|
||||
|
||||
# define how to run a test
|
||||
|
||||
|
@ -51,7 +51,7 @@ def test2(tests, server, description):
|
||||
response = dns.resolver.resolve(qname, rtype)
|
||||
except dns.resolver.NoNameservers:
|
||||
# host did not have an answer for this query
|
||||
print("Could not connect to %s for DNS query." % server)
|
||||
print("Could not connect to {} for DNS query.".format(server))
|
||||
sys.exit(1)
|
||||
except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
|
||||
# host did not have an answer for this query; not sure what the
|
||||
@ -79,7 +79,7 @@ def test2(tests, server, description):
|
||||
# Test the response from the machine itself.
|
||||
if not test(ipaddr, "Mail-in-a-Box"):
|
||||
print ()
|
||||
print ("Please run the Mail-in-a-Box setup script on %s again." % hostname)
|
||||
print ("Please run the Mail-in-a-Box setup script on {} again.".format(hostname))
|
||||
sys.exit(1)
|
||||
else:
|
||||
print ("The Mail-in-a-Box provided correct DNS answers.")
|
||||
@ -89,7 +89,7 @@ else:
|
||||
# to see if the machine is hooked up to recursive DNS properly.
|
||||
if not test("8.8.8.8", "Google Public DNS"):
|
||||
print ()
|
||||
print ("Check that the nameserver settings for %s are correct at your domain registrar. It may take a few hours for Google Public DNS to update after changes on your Mail-in-a-Box." % hostname)
|
||||
print ("Check that the nameserver settings for {} are correct at your domain registrar. It may take a few hours for Google Public DNS to update after changes on your Mail-in-a-Box.".format(hostname))
|
||||
sys.exit(1)
|
||||
else:
|
||||
print ("Your domain registrar or DNS host appears to be configured correctly as well. Public DNS provides the same answers.")
|
||||
|
@ -46,7 +46,7 @@ reverse_ip = dns.reversename.from_address(ipaddr) # e.g. "1.0.0.127.in-addr.arpa
|
||||
try:
|
||||
reverse_dns = dns.resolver.resolve(reverse_ip, 'PTR')[0].target.to_text(omit_final_dot=True) # => hostname
|
||||
except dns.resolver.NXDOMAIN:
|
||||
print("Reverse DNS lookup failed for %s. SMTP EHLO name check skipped." % ipaddr)
|
||||
print("Reverse DNS lookup failed for {}. SMTP EHLO name check skipped.".format(ipaddr))
|
||||
reverse_dns = None
|
||||
if reverse_dns is not None:
|
||||
server.ehlo_or_helo_if_needed() # must send EHLO before getting the server's EHLO name
|
||||
@ -54,7 +54,7 @@ if reverse_dns is not None:
|
||||
if helo_name != reverse_dns:
|
||||
print("The server's EHLO name does not match its reverse hostname. Check DNS settings.")
|
||||
else:
|
||||
print("SMTP EHLO name (%s) is OK." % helo_name)
|
||||
print("SMTP EHLO name ({}) is OK.".format(helo_name))
|
||||
|
||||
# Login and send a test email.
|
||||
server.login(emailaddress, pw)
|
||||
|
@ -192,8 +192,7 @@ class CatEOF(Grammar):
|
||||
def value(self):
|
||||
content = self[9].string
|
||||
content = re.sub(r"\\([$])", r"\1", content) # un-escape bash-escaped characters
|
||||
return "<div class='write-to'><div class='filename'>%s <span>(%s)</span></div><pre>%s</pre></div>\n" \
|
||||
% (self[4].string,
|
||||
return "<div class='write-to'><div class='filename'>{} <span>({})</span></div><pre>{}</pre></div>\n".format(self[4].string,
|
||||
"overwrite" if ">>" not in self[2].string else "append to",
|
||||
cgi.escape(content))
|
||||
|
||||
@ -230,7 +229,7 @@ class EditConf(Grammar):
|
||||
for opt in re.split("\s+", self[4].string):
|
||||
k, v = opt.split("=", 1)
|
||||
v = re.sub(r"\n+", "", fixup_tokens(v)) # not sure why newlines are getting doubled
|
||||
options.append("%s%s%s" % (k, eq, v))
|
||||
options.append("{}{}{}".format(k, eq, v))
|
||||
return "<div class='write-to'><div class='filename'>" + self[1].string + " <span>(change settings)</span></div><pre>" + "\n".join(cgi.escape(s) for s in options) + "</pre></div>\n"
|
||||
|
||||
class CaptureOutput(Grammar):
|
||||
@ -248,7 +247,7 @@ class SedReplace(Grammar):
|
||||
class EchoPipe(Grammar):
|
||||
grammar = OPTIONAL(SPACE), L("echo "), REST_OF_LINE, L(' | '), REST_OF_LINE, EOL
|
||||
def value(self):
|
||||
text = " ".join("\"%s\"" % s for s in self[2].string.split(" "))
|
||||
text = " ".join("\"{}\"".format(s) for s in self[2].string.split(" "))
|
||||
return "<pre class='shell'><div>echo " + recode_bash(text) + " \<br> | " + recode_bash(self[4].string) + "</div></pre>\n"
|
||||
|
||||
def shell_line(bash):
|
||||
@ -414,8 +413,7 @@ class BashScript(Grammar):
|
||||
parser = BashScript.parser()
|
||||
result = parser.parse_string(string)
|
||||
|
||||
v = "<div class='row'><div class='col-xs-12 sourcefile'>view the bash source for the following section at <a href=\"%s\">%s</a></div></div>\n" \
|
||||
% ("https://github.com/mail-in-a-box/mailinabox/tree/master/" + fn, fn)
|
||||
v = "<div class='row'><div class='col-xs-12 sourcefile'>view the bash source for the following section at <a href=\"{}\">{}</a></div></div>\n".format("https://github.com/mail-in-a-box/mailinabox/tree/master/" + fn, fn)
|
||||
|
||||
mode = 0
|
||||
for item in result.value():
|
||||
@ -429,7 +427,7 @@ class BashScript(Grammar):
|
||||
mode = 0
|
||||
clz = "contd"
|
||||
if mode == 0:
|
||||
v += "<div class='row %s'>\n" % clz
|
||||
v += "<div class='row {}'>\n".format(clz)
|
||||
v += "<div class='col-md-6 prose'>\n"
|
||||
v += item
|
||||
mode = 1
|
||||
|
Loading…
Reference in New Issue
Block a user