diff --git a/core/admin/Dockerfile b/core/admin/Dockerfile index cdc426c6..a4f28481 100644 --- a/core/admin/Dockerfile +++ b/core/admin/Dockerfile @@ -38,7 +38,7 @@ RUN set -eu \ && pip3 install -r requirements.txt \ && apk del --no-cache build-dep -COPY --from=assets static ./mailu/ui/static +COPY --from=assets static ./mailu/static COPY mailu ./mailu COPY migrations ./migrations COPY start.py /start.py @@ -51,4 +51,4 @@ ENV FLASK_APP mailu CMD /start.py -HEALTHCHECK CMD curl -f -L http://localhost/ui/login?next=ui.index || exit 1 +HEALTHCHECK CMD curl -f -L http://localhost/sso/login?next=ui.index || exit 1 diff --git a/core/admin/mailu/__init__.py b/core/admin/mailu/__init__.py index 7fb04380..e4024e47 100644 --- a/core/admin/mailu/__init__.py +++ b/core/admin/mailu/__init__.py @@ -11,7 +11,7 @@ import hmac def create_app_from_config(config): """ Create a new application based on the given configuration """ - app = flask.Flask(__name__) + app = flask.Flask(__name__, static_folder='static', static_url_path='/static') app.cli.add_command(manage.mailu) # Bootstrap is used for error display and flash messages @@ -58,10 +58,10 @@ def create_app_from_config(config): ) # Import views - from mailu import ui, internal - app.register_blueprint(ui.ui, url_prefix='/ui') + from mailu import ui, internal, sso + app.register_blueprint(ui.ui, url_prefix=app.config['WEB_ADMIN']) app.register_blueprint(internal.internal, url_prefix='/internal') - + app.register_blueprint(sso.sso, url_prefix='/sso') return app @@ -70,3 +70,4 @@ def create_app(): """ config = configuration.ConfigManager() return create_app_from_config(config) + diff --git a/core/admin/mailu/configuration.py b/core/admin/mailu/configuration.py index d33efa12..9829f798 100644 --- a/core/admin/mailu/configuration.py +++ b/core/admin/mailu/configuration.py @@ -58,6 +58,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/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/internal/views/auth.py b/core/admin/mailu/internal/views/auth.py index c5cd9e28..1afb53b5 100644 --- a/core/admin/mailu/internal/views/auth.py +++ b/core/admin/mailu/internal/views/auth.py @@ -41,7 +41,7 @@ def nginx_authentication(): elif is_valid_user: utils.limiter.rate_limit_user(username, client_ip) else: - rate_limit_ip(client_ip) + utils.limiter.rate_limit_ip(client_ip) return response @internal.route("/auth/admin") 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 new file mode 100644 index 00000000..98b5abd0 --- /dev/null +++ b/core/admin/mailu/sso/__init__.py @@ -0,0 +1,5 @@ +from flask import Blueprint + +sso = Blueprint('sso', __name__, static_folder=None, 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..c190b8bc --- /dev/null +++ b/core/admin/mailu/sso/forms.py @@ -0,0 +1,11 @@ +from wtforms import validators, fields +from flask_babel import lazy_gettext as _ +import flask_wtf + +class LoginForm(flask_wtf.FlaskForm): + class Meta: + csrf = False + email = fields.StringField(_('E-mail'), [validators.Email(), validators.DataRequired()]) + pw = fields.PasswordField(_('Password'), [validators.DataRequired()]) + submitAdmin = fields.SubmitField(_('Sign in')) + submitWebmail = 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..9dfb25a5 --- /dev/null +++ b/core/admin/mailu/sso/templates/base_sso.html @@ -0,0 +1,86 @@ +{%- import "macros.html" as macros %} +{%- import "bootstrap/utils.html" as utils %} + + +
+ + + + + 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/__init__.py b/core/admin/mailu/ui/__init__.py
index ec3601a1..49338cd1 100644
--- a/core/admin/mailu/ui/__init__.py
+++ b/core/admin/mailu/ui/__init__.py
@@ -1,6 +1,6 @@
from flask import Blueprint
-ui = Blueprint('ui', __name__, static_folder='static', template_folder='templates')
+ui = Blueprint('ui', __name__, static_folder=None, template_folder='templates')
from mailu.ui.views import *
diff --git a/core/admin/mailu/ui/forms.py b/core/admin/mailu/ui/forms.py
index 60be1699..24d6f899 100644
--- a/core/admin/mailu/ui/forms.py
+++ b/core/admin/mailu/ui/forms.py
@@ -44,15 +44,6 @@ 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()])
max_users = fields_.IntegerField(_('Maximum user count'), [validators.NumberRange(min=-1)], default=10)
diff --git a/core/admin/mailu/ui/templates/base.html b/core/admin/mailu/ui/templates/base.html
index fc27d12b..e646e579 100644
--- a/core/admin/mailu/ui/templates/base.html
+++ b/core/admin/mailu/ui/templates/base.html
@@ -1,15 +1,15 @@
{%- import "macros.html" as macros %}
{%- import "bootstrap/utils.html" as utils %}
-
+