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, diff --git a/core/admin/mailu/internal/views.py b/core/admin/mailu/internal/views.py index 955b5390..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) @@ -41,7 +42,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 diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index e439d997..66b0d563 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) @@ -256,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)) else None + return user if (user and user.enabled and user.check_password(password)) else None login_manager.user_loader(User.query.get) 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") %} 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')