known devices, finish migration?
This commit is contained in:
7 files changed
+927
-183
No files matched your search
@@ -7,7 +7,7 @@ use tracing::{info, warn};
|
||||
|
||||
use crate::api::json_error;
|
||||
use crate::runtime::{AppState, SessionEvent};
|
||||
use crate::state::AuditEventInput;
|
||||
use crate::state::{AuditEventInput, DeviceIdentifierInput, KnownDeviceInput};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct EnrollRequest {
|
||||
@@ -72,6 +72,48 @@ pub struct StateStatsResponse {
|
||||
pub expired_enroll_token_count: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct CreateKnownDeviceRequest {
|
||||
pub display_name: String,
|
||||
#[serde(default)]
|
||||
pub pinned: bool,
|
||||
pub notes: Option<String>,
|
||||
#[serde(default)]
|
||||
pub identifiers: Vec<DeviceIdentifierRequest>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct DeviceIdentifierRequest {
|
||||
pub kind: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct KnownDeviceResponse {
|
||||
pub device_id: String,
|
||||
pub display_name: String,
|
||||
pub pinned: bool,
|
||||
pub created_at_unix: u64,
|
||||
pub updated_at_unix: u64,
|
||||
pub notes: Option<String>,
|
||||
pub identifiers: Vec<DeviceIdentifierResponse>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct DeviceIdentifierResponse {
|
||||
pub identifier_key: String,
|
||||
pub device_id: String,
|
||||
pub kind: String,
|
||||
pub value: String,
|
||||
pub created_at_unix: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct ForgetKnownDeviceResponse {
|
||||
pub device_id: String,
|
||||
pub forgotten: bool,
|
||||
}
|
||||
|
||||
pub async fn healthz() -> &'static str {
|
||||
"ok"
|
||||
}
|
||||
@@ -407,6 +449,116 @@ pub async fn set_agent_nickname(
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn create_known_device(
|
||||
State(state): State<AppState>,
|
||||
Json(req): Json<CreateKnownDeviceRequest>,
|
||||
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
|
||||
let input = KnownDeviceInput {
|
||||
display_name: req.display_name,
|
||||
pinned: req.pinned,
|
||||
notes: req.notes,
|
||||
identifiers: req
|
||||
.identifiers
|
||||
.into_iter()
|
||||
.map(|identifier| DeviceIdentifierInput {
|
||||
kind: identifier.kind,
|
||||
value: identifier.value,
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
|
||||
match state.store.create_known_device(input).await {
|
||||
Ok(device) => Ok((StatusCode::CREATED, Json(known_device_response(device)))),
|
||||
Err(err) => {
|
||||
warn!(error = %err, "failed to create known device");
|
||||
Err(json_error(
|
||||
StatusCode::BAD_REQUEST,
|
||||
"create_known_device_failed",
|
||||
&err.to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn list_known_devices(
|
||||
State(state): State<AppState>,
|
||||
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
|
||||
match state.store.list_known_devices().await {
|
||||
Ok(devices) => Ok((
|
||||
StatusCode::OK,
|
||||
Json(
|
||||
devices
|
||||
.into_iter()
|
||||
.map(known_device_response)
|
||||
.collect::<Vec<_>>(),
|
||||
),
|
||||
)),
|
||||
Err(err) => {
|
||||
warn!(error = %err, "failed to list known devices");
|
||||
Err(json_error(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"list_known_devices_failed",
|
||||
&err.to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn forget_known_device(
|
||||
State(state): State<AppState>,
|
||||
AxumPath(device_id): AxumPath<String>,
|
||||
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
|
||||
match state.store.forget_known_device(&device_id).await {
|
||||
Ok(forgotten) => Ok((
|
||||
StatusCode::OK,
|
||||
Json(ForgetKnownDeviceResponse {
|
||||
device_id,
|
||||
forgotten,
|
||||
}),
|
||||
)),
|
||||
Err(err) => {
|
||||
warn!(error = %err, "failed to forget known device");
|
||||
Err(json_error(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"forget_known_device_failed",
|
||||
&err.to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn attach_device_identifier(
|
||||
State(state): State<AppState>,
|
||||
AxumPath(device_id): AxumPath<String>,
|
||||
Json(req): Json<DeviceIdentifierRequest>,
|
||||
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
|
||||
let input = DeviceIdentifierInput {
|
||||
kind: req.kind,
|
||||
value: req.value,
|
||||
};
|
||||
|
||||
match state
|
||||
.store
|
||||
.attach_device_identifier(&device_id, input)
|
||||
.await
|
||||
{
|
||||
Ok(Some(device)) => Ok((StatusCode::OK, Json(known_device_response(device)))),
|
||||
Ok(None) => Err(json_error(
|
||||
StatusCode::NOT_FOUND,
|
||||
"known_device_not_found",
|
||||
"known device not found",
|
||||
)),
|
||||
Err(err) => {
|
||||
warn!(error = %err, "failed to attach device identifier");
|
||||
Err(json_error(
|
||||
StatusCode::BAD_REQUEST,
|
||||
"attach_device_identifier_failed",
|
||||
&err.to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn state_stats(
|
||||
State(state): State<AppState>,
|
||||
) -> Result<impl IntoResponse, (StatusCode, Json<serde_json::Value>)> {
|
||||
@@ -431,3 +583,25 @@ pub async fn state_stats(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn known_device_response(device: crate::state::KnownDevice) -> KnownDeviceResponse {
|
||||
KnownDeviceResponse {
|
||||
device_id: device.device_id,
|
||||
display_name: device.display_name,
|
||||
pinned: device.pinned,
|
||||
created_at_unix: device.created_at_unix,
|
||||
updated_at_unix: device.updated_at_unix,
|
||||
notes: device.notes,
|
||||
identifiers: device
|
||||
.identifiers
|
||||
.into_iter()
|
||||
.map(|identifier| DeviceIdentifierResponse {
|
||||
identifier_key: identifier.identifier_key,
|
||||
device_id: identifier.device_id,
|
||||
kind: identifier.kind,
|
||||
value: identifier.value,
|
||||
created_at_unix: identifier.created_at_unix,
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user