diff --git a/src/backend/InvenTree/InvenTree/forms.py b/src/backend/InvenTree/InvenTree/auth_overrides.py
similarity index 72%
rename from src/backend/InvenTree/InvenTree/forms.py
rename to src/backend/InvenTree/InvenTree/auth_overrides.py
index d446ee0cd9..16f2aeb7a1 100644
--- a/src/backend/InvenTree/InvenTree/forms.py
+++ b/src/backend/InvenTree/InvenTree/auth_overrides.py
@@ -1,11 +1,11 @@
-"""Helper forms which subclass Django forms to provide additional functionality."""
+"""Overrides for allauth and adjacent packages to enforce InvenTree specific auth settings and restirctions."""
import logging
from urllib.parse import urlencode
from django import forms
from django.conf import settings
-from django.contrib.auth.models import Group, User
+from django.contrib.auth.models import Group
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
@@ -17,9 +17,6 @@ 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
-from crispy_forms.layout import Field, Layout
from dj_rest_auth.registration.serializers import RegisterSerializer
from rest_framework import serializers
@@ -31,115 +28,6 @@ from InvenTree.exceptions import log_error
logger = logging.getLogger('inventree')
-class HelperForm(forms.ModelForm):
- """Provides simple integration of crispy_forms extension."""
-
- # Custom field decorations can be specified here, per form class
- field_prefix = {}
- field_suffix = {}
- field_placeholder = {}
-
- def __init__(self, *args, **kwargs):
- """Setup layout."""
- super(forms.ModelForm, self).__init__(*args, **kwargs)
- self.helper = FormHelper()
-
- self.helper.form_tag = False
- self.helper.form_show_errors = True
-
- """
- Create a default 'layout' for this form.
- Ref: https://django-crispy-forms.readthedocs.io/en/latest/layouts.html
- This is required to do fancy things later (like adding PrependedText, etc).
-
- Simply create a 'blank' layout for each available field.
- """
-
- self.rebuild_layout()
-
- def rebuild_layout(self):
- """Build crispy layout out of current fields."""
- layouts = []
-
- for field in self.fields:
- prefix = self.field_prefix.get(field, None)
- suffix = self.field_suffix.get(field, None)
- placeholder = self.field_placeholder.get(field, '')
-
- # Look for font-awesome icons
- if prefix and prefix.startswith('fa-'):
- prefix = f""
-
- if suffix and suffix.startswith('fa-'):
- suffix = f""
-
- if prefix and suffix:
- layouts.append(
- Field(
- PrependedAppendedText(
- field,
- prepended_text=prefix,
- appended_text=suffix,
- placeholder=placeholder,
- )
- )
- )
-
- elif prefix:
- layouts.append(
- Field(PrependedText(field, prefix, placeholder=placeholder))
- )
-
- elif suffix:
- layouts.append(
- Field(AppendedText(field, suffix, placeholder=placeholder))
- )
-
- else:
- layouts.append(Field(field, placeholder=placeholder))
-
- self.helper.layout = Layout(*layouts)
-
-
-class SetPasswordForm(HelperForm):
- """Form for setting user password."""
-
- class Meta:
- """Metaclass options."""
-
- model = User
- fields = ['enter_password', 'confirm_password', 'old_password']
-
- enter_password = forms.CharField(
- max_length=100,
- min_length=8,
- required=True,
- initial='',
- widget=forms.PasswordInput(attrs={'autocomplete': 'off'}),
- label=_('Enter password'),
- help_text=_('Enter new password'),
- )
-
- confirm_password = forms.CharField(
- max_length=100,
- min_length=8,
- required=True,
- initial='',
- widget=forms.PasswordInput(attrs={'autocomplete': 'off'}),
- label=_('Confirm password'),
- help_text=_('Confirm new password'),
- )
-
- old_password = forms.CharField(
- label=_('Old password'),
- strip=False,
- required=False,
- widget=forms.PasswordInput(
- attrs={'autocomplete': 'current-password', 'autofocus': True}
- ),
- )
-
-
# override allauth
class CustomLoginForm(LoginForm):
"""Custom login form to override default allauth behaviour."""
@@ -214,7 +102,10 @@ class CustomTOTPDeviceForm(TOTPDeviceForm):
def registration_enabled():
"""Determine whether user registration is enabled."""
- if get_global_setting('LOGIN_ENABLE_REG') or InvenTree.sso.registration_enabled():
+ if (
+ get_global_setting('LOGIN_ENABLE_REG')
+ or InvenTree.sso.sso_registration_enabled()
+ ):
if settings.EMAIL_HOST:
return True
else:
@@ -316,10 +207,8 @@ class CustomAccountAdapter(
def get_email_confirmation_url(self, request, emailconfirmation):
"""Construct the email confirmation url."""
- from InvenTree.helpers_model import construct_absolute_url
-
url = super().get_email_confirmation_url(request, emailconfirmation)
- url = construct_absolute_url(url)
+ url = InvenTree.helpers_model.construct_absolute_url(url)
return url
diff --git a/src/backend/InvenTree/InvenTree/settings.py b/src/backend/InvenTree/InvenTree/settings.py
index fea09801ac..bd2829b933 100644
--- a/src/backend/InvenTree/InvenTree/settings.py
+++ b/src/backend/InvenTree/InvenTree/settings.py
@@ -592,7 +592,7 @@ REST_AUTH = {
OLD_PASSWORD_FIELD_ENABLED = True
REST_AUTH_REGISTER_SERIALIZERS = {
- 'REGISTER_SERIALIZER': 'InvenTree.forms.CustomRegisterSerializer'
+ 'REGISTER_SERIALIZER': 'InvenTree.auth_overrides.CustomRegisterSerializer'
}
# JWT settings - rest_framework_simplejwt
@@ -1312,8 +1312,8 @@ REMOVE_SUCCESS_URL = 'settings'
# override forms / adapters
ACCOUNT_FORMS = {
- 'login': 'InvenTree.forms.CustomLoginForm',
- 'signup': 'InvenTree.forms.CustomSignupForm',
+ 'login': 'InvenTree.auth_overrides.CustomLoginForm',
+ 'signup': 'InvenTree.auth_overrides.CustomSignupForm',
'add_email': 'allauth.account.forms.AddEmailForm',
'change_password': 'allauth.account.forms.ChangePasswordForm',
'set_password': 'allauth.account.forms.SetPasswordForm',
@@ -1321,12 +1321,12 @@ ACCOUNT_FORMS = {
'reset_password_from_key': 'allauth.account.forms.ResetPasswordKeyForm',
'disconnect': 'allauth.socialaccount.forms.DisconnectForm',
}
-ALLAUTH_2FA_FORMS = {'setup': 'InvenTree.forms.CustomTOTPDeviceForm'}
+ALLAUTH_2FA_FORMS = {'setup': 'InvenTree.auth_overrides.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'
+SOCIALACCOUNT_ADAPTER = 'InvenTree.auth_overrides.CustomSocialAccountAdapter'
+ACCOUNT_ADAPTER = 'InvenTree.auth_overrides.CustomAccountAdapter'
# Markdownify configuration
# Ref: https://django-markdownify.readthedocs.io/en/latest/settings.html
diff --git a/src/backend/InvenTree/InvenTree/social_auth_urls.py b/src/backend/InvenTree/InvenTree/social_auth_urls.py
index a7ad13dd6f..27660d2502 100644
--- a/src/backend/InvenTree/InvenTree/social_auth_urls.py
+++ b/src/backend/InvenTree/InvenTree/social_auth_urls.py
@@ -198,8 +198,8 @@ class SocialProviderListView(ListAPI):
provider_list.append(provider_data)
data = {
- 'sso_enabled': InvenTree.sso.login_enabled(),
- 'sso_registration': InvenTree.sso.registration_enabled(),
+ 'sso_enabled': InvenTree.sso.sso_login_enabled(),
+ 'sso_registration': InvenTree.sso.sso_registration_enabled(),
'mfa_required': settings.MFA_ENABLED
and get_global_setting('LOGIN_ENFORCE_MFA'),
'mfa_enabled': settings.MFA_ENABLED,
diff --git a/src/backend/InvenTree/InvenTree/sso.py b/src/backend/InvenTree/InvenTree/sso.py
index b77e9c136e..31de8dd167 100644
--- a/src/backend/InvenTree/InvenTree/sso.py
+++ b/src/backend/InvenTree/InvenTree/sso.py
@@ -69,12 +69,12 @@ def provider_display_name(provider):
return provider.name
-def login_enabled() -> bool:
+def sso_login_enabled() -> bool:
"""Return True if SSO login is enabled."""
return str2bool(get_global_setting('LOGIN_ENABLE_SSO'))
-def registration_enabled() -> bool:
+def sso_registration_enabled() -> bool:
"""Return True if SSO registration is enabled."""
return str2bool(get_global_setting('LOGIN_ENABLE_SSO_REG'))
diff --git a/src/backend/InvenTree/InvenTree/test_sso.py b/src/backend/InvenTree/InvenTree/test_sso.py
index e20f11d3ae..31481bc09d 100644
--- a/src/backend/InvenTree/InvenTree/test_sso.py
+++ b/src/backend/InvenTree/InvenTree/test_sso.py
@@ -8,7 +8,7 @@ from allauth.socialaccount.models import SocialAccount, SocialLogin
from common.models import InvenTreeSetting
from InvenTree import sso
-from InvenTree.forms import RegistratonMixin
+from InvenTree.auth_overrides import RegistratonMixin
class Dummy: