use axum::{
extract::{Path, State},
http::StatusCode,
Json,
};
use uuid::Uuid;
use super::router::AppState;
use crate::db::{ApiKey, ApiKeyCreated, ApiKeysRepository, NewApiKey};
use crate::error::ProblemDetails;
pub async fn create_api_key(
State(state): State<AppState>,
Path(project_id): Path<Uuid>,
Json(input): Json<NewApiKey>,
) -> Result<(StatusCode, Json<ApiKeyCreated>), ProblemDetails> {
let repo = ApiKeysRepository::new(state.pool.clone());
let created = repo.create(project_id, input).await?;
Ok((StatusCode::CREATED, Json(created)))
}
pub async fn list_api_keys(
State(state): State<AppState>,
Path(project_id): Path<Uuid>,
) -> Result<Json<Vec<ApiKey>>, ProblemDetails> {
let repo = ApiKeysRepository::new(state.pool.clone());
let keys = repo.list_for_project(project_id).await?;
Ok(Json(keys))
}
pub async fn revoke_api_key(
State(state): State<AppState>,
Path((project_id, key_id)): Path<(Uuid, Uuid)>,
) -> Result<StatusCode, ProblemDetails> {
let repo = ApiKeysRepository::new(state.pool.clone());
let key = repo
.get(key_id)
.await?
.ok_or_else(|| ProblemDetails::not_found(format!("API key {} not found", key_id)))?;
if key.project_id != project_id {
return Err(ProblemDetails::not_found(format!(
"API key {} not found in project {}",
key_id, project_id
)));
}
repo.revoke(key_id).await?;
Ok(StatusCode::NO_CONTENT)
}