fix: restore tubco user onboarding access
Some checks failed
CI / python-validation (push) Has been cancelled
CI / docker-release-gate (push) Has been cancelled
i18n / compile-translations (push) Has been cancelled

This commit is contained in:
Md Bayazid Bostame
2026-04-08 13:38:30 +02:00
parent 0a38e04606
commit b60d9eaeb7
4 changed files with 87 additions and 1 deletions

View File

@@ -131,7 +131,13 @@ class AppLoginForm(forms.Form):
username = cleaned_data.get('username')
password = cleaned_data.get('password')
if username and password:
self.user_cache = authenticate(self.request, username=username, password=password)
login_value = (username or '').strip()
auth_username = login_value
user_model = get_user_model()
matched_user = user_model.objects.filter(email__iexact=login_value).first()
if matched_user:
auth_username = matched_user.username
self.user_cache = authenticate(self.request, username=auth_username, password=password)
if self.user_cache is None:
raise ValidationError(self.error_messages['invalid_login'], code='invalid_login')
if not self.user_cache.is_active:

View File

@@ -0,0 +1,62 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('workflows', '0058_alter_formsectionconfig_options_and_more'),
]
operations = [
migrations.SeparateDatabaseAndState(
database_operations=[
migrations.RunSQL(
sql=(
"ALTER TABLE workflows_userprofile "
"ADD COLUMN IF NOT EXISTS temporary_role_key varchar(64) NOT NULL DEFAULT '';"
),
reverse_sql=(
"ALTER TABLE workflows_userprofile "
"DROP COLUMN IF EXISTS temporary_role_key;"
),
),
migrations.RunSQL(
sql=(
"ALTER TABLE workflows_userprofile "
"ADD COLUMN IF NOT EXISTS temporary_role_expires_at timestamptz NULL;"
),
reverse_sql=(
"ALTER TABLE workflows_userprofile "
"DROP COLUMN IF EXISTS temporary_role_expires_at;"
),
),
migrations.RunSQL(
sql=(
"ALTER TABLE workflows_userprofile "
"ADD COLUMN IF NOT EXISTS temporary_role_reason text NOT NULL DEFAULT '';"
),
reverse_sql=(
"ALTER TABLE workflows_userprofile "
"DROP COLUMN IF EXISTS temporary_role_reason;"
),
),
],
state_operations=[
migrations.AddField(
model_name='userprofile',
name='temporary_role_key',
field=models.CharField(blank=True, default='', max_length=64),
),
migrations.AddField(
model_name='userprofile',
name='temporary_role_expires_at',
field=models.DateTimeField(blank=True, null=True),
),
migrations.AddField(
model_name='userprofile',
name='temporary_role_reason',
field=models.TextField(blank=True, default=''),
),
],
),
]

View File

@@ -61,6 +61,9 @@ class UserProfile(models.Model):
totp_secret = models.CharField(max_length=64, blank=True, default='')
totp_enabled = models.BooleanField(default=False)
totp_confirmed_at = models.DateTimeField(null=True, blank=True)
temporary_role_key = models.CharField(max_length=64, blank=True, default='')
temporary_role_expires_at = models.DateTimeField(null=True, blank=True)
temporary_role_reason = models.TextField(blank=True, default='')
totp_recovery_codes = models.JSONField(default=list, blank=True)
notification_preferences = models.JSONField(default=dict, blank=True)
updated_at = models.DateTimeField(auto_now=True)

View File

@@ -32,6 +32,10 @@ class AccountUISmokeTests(TestCase):
def test_user_profile_is_created_automatically(self):
self.assertTrue(UserProfile.objects.filter(user=self.user).exists())
profile = UserProfile.objects.get(user=self.user)
self.assertEqual(profile.temporary_role_key, '')
self.assertIsNone(profile.temporary_role_expires_at)
self.assertEqual(profile.temporary_role_reason, '')
def test_notification_preferences_can_be_updated(self):
response = self.client.post(
@@ -179,3 +183,14 @@ class AccountUISmokeTests(TestCase):
self.assertEqual(response.status_code, 302)
profile.refresh_from_db()
self.assertEqual(profile.totp_recovery_codes, [])
def test_login_accepts_email_after_password_is_set(self):
client = Client()
response = client.post(
'/accounts/login/',
{'username': 'profile@example.com', 'password': 'secret-12345'},
HTTP_HOST='localhost',
)
self.assertEqual(response.status_code, 302)