🚧 Update certificate management
This commit is contained in:
+50
-1
@@ -169,6 +169,18 @@ class MqttClientOut(BaseModel):
|
||||
last_known_connection: datetime | None
|
||||
|
||||
|
||||
class ClientIdUpdate(BaseModel):
|
||||
"""PUT /clients/{username}/clientid — bind or clear the expected
|
||||
client ID (spec section 11: "bind an expected client ID").
|
||||
|
||||
An empty string clears the binding: any client id may then connect
|
||||
with these credentials. A bound ID restricts connections to exactly
|
||||
that client id (anti-credential-sharing).
|
||||
"""
|
||||
|
||||
clientid: str = Field(default="", max_length=200)
|
||||
|
||||
|
||||
class MqttPasswordReset(BaseModel):
|
||||
"""Response for create/reset — plaintext shown exactly once (spec 11)."""
|
||||
|
||||
@@ -203,6 +215,8 @@ class ListenerIn(BaseModel):
|
||||
tls_min_version: Literal["tlsv1.2", "tlsv1.3"] | None = None
|
||||
require_certificate: bool = False
|
||||
use_identity_as_username: bool = False
|
||||
# Bound server certificate (PKI): emitted as certfile/keyfile/cafile.
|
||||
cert_id: uuid.UUID | None = None
|
||||
|
||||
|
||||
class ListenerOut(ListenerIn):
|
||||
@@ -269,6 +283,10 @@ class CertificateOut(BaseModel):
|
||||
common_name: str
|
||||
is_ca: bool
|
||||
parent_id: uuid.UUID | None
|
||||
cert_type: str
|
||||
# MQTT client this certificate authenticates (client certs only;
|
||||
# the CN equals the username — spec section 24).
|
||||
username: str | None = None
|
||||
key_algorithm: str
|
||||
serial_number: str
|
||||
dns_sans: list[str]
|
||||
@@ -278,4 +296,35 @@ class CertificateOut(BaseModel):
|
||||
expiry_date: datetime
|
||||
created_at: datetime
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
|
||||
class ClientCertCreate(BaseModel):
|
||||
"""Issue a client certificate bound to an MQTT client (spec section 20).
|
||||
|
||||
The certificate CN is the MQTT username — with
|
||||
use_identity_as_username the broker maps CN -> dynsec identity
|
||||
(spec section 24), so the dynsec client must already exist.
|
||||
"""
|
||||
|
||||
username: str = Field(min_length=1, max_length=100)
|
||||
ca_id: uuid.UUID
|
||||
validity_days: int = Field(gt=0, le=36500)
|
||||
|
||||
|
||||
class CertificateBundle(BaseModel):
|
||||
"""One-time download payload (spec sections 20, 44).
|
||||
|
||||
Contains EVERYTHING including the plaintext private key — shown
|
||||
exactly once, never retrievable afterwards from the inventory.
|
||||
"""
|
||||
|
||||
certificate_id: uuid.UUID
|
||||
username: str
|
||||
certificate_pem: str
|
||||
private_key_pem: str
|
||||
ca_chain_pem: str
|
||||
download_hint: str = (
|
||||
"Store these files securely now — the private key cannot be "
|
||||
"retrieved again."
|
||||
)
|
||||
Reference in New Issue
Block a user