fix: deprecate passwords, use phone auth source of truth

This commit is contained in:
2026-03-14 00:47:31 +03:00
parent c391a9b8e5
commit 0b76356169
4 changed files with 60 additions and 2 deletions
@@ -47,3 +47,32 @@ def test_phone_auth_creates_user_and_issues_tokens(client):
user = User.objects.filter(phone_number="+966512345678").first()
assert user is not None
assert user.is_phone_verified is True
@pytest.mark.django_db
@override_settings(OTP_PROVIDER="console")
def test_phone_auth_refresh_endpoint_still_works(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"]
verify_response = client.post(
reverse("phone_auth_verify"),
{"request_id": request_id, "code": "123456"},
content_type="application/json",
)
assert verify_response.status_code == 200
refresh = verify_response.json()["refresh"]
refresh_response = client.post(
reverse("token_refresh"),
{"refresh": refresh},
content_type="application/json",
)
assert refresh_response.status_code == 200
assert "access" in refresh_response.json()
@@ -91,3 +91,17 @@ def test_db_rejects_duplicate_phone_number():
User.objects.create_user(phone_number="+966512345678")
with pytest.raises(IntegrityError):
User.objects.create_user(phone_number="+966512345678")
@pytest.mark.django_db
def test_password_token_endpoint_is_disabled(client):
User.objects.create_user(phone_number="+966512345678", password="StrongPass123")
response = client.post(
reverse("token_obtain_pair"),
{"phone_number": "+966512345678", "password": "StrongPass123"},
content_type="application/json",
)
assert response.status_code == 410
assert "detail" in response.json()
+3 -2
View File
@@ -1,5 +1,5 @@
from django.urls import path
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
from rest_framework_simplejwt.views import TokenRefreshView
from apps.accounts.views import (
MeView,
@@ -7,6 +7,7 @@ from apps.accounts.views import (
OTPVerifyView,
PhoneAuthRequestView,
PhoneAuthVerifyView,
PasswordTokenObtainDeprecatedView,
RegisterView,
SocialLoginPlaceholderView,
)
@@ -14,7 +15,7 @@ from apps.accounts.views import (
urlpatterns = [
path("register/", RegisterView.as_view(), name="register"),
path("me/", MeView.as_view(), name="me"),
path("token/", TokenObtainPairView.as_view(), name="token_obtain_pair"),
path("token/", PasswordTokenObtainDeprecatedView.as_view(), name="token_obtain_pair"),
path("token/refresh/", TokenRefreshView.as_view(), name="token_refresh"),
path("otp/request/", OTPRequestView.as_view(), name="otp_request"),
path("otp/verify/", OTPVerifyView.as_view(), name="otp_verify"),
+14
View File
@@ -169,3 +169,17 @@ class SocialLoginPlaceholderView(APIView):
{"detail": _("Social login not configured yet. Add OAuth provider config.")},
status=status.HTTP_501_NOT_IMPLEMENTED,
)
class PasswordTokenObtainDeprecatedView(APIView):
permission_classes = [permissions.AllowAny]
def post(self, request):
return Response(
{
"detail": _(
"Password login is deprecated. Use /api/auth/phone/request/ then /api/auth/phone/verify/."
)
},
status=status.HTTP_410_GONE,
)