diff --git a/Dockerfile b/Dockerfile index 9e298167..cbd3a4a1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ ENV DEBUG="False" \ ALLOW_PUBLIC_PROJECT_CREATION="True" \ BABEL_DEFAULT_TIMEZONE="UTC" \ GREENLET_TEST_CPP="no" \ - MAIL_DEFAULT_SENDER="('Budget manager', 'budget@notmyidea.org')" \ + MAIL_DEFAULT_SENDER="('Budget manager', 'admin@example.com')" \ MAIL_PASSWORD="" \ MAIL_PORT="25" \ MAIL_SERVER="localhost" \ @@ -23,6 +23,7 @@ ENV DEBUG="False" \ MAIL_USERNAME="" \ SECRET_KEY="tralala" \ SESSION_COOKIE_SECURE="True" \ + SHOW_ADMIN_EMAIL="True" \ SQLALCHEMY_DATABASE_URI="sqlite:////database/ihatemoney.db" \ SQLALCHEMY_TRACK_MODIFICATIONS="False" \ ENABLE_CAPTCHA="False" \ diff --git a/conf/entrypoint.sh b/conf/entrypoint.sh index 4d48f86c..81fcd720 100755 --- a/conf/entrypoint.sh +++ b/conf/entrypoint.sh @@ -19,6 +19,7 @@ MAIL_USE_TLS = $MAIL_USE_TLS MAIL_USERNAME = "$MAIL_USERNAME" SECRET_KEY = "$SECRET_KEY" SESSION_COOKIE_SECURE = $SESSION_COOKIE_SECURE +SHOW_ADMIN_EMAIL = $SHOW_ADMIN_EMAIL SQLACHEMY_DEBUG = DEBUG SQLALCHEMY_DATABASE_URI = "$SQLALCHEMY_DATABASE_URI" SQLALCHEMY_TRACK_MODIFICATIONS = $SQLALCHEMY_TRACK_MODIFICATIONS diff --git a/docker-compose.yml b/docker-compose.yml index 2890847a..40c7ed21 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,7 @@ services: - ALLOW_PUBLIC_PROJECT_CREATION=True - BABEL_DEFAULT_TIMEZONE=UTC - GREENLET_TEST_CPP=no - - MAIL_DEFAULT_SENDER=('Budget manager', 'budget@notmyidea.org') + - MAIL_DEFAULT_SENDER=('Budget manager', 'admin@example.com') - MAIL_PASSWORD= - MAIL_PORT=25 - MAIL_SERVER=localhost @@ -22,6 +22,7 @@ services: - MAIL_USERNAME= - SECRET_KEY=tralala - SESSION_COOKIE_SECURE=True + - SHOW_ADMIN_EMAIL=True - SQLALCHEMY_DATABASE_URI=sqlite:////database/ihatemoney.db - SQLALCHEMY_TRACK_MODIFICATIONS=False - ENABLE_CAPTCHA=False diff --git a/docs/configuration.md b/docs/configuration.md index 71ae2291..40149d6e 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -79,9 +79,19 @@ for details. A python tuple describing the name and email address to use when sending emails. -- **Default value:** `("Budget manager", "budget@notmyidea.org")` +- **Default value:** `("Budget manager", "admin@example.com")` - **Production value:** Any tuple you want. +## SHOW_ADMIN_EMAIL + +A boolean that determines whether the admin email (`MAIL_DEFAULT_SENDER`) is +shown in error messages. This also needs `MAIL_DEFAULT_SENDER` to be set to a +non default value to show it in the error messages. + +- **Default value:** `True` +- **Production value:** Usually `True` unless you don't want the admin + email to be shown for privacy reasons. + ## ACTIVATE_DEMO_PROJECT If set to `True`, a demo project will be available on the frontpage. diff --git a/ihatemoney/conf-templates/ihatemoney.cfg.j2 b/ihatemoney/conf-templates/ihatemoney.cfg.j2 index f33930dd..8538a206 100644 --- a/ihatemoney/conf-templates/ihatemoney.cfg.j2 +++ b/ihatemoney/conf-templates/ihatemoney.cfg.j2 @@ -19,7 +19,11 @@ SQLALCHEMY_TRACK_MODIFICATIONS = False SECRET_KEY = "{{ secret_key }}" # A python tuple describing the name and email adress of the sender of the mails. -MAIL_DEFAULT_SENDER = ("Budget manager", "budget@notmyidea.org") # CUSTOMIZE +MAIL_DEFAULT_SENDER = ("Budget manager", "admin@example.com") # CUSTOMIZE + +# A boolean that determines whether the admin email (MAIL_DEFAULT_SENDER) is +# shown in error messages. +SHOW_ADMIN_EMAIL = True # If set to True, a demonstration project will be activated. ACTIVATE_DEMO_PROJECT = True diff --git a/ihatemoney/default_settings.py b/ihatemoney/default_settings.py index 860e3b1e..46265f5c 100644 --- a/ihatemoney/default_settings.py +++ b/ihatemoney/default_settings.py @@ -3,7 +3,8 @@ DEBUG = SQLACHEMY_ECHO = False SQLALCHEMY_DATABASE_URI = "sqlite:////tmp/ihatemoney.db" SQLALCHEMY_TRACK_MODIFICATIONS = False SECRET_KEY = "tralala" -MAIL_DEFAULT_SENDER = ("Budget manager", "budget@notmyidea.org") +MAIL_DEFAULT_SENDER = ("Budget manager", "admin@example.com") +SHOW_ADMIN_EMAIL = True ACTIVATE_DEMO_PROJECT = True ADMIN_PASSWORD = "" ALLOW_PUBLIC_PROJECT_CREATION = True diff --git a/ihatemoney/tests/ihatemoney.cfg b/ihatemoney/tests/ihatemoney.cfg index 648a01c4..0d2b7368 100644 --- a/ihatemoney/tests/ihatemoney.cfg +++ b/ihatemoney/tests/ihatemoney.cfg @@ -6,4 +6,4 @@ SQLACHEMY_ECHO = DEBUG SECRET_KEY = "supersecret" -MAIL_DEFAULT_SENDER = ("Budget manager", "budget@notmyidea.org") +MAIL_DEFAULT_SENDER = ("Budget manager", "admin@example.com") diff --git a/ihatemoney/tests/ihatemoney_envvar.cfg b/ihatemoney/tests/ihatemoney_envvar.cfg index 0feec9b8..4790bd2c 100644 --- a/ihatemoney/tests/ihatemoney_envvar.cfg +++ b/ihatemoney/tests/ihatemoney_envvar.cfg @@ -6,4 +6,4 @@ SQLACHEMY_ECHO = DEBUG SECRET_KEY = "lalatra" -MAIL_DEFAULT_SENDER = ("Budget manager", "budget@notmyidea.org") +MAIL_DEFAULT_SENDER = ("Budget manager", "admin@example.com") diff --git a/ihatemoney/tests/main_test.py b/ihatemoney/tests/main_test.py index 678f976a..24243fac 100644 --- a/ihatemoney/tests/main_test.py +++ b/ihatemoney/tests/main_test.py @@ -26,7 +26,7 @@ class ConfigurationTestCase(BaseTestCase): self.assertFalse(self.app.config["SQLALCHEMY_TRACK_MODIFICATIONS"]) self.assertEqual( self.app.config["MAIL_DEFAULT_SENDER"], - ("Budget manager", "budget@notmyidea.org"), + ("Budget manager", "admin@example.com"), ) self.assertTrue(self.app.config["ACTIVATE_DEMO_PROJECT"]) self.assertTrue(self.app.config["ALLOW_PUBLIC_PROJECT_CREATION"]) diff --git a/ihatemoney/utils.py b/ihatemoney/utils.py index d0602098..9ed0c0d8 100644 --- a/ihatemoney/utils.py +++ b/ihatemoney/utils.py @@ -12,7 +12,7 @@ import socket from babel import Locale from babel.numbers import get_currency_name, get_currency_symbol -from flask import current_app, redirect, render_template +from flask import current_app, flash, redirect, render_template from flask_babel import get_locale, lazy_gettext as _ import jinja2 from markupsafe import Markup, escape @@ -48,6 +48,26 @@ def send_email(mail_message): return True +def flash_email_error(error_message, category="danger"): + """Helper to flash a message for email errors. It will also show the + admin email as a contact if MAIL_DEFAULT_SENDER is set to not the + default value and SHOW_ADMIN_EMAIL is True. + """ + (admin_name, admin_email) = current_app.config.get("MAIL_DEFAULT_SENDER") + error_extension = "." + if admin_email != "admin@example.com" and current_app.config.get( + "SHOW_ADMIN_EMAIL" + ): + error_extension = f" or contact the administrator at {admin_email}." + + flash( + _( + f"{error_message} Please check the email configuration of the server{error_extension}" + ), + category=category, + ) + + class Redirect303(HTTPException, RoutingException): """Raise if the map requests a redirect. This is for example the case if diff --git a/ihatemoney/web.py b/ihatemoney/web.py index bffbfc4e..dde205ab 100644 --- a/ihatemoney/web.py +++ b/ihatemoney/web.py @@ -55,6 +55,7 @@ from ihatemoney.utils import ( LoginThrottler, Redirect303, csv2list_of_dicts, + flash_email_error, format_form_errors, list_of_dicts2csv, list_of_dicts2json, @@ -329,11 +330,9 @@ def create_project(): else: # Display the error as a simple "info" alert, because it's # not critical and doesn't prevent using the project. - flash( - _( - "We tried to send you an reminder email, but there was an error. " - "You can still use the project normally." - ), + flash_email_error( + "We tried to send you an reminder email, but there was an error. " + "You can still use the project normally.", category="info", ) return redirect(url_for(".list_bills", project_id=project.id)) @@ -358,14 +357,9 @@ def remind_password(): if success: return redirect(url_for(".password_reminder_sent")) else: - flash( - _( - "Sorry, there was an error while sending you an email " - "with password reset instructions. " - "Please check the email configuration of the server " - "or contact the administrator." - ), - category="danger", + flash_email_error( + "Sorry, there was an error while sending you an email with " + "password reset instructions." ) # Fall-through: we stay on the same page and display the form again return render_template("password_reminder.html", form=form) @@ -588,13 +582,8 @@ def invite(): flash(_("Your invitations have been sent"), category="success") return redirect(url_for(".list_bills")) else: - flash( - _( - "Sorry, there was an error while trying to send the invitation emails. " - "Please check the email configuration of the server " - "or contact the administrator." - ), - category="danger", + flash_email_error( + "Sorry, there was an error while trying to send the invitation emails." ) # Fall-through: we stay on the same page and display the form again return render_template("send_invites.html", form=form)