From f585197e52815c333f7c3be67b8f48fd1f8c534e Mon Sep 17 00:00:00 2001 From: Stefan Auditor Date: Sun, 15 Apr 2018 11:23:58 +0200 Subject: [PATCH 1/7] Add enabled flag to user model --- core/admin/mailu/models.py | 1 + .../migrations/versions/49d77a93118e_.py | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 core/admin/migrations/versions/49d77a93118e_.py diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index 48f7b91e..ae5cae6e 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -183,6 +183,7 @@ class User(Base, Email): password = db.Column(db.String(255), nullable=False) quota_bytes = db.Column(db.Integer(), nullable=False, default=10**9) global_admin = db.Column(db.Boolean(), nullable=False, default=False) + enabled = db.Column(db.Boolean(), nullable=False, default=True) # Features enable_imap = db.Column(db.Boolean(), nullable=False, default=True) diff --git a/core/admin/migrations/versions/49d77a93118e_.py b/core/admin/migrations/versions/49d77a93118e_.py new file mode 100644 index 00000000..98dd9e34 --- /dev/null +++ b/core/admin/migrations/versions/49d77a93118e_.py @@ -0,0 +1,24 @@ +""" Add enabled flag to user model + +Revision ID: 49d77a93118e +Revises: 423155f8fc15 +Create Date: 2018-04-15 11:17:32.306088 + +""" + +# revision identifiers, used by Alembic. +revision = '49d77a93118e' +down_revision = '423155f8fc15' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + with op.batch_alter_table('user') as batch: + batch.add_column(sa.Column('enabled', sa.Boolean(), nullable=False, server_default=sa.sql.expression.true())) + + +def downgrade(): + with op.batch_alter_table('user') as batch: + batch.drop_column('user', 'enabled') From 7139a27bf1934e2f2148ec6ea8b9ffd9a5d89f03 Mon Sep 17 00:00:00 2001 From: Stefan Auditor Date: Sun, 15 Apr 2018 11:35:37 +0200 Subject: [PATCH 2/7] Add field to ui for user enabled flag --- core/admin/mailu/ui/forms.py | 1 + core/admin/mailu/ui/templates/user/create.html | 1 + 2 files changed, 2 insertions(+) diff --git a/core/admin/mailu/ui/forms.py b/core/admin/mailu/ui/forms.py index 22dbb351..c17da724 100644 --- a/core/admin/mailu/ui/forms.py +++ b/core/admin/mailu/ui/forms.py @@ -72,6 +72,7 @@ class UserForm(flask_wtf.FlaskForm): enable_imap = fields.BooleanField(_('Allow IMAP access'), default=True) enable_pop = fields.BooleanField(_('Allow POP3 access'), default=True) comment = fields.StringField(_('Comment')) + enabled = fields.BooleanField(_('Enabled'), default=True) submit = fields.SubmitField(_('Save')) diff --git a/core/admin/mailu/ui/templates/user/create.html b/core/admin/mailu/ui/templates/user/create.html index 053bfba5..09e83155 100644 --- a/core/admin/mailu/ui/templates/user/create.html +++ b/core/admin/mailu/ui/templates/user/create.html @@ -16,6 +16,7 @@ {{ macros.form_field(form.localpart, append='@'+domain.name+'') }} {{ macros.form_fields((form.pw, form.pw2)) }} {{ macros.form_field(form.comment) }} + {{ macros.form_field(form.enabled) }} {% endcall %} {% call macros.box(_("Features and quotas"), theme="success") %} From 3b66fcada77610fb07790e2ed298c4af1336910e Mon Sep 17 00:00:00 2001 From: Stefan Auditor Date: Sun, 15 Apr 2018 13:00:38 +0200 Subject: [PATCH 3/7] Respect user enabled flag on user.login --- core/admin/mailu/models.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index ae5cae6e..8d42ac2a 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -221,6 +221,9 @@ class User(Base, Email): default=scheme_dict[app.config['PASSWORD_SCHEME']], ) + def is_enabled(self): + return self.enabled + def check_password(self, password): reference = re.match('({[^}]+})?(.*)', self.password).group(2) return User.pw_context.verify(password, reference) @@ -257,7 +260,7 @@ class User(Base, Email): @classmethod def login(cls, email, password): user = cls.query.get(email) - return user if (user and user.check_password(password)) else None + return user if (user and user.check_password(password) and user.is_enabled()) else None login_manager.user_loader(User.query.get) From 733b89bff5b241b00034fa0cd0183fb710badd51 Mon Sep 17 00:00:00 2001 From: Stefan Auditor Date: Sun, 15 Apr 2018 13:42:08 +0200 Subject: [PATCH 4/7] Remove is_enabled method and use the enabled attribute instead --- core/admin/mailu/models.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index 8d42ac2a..ef222327 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -221,9 +221,6 @@ class User(Base, Email): default=scheme_dict[app.config['PASSWORD_SCHEME']], ) - def is_enabled(self): - return self.enabled - def check_password(self, password): reference = re.match('({[^}]+})?(.*)', self.password).group(2) return User.pw_context.verify(password, reference) @@ -260,7 +257,7 @@ class User(Base, Email): @classmethod def login(cls, email, password): user = cls.query.get(email) - return user if (user and user.check_password(password) and user.is_enabled()) else None + return user if (user and user.enabled and user.check_password(password)) else None login_manager.user_loader(User.query.get) From 6fc22e54328e640f0eb7df4fb89d2363084c4224 Mon Sep 17 00:00:00 2001 From: Stefan Auditor Date: Sun, 15 Apr 2018 13:43:30 +0200 Subject: [PATCH 5/7] Respect user.enabled status in internal authentication --- core/admin/mailu/internal/nginx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/admin/mailu/internal/nginx.py b/core/admin/mailu/internal/nginx.py index 84ee8596..cb6bc9cb 100644 --- a/core/admin/mailu/internal/nginx.py +++ b/core/admin/mailu/internal/nginx.py @@ -51,7 +51,7 @@ def handle_authentication(headers): status = False elif protocol == "pop3" and not user.enable_pop: status = False - if status: + if status and user.enabled: return { "Auth-Status": "OK", "Auth-Server": server, From c8540ddba7312a648c56d753ace1a8dc8f6a4136 Mon Sep 17 00:00:00 2001 From: Stefan Auditor Date: Sun, 15 Apr 2018 14:02:15 +0200 Subject: [PATCH 6/7] Respect user enabled flag in basic authentication --- core/admin/mailu/internal/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/admin/mailu/internal/views.py b/core/admin/mailu/internal/views.py index 955b5390..2b441ce7 100644 --- a/core/admin/mailu/internal/views.py +++ b/core/admin/mailu/internal/views.py @@ -41,7 +41,7 @@ def basic_authentication(): encoded = authorization.replace("Basic ", "") user_email, password = base64.b64decode(encoded).split(b":") user = models.User.query.get(user_email.decode("utf8")) - if user and user.check_password(password.decode("utf8")): + if user and user.enabled and user.check_password(password.decode("utf8")): response = flask.Response() response.headers["X-User"] = user.email return response From e843f7ef1f676c3ed04364ed7c7dd799774e7956 Mon Sep 17 00:00:00 2001 From: Stefan Auditor Date: Sun, 15 Apr 2018 19:53:24 +0200 Subject: [PATCH 7/7] Respect user enabled flag in admin authentication --- core/admin/mailu/internal/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/admin/mailu/internal/views.py b/core/admin/mailu/internal/views.py index 2b441ce7..b97d329e 100644 --- a/core/admin/mailu/internal/views.py +++ b/core/admin/mailu/internal/views.py @@ -27,7 +27,8 @@ def admin_authentication(): """ Fails if the user is not an authenticated admin. """ if (not flask_login.current_user.is_anonymous - and flask_login.current_user.global_admin): + and flask_login.current_user.global_admin + and flask_login.current_user.enabled): return "" return flask.abort(403)