From 9fac3d7ad3895c1e03016dd3eadbff186c875711 Mon Sep 17 00:00:00 2001 From: Diman0 Date: Thu, 2 Sep 2021 13:36:42 +0200 Subject: [PATCH 01/37] Initial implementation for standalone sso page --- core/admin/Dockerfile | 1 + core/admin/mailu/__init__.py | 4 +- core/admin/mailu/sso/__init__.py | 6 +++ core/admin/mailu/sso/forms.py | 14 ++++++ core/admin/mailu/sso/templates/base_sso.html | 51 ++++++++++++++++++++ core/admin/mailu/sso/templates/form_sso.html | 7 +++ core/admin/mailu/sso/templates/login.html | 9 ++++ core/admin/mailu/sso/views/__init__.py | 3 ++ core/admin/mailu/sso/views/base.py | 30 ++++++++++++ core/admin/mailu/sso/views/hello.py | 6 +++ core/admin/mailu/ui/forms.py | 4 +- core/admin/mailu/ui/templates/login.html | 9 ---- core/admin/mailu/ui/views/base.py | 3 +- core/admin/mailu/utils.py | 4 +- 14 files changed, 135 insertions(+), 16 deletions(-) create mode 100644 core/admin/mailu/sso/__init__.py create mode 100644 core/admin/mailu/sso/forms.py create mode 100644 core/admin/mailu/sso/templates/base_sso.html create mode 100644 core/admin/mailu/sso/templates/form_sso.html create mode 100644 core/admin/mailu/sso/templates/login.html create mode 100644 core/admin/mailu/sso/views/__init__.py create mode 100644 core/admin/mailu/sso/views/base.py create mode 100644 core/admin/mailu/sso/views/hello.py delete mode 100644 core/admin/mailu/ui/templates/login.html diff --git a/core/admin/Dockerfile b/core/admin/Dockerfile index 97cf1736..2406bb5c 100644 --- a/core/admin/Dockerfile +++ b/core/admin/Dockerfile @@ -31,6 +31,7 @@ RUN apk add --no-cache openssl curl postgresql-libs mariadb-connector-c \ && apk del --no-cache build-dep COPY --from=assets static ./mailu/ui/static +COPY --from=assets static ./mailu/sso/static COPY mailu ./mailu COPY migrations ./migrations COPY start.py /start.py diff --git a/core/admin/mailu/__init__.py b/core/admin/mailu/__init__.py index 8ab8ed0e..f80533fe 100644 --- a/core/admin/mailu/__init__.py +++ b/core/admin/mailu/__init__.py @@ -48,10 +48,10 @@ def create_app_from_config(config): ) # Import views - from mailu import ui, internal + from mailu import ui, internal, sso app.register_blueprint(ui.ui, url_prefix='/ui') app.register_blueprint(internal.internal, url_prefix='/internal') - + app.register_blueprint(sso.sso, url_prefix='/sso') return app diff --git a/core/admin/mailu/sso/__init__.py b/core/admin/mailu/sso/__init__.py new file mode 100644 index 00000000..2d3c6d84 --- /dev/null +++ b/core/admin/mailu/sso/__init__.py @@ -0,0 +1,6 @@ +from flask import Blueprint + + +sso = Blueprint('sso', __name__, static_folder='static', template_folder='templates') + +from mailu.sso.views import * diff --git a/core/admin/mailu/sso/forms.py b/core/admin/mailu/sso/forms.py new file mode 100644 index 00000000..a81667a2 --- /dev/null +++ b/core/admin/mailu/sso/forms.py @@ -0,0 +1,14 @@ +from wtforms import validators, fields, widgets +from wtforms_components import fields as fields_ +from flask_babel import lazy_gettext as _ + +import flask_login +import flask_wtf +import re + +class LoginForm(flask_wtf.FlaskForm): + class Meta: + csrf = False + email = fields.StringField(_('E-mail'), [validators.Email()]) + pw = fields.PasswordField(_('Password'), [validators.DataRequired()]) + submit = fields.SubmitField(_('Sign in')) diff --git a/core/admin/mailu/sso/templates/base_sso.html b/core/admin/mailu/sso/templates/base_sso.html new file mode 100644 index 00000000..a95cb23b --- /dev/null +++ b/core/admin/mailu/sso/templates/base_sso.html @@ -0,0 +1,51 @@ +{% import "macros.html" as macros %} +{% import "bootstrap/utils.html" as utils %} + + + + + + + Mailu-login - {{ config["SITENAME"] }} + + +
+
+ +
+ +
+
+
+ {% block main_action %} + {% endblock %} +
+

+ {% block title %}{% endblock %} + {% block subtitle %}{% endblock %} +

+
+ +
+ {{ utils.flashed_messages(container=False) }} + {% block content %}{% endblock %} +
+
+ +
+ + + + diff --git a/core/admin/mailu/sso/templates/form_sso.html b/core/admin/mailu/sso/templates/form_sso.html new file mode 100644 index 00000000..fcabad41 --- /dev/null +++ b/core/admin/mailu/sso/templates/form_sso.html @@ -0,0 +1,7 @@ +{% extends "base_sso.html" %} + +{% block content %} +{% call macros.box() %} +{{ macros.form(form) }} +{% endcall %} +{% endblock %} diff --git a/core/admin/mailu/sso/templates/login.html b/core/admin/mailu/sso/templates/login.html new file mode 100644 index 00000000..851e6643 --- /dev/null +++ b/core/admin/mailu/sso/templates/login.html @@ -0,0 +1,9 @@ +{% extends "form_sso.html" %} + +{% block title %} +{% trans %}Sign in{% endtrans %} +{% endblock %} + +{% block subtitle %} +{% trans %}to access IF statement for switch text for loggin in what the administration tools{% endtrans %} +{% endblock %} diff --git a/core/admin/mailu/sso/views/__init__.py b/core/admin/mailu/sso/views/__init__.py new file mode 100644 index 00000000..38efde4c --- /dev/null +++ b/core/admin/mailu/sso/views/__init__.py @@ -0,0 +1,3 @@ +__all__ = [ + 'base', 'hello' +] diff --git a/core/admin/mailu/sso/views/base.py b/core/admin/mailu/sso/views/base.py new file mode 100644 index 00000000..dd6f60c9 --- /dev/null +++ b/core/admin/mailu/sso/views/base.py @@ -0,0 +1,30 @@ +from mailu import models +from mailu.sso import sso, forms + +from flask import current_app as app +import flask +import flask_login + +@sso.route('/login', methods=['GET', 'POST']) +def login(): + form = forms.LoginForm() + if form.validate_on_submit(): + user = models.User.login(form.email.data, form.pw.data) + if user: + flask.session.regenerate() + flask_login.login_user(user) + endpoint = flask.request.args.get('next', 'ui.index') + return flask.redirect(flask.url_for(endpoint) + or flask.url_for('ui.index')) + else: + flask.flash('Wrong e-mail or password', 'error') + return flask.render_template('login.html', form=form) + +""" +@ui.route('/logout', methods=['GET']) +@access.authenticated +def logout(): + flask_login.logout_user() + flask.session.destroy() + return flask.redirect(flask.url_for('.index')) +""" \ No newline at end of file diff --git a/core/admin/mailu/sso/views/hello.py b/core/admin/mailu/sso/views/hello.py new file mode 100644 index 00000000..2e9b5e35 --- /dev/null +++ b/core/admin/mailu/sso/views/hello.py @@ -0,0 +1,6 @@ +from mailu.sso import sso +from flask import current_app as app + +@sso.route("/") +def hello_world(): + return "

Hello, World!

" diff --git a/core/admin/mailu/ui/forms.py b/core/admin/mailu/ui/forms.py index 32bb31ab..dff7008e 100644 --- a/core/admin/mailu/ui/forms.py +++ b/core/admin/mailu/ui/forms.py @@ -44,14 +44,14 @@ class MultipleEmailAddressesVerify(object): class ConfirmationForm(flask_wtf.FlaskForm): submit = fields.SubmitField(_('Confirm')) - +""" class LoginForm(flask_wtf.FlaskForm): class Meta: csrf = False email = fields.StringField(_('E-mail'), [validators.Email()]) pw = fields.PasswordField(_('Password'), [validators.DataRequired()]) submit = fields.SubmitField(_('Sign in')) - +""" class DomainForm(flask_wtf.FlaskForm): name = fields.StringField(_('Domain name'), [validators.DataRequired()]) diff --git a/core/admin/mailu/ui/templates/login.html b/core/admin/mailu/ui/templates/login.html deleted file mode 100644 index 26c47c08..00000000 --- a/core/admin/mailu/ui/templates/login.html +++ /dev/null @@ -1,9 +0,0 @@ -{% extends "form.html" %} - -{% block title %} -{% trans %}Sign in{% endtrans %} -{% endblock %} - -{% block subtitle %} -{% trans %}to access the administration tools{% endtrans %} -{% endblock %} diff --git a/core/admin/mailu/ui/views/base.py b/core/admin/mailu/ui/views/base.py index eb5490bc..fc9daba6 100644 --- a/core/admin/mailu/ui/views/base.py +++ b/core/admin/mailu/ui/views/base.py @@ -12,6 +12,7 @@ def index(): return flask.redirect(flask.url_for('.user_settings')) +""" @ui.route('/login', methods=['GET', 'POST']) def login(): form = forms.LoginForm() @@ -26,7 +27,7 @@ def login(): else: flask.flash('Wrong e-mail or password', 'error') return flask.render_template('login.html', form=form) - +""" @ui.route('/logout', methods=['GET']) @access.authenticated diff --git a/core/admin/mailu/utils.py b/core/admin/mailu/utils.py index 02150754..c30f259e 100644 --- a/core/admin/mailu/utils.py +++ b/core/admin/mailu/utils.py @@ -28,13 +28,13 @@ from werkzeug.contrib import fixers # Login configuration login = flask_login.LoginManager() -login.login_view = "ui.login" +login.login_view = "sso.login" @login.unauthorized_handler def handle_needs_login(): """ redirect unauthorized requests to login page """ return flask.redirect( - flask.url_for('ui.login', next=flask.request.endpoint) + flask.url_for('sso.login', next=flask.request.endpoint) ) # Rate limiter From 8868aec0dcd02101ea09396c5d064b046b75ea44 Mon Sep 17 00:00:00 2001 From: Diman0 Date: Thu, 2 Sep 2021 17:08:50 +0200 Subject: [PATCH 02/37] Merge master. Make sso login working for admin. --- core/admin/mailu/configuration.py | 1 + core/admin/mailu/sso/forms.py | 2 + core/admin/mailu/sso/templates/base_sso.html | 61 +++++++++++-------- core/admin/mailu/sso/templates/form_sso.html | 2 +- core/admin/mailu/sso/templates/login.html | 6 +- .../mailu/sso/templates/sidebar_sso.html | 60 ++++++++++++++++++ core/admin/mailu/sso/views/base.py | 15 ++--- core/admin/mailu/ui/templates/sidebar.html | 2 +- core/nginx/conf/nginx.conf | 8 ++- 9 files changed, 115 insertions(+), 42 deletions(-) create mode 100644 core/admin/mailu/sso/templates/sidebar_sso.html diff --git a/core/admin/mailu/configuration.py b/core/admin/mailu/configuration.py index 7cd3a56b..025a173c 100644 --- a/core/admin/mailu/configuration.py +++ b/core/admin/mailu/configuration.py @@ -51,6 +51,7 @@ DEFAULT_CONFIG = { # Web settings 'SITENAME': 'Mailu', 'WEBSITE': 'https://mailu.io', + 'ADMIN' : 'none', 'WEB_ADMIN': '/admin', 'WEB_WEBMAIL': '/webmail', 'WEBMAIL': 'none', diff --git a/core/admin/mailu/sso/forms.py b/core/admin/mailu/sso/forms.py index a81667a2..bc2b5363 100644 --- a/core/admin/mailu/sso/forms.py +++ b/core/admin/mailu/sso/forms.py @@ -6,6 +6,8 @@ import flask_login import flask_wtf import re +LOCALPART_REGEX = "^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*$" + class LoginForm(flask_wtf.FlaskForm): class Meta: csrf = False diff --git a/core/admin/mailu/sso/templates/base_sso.html b/core/admin/mailu/sso/templates/base_sso.html index a95cb23b..0edd692c 100644 --- a/core/admin/mailu/sso/templates/base_sso.html +++ b/core/admin/mailu/sso/templates/base_sso.html @@ -6,46 +6,53 @@ - Mailu-login - {{ config["SITENAME"] }} + Mailu - {{ config["SITENAME"] }} - +
-
- -
- + +
-
- {% block main_action %} - {% endblock %} +
+
+
+

{% block title %}{% endblock %}

+ {% block subtitle %}{% endblock %} +
+
+ {% block main_action %} + {% endblock %} +
+
-

- {% block title %}{% endblock %} - {% block subtitle %}{% endblock %} -

-
+
{{ utils.flashed_messages(container=False) }} {% block content %}{% endblock %} -
+
- - + + diff --git a/core/admin/mailu/sso/templates/form_sso.html b/core/admin/mailu/sso/templates/form_sso.html index fcabad41..d28b82bf 100644 --- a/core/admin/mailu/sso/templates/form_sso.html +++ b/core/admin/mailu/sso/templates/form_sso.html @@ -1,7 +1,7 @@ {% extends "base_sso.html" %} {% block content %} -{% call macros.box() %} +{% call macros.card() %} {{ macros.form(form) }} {% endcall %} {% endblock %} diff --git a/core/admin/mailu/sso/templates/login.html b/core/admin/mailu/sso/templates/login.html index 851e6643..81d83a46 100644 --- a/core/admin/mailu/sso/templates/login.html +++ b/core/admin/mailu/sso/templates/login.html @@ -5,5 +5,9 @@ {% endblock %} {% block subtitle %} -{% trans %}to access IF statement for switch text for loggin in what the administration tools{% endtrans %} +{% if endpoint == 'ui.index' %} +{% trans %}to access the configuration page{% endtrans %} +{% elif endpoint == 'ui.webmail' %} +{% trans %}to access the webmail page{% endtrans %} +{% endif %} {% endblock %} diff --git a/core/admin/mailu/sso/templates/sidebar_sso.html b/core/admin/mailu/sso/templates/sidebar_sso.html new file mode 100644 index 00000000..6e919731 --- /dev/null +++ b/core/admin/mailu/sso/templates/sidebar_sso.html @@ -0,0 +1,60 @@ + diff --git a/core/admin/mailu/sso/views/base.py b/core/admin/mailu/sso/views/base.py index dd6f60c9..702b1582 100644 --- a/core/admin/mailu/sso/views/base.py +++ b/core/admin/mailu/sso/views/base.py @@ -1,5 +1,6 @@ from mailu import models from mailu.sso import sso, forms +from mailu.ui import access from flask import current_app as app import flask @@ -8,23 +9,15 @@ import flask_login @sso.route('/login', methods=['GET', 'POST']) def login(): form = forms.LoginForm() + endpoint = flask.request.args.get('next', 'ui.index') if form.validate_on_submit(): user = models.User.login(form.email.data, form.pw.data) if user: flask.session.regenerate() flask_login.login_user(user) - endpoint = flask.request.args.get('next', 'ui.index') return flask.redirect(flask.url_for(endpoint) or flask.url_for('ui.index')) else: flask.flash('Wrong e-mail or password', 'error') - return flask.render_template('login.html', form=form) - -""" -@ui.route('/logout', methods=['GET']) -@access.authenticated -def logout(): - flask_login.logout_user() - flask.session.destroy() - return flask.redirect(flask.url_for('.index')) -""" \ No newline at end of file + return flask.render_template('login.html', form=form, endpoint=endpoint) + \ No newline at end of file diff --git a/core/admin/mailu/ui/templates/sidebar.html b/core/admin/mailu/ui/templates/sidebar.html index 0fdae9db..0938f8ac 100644 --- a/core/admin/mailu/ui/templates/sidebar.html +++ b/core/admin/mailu/ui/templates/sidebar.html @@ -125,7 +125,7 @@ {% else %} diff --git a/core/admin/mailu/ui/templates/base.html b/core/admin/mailu/ui/templates/base.html index 12f61149..e646e579 100644 --- a/core/admin/mailu/ui/templates/base.html +++ b/core/admin/mailu/ui/templates/base.html @@ -38,7 +38,7 @@ {{ session['language'] }} From 9bc685c30b339b70b106f8c5a1f74d20449d70c9 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 29 Oct 2021 15:34:00 +0200 Subject: [PATCH 37/37] removed some more whitespace --- core/admin/mailu/internal/templates/default.sieve | 4 ++-- core/admin/mailu/manage.py | 2 +- core/admin/mailu/sso/__init__.py | 2 +- core/admin/mailu/sso/templates/form_sso.html | 6 +++--- core/admin/mailu/translations/pl/LC_MESSAGES/messages.po | 4 ++-- core/admin/mailu/ui/templates/macros.html | 2 +- core/admin/migrations/env.py | 2 +- core/dovecot/start.py | 2 +- core/postfix/start.py | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/core/admin/mailu/internal/templates/default.sieve b/core/admin/mailu/internal/templates/default.sieve index 5e995611..a29e7aba 100644 --- a/core/admin/mailu/internal/templates/default.sieve +++ b/core/admin/mailu/internal/templates/default.sieve @@ -19,7 +19,7 @@ if header :index 2 :matches "Received" "from * by * for <*>; *" } {% if user.spam_enabled %} -if spamtest :percent :value "gt" :comparator "i;ascii-numeric" "{{ user.spam_threshold }}" +if spamtest :percent :value "gt" :comparator "i;ascii-numeric" "{{ user.spam_threshold }}" { setflag "\\seen"; fileinto :create "Junk"; @@ -32,6 +32,6 @@ if exists "X-Virus" { stop; } -{% if user.reply_active %} +{% if user.reply_active %} vacation :days 1 {% if user.displayed_name != "" %}:from "{{ user.displayed_name }} <{{ user.email }}>"{% endif %} :subject "{{ user.reply_subject }}" "{{ user.reply_body }}"; {% endif %} diff --git a/core/admin/mailu/manage.py b/core/admin/mailu/manage.py index 54f4b826..937c9f49 100644 --- a/core/admin/mailu/manage.py +++ b/core/admin/mailu/manage.py @@ -119,7 +119,7 @@ def password(localpart, domain_name, password): """ Change the password of an user """ email = f'{localpart}@{domain_name}' - user = models.User.query.get(email) + user = models.User.query.get(email) if user: user.set_password(password) else: diff --git a/core/admin/mailu/sso/__init__.py b/core/admin/mailu/sso/__init__.py index cc066234..98b5abd0 100644 --- a/core/admin/mailu/sso/__init__.py +++ b/core/admin/mailu/sso/__init__.py @@ -1,5 +1,5 @@ from flask import Blueprint -sso = Blueprint('sso', __name__, static_folder=None ,template_folder='templates') +sso = Blueprint('sso', __name__, static_folder=None, template_folder='templates') from mailu.sso.views import * diff --git a/core/admin/mailu/sso/templates/form_sso.html b/core/admin/mailu/sso/templates/form_sso.html index efcc95a9..b14e7600 100644 --- a/core/admin/mailu/sso/templates/form_sso.html +++ b/core/admin/mailu/sso/templates/form_sso.html @@ -3,9 +3,9 @@ {%- block content %} {%- call macros.card() %}
- {{ macros.form_field(form.email) }} - {{ macros.form_field(form.pw) }} - {{ macros.form_fields( fields, label=False, class="btn btn-default", spacing=False) }} + {{ macros.form_field(form.email) }} + {{ macros.form_field(form.pw) }} + {{ macros.form_fields(fields, label=False, class="btn btn-default", spacing=False) }}
{%- endcall %} {%- endblock %} diff --git a/core/admin/mailu/translations/pl/LC_MESSAGES/messages.po b/core/admin/mailu/translations/pl/LC_MESSAGES/messages.po index 664ff571..09130a7b 100644 --- a/core/admin/mailu/translations/pl/LC_MESSAGES/messages.po +++ b/core/admin/mailu/translations/pl/LC_MESSAGES/messages.po @@ -551,11 +551,11 @@ msgid "" "cache\n" " expires." msgstr "" -"Jeśli nie wiesz, jak skonfigurować rekord MX dla swojej " +"Jeśli nie wiesz, jak skonfigurować rekord MX dla swojej " "strefy DNS,\n" "skontaktuj się z dostawcą DNS lub administratorem. Proszę również " "poczekać\n" -"kilka minut po ustawieniu MX , żeby pamięć podręczna " +"kilka minut po ustawieniu MX , żeby pamięć podręczna " "serwera lokalnego wygasła." #: mailu/ui/templates/fetch/create.html:4 diff --git a/core/admin/mailu/ui/templates/macros.html b/core/admin/mailu/ui/templates/macros.html index d18e6584..5143b697 100644 --- a/core/admin/mailu/ui/templates/macros.html +++ b/core/admin/mailu/ui/templates/macros.html @@ -58,7 +58,7 @@
{{ form.hidden_tag() }} {%- for field in form %} - {%- if bootstrap_is_hidden_field(field) %} + {%- if bootstrap_is_hidden_field(field) %} {{ field() }} {%- else %} {{ form_field(field) }} diff --git a/core/admin/migrations/env.py b/core/admin/migrations/env.py index cdfd2248..3e45bb18 100755 --- a/core/admin/migrations/env.py +++ b/core/admin/migrations/env.py @@ -37,7 +37,7 @@ def run_migrations_offline(): This configures the context with just a URL and not an Engine, though an Engine is acceptable - here as well. By skipping the Engine creation + here as well. By skipping the Engine creation we don't even need a DBAPI to be available. Calls to context.execute() here emit the given string to the diff --git a/core/dovecot/start.py b/core/dovecot/start.py index 1845eb93..03bdfa80 100755 --- a/core/dovecot/start.py +++ b/core/dovecot/start.py @@ -6,7 +6,7 @@ import multiprocessing import logging as log import sys -from podop import run_server +from podop import run_server from socrate import system, conf log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING")) diff --git a/core/postfix/start.py b/core/postfix/start.py index c889dce1..06a097b8 100755 --- a/core/postfix/start.py +++ b/core/postfix/start.py @@ -7,7 +7,7 @@ import multiprocessing import logging as log import sys -from podop import run_server +from podop import run_server from pwd import getpwnam from socrate import system, conf