Implement password handling for unattended access
build / build-linux-amd64 (push) Successful in 2m0s
build / build-linux-amd64 (push) Successful in 2m0s
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
//! `POST /api/unattended-password` — agent-side reporting of the per-boot
|
||||
//! "permanent password" used for unattended access (no logged-in user to
|
||||
//! click the approval popup). hello-agent generates a random password
|
||||
//! every time the service starts and posts it here so the admin UI can
|
||||
//! surface it for support staff.
|
||||
//!
|
||||
//! Auth model mirrors `/api/sysinfo`: the request must carry the agent's
|
||||
//! `(id, uuid)` and that pair must already correspond to a registered
|
||||
//! peer in `peer`. There's no shared secret beyond that — same trust
|
||||
//! boundary the existing sysinfo endpoint already operates under.
|
||||
|
||||
use crate::api::error::ApiError;
|
||||
use crate::api::state::AppState;
|
||||
use axum::extract::Extension;
|
||||
use axum::Json;
|
||||
use serde_json::Value;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Body: `{"id": "...", "uuid": "...", "password": "..."}`
|
||||
/// Response (bare string, like sysinfo): `"OK"` or `"ID_NOT_FOUND"`.
|
||||
pub async fn unattended_password(
|
||||
Extension(state): Extension<Arc<AppState>>,
|
||||
Json(payload): Json<Value>,
|
||||
) -> Result<String, ApiError> {
|
||||
let id = payload
|
||||
.get("id")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or_default();
|
||||
let uuid = payload
|
||||
.get("uuid")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or_default();
|
||||
let password = payload
|
||||
.get("password")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or_default();
|
||||
if id.is_empty() || uuid.is_empty() || password.is_empty() {
|
||||
return Err(ApiError::BadRequest(
|
||||
"id, uuid, and password are required".into(),
|
||||
));
|
||||
}
|
||||
|
||||
let peer = state
|
||||
.db
|
||||
.get_peer(id)
|
||||
.await
|
||||
.map_err(|e| ApiError::Internal(e.to_string()))?;
|
||||
if peer.is_none() {
|
||||
return Ok("ID_NOT_FOUND".to_string());
|
||||
}
|
||||
|
||||
state
|
||||
.db
|
||||
.set_unattended_password(id, uuid, password)
|
||||
.await
|
||||
.map_err(|e| ApiError::Internal(e.to_string()))?;
|
||||
Ok("OK".to_string())
|
||||
}
|
||||
Reference in New Issue
Block a user