mirror of
https://github.com/complexcaresolutions/dak.c2s.git
synced 2026-03-17 20:43:41 +00:00
feat: add MFA disable (self-service + admin reset) endpoints
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
661f1ce552
commit
fc609401c3
3 changed files with 57 additions and 0 deletions
|
|
@ -170,6 +170,34 @@ def update_user(
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete("/users/{user_id}/mfa")
|
||||||
|
def admin_reset_mfa(
|
||||||
|
user_id: int,
|
||||||
|
request: Request,
|
||||||
|
admin: User = Depends(require_admin),
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
):
|
||||||
|
"""Admin: reset MFA on a user's account."""
|
||||||
|
user = db.query(User).filter(User.id == user_id).first()
|
||||||
|
if not user:
|
||||||
|
raise HTTPException(status_code=404, detail="User not found")
|
||||||
|
|
||||||
|
user.mfa_secret = None
|
||||||
|
user.mfa_enabled = False
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
log_action(
|
||||||
|
db,
|
||||||
|
user_id=admin.id,
|
||||||
|
action="mfa_reset",
|
||||||
|
entity_type="user",
|
||||||
|
entity_id=user.id,
|
||||||
|
ip_address=request.client.host if request.client else None,
|
||||||
|
user_agent=request.headers.get("user-agent"),
|
||||||
|
)
|
||||||
|
return {"detail": "MFA reset"}
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Invitations
|
# Invitations
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ from app.models.user import User
|
||||||
from app.schemas.auth import (
|
from app.schemas.auth import (
|
||||||
ChangePasswordRequest,
|
ChangePasswordRequest,
|
||||||
LoginRequest,
|
LoginRequest,
|
||||||
|
MFADisableRequest,
|
||||||
MFASetupResponse,
|
MFASetupResponse,
|
||||||
MFAVerifyRequest,
|
MFAVerifyRequest,
|
||||||
RefreshRequest,
|
RefreshRequest,
|
||||||
|
|
@ -25,6 +26,7 @@ from app.services.auth_service import (
|
||||||
authenticate_user,
|
authenticate_user,
|
||||||
change_password,
|
change_password,
|
||||||
create_tokens,
|
create_tokens,
|
||||||
|
disable_mfa,
|
||||||
refresh_access_token,
|
refresh_access_token,
|
||||||
register_user,
|
register_user,
|
||||||
revoke_refresh_token,
|
revoke_refresh_token,
|
||||||
|
|
@ -139,6 +141,17 @@ def mfa_verify(
|
||||||
return {"detail": "MFA enabled"}
|
return {"detail": "MFA enabled"}
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete("/mfa")
|
||||||
|
def mfa_disable(
|
||||||
|
data: MFADisableRequest,
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
current_user: User = Depends(get_current_user),
|
||||||
|
):
|
||||||
|
"""Disable MFA on the authenticated user's account (requires password)."""
|
||||||
|
disable_mfa(db, current_user, data.password)
|
||||||
|
return {"detail": "MFA disabled"}
|
||||||
|
|
||||||
|
|
||||||
@router.post("/change-password")
|
@router.post("/change-password")
|
||||||
def change_password_endpoint(
|
def change_password_endpoint(
|
||||||
data: ChangePasswordRequest,
|
data: ChangePasswordRequest,
|
||||||
|
|
|
||||||
|
|
@ -319,3 +319,19 @@ def update_profile(
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(user)
|
db.refresh(user)
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# MFA disable
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def disable_mfa(db: Session, user: User, password: str) -> None:
|
||||||
|
"""Disable MFA on the user's account after verifying their password."""
|
||||||
|
if not verify_password(password, user.password_hash):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Incorrect password",
|
||||||
|
)
|
||||||
|
user.mfa_secret = None
|
||||||
|
user.mfa_enabled = False
|
||||||
|
db.commit()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue