Update to V5.5

This commit is contained in:
Red Queen
2023-10-31 11:00:41 +01:00
parent 42749bedc4
commit ffdbde06bc
12 changed files with 41 additions and 26 deletions

View File

@@ -1,2 +1,2 @@
* Zhang Huangbin <zhb@iredmail.org> * Zhang Huangbin <zhb@iredmail.org>
* Harold Finch <finch-harry@icloud.com> * Red-Queen <finch-harry@icloud.com>

View File

@@ -1,3 +1,14 @@
# 5.5
* Improvements:
- New setting `NO_PROXY`, used to specify hosts which shouldn't be reached
via proxy (the `HTTP_PROXY` setting).
* Fixed issues:
- Not remove relevant records from `moderators` table while removing
mailing list.
- Used quota is always empty if email address contains upper cases.
- Can not close modal window.
# 5.4 # 5.4
* RESTful API: * RESTful API:
+ `GET /api/users/<domain>`: Export used quota info. + `GET /api/users/<domain>`: Export used quota info.

Binary file not shown.

View File

@@ -6,11 +6,11 @@ msgstr ""
"Last-Translator: Zhang Huangbin\n" "Last-Translator: Zhang Huangbin\n"
"Language: zh_Hans_CN\n" "Language: zh_Hans_CN\n"
"Language-Team: Simplified Chinese\n" "Language-Team: Simplified Chinese\n"
"Plural-Forms: nplurals=1; plural=0\n" "Plural-Forms: nplurals=1; plural=0;\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.3.4\n" "Generated-By: Babel 2.11.0\n"
#, python-format #, python-format
msgid "%d admin(s) found." msgid "%d admin(s) found."
@@ -690,10 +690,10 @@ msgid "Display Name"
msgstr "显示名称" msgstr "显示名称"
msgid "Do not apply greylisting on emails sent from domains listed below" msgid "Do not apply greylisting on emails sent from domains listed below"
msgstr "对选中的帐号启用灰名单" msgstr "对下列域名发来的邮件不启用灰名单"
msgid "Do not apply greylisting on listed senders" msgid "Do not apply greylisting on listed senders"
msgstr "对选中的帐号启用灰名单" msgstr "对下列发件人不启用灰名单"
msgid "Do not archive received emails" msgid "Do not archive received emails"
msgstr "对收到的邮件不做归档" msgstr "对收到的邮件不做归档"

View File

@@ -1,5 +1,5 @@
__author__ = "Zhang Huangbin" __author__ = "Zhang Huangbin"
__author_mail__ = "zhb@iredmail.org" __author_mail__ = "zhb@iredmail.org"
__version_ldap__ = "5.5" __version_ldap__ = "5.6"
__version_sql__ = "5.4" __version_sql__ = "5.5"
__url_license_terms__ = "http://www.iredmail.org/pricing.html#EULA" __url_license_terms__ = "http://www.iredmail.org/pricing.html#EULA"

View File

@@ -64,6 +64,7 @@ SKIN = "default"
# - Without authentication: HTTP_PROXY = "http://192.168.1.1:3128" # - Without authentication: HTTP_PROXY = "http://192.168.1.1:3128"
# - With authentication: HTTP_PROXY = "http://user:password@192.168.1.1:3128" # - With authentication: HTTP_PROXY = "http://user:password@192.168.1.1:3128"
HTTP_PROXY = "" HTTP_PROXY = ""
# Specify hosts which shouldn't be reached via proxy. # Specify hosts which shouldn't be reached via proxy.
# It should be a comma-separated list of hostname suffixes, optionally with # It should be a comma-separated list of hostname suffixes, optionally with
# `:port` appended, for example: `cern.ch,ncsa.uiuc.edu,some.host:8080`. # `:port` appended, for example: `cern.ch,ncsa.uiuc.edu,some.host:8080`.

View File

@@ -188,8 +188,10 @@ def verify_bcrypt_password(challenge_password: str, plain_password: str) -> bool
except: except:
return False return False
crypt_suffixes = ("{CRYPT}$2a$", "{CRYPT}$2b$", crypt_suffixes = (
"{crypt}$2a$", "{crypt}$2b$") "{CRYPT}$2a$", "{CRYPT}$2b$", "{CRYPT}$2x$", "{CRYPT}$2y$",
"{crypt}$2a$", "{crypt}$2b$", "{crypt}$2x$", "{crypt}$2y$",
)
blf_crypt_suffixes = ("{BLF-CRYPT}", "{blf-crypt}") blf_crypt_suffixes = ("{BLF-CRYPT}", "{blf-crypt}")
if challenge_password.startswith(crypt_suffixes): if challenge_password.startswith(crypt_suffixes):

View File

@@ -459,7 +459,7 @@ TIMEZONES = {
"Antarctica/Casey": "GMT+08:00", "Antarctica/Casey": "GMT+08:00",
"Asia/Beijing": "GMT+08:00", "Asia/Beijing": "GMT+08:00",
"Asia/Brunei": "GMT+08:00", "Asia/Brunei": "GMT+08:00",
"Asia/Chita": "GMT+08:00", "Asia/China": "GMT+08:00",
"Asia/Choibalsan": "GMT+08:00", "Asia/Choibalsan": "GMT+08:00",
"Asia/Hong_Kong": "GMT+08:00", "Asia/Hong_Kong": "GMT+08:00",
"Asia/Irkutsk": "GMT+08:00", "Asia/Irkutsk": "GMT+08:00",

View File

@@ -720,14 +720,17 @@ def delete_maillists(accounts, keep_archive=True, conn=None):
if not iredutils.is_domain(domain): if not iredutils.is_domain(domain):
return True, return True,
sql_vars = {'domain': domain, 'accounts': accounts} sql_vars = {
'domain': domain,
'accounts': accounts,
}
try: try:
if not conn: if not conn:
_wrap = SQLWrap() _wrap = SQLWrap()
conn = _wrap.conn conn = _wrap.conn
for tbl in ['maillists', 'maillist_owners']: for tbl in ['maillists', 'maillist_owners', 'moderators']:
conn.delete(tbl, conn.delete(tbl,
vars=sql_vars, vars=sql_vars,
where='address IN $accounts') where='address IN $accounts')

View File

@@ -477,7 +477,7 @@ def get_paged_users(conn,
qr = conn.query(""" qr = conn.query("""
SELECT SELECT
mailbox.username, mailbox.name, mailbox.quota, LOWER(mailbox.username) AS username, mailbox.name, mailbox.quota,
mailbox.employeeid, mailbox.active, mailbox.isadmin, mailbox.employeeid, mailbox.active, mailbox.isadmin,
mailbox.isglobaladmin, mailbox.passwordlastchange, mailbox.isglobaladmin, mailbox.passwordlastchange,
%s %s
@@ -503,7 +503,7 @@ def get_paged_users(conn,
'mailbox', 'mailbox',
vars=sql_vars, vars=sql_vars,
# Just query what we need to reduce memory use. # Just query what we need to reduce memory use.
what='username,name,quota,employeeid,active,isadmin,isglobaladmin,passwordlastchange', what='LOWER(username) AS username,name,quota,employeeid,active,isadmin,isglobaladmin,passwordlastchange',
where=sql_where, where=sql_where,
order=sql_order, order=sql_order,
limit=settings.PAGE_SIZE_LIMIT, limit=settings.PAGE_SIZE_LIMIT,
@@ -515,7 +515,7 @@ def get_paged_users(conn,
'mailbox', 'mailbox',
vars=sql_vars, vars=sql_vars,
# Just query what we need to reduce memory use. # Just query what we need to reduce memory use.
what='username,name,quota,employeeid,active,isadmin,isglobaladmin,passwordlastchange', what='LOWER(username) AS username,name,quota,employeeid,active,isadmin,isglobaladmin,passwordlastchange',
where=sql_where, where=sql_where,
order='username ASC', order='username ASC',
limit=settings.PAGE_SIZE_LIMIT, limit=settings.PAGE_SIZE_LIMIT,

View File

@@ -126,11 +126,16 @@ while True:
logger.info('Delete incoming/outgoing emails which older than %d days' % keep_inout_days) logger.info('Delete incoming/outgoing emails which older than %d days' % keep_inout_days)
_now = int(time.time()) _now = int(time.time())
_expire_seconds = _now - (keep_inout_days * 86400)
sql_where = """time_num < %d AND (quar_type <> 'Q' OR quar_type IS NULL)""" % _expire_seconds if settings.AMAVISD_REMOVE_QUARANTINED_IN_DAYS <= settings.AMAVISD_REMOVE_MAILLOG_IN_DAYS:
_expire_seconds = _now - (keep_inout_days * 86400)
else:
_expire_seconds = _now - (keep_quar_days * 86400)
sql_where = """time_num < %d""" % _expire_seconds
# We experienced an issue with PostgreSQL, it always return an non-existing # We experienced an issue with PostgreSQL, it always return an non-existing
# SQL record, and it causes endless loop. As a hack, we store all removed # SQL record, and it causes endless loop. As a workaround, we store all removed
# `mail_id` and compare new `mail_id` with this list. # `mail_id` and compare new `mail_id` with this list.
_removed_ids = set() _removed_ids = set()

View File

@@ -760,18 +760,11 @@ elif egrep '^backend.*mysql' ${IRA_CONF_PY} &>/dev/null; then
elif egrep '^backend.*pgsql' ${IRA_CONF_PY} &>/dev/null; then elif egrep '^backend.*pgsql' ${IRA_CONF_PY} &>/dev/null; then
[ X"$(has_python_module psycopg2)" == X'NO' ] && REQUIRED_PKGS="${REQUIRED_PKGS} ${PKG_PY_PGSQL}" [ X"$(has_python_module psycopg2)" == X'NO' ] && REQUIRED_PKGS="${REQUIRED_PKGS} ${PKG_PY_PGSQL}"
fi fi
[ X"$(has_python_module pip)" == X'NO' ] && REQUIRED_PKGS="${REQUIRED_PKGS} ${PKG_PY_PIP}" [ X"$(has_python_module pip)" == X'NO' ] && REQUIRED_PKGS="${REQUIRED_PKGS} ${PKG_PY_PIP}"
[ X"$(has_python_module simplejson)" == X'NO' ] && REQUIRED_PKGS="${REQUIRED_PKGS} ${PKG_PY_JSON}" [ X"$(has_python_module simplejson)" == X'NO' ] && REQUIRED_PKGS="${REQUIRED_PKGS} ${PKG_PY_JSON}"
[ X"$(has_python_module dns)" == X'NO' ] && REQUIRED_PKGS="${REQUIRED_PKGS} ${PKG_PY_DNS}" [ X"$(has_python_module dns)" == X'NO' ] && REQUIRED_PKGS="${REQUIRED_PKGS} ${PKG_PY_DNS}"
[ X"$(has_python_module requests)" == X'NO' ] && REQUIRED_PKGS="${REQUIRED_PKGS} ${PKG_PY_REQUESTS}" [ X"$(has_python_module requests)" == X'NO' ] && REQUIRED_PKGS="${REQUIRED_PKGS} ${PKG_PY_REQUESTS}"
if [ X"$(has_python_module web)" == X'NO' ]; then
PIP3_MODS="${PIP3_MODS} web.py>=0.61"
else # Verify module version.
_webpy_ver=$(${CMD_PYTHON3} -c "import web; print(web.__version__)")
if echo ${_webpy_ver} | grep '^0\.[45]' &>/dev/null; then
PIP3_MODS="${PIP3_MODS} web.py>=0.61"
fi
fi
[ X"$(has_python_module jinja2)" == X'NO' ] && REQUIRED_PKGS="${REQUIRED_PKGS} ${PKG_PY_JINJA}" [ X"$(has_python_module jinja2)" == X'NO' ] && REQUIRED_PKGS="${REQUIRED_PKGS} ${PKG_PY_JINJA}"
if [ X"${REQUIRED_PKGS}" != X'' ]; then if [ X"${REQUIRED_PKGS}" != X'' ]; then