diff --git a/docs/docs/start/config.md b/docs/docs/start/config.md index 98498f25fc..e038c78753 100644 --- a/docs/docs/start/config.md +++ b/docs/docs/start/config.md @@ -297,6 +297,10 @@ Alternatively this location can be specified with the `INVENTREE_BACKUP_DIR` env InvenTree provides allowance for additional sign-in options. The following options are not enabled by default, and care must be taken by the system administrator when configuring these settings. +| Environment Variable | Configuration File | Description | Default | +| --- | --- | --- | --- | +| INVENTREE_MFA_ENABLED | mfa_enabled | Enable or disable multi-factor authentication support for the InvenTree server | True | + ### Single Sign On Single Sign On (SSO) allows users to sign in to InvenTree using a third-party authentication provider. This functionality is provided by the [django-allauth](https://docs.allauth.org/en/latest/) package. diff --git a/src/backend/InvenTree/InvenTree/forms.py b/src/backend/InvenTree/InvenTree/forms.py index cffb987e1f..0997f1a38b 100644 --- a/src/backend/InvenTree/InvenTree/forms.py +++ b/src/backend/InvenTree/InvenTree/forms.py @@ -15,6 +15,7 @@ from allauth.account.forms import LoginForm, SignupForm, set_form_field_order from allauth.core.exceptions import ImmediateHttpResponse from allauth.socialaccount.adapter import DefaultSocialAccountAdapter from allauth_2fa.adapter import OTPAdapter +from allauth_2fa.forms import TOTPDeviceForm from allauth_2fa.utils import user_has_valid_totp_device from crispy_forms.bootstrap import AppendedText, PrependedAppendedText, PrependedText from crispy_forms.helper import FormHelper @@ -211,6 +212,16 @@ class CustomSignupForm(SignupForm): return cleaned_data +class CustomTOTPDeviceForm(TOTPDeviceForm): + """Ensure that db registration is enabled.""" + + def __init__(self, user, metadata=None, **kwargs): + """Override to check if registration is open.""" + if not settings.MFA_ENABLED: + raise forms.ValidationError(_('MFA Registration is disabled.')) + super().__init__(user, metadata, **kwargs) + + def registration_enabled(): """Determine whether user registration is enabled.""" if get_global_setting('LOGIN_ENABLE_REG') or InvenTree.sso.registration_enabled(): diff --git a/src/backend/InvenTree/InvenTree/settings.py b/src/backend/InvenTree/InvenTree/settings.py index cedeb4e215..0d7b306ff2 100644 --- a/src/backend/InvenTree/InvenTree/settings.py +++ b/src/backend/InvenTree/InvenTree/settings.py @@ -1210,6 +1210,9 @@ ACCOUNT_FORMS = { 'reset_password_from_key': 'allauth.account.forms.ResetPasswordKeyForm', 'disconnect': 'allauth.socialaccount.forms.DisconnectForm', } +ALLAUTH_2FA_FORMS = {'setup': 'InvenTree.forms.CustomTOTPDeviceForm'} +# Determine if multi-factor authentication is enabled for this server (default = True) +MFA_ENABLED = get_boolean_setting('INVENTREE_MFA_ENABLED', 'mfa_enabled', True) SOCIALACCOUNT_ADAPTER = 'InvenTree.forms.CustomSocialAccountAdapter' ACCOUNT_ADAPTER = 'InvenTree.forms.CustomAccountAdapter' diff --git a/src/backend/InvenTree/InvenTree/social_auth_urls.py b/src/backend/InvenTree/InvenTree/social_auth_urls.py index 49d9e461ee..9702750b49 100644 --- a/src/backend/InvenTree/InvenTree/social_auth_urls.py +++ b/src/backend/InvenTree/InvenTree/social_auth_urls.py @@ -3,6 +3,7 @@ import logging from importlib import import_module +from django.conf import settings from django.urls import NoReverseMatch, include, path, reverse from allauth.account.models import EmailAddress @@ -177,7 +178,9 @@ class SocialProviderListView(ListAPI): data = { 'sso_enabled': InvenTree.sso.login_enabled(), 'sso_registration': InvenTree.sso.registration_enabled(), - 'mfa_required': get_global_setting('LOGIN_ENFORCE_MFA'), + 'mfa_required': settings.MFA_ENABLED + and get_global_setting('LOGIN_ENFORCE_MFA'), + 'mfa_enabled': settings.MFA_ENABLED, 'providers': provider_list, 'registration_enabled': get_global_setting('LOGIN_ENABLE_REG'), 'password_forgotten_enabled': get_global_setting('LOGIN_ENABLE_PWD_FORGOT'),