From 435508be1e33e30c2f5990d4c9b687c3bfd44cdc Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Fri, 27 Oct 2023 13:39:36 +0200 Subject: [PATCH 1/3] Introduce AUTH_REQUIRE_TOKENS --- core/admin/mailu/configuration.py | 1 + core/admin/mailu/internal/nginx.py | 8 ++++++-- docs/configuration.rst | 6 +++++- towncrier/newsfragments/3004.misc | 1 + 4 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 towncrier/newsfragments/3004.misc diff --git a/core/admin/mailu/configuration.py b/core/admin/mailu/configuration.py index d324bf8d..caccfe5e 100644 --- a/core/admin/mailu/configuration.py +++ b/core/admin/mailu/configuration.py @@ -72,6 +72,7 @@ DEFAULT_CONFIG = { 'LOGO_URL': None, 'LOGO_BACKGROUND': None, # Advanced settings + 'AUTH_REQUIRE_TOKENS': False, 'API': False, 'WEB_API': '/api', 'API_TOKEN': None, diff --git a/core/admin/mailu/internal/nginx.py b/core/admin/mailu/internal/nginx.py index 90b59712..4378ad67 100644 --- a/core/admin/mailu/internal/nginx.py +++ b/core/admin/mailu/internal/nginx.py @@ -50,8 +50,12 @@ def check_credentials(user, password, ip, protocol=None, auth_port=None, source_ app.logger.info(f'Login attempt for: {user}/{protocol}/{auth_port} from: {ip}/{source_port}: failed: badip: token-{token.id}: {token.comment or ""!r}') return False # we can return directly here since the token is valid if user.check_password(password): - app.logger.info(f'Login attempt for: {user}/{protocol}/{auth_port} from: {ip}/{source_port}: success: password') - return True + if app.config['AUTH_REQUIRE_TOKENS'] and protocol != 'web': + app.logger.info(f'Login attempt for: {user}/{protocol}/{auth_port} from: {ip}/{source_port}: failed: password but AUTH_REQUIRE_TOKENS=True') + return False + else: + app.logger.info(f'Login attempt for: {user}/{protocol}/{auth_port} from: {ip}/{source_port}: success: password') + return True app.logger.info(f'Login attempt for: {user}/{protocol}/{auth_port} from: {ip}/{source_port}: failed: badauth: {utils.truncated_pw_hash(password)}') return False diff --git a/docs/configuration.rst b/docs/configuration.rst index fbf284a4..bccc9116 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -214,7 +214,11 @@ Depending on your particular deployment you most probably will want to change th Advanced settings ----------------- -The ``API_TOKEN`` (default: None) configures the authentication token. +The ``AUTH_REQUIRE_TOKENS`` (default: False) setting controls whether thick clients can + authenticate using passwords or whether they are forced to use tokens/application + specific passwords. + +The ``API_TOKEN`` (default: None) setting configures the authentication token. This token must be passed as request header to the API as authentication token. This is a mandatory setting for using the RESTful API. diff --git a/towncrier/newsfragments/3004.misc b/towncrier/newsfragments/3004.misc new file mode 100644 index 00000000..69f46598 --- /dev/null +++ b/towncrier/newsfragments/3004.misc @@ -0,0 +1 @@ +Introduce AUTH_REQUIRE_TOKENS to enforce that thick clients use tokens instead of passwords From 3e2a6d84ce6ed8db6a75bc665b9b1a9adb371f9a Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Fri, 27 Oct 2023 13:41:51 +0200 Subject: [PATCH 2/3] doh --- towncrier/newsfragments/{3004.misc => 3007.misc} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename towncrier/newsfragments/{3004.misc => 3007.misc} (100%) diff --git a/towncrier/newsfragments/3004.misc b/towncrier/newsfragments/3007.misc similarity index 100% rename from towncrier/newsfragments/3004.misc rename to towncrier/newsfragments/3007.misc From 2494a344a7101ae36cd36d4837f2caa2dcf14139 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Fri, 27 Oct 2023 15:14:51 +0200 Subject: [PATCH 3/3] Ammend wording as suggested --- 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 4378ad67..12befa84 100644 --- a/core/admin/mailu/internal/nginx.py +++ b/core/admin/mailu/internal/nginx.py @@ -51,7 +51,7 @@ def check_credentials(user, password, ip, protocol=None, auth_port=None, source_ return False # we can return directly here since the token is valid if user.check_password(password): if app.config['AUTH_REQUIRE_TOKENS'] and protocol != 'web': - app.logger.info(f'Login attempt for: {user}/{protocol}/{auth_port} from: {ip}/{source_port}: failed: password but AUTH_REQUIRE_TOKENS=True') + app.logger.info(f'Login attempt for: {user}/{protocol}/{auth_port} from: {ip}/{source_port}: failed: password ok, but a token is required') return False else: app.logger.info(f'Login attempt for: {user}/{protocol}/{auth_port} from: {ip}/{source_port}: success: password')