netmito 0.6.8

A Unified Distributed Transport Evaluation Framework
Documentation
use std::net::SocketAddr;

use axum::{
    extract::{ConnectInfo, Path, State},
    middleware,
    routing::{get, post},
    Extension, Json, Router,
};

use crate::{
    config::InfraPool,
    error::ApiError,
    schema::*,
    service::{
        self,
        auth::{user_auth_middleware, AuthUser, AuthUserWithName},
    },
};

pub fn users_router(st: InfraPool) -> Router<InfraPool> {
    Router::new()
        .route("/{username}/password", post(change_password))
        .route("/groups", get(query_groups))
        .route_layer(middleware::from_fn_with_state(
            st.clone(),
            user_auth_middleware,
        ))
        .with_state(st)
}

pub async fn user_login(
    ConnectInfo(addr): ConnectInfo<SocketAddr>,
    State(pool): State<InfraPool>,
    Json(req): Json<UserLoginReq>,
) -> Result<Json<UserLoginResp>, ApiError> {
    let token =
        service::auth::user_login(&pool.db, &req.username, &req.md5_password, req.retain, addr)
            .await
            .map_err(|e| match e {
                crate::error::Error::AuthError(err) => ApiError::AuthError(err),
                crate::error::Error::ApiError(e) => e,
                _ => {
                    tracing::error!("{}", e);
                    ApiError::InternalServerError
                }
            })?;
    Ok(Json(UserLoginResp { token }))
}

pub async fn user_auth(Extension(u): Extension<AuthUserWithName>) -> String {
    u.username
}

pub async fn change_password(
    ConnectInfo(addr): ConnectInfo<SocketAddr>,
    Extension(u): Extension<AuthUser>,
    State(pool): State<InfraPool>,
    Path(username): Path<String>,
    Json(req): Json<UserChangePasswordReq>,
) -> Result<Json<UserChangePasswordResp>, ApiError> {
    let token = service::auth::user_change_password(&pool.db, u.id, addr, username, req)
        .await
        .map_err(|e| match e {
            crate::error::Error::AuthError(err) => ApiError::AuthError(err),
            crate::error::Error::ApiError(e) => e,
            _ => {
                tracing::error!("{}", e);
                ApiError::InternalServerError
            }
        })?;
    Ok(Json(UserChangePasswordResp { token }))
}

pub async fn query_groups(
    Extension(u): Extension<AuthUser>,
    State(pool): State<InfraPool>,
) -> Result<Json<GroupsQueryResp>, ApiError> {
    let groups = service::group::query_user_groups(u.id, &pool)
        .await
        .map_err(|e| match e {
            crate::error::Error::AuthError(err) => ApiError::AuthError(err),
            crate::error::Error::ApiError(e) => e,
            _ => {
                tracing::error!("{}", e);
                ApiError::InternalServerError
            }
        })?;
    Ok(Json(GroupsQueryResp { groups }))
}