mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2026-02-05 06:05:18 -05:00
feat: Add analytics, incident, and alert models and APIs, along with user permissions and bulk profile lookups.
This commit is contained in:
@@ -166,7 +166,7 @@ def setup_totp(request):
|
||||
def activate_totp(request):
|
||||
"""Verify TOTP code and activate MFA."""
|
||||
from allauth.mfa.models import Authenticator
|
||||
from allauth.mfa.recovery_codes.internal import auth as recovery_auth
|
||||
from allauth.mfa.recovery_codes.internal.auth import RecoveryCodes
|
||||
from allauth.mfa.totp.internal import auth as totp_auth
|
||||
|
||||
user = request.user
|
||||
@@ -178,8 +178,9 @@ def activate_totp(request):
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
|
||||
# Get pending secret from session
|
||||
secret = request.session.get("pending_totp_secret")
|
||||
# Get pending secret from session OR from request body
|
||||
# (request body is used as fallback for JWT auth where sessions may not persist)
|
||||
secret = request.session.get("pending_totp_secret") or request.data.get("secret", "").strip()
|
||||
if not secret:
|
||||
return Response(
|
||||
{"detail": "No pending TOTP setup. Please start setup again."},
|
||||
@@ -207,16 +208,13 @@ def activate_totp(request):
|
||||
data={"secret": secret},
|
||||
)
|
||||
|
||||
# Generate recovery codes
|
||||
codes = recovery_auth.generate_recovery_codes()
|
||||
Authenticator.objects.create(
|
||||
user=user,
|
||||
type=Authenticator.Type.RECOVERY_CODES,
|
||||
data={"codes": codes},
|
||||
)
|
||||
# Generate recovery codes using allauth's RecoveryCodes API
|
||||
recovery_instance = RecoveryCodes.activate(user)
|
||||
codes = recovery_instance.get_unused_codes()
|
||||
|
||||
# Clear session
|
||||
del request.session["pending_totp_secret"]
|
||||
# Clear session (only if it exists - won't exist with JWT auth + secret from body)
|
||||
if "pending_totp_secret" in request.session:
|
||||
del request.session["pending_totp_secret"]
|
||||
|
||||
return Response(
|
||||
{
|
||||
@@ -361,7 +359,7 @@ def verify_totp(request):
|
||||
def regenerate_recovery_codes(request):
|
||||
"""Regenerate recovery codes."""
|
||||
from allauth.mfa.models import Authenticator
|
||||
from allauth.mfa.recovery_codes.internal import auth as recovery_auth
|
||||
from allauth.mfa.recovery_codes.internal.auth import RecoveryCodes
|
||||
|
||||
user = request.user
|
||||
password = request.data.get("password", "")
|
||||
@@ -380,15 +378,14 @@ def regenerate_recovery_codes(request):
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
|
||||
# Generate new codes
|
||||
codes = recovery_auth.generate_recovery_codes()
|
||||
# Delete existing recovery codes first (so activate creates new ones)
|
||||
Authenticator.objects.filter(
|
||||
user=user, type=Authenticator.Type.RECOVERY_CODES
|
||||
).delete()
|
||||
|
||||
# Update or create recovery codes authenticator
|
||||
authenticator, created = Authenticator.objects.update_or_create(
|
||||
user=user,
|
||||
type=Authenticator.Type.RECOVERY_CODES,
|
||||
defaults={"data": {"codes": codes}},
|
||||
)
|
||||
# Generate new recovery codes using allauth's RecoveryCodes API
|
||||
recovery_instance = RecoveryCodes.activate(user)
|
||||
codes = recovery_instance.get_unused_codes()
|
||||
|
||||
return Response(
|
||||
{
|
||||
|
||||
@@ -377,7 +377,7 @@ class MFALoginVerifyAPIView(APIView):
|
||||
"""Verify TOTP code against user's authenticator."""
|
||||
try:
|
||||
from allauth.mfa.models import Authenticator
|
||||
from allauth.mfa.totp import TOTP
|
||||
from allauth.mfa.totp.internal import auth as totp_auth
|
||||
|
||||
try:
|
||||
authenticator = Authenticator.objects.get(
|
||||
@@ -387,9 +387,12 @@ class MFALoginVerifyAPIView(APIView):
|
||||
except Authenticator.DoesNotExist:
|
||||
return False
|
||||
|
||||
# Get the TOTP instance and verify
|
||||
totp = TOTP(authenticator)
|
||||
return totp.validate_code(code)
|
||||
# Get the secret from authenticator data and verify
|
||||
secret = authenticator.data.get("secret")
|
||||
if not secret:
|
||||
return False
|
||||
|
||||
return totp_auth.validate_totp_code(secret, code)
|
||||
|
||||
except ImportError:
|
||||
logger.error("allauth.mfa not available for TOTP verification")
|
||||
|
||||
Reference in New Issue
Block a user