codetics-ocpp-service 0.1.0

Codetics OCPP: Charging Station Management System (CSMS) service for OCPP 1.6J, 2.0.1 and 2.1, with TLS security profiles, smart charging, reservations and tariffs
Documentation
// SPDX-License-Identifier: Apache-2.0
// Copyright 2026 Kevin Vavelin, Codetics (https://codetics.fr)

//! Authorization token management.

use axum::Json;
use axum::extract::{Path, Query, State};
use axum::http::StatusCode;
use serde::Deserialize;

use crate::db::{self, tokens::IdToken};
use crate::error::AppError;
use crate::state::App;

#[derive(Debug, Deserialize)]
pub struct Page {
    pub limit: Option<i64>,
    pub offset: Option<i64>,
}

pub async fn list(
    State(app): State<App>,
    Query(p): Query<Page>,
) -> Result<Json<Vec<IdToken>>, AppError> {
    Ok(Json(
        db::tokens::list(
            &app.db,
            p.limit.unwrap_or(100).clamp(1, 1000),
            p.offset.unwrap_or(0).max(0),
        )
        .await?,
    ))
}

pub async fn upsert(
    State(app): State<App>,
    Json(t): Json<IdToken>,
) -> Result<Json<IdToken>, AppError> {
    if t.id_token.is_empty() || t.id_token.len() > 255 {
        return Err(AppError::BadRequest(
            "id_token must be 1-255 characters".into(),
        ));
    }
    Ok(Json(db::tokens::upsert(&app.db, &t).await?))
}

pub async fn delete(
    State(app): State<App>,
    Path((token_type, id_token)): Path<(String, String)>,
) -> Result<StatusCode, AppError> {
    if db::tokens::delete(&app.db, &id_token, &token_type).await? {
        Ok(StatusCode::NO_CONTENT)
    } else {
        Err(AppError::NotFound(id_token))
    }
}