45 lines
1.2 KiB
Python
45 lines
1.2 KiB
Python
"""What the second-factor endpoints accept and return.
|
|
|
|
The shapes are small; what matters is what is *absent*. There is no schema that
|
|
returns a secret after enrolment, and none that returns a recovery code after it
|
|
has been issued. Both are handed over once and are unreadable afterwards, and a
|
|
response model is the only place that promise can be broken by accident.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import List, Optional
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class MfaStatus(BaseModel):
|
|
enabled: bool
|
|
enrolment_pending: bool
|
|
recovery_codes_remaining: int
|
|
|
|
|
|
class MfaEnrolmentStarted(BaseModel):
|
|
secret: str
|
|
otpauth_uri: str
|
|
|
|
|
|
class MfaCode(BaseModel):
|
|
code: str = Field(min_length=1, max_length=64)
|
|
|
|
|
|
class MfaRecoveryCodes(BaseModel):
|
|
codes: List[str]
|
|
|
|
|
|
class MfaPasswordConfirm(BaseModel):
|
|
"""Turning a factor off, or replacing the recovery codes.
|
|
|
|
The current password is required for both. A session token is enough to use
|
|
the account; it must not be enough to take away the thing protecting it,
|
|
because a stolen session would otherwise disarm the account and keep it.
|
|
"""
|
|
|
|
password: str = Field(min_length=1)
|
|
code: Optional[str] = None
|