diff --git a/CHANGELOG.md b/CHANGELOG.md
index 07b5b164..ad916685 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -29,7 +29,6 @@ v1.6.0 - unreleased
- Feature: Automated Releases ([#487](https://github.com/Mailu/Mailu/issues/487))
- Feature: Support for ARC ([#495](https://github.com/Mailu/Mailu/issues/495))
- Feature: Add posibilty to run webmail on root ([#501](https://github.com/Mailu/Mailu/issues/501))
-- Feature: Upgrade docker-compose.yml to version 3 ([#539](https://github.com/Mailu/Mailu/issues/539))
- Feature: Documentation to deploy mailu on a docker swarm ([#551](https://github.com/Mailu/Mailu/issues/551))
- Feature: Add optional Maildir-Compression ([#553](https://github.com/Mailu/Mailu/issues/553))
- Feature: Preserve rspamd history on container restart ([#561](https://github.com/Mailu/Mailu/issues/561))
@@ -80,6 +79,7 @@ v1.6.0 - unreleased
- Enhancement: Include favicon package ([#801](https://github.com/Mailu/Mailu/issues/801), ([#802](https://github.com/Mailu/Mailu/issues/802))
- Enhancement: Add logging at critical places in python start.py scripts. Implement LOG_LEVEL to control verbosity ([#588](https://github.com/Mailu/Mailu/issues/588))
- Enhancement: Mark message as seen when reporting as spam
+- Enhancement: Better support and document IPv6 ([#827](https://github.com/Mailu/Mailu/issues/827))
- Upstream: Update Roundcube
- Upstream: Update Rainloop
- Bug: Rainloop fails with "domain not allowed" ([#93](https://github.com/Mailu/Mailu/issues/93))
@@ -116,6 +116,8 @@ v1.6.0 - unreleased
- Bug: Don't recursivly chown on mailboxes ([#776](https://github.com/Mailu/Mailu/issues/776))
- Bug: Fix forced password input for user edit ([#745](https://github.com/Mailu/Mailu/issues/745))
- Bug: Fetched accounts: Password field is of type "text" ([#789](https://github.com/Mailu/Mailu/issues/789))
+- Bug: Auto-forward destination not accepting top level domains ([#818](https://github.com/Mailu/Mailu/issues/818))
+- Bug: DOMAIN_REGISTRATION=False in .env was not treated correctly ([#830](https://github.com/Mailu/Mailu/issues/830))
v1.5.1 - 2017-11-21
-------------------
diff --git a/core/admin/mailu/configuration.py b/core/admin/mailu/configuration.py
index 95004017..a8cd3e25 100644
--- a/core/admin/mailu/configuration.py
+++ b/core/admin/mailu/configuration.py
@@ -30,11 +30,11 @@ DEFAULT_CONFIG = {
'POSTMASTER': 'postmaster',
'TLS_FLAVOR': 'cert',
'AUTH_RATELIMIT': '10/minute;1000/hour',
- 'DISABLE_STATISTICS': 'False',
+ 'DISABLE_STATISTICS': False,
# Mail settings
'DMARC_RUA': None,
'DMARC_RUF': None,
- 'WELCOME': 'False',
+ 'WELCOME': False,
'WELCOME_SUBJECT': 'Dummy welcome topic',
'WELCOME_BODY': 'Dummy welcome body',
'DKIM_SELECTOR': 'dkim',
@@ -74,13 +74,21 @@ class ConfigManager(dict):
def __init__(self):
self.config = dict()
+ def __coerce_value(self, value):
+ if isinstance(value, str) and value.lower() in ('true','yes'):
+ return True
+ elif isinstance(value, str) and value.lower() in ('false', 'no'):
+ return False
+ return value
+
def init_app(self, app):
self.config.update(app.config)
# get environment variables
self.config.update({
- key: os.environ.get(key, value)
+ key: self.__coerce_value(os.environ.get(key, value))
for key, value in DEFAULT_CONFIG.items()
})
+
# automatically set the sqlalchemy string
if self.config['DB_FLAVOR']:
template = self.DB_TEMPLATES[self.config['DB_FLAVOR']]
diff --git a/core/admin/mailu/manage.py b/core/admin/mailu/manage.py
index 4846c2d6..e11644e7 100644
--- a/core/admin/mailu/manage.py
+++ b/core/admin/mailu/manage.py
@@ -31,7 +31,7 @@ def advertise():
instance_id = str(uuid.uuid4())
with open(app.config["INSTANCE_ID_PATH"], "w") as handle:
handle.write(instance_id)
- if app.config["DISABLE_STATISTICS"].lower() != "true":
+ if not app.config["DISABLE_STATISTICS"]:
try:
socket.gethostbyname(app.config["STATS_ENDPOINT"].format(instance_id))
except:
diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py
index 37823f02..8bfb12fb 100644
--- a/core/admin/mailu/models.py
+++ b/core/admin/mailu/models.py
@@ -101,8 +101,8 @@ class Base(db.Model):
}
)
- created_at = db.Column(db.Date, nullable=False, default=datetime.now)
- updated_at = db.Column(db.Date, nullable=True, onupdate=datetime.now)
+ created_at = db.Column(db.Date, nullable=False, default=date.today)
+ updated_at = db.Column(db.Date, nullable=True, onupdate=date.today)
comment = db.Column(db.String(255), nullable=True)
@@ -131,7 +131,7 @@ class Domain(Base):
backref=db.backref('manager_of'), lazy='dynamic')
max_users = db.Column(db.Integer, nullable=False, default=-1)
max_aliases = db.Column(db.Integer, nullable=False, default=-1)
- max_quota_bytes = db.Column(db.Integer(), nullable=False, default=0)
+ max_quota_bytes = db.Column(db.BigInteger(), nullable=False, default=0)
signup_enabled = db.Column(db.Boolean(), nullable=False, default=False)
@property
@@ -307,8 +307,8 @@ class User(Base, Email):
domain = db.relationship(Domain,
backref=db.backref('users', cascade='all, delete-orphan'))
password = db.Column(db.String(255), nullable=False)
- quota_bytes = db.Column(db.Integer(), nullable=False, default=10**9)
- quota_bytes_used = db.Column(db.Integer(), nullable=False, default=0)
+ quota_bytes = db.Column(db.BigInteger(), nullable=False, default=10**9)
+ quota_bytes_used = db.Column(db.BigInteger(), nullable=False, default=0)
global_admin = db.Column(db.Boolean(), nullable=False, default=False)
enabled = db.Column(db.Boolean(), nullable=False, default=True)
@@ -410,7 +410,7 @@ class User(Base, Email):
return emails
def send_welcome(self):
- if app.config["WELCOME"].lower() == "true":
+ if app.config["WELCOME"]:
self.sendmail(app.config["WELCOME_SUBJECT"],
app.config["WELCOME_BODY"])
diff --git a/core/admin/mailu/ui/forms.py b/core/admin/mailu/ui/forms.py
index e8302199..48355748 100644
--- a/core/admin/mailu/ui/forms.py
+++ b/core/admin/mailu/ui/forms.py
@@ -37,7 +37,7 @@ class MultipleEmailAddressesVerify(object):
self.message = message
def __call__(self, form, field):
- pattern = re.compile(r'^([_a-z0-9\-]+)(\.[_a-z0-9\-]+)*@([a-z0-9\-]{2,}\.)*([a-z]{2,4})(,([_a-z0-9\-]+)(\.[_a-z0-9\-]+)*@([a-z0-9\-]{2,}\.)*([a-z]{2,4}))*$')
+ pattern = re.compile(r'^([_a-z0-9\-]+)(\.[_a-z0-9\-]+)*@([a-z0-9\-]{2,}\.)*([a-z]{2,})(,([_a-z0-9\-]+)(\.[_a-z0-9\-]+)*@([a-z0-9\-]{2,}\.)*([a-z]{2,}))*$')
if not pattern.match(field.data.replace(" ", "")):
raise validators.ValidationError(self.message)
diff --git a/core/admin/migrations/versions/3b7eee912b41_.py b/core/admin/migrations/versions/3b7eee912b41_.py
new file mode 100644
index 00000000..17f1e0ef
--- /dev/null
+++ b/core/admin/migrations/versions/3b7eee912b41_.py
@@ -0,0 +1,30 @@
+"""change quota type to bigint
+
+Revision ID: 3b7eee912b41
+Revises: fc099bd15cbe
+Create Date: 2019-01-15 08:51:05.346257
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '3b7eee912b41'
+down_revision = 'fc099bd15cbe'
+
+from alembic import op
+import sqlalchemy as sa
+
+def upgrade():
+ with op.batch_alter_table('domain') as batch:
+ batch.alter_column('max_quota_bytes', type_=sa.BigInteger(), nullable=False, server_default='0')
+
+ with op.batch_alter_table('user') as batch:
+ batch.alter_column('quota_bytes', type_=sa.BigInteger(), nullable=False)
+ batch.alter_column('quota_bytes_used', type_=sa.BigInteger(), nullable=False, server_default='0')
+
+def downgrade():
+ with op.batch_alter_table('domain') as batch:
+ batch.alter_column('max_quota_bytes', type_=sa.Integer(), nullable=False, server_default='0')
+
+ with op.batch_alter_table('user') as batch:
+ batch.alter_column('quota_bytes', type_=sa.Integer(), nullable=False)
+ batch.alter_column('quota_bytes_used', type_=sa.Integer(), nullable=False, server_default='0')
diff --git a/core/dovecot/start.py b/core/dovecot/start.py
index 15e370de..bae92260 100755
--- a/core/dovecot/start.py
+++ b/core/dovecot/start.py
@@ -16,10 +16,11 @@ log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING"))
def start_podop():
os.setuid(8)
+ url = "http://" + os.environ["ADMIN_ADDRESS"] + "/internal/dovecot/§"
run_server(0, "dovecot", "/tmp/podop.socket", [
- ("quota", "url", "http://admin/internal/dovecot/§"),
- ("auth", "url", "http://admin/internal/dovecot/§"),
- ("sieve", "url", "http://admin/internal/dovecot/§"),
+ ("quota", "url", url ),
+ ("auth", "url", url),
+ ("sieve", "url", url),
])
def convert(src, dst):
@@ -42,6 +43,7 @@ def resolve(hostname):
# Actual startup script
os.environ["FRONT_ADDRESS"] = resolve(os.environ.get("FRONT_ADDRESS", "front"))
os.environ["REDIS_ADDRESS"] = resolve(os.environ.get("REDIS_ADDRESS", "redis"))
+os.environ["ADMIN_ADDRESS"] = resolve(os.environ.get("ADMIN_ADDRESS", "admin"))
if os.environ["WEBMAIL"] != "none":
os.environ["WEBMAIL_ADDRESS"] = resolve(os.environ.get("WEBMAIL_ADDRESS", "webmail"))
diff --git a/core/postfix/start.py b/core/postfix/start.py
index a06b3833..e3b3eb40 100755
--- a/core/postfix/start.py
+++ b/core/postfix/start.py
@@ -17,14 +17,15 @@ log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING"))
def start_podop():
os.setuid(100)
+ url = "http://" + os.environ["ADMIN_ADDRESS"] + "/internal/postfix/"
# TODO: Remove verbosity setting from Podop?
run_server(0, "postfix", "/tmp/podop.socket", [
- ("transport", "url", "http://admin/internal/postfix/transport/§"),
- ("alias", "url", "http://admin/internal/postfix/alias/§"),
- ("domain", "url", "http://admin/internal/postfix/domain/§"),
- ("mailbox", "url", "http://admin/internal/postfix/mailbox/§"),
- ("senderaccess", "url", "http://admin/internal/postfix/sender/access/§"),
- ("senderlogin", "url", "http://admin/internal/postfix/sender/login/§")
+ ("transport", "url", url + "transport/§"),
+ ("alias", "url", url + "alias/§"),
+ ("domain", "url", url + "domain/§"),
+ ("mailbox", "url", url + "mailbox/§"),
+ ("senderaccess", "url", url + "sender/access/§"),
+ ("senderlogin", "url", url + "sender/login/§")
])
def convert(src, dst):
@@ -46,6 +47,7 @@ def resolve(hostname):
# Actual startup script
os.environ["FRONT_ADDRESS"] = resolve(os.environ.get("FRONT_ADDRESS", "front"))
+os.environ["ADMIN_ADDRESS"] = resolve(os.environ.get("ADMIN_ADDRESS", "admin"))
os.environ["HOST_ANTISPAM"] = os.environ.get("HOST_ANTISPAM", "antispam:11332")
os.environ["HOST_LMTP"] = os.environ.get("HOST_LMTP", "imap:2525")
diff --git a/docs/compose/.env b/docs/compose/.env
index cf906b58..218b94d2 100644
--- a/docs/compose/.env
+++ b/docs/compose/.env
@@ -1,3 +1,5 @@
+# WARNING: this file is being deprecated over the new setup utility, found at https://setup.mailu.io
+
# Mailu main configuration file
## Most configuration variables can be modified through the Web interface,
# these few settings must however be configured before starting the mail
diff --git a/docs/compose/docker-compose.yml b/docs/compose/docker-compose.yml
index 2cff9608..2686ee27 100644
--- a/docs/compose/docker-compose.yml
+++ b/docs/compose/docker-compose.yml
@@ -1,3 +1,5 @@
+# WARNING: this file is being deprecated over the new setup utility, found at https://setup.mailu.io
+
version: '2'
services:
diff --git a/docs/compose/setup.rst b/docs/compose/setup.rst
index 3ff1f678..c1a620e6 100644
--- a/docs/compose/setup.rst
+++ b/docs/compose/setup.rst
@@ -12,34 +12,22 @@ Mailu will store all of its persistent data in a path of your choice
mkdir /mailu
cd /mailu
-Download the initial configuration file
----------------------------------------
+Create the configuration files
+------------------------------
-Docker Compose configuration is stored in a file named
-:download:`docker-compose.yml`. Additionally, Mailu
-relies on a :download:`.env` file for various settings. Download
-the proper template files from the git repository. To download the configuration
-for the ``VERSION_TAG`` branch, use:
+Docker Compose configuration is stored in a file named ``docker-compose.yml``.
+Additionally, Mailu relies on a ``mailu.env`` file for various settings.
+Both files can be generated by the `mailu setup utility`_. The setup utility
+is mostly self-explanatory, with some more additional information in this section.
-.. code-block:: bash
+.. _`mailu setup utility`: https://setup.mailu.io
- wget https://mailu.io/VERSION_TAG/_downloads/docker-compose.yml
- wget https://mailu.io/VERSION_TAG/_downloads/.env
-
-Important configuration variables
----------------------------------
-
-Open the ``.env`` file and review the following variable settings:
-
-- Change ``ROOT`` if you have your setup directory in a different location then ``/mailu``.
-- Check ``VERSION`` to reflect the version you picked. (``master`` or ``1.5``).
-
-Make sure to read the comments in the file and instructions from the :ref:`common_cfg` section.
+.. _tls_flavor:
TLS certificates
````````````````
-Set the ``TLS_FLAVOR`` to one of the following
+Sets the ``TLS_FLAVOR`` to one of the following
values:
- ``cert`` is the default and requires certificates to be setup manually;
@@ -59,7 +47,7 @@ values:
Bind address
````````````
-Modify ``BIND_ADDRESS4`` and ``BIND_ADDRESS6`` to match the public IP addresses assigned to your server. For IPv6 you will need the `` Mailu comes with multiple base features, including a specific admin
-interface, Web email clients (webmails), antispam, antivirus, etc. If you
-wish to disable some of these features, you are free to do so. Emails will be available through IMAP and POP3. You may also enable a Web
-email client. These do add some complexity but provide an easier way of
-accessing messages for beginner users.
A Webmail is a Web interface exposing an email client. Mailu webmails are +bound to the internal IMAP and SMTP server for users to access their mailbox through +the Web. By exposing a complex application such as a Webmail, you should be aware of +the security implications caused by such an increase of attack surface.
Email filtering is a really important features. You can still disable it, which -will prevent Mailu from doing spam filtering, virus filtering, and from applying -white and blacklists that you may configure in the admin interface. You may -also disable the antivirus if required (it does use aroung 1GB of ram).
+An antivirus server helps fighting large scale virus spreading campaigns that leverage +e-mail for initial infection. Make sure that you have at least 1GB of memory for ClamAV to +load its signature database.
A Webdav server exposes a Dav interface over HTTP so that clients can store +contacts or calendars using the mail account.
+Fetchmail allows to download mails over IMAP/POP3 and uploads it your Mailu mailbox.
+