58 lines
1.7 KiB
Rust
58 lines
1.7 KiB
Rust
use crate::models::{
|
|
_entities::{audio_albums, audio_tracks, audit_logs, blog_articles, users},
|
|
users as users_model,
|
|
};
|
|
use loco_rs::prelude::*;
|
|
use sea_orm::{EntityTrait, PaginatorTrait};
|
|
use serde::Serialize;
|
|
|
|
#[derive(Debug, Serialize)]
|
|
struct DashboardResponse {
|
|
users: u64,
|
|
blog_articles: u64,
|
|
audio_albums: u64,
|
|
audio_tracks: u64,
|
|
audit_logs: u64,
|
|
}
|
|
|
|
pub(crate) fn admin_email(ctx: &AppContext) -> Option<&str> {
|
|
ctx.config
|
|
.settings
|
|
.as_ref()
|
|
.and_then(|settings| settings.get("admin_email"))
|
|
.and_then(|email| email.as_str())
|
|
}
|
|
|
|
pub(crate) fn is_admin(ctx: &AppContext, user: &users::Model) -> bool {
|
|
admin_email(ctx).is_some_and(|email| user.email.eq_ignore_ascii_case(email))
|
|
}
|
|
|
|
pub(crate) async fn current_admin(auth: auth::JWT, ctx: &AppContext) -> Result<users::Model> {
|
|
let user = users_model::Model::find_by_pid(&ctx.db, &auth.claims.pid).await?;
|
|
|
|
if !is_admin(ctx, &user) {
|
|
return unauthorized("admin only");
|
|
}
|
|
|
|
Ok(user)
|
|
}
|
|
|
|
#[debug_handler]
|
|
async fn dashboard(auth: auth::JWT, State(ctx): State<AppContext>) -> Result<Response> {
|
|
current_admin(auth, &ctx).await?;
|
|
|
|
format::json(DashboardResponse {
|
|
users: users::Entity::find().count(&ctx.db).await?,
|
|
blog_articles: blog_articles::Entity::find().count(&ctx.db).await?,
|
|
audio_albums: audio_albums::Entity::find().count(&ctx.db).await?,
|
|
audio_tracks: audio_tracks::Entity::find().count(&ctx.db).await?,
|
|
audit_logs: audit_logs::Entity::find().count(&ctx.db).await?,
|
|
})
|
|
}
|
|
|
|
pub fn routes() -> Routes {
|
|
Routes::new()
|
|
.prefix("/api/admin")
|
|
.add("/dashboard", get(dashboard))
|
|
}
|