feat: finished auditlog object and added endpoint to get all auditlogs

This commit is contained in:
BAaboe 2025-08-05 10:52:22 +02:00
parent 6017b7087f
commit e1d3a73687
3 changed files with 91 additions and 2 deletions

View file

@ -0,0 +1,37 @@
use std::sync::Arc;
use ::uuid::Uuid;
use axum::{
Extension, Json,
extract::{Path, Query, State},
http::StatusCode,
response::IntoResponse,
};
use crate::{
api::v1::auth::CurrentUser, error::Error, objects::{AuditLog, Member, PaginationRequest, Permissions}, utils::global_checks, AppState
};
pub async fn get(
State(app_state): State<Arc<AppState>>,
Path(guild_uuid): Path<Uuid>,
Query(pagination): Query<PaginationRequest>,
Extension(CurrentUser(uuid)): Extension<CurrentUser<Uuid>>,
) -> Result<impl IntoResponse, Error> {
let mut conn = app_state.pool.get().await?;
global_checks(&mut conn, &app_state.config, uuid).await?;
let caller = Member::check_membership(&mut conn, uuid, guild_uuid).await?;
caller.check_permission(&mut conn, &app_state.cache_pool, Permissions::ManageGuild).await?;
let logs = AuditLog::fetch_page(
&mut conn,
guild_uuid,
pagination,
)
.await?;
Ok((StatusCode::OK, Json(logs)))
}

View file

@ -17,6 +17,7 @@ mod channels;
mod invites;
mod members;
mod roles;
mod auditlogs;
use crate::{
AppState,
@ -46,6 +47,8 @@ pub fn router() -> Router<Arc<AppState>> {
// Bans
.route("/bans", get(bans::get))
.route("/bans/{uuid}", delete(bans::unban))
// Audit Logs
.route("/auditlogs", get(auditlogs::get))
}
/// `GET /api/v1/guilds/{uuid}` DESCRIPTION

View file

@ -1,7 +1,7 @@
use uuid::Uuid;
use diesel::{insert_into, Insertable, Queryable, Selectable, SelectableHelper};
use diesel::{insert_into, Insertable, QueryDsl, Queryable, Selectable, SelectableHelper, ExpressionMethods};
use serde::{Deserialize, Serialize};
use crate::{error::Error, schema::audit_logs, Conn};
use crate::{error::Error, objects::{load_or_empty, Pagination, PaginationRequest}, schema::audit_logs, Conn};
use diesel_async::RunQueryDsl;
@ -25,6 +25,55 @@ pub struct AuditLog {
impl AuditLog {
pub async fn count(conn: &mut Conn, guild_uuid: Uuid) -> Result<i64, Error> {
use audit_logs::dsl;
let count: i64 = dsl::audit_logs
.filter(dsl::guild_uuid.eq(guild_uuid))
.count()
.get_result(conn)
.await?;
Ok(count)
}
pub async fn fetch_page(
conn: &mut Conn,
guild_uuid: Uuid,
pagination: PaginationRequest,
) -> Result<Pagination<AuditLog>, Error> {
// TODO: Maybe add cache, but I do not know how
let per_page = pagination.per_page.unwrap_or(20);
let offset = (pagination.page - 1) * per_page;
if !(10..=100).contains(&per_page) {
return Err(Error::BadRequest(
"Invalid amount per page requested".to_string(),
));
}
use audit_logs::dsl;
let logs: Vec<AuditLog> = load_or_empty(
dsl::audit_logs
.filter(dsl::guild_uuid.eq(guild_uuid))
.limit(per_page.into())
.offset(offset as i64)
.select(AuditLog::as_select())
.load(conn)
.await
)?;
let pages = (AuditLog::count(conn, guild_uuid).await? as f32 / per_page as f32).ceil();
let paginated_logs = Pagination::<AuditLog> {
objects: logs.clone(),
amount: logs.len() as i32,
pages: pages as i32,
page: pagination.page,
};
Ok(paginated_logs)
}
#[allow(clippy::new_ret_no_self)]
pub async fn new(
conn: &mut Conn,