Skip to main content

zlicenser_server/http/
revoke.rs

1use std::sync::Arc;
2
3use axum::{
4    Json,
5    extract::{Path, State},
6    http::{HeaderMap, StatusCode},
7    response::{IntoResponse, Response},
8};
9use serde::Deserialize;
10use uuid::Uuid;
11
12use crate::issuance::handlers::HandlerContext;
13use crate::storage::{Storage, types::RevocationSource};
14
15#[derive(Deserialize)]
16pub struct RevokeBody {
17    pub reason: Option<String>,
18}
19
20pub async fn revoke_handler<S: Storage + Clone + Send + Sync + 'static>(
21    State(ctx): State<Arc<HandlerContext<S>>>,
22    headers: HeaderMap,
23    Path(id): Path<Uuid>,
24    Json(body): Json<RevokeBody>,
25) -> Response {
26    if let Some(expected_token) = ctx.config.api_bearer_token.as_deref() {
27        let auth = headers
28            .get("authorization")
29            .and_then(|v| v.to_str().ok())
30            .and_then(|v| v.strip_prefix("Bearer "));
31        match auth {
32            Some(token) if token == expected_token => {}
33            _ => {
34                return (StatusCode::UNAUTHORIZED, "invalid bearer token").into_response();
35            }
36        }
37    }
38
39    match crate::issuance::revoke::revoke_license(
40        &ctx.storage,
41        id,
42        body.reason,
43        RevocationSource::Api,
44    )
45    .await
46    {
47        Ok(()) => StatusCode::NO_CONTENT.into_response(),
48        Err(e) => e.into_response(),
49    }
50}