feat: deprecate email, pre-verify users + documentation
This commit is contained in:
@@ -7,12 +7,12 @@ from apps.accounts.models import PhoneOTP, User
|
||||
@admin.register(User)
|
||||
class UserAdmin(DjangoUserAdmin):
|
||||
model = User
|
||||
list_display = ("email", "phone_number", "role", "is_staff", "is_phone_verified")
|
||||
list_display = ("phone_number", "email", "role", "is_staff", "is_phone_verified")
|
||||
list_filter = ("role", "is_staff", "is_phone_verified")
|
||||
ordering = ("email",)
|
||||
ordering = ("phone_number",)
|
||||
search_fields = ("email", "phone_number")
|
||||
fieldsets = (
|
||||
(None, {"fields": ("email", "password")}),
|
||||
(None, {"fields": ("phone_number", "password")}),
|
||||
("Personal", {"fields": ("first_name", "last_name", "phone_number")}),
|
||||
("Roles", {"fields": ("role", "is_phone_verified")}),
|
||||
("Permissions", {"fields": ("is_active", "is_staff", "is_superuser", "groups", "user_permissions")}),
|
||||
@@ -21,7 +21,7 @@ class UserAdmin(DjangoUserAdmin):
|
||||
add_fieldsets = (
|
||||
(None, {
|
||||
"classes": ("wide",),
|
||||
"fields": ("email", "password1", "password2", "role"),
|
||||
"fields": ("phone_number", "password1", "password2", "role"),
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
@@ -71,8 +71,18 @@ class User(AbstractBaseUser, PermissionsMixin):
|
||||
),
|
||||
]
|
||||
|
||||
@property
|
||||
def display_name(self) -> str:
|
||||
first = (self.first_name or "").strip()
|
||||
last = (self.last_name or "").strip()
|
||||
if first or last:
|
||||
return f"{first} {last}".strip()
|
||||
if self.email:
|
||||
return self.email
|
||||
return self.phone_number
|
||||
|
||||
def __str__(self):
|
||||
return self.email or self.phone_number or str(self.id)
|
||||
return self.display_name
|
||||
|
||||
|
||||
class OtpChannel(models.TextChoices):
|
||||
|
||||
@@ -76,3 +76,25 @@ def test_phone_auth_refresh_endpoint_still_works(client):
|
||||
)
|
||||
assert refresh_response.status_code == 200
|
||||
assert "access" in refresh_response.json()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@override_settings(OTP_PROVIDER="console")
|
||||
def test_phone_auth_verify_returns_404_when_user_removed(client):
|
||||
with patch("apps.accounts.services.otp.generate_code", return_value="123456"):
|
||||
request_response = client.post(
|
||||
reverse("phone_auth_request"),
|
||||
{"phone_number": "0512345678", "channel": "sms"},
|
||||
content_type="application/json",
|
||||
)
|
||||
request_id = request_response.json()["request_id"]
|
||||
|
||||
User.objects.filter(phone_number="+966512345678").delete()
|
||||
|
||||
verify_response = client.post(
|
||||
reverse("phone_auth_verify"),
|
||||
{"request_id": request_id, "code": "123456"},
|
||||
content_type="application/json",
|
||||
)
|
||||
|
||||
assert verify_response.status_code == 404
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import pytest
|
||||
|
||||
from apps.accounts.models import User
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_display_name_prefers_full_name():
|
||||
user = User.objects.create_user(
|
||||
phone_number="+966500000001",
|
||||
first_name="Sara",
|
||||
last_name="Ali",
|
||||
email="sara@example.com",
|
||||
)
|
||||
|
||||
assert user.display_name == "Sara Ali"
|
||||
assert str(user) == "Sara Ali"
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_display_name_falls_back_to_email():
|
||||
user = User.objects.create_user(
|
||||
phone_number="+966500000002",
|
||||
email="fallback@example.com",
|
||||
)
|
||||
|
||||
assert user.display_name == "fallback@example.com"
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_display_name_falls_back_to_phone_when_no_email():
|
||||
user = User.objects.create_user(
|
||||
phone_number="+966500000003",
|
||||
)
|
||||
|
||||
assert user.display_name == "+966500000003"
|
||||
Reference in New Issue
Block a user