Compare commits
13 commits
main
...
wip/auditl
Author | SHA1 | Date | |
---|---|---|---|
e663c1bbae | |||
6afa78c8e8 | |||
dee248e02d | |||
55ef6ddde2 | |||
362e4bc2e8 | |||
d84b7cf126 | |||
9d6ec5286b | |||
95ef27c32d | |||
2b9a44c4f0 | |||
e1d3a73687 | |||
6017b7087f | |||
b49e5036be | |||
e8de96b2d0 |
16 changed files with 251 additions and 36 deletions
2
migrations/2025-08-04-195527_add_audit_log/down.sql
Normal file
2
migrations/2025-08-04-195527_add_audit_log/down.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
DROP TABLE audit_logs;
|
14
migrations/2025-08-04-195527_add_audit_log/up.sql
Normal file
14
migrations/2025-08-04-195527_add_audit_log/up.sql
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
-- Your SQL goes here
|
||||||
|
CREATE TABLE audit_logs (
|
||||||
|
uuid UUID PRIMARY KEY NOT NULL,
|
||||||
|
guild_uuid UUID NOT NULL,
|
||||||
|
action_id INT2 NOT NULL,
|
||||||
|
by_uuid UUID NOT NULL REFERENCES guild_members(uuid),
|
||||||
|
channel_uuid UUID REFERENCES channels(uuid) DEFAULT NULL,
|
||||||
|
user_uuid UUID REFERENCES users(uuid) DEFAULT NULL,
|
||||||
|
message_uuid UUID REFERENCES messages(uuid) DEFAULT NULL,
|
||||||
|
role_uuid UUID REFERENCES roles(uuid) DEFAULT NULL,
|
||||||
|
audit_message VARCHAR(200) DEFAULT NULL,
|
||||||
|
changed_from VARCHAR(200) DEFAULT NULL,
|
||||||
|
changed_to VARCHAR(200) DEFAULT NULL
|
||||||
|
);
|
|
@ -6,11 +6,7 @@ pub mod socket;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AppState,
|
api::v1::auth::CurrentUser, error::Error, objects::{AuditLog, AuditLogId, Channel, Member, Permissions}, utils::global_checks, AppState
|
||||||
api::v1::auth::CurrentUser,
|
|
||||||
error::Error,
|
|
||||||
objects::{Channel, Member, Permissions},
|
|
||||||
utils::global_checks,
|
|
||||||
};
|
};
|
||||||
use axum::{
|
use axum::{
|
||||||
Extension, Json,
|
Extension, Json,
|
||||||
|
@ -55,7 +51,9 @@ pub async fn delete(
|
||||||
.check_permission(&mut conn, &app_state.cache_pool, Permissions::ManageChannel)
|
.check_permission(&mut conn, &app_state.cache_pool, Permissions::ManageChannel)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
let log_entry = AuditLog::new(channel.guild_uuid, AuditLogId::ChannelDelete as i16, member.uuid, None, None, None, None, Some(channel.name.clone()), None, None).await;
|
||||||
channel.delete(&mut conn, &app_state.cache_pool).await?;
|
channel.delete(&mut conn, &app_state.cache_pool).await?;
|
||||||
|
log_entry.push(&mut conn).await?;
|
||||||
|
|
||||||
Ok(StatusCode::OK)
|
Ok(StatusCode::OK)
|
||||||
}
|
}
|
||||||
|
@ -117,12 +115,15 @@ pub async fn patch(
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if let Some(new_name) = &new_info.name {
|
if let Some(new_name) = &new_info.name {
|
||||||
|
let log_entry = AuditLog::new(channel.guild_uuid, AuditLogId::ChannelUpdateName as i16, member.uuid, Some(channel_uuid), None, None, None, None, Some(channel.name.clone()), Some(new_name.clone())).await;
|
||||||
channel
|
channel
|
||||||
.set_name(&mut conn, &app_state.cache_pool, new_name.to_string())
|
.set_name(&mut conn, &app_state.cache_pool, new_name.to_string())
|
||||||
.await?;
|
.await?;
|
||||||
|
log_entry.push(&mut conn).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(new_description) = &new_info.description {
|
if let Some(new_description) = &new_info.description {
|
||||||
|
let log_entry = AuditLog::new(channel.guild_uuid, AuditLogId::ChannelUpdateDescripiton as i16, member.uuid, Some(channel_uuid), None, None, None, None, Some(channel.description.clone().unwrap_or("".to_string())), Some(new_description.clone())).await;
|
||||||
channel
|
channel
|
||||||
.set_description(
|
.set_description(
|
||||||
&mut conn,
|
&mut conn,
|
||||||
|
@ -130,6 +131,7 @@ pub async fn patch(
|
||||||
new_description.to_string(),
|
new_description.to_string(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
log_entry.push(&mut conn).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(new_is_above) = &new_info.is_above {
|
if let Some(new_is_above) = &new_info.is_above {
|
||||||
|
|
37
src/api/v1/guilds/uuid/auditlogs.rs
Normal file
37
src/api/v1/guilds/uuid/auditlogs.rs
Normal 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::{
|
||||||
|
AppState,
|
||||||
|
api::v1::auth::CurrentUser,
|
||||||
|
error::Error,
|
||||||
|
objects::{AuditLog, Member, PaginationRequest, Permissions},
|
||||||
|
utils::global_checks,
|
||||||
|
};
|
||||||
|
|
||||||
|
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)))
|
||||||
|
}
|
|
@ -9,11 +9,7 @@ use axum::{
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AppState,
|
api::v1::auth::CurrentUser, error::Error, objects::{AuditLog, AuditLogId, GuildBan, Member, Permissions}, utils::global_checks, AppState
|
||||||
api::v1::auth::CurrentUser,
|
|
||||||
error::Error,
|
|
||||||
objects::{GuildBan, Member, Permissions},
|
|
||||||
utils::global_checks,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub async fn get(
|
pub async fn get(
|
||||||
|
@ -51,7 +47,9 @@ pub async fn unban(
|
||||||
|
|
||||||
let ban = GuildBan::fetch_one(&mut conn, guild_uuid, user_uuid).await?;
|
let ban = GuildBan::fetch_one(&mut conn, guild_uuid, user_uuid).await?;
|
||||||
|
|
||||||
|
let log_entry = AuditLog::new(guild_uuid, AuditLogId::MemberUnban as i16, caller.uuid, None, Some(ban.user_uuid), None, None, None, None, None).await;
|
||||||
ban.unban(&mut conn).await?;
|
ban.unban(&mut conn).await?;
|
||||||
|
log_entry.push(&mut conn).await?;
|
||||||
|
|
||||||
Ok(StatusCode::OK)
|
Ok(StatusCode::OK)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,7 @@ use axum::{
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AppState,
|
api::v1::auth::CurrentUser, error::Error, objects::{AuditLog, AuditLogId, Channel, Member, Permissions}, utils::{global_checks, order_by_is_above, CacheFns}, AppState
|
||||||
api::v1::auth::CurrentUser,
|
|
||||||
error::Error,
|
|
||||||
objects::{Channel, Member, Permissions},
|
|
||||||
utils::{CacheFns, global_checks, order_by_is_above},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -83,5 +79,7 @@ pub async fn create(
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
AuditLog::new(guild_uuid, AuditLogId::ChannelCreate as i16, member.uuid, Some(channel.uuid), None, None, None, Some(channel.name.clone()), None, None).await.push(&mut conn).await?;
|
||||||
|
|
||||||
Ok((StatusCode::OK, Json(channel)))
|
Ok((StatusCode::OK, Json(channel)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,7 @@ use serde::Deserialize;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AppState,
|
api::v1::auth::CurrentUser, error::Error, objects::{AuditLog, AuditLogId, Guild, Member, Permissions}, utils::global_checks, AppState
|
||||||
api::v1::auth::CurrentUser,
|
|
||||||
error::Error,
|
|
||||||
objects::{Guild, Member, Permissions},
|
|
||||||
utils::global_checks,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -62,5 +58,7 @@ pub async fn create(
|
||||||
.create_invite(&mut conn, uuid, invite_request.custom_id.clone())
|
.create_invite(&mut conn, uuid, invite_request.custom_id.clone())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
AuditLog::new(guild_uuid, AuditLogId::InviteCreate as i16, member.uuid, None, None, None, None, Some(invite.id.clone()), None, None).await.push(&mut conn).await?;
|
||||||
|
|
||||||
Ok((StatusCode::OK, Json(invite)))
|
Ok((StatusCode::OK, Json(invite)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ use axum::{
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
mod auditlogs;
|
||||||
mod bans;
|
mod bans;
|
||||||
mod channels;
|
mod channels;
|
||||||
mod invites;
|
mod invites;
|
||||||
|
@ -46,6 +47,8 @@ pub fn router() -> Router<Arc<AppState>> {
|
||||||
// Bans
|
// Bans
|
||||||
.route("/bans", get(bans::get))
|
.route("/bans", get(bans::get))
|
||||||
.route("/bans/{uuid}", delete(bans::unban))
|
.route("/bans/{uuid}", delete(bans::unban))
|
||||||
|
// Audit Logs
|
||||||
|
.route("/auditlogs", get(auditlogs::get))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `GET /api/v1/guilds/{uuid}` DESCRIPTION
|
/// `GET /api/v1/guilds/{uuid}` DESCRIPTION
|
||||||
|
|
|
@ -10,11 +10,7 @@ use axum::{
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AppState,
|
api::v1::auth::CurrentUser, error::Error, objects::{AuditLog, AuditLogId, Member, Permissions, Role}, utils::{global_checks, order_by_is_above, CacheFns}, AppState
|
||||||
api::v1::auth::CurrentUser,
|
|
||||||
error::Error,
|
|
||||||
objects::{Member, Permissions, Role},
|
|
||||||
utils::{CacheFns, global_checks, order_by_is_above},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod uuid;
|
pub mod uuid;
|
||||||
|
@ -71,7 +67,10 @@ pub async fn create(
|
||||||
.check_permission(&mut conn, &app_state.cache_pool, Permissions::ManageRole)
|
.check_permission(&mut conn, &app_state.cache_pool, Permissions::ManageRole)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
// TODO: roles permission
|
||||||
let role = Role::new(&mut conn, guild_uuid, role_info.name.clone()).await?;
|
let role = Role::new(&mut conn, guild_uuid, role_info.name.clone()).await?;
|
||||||
|
|
||||||
|
AuditLog::new(guild_uuid, AuditLogId::RoleCreate as i16, member.uuid, None, None, None, Some(role.uuid), Some(role_info.name.clone()) , None, None).await.push(&mut conn).await?;
|
||||||
|
|
||||||
Ok((StatusCode::OK, Json(role)).into_response())
|
Ok((StatusCode::OK, Json(role)).into_response())
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,7 @@ use axum::{
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AppState,
|
api::v1::auth::CurrentUser, error::Error, objects::{AuditLog, AuditLogId, Member, Permissions}, utils::global_checks, AppState
|
||||||
api::v1::auth::CurrentUser,
|
|
||||||
error::Error,
|
|
||||||
objects::{Member, Permissions},
|
|
||||||
utils::global_checks,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -42,7 +38,9 @@ pub async fn post(
|
||||||
.check_permission(&mut conn, &app_state.cache_pool, Permissions::BanMember)
|
.check_permission(&mut conn, &app_state.cache_pool, Permissions::BanMember)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
let log_entry = AuditLog::new(member.guild_uuid, AuditLogId::MemberBan as i16, caller.uuid, None, Some(member.user_uuid), None, None, Some(payload.reason.clone()), None, None).await;
|
||||||
member.ban(&mut conn, &payload.reason).await?;
|
member.ban(&mut conn, &payload.reason).await?;
|
||||||
|
log_entry.push(&mut conn).await?;
|
||||||
|
|
||||||
Ok(StatusCode::OK)
|
Ok(StatusCode::OK)
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,9 +54,9 @@ pub async fn delete(
|
||||||
Member::fetch_one_with_uuid(&mut conn, &app_state.cache_pool, Some(&me), member_uuid)
|
Member::fetch_one_with_uuid(&mut conn, &app_state.cache_pool, Some(&me), member_uuid)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let deleter = Member::check_membership(&mut conn, uuid, member.guild_uuid).await?;
|
let caller = Member::check_membership(&mut conn, uuid, member.guild_uuid).await?;
|
||||||
|
|
||||||
deleter
|
caller
|
||||||
.check_permission(&mut conn, &app_state.cache_pool, Permissions::KickMember)
|
.check_permission(&mut conn, &app_state.cache_pool, Permissions::KickMember)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
138
src/objects/auditlog.rs
Normal file
138
src/objects/auditlog.rs
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
use crate::{
|
||||||
|
Conn,
|
||||||
|
error::Error,
|
||||||
|
objects::{Pagination, PaginationRequest, load_or_empty},
|
||||||
|
schema::audit_logs,
|
||||||
|
};
|
||||||
|
use diesel::{
|
||||||
|
ExpressionMethods, Insertable, QueryDsl, Queryable, Selectable, SelectableHelper, insert_into,
|
||||||
|
};
|
||||||
|
use diesel_async::RunQueryDsl;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
pub enum AuditLogId {
|
||||||
|
MessageDelete = 100,
|
||||||
|
MessageEdit = 101,
|
||||||
|
|
||||||
|
ChannelCreate = 200,
|
||||||
|
ChannelDelete = 201,
|
||||||
|
ChannelUpdateName = 202,
|
||||||
|
ChannelUpdateDescripiton = 203,
|
||||||
|
|
||||||
|
RoleCreate = 300,
|
||||||
|
RoleDelete = 301,
|
||||||
|
RoleUpdateName = 302,
|
||||||
|
RoleUpdatePermission = 303,
|
||||||
|
InviteCreate = 304,
|
||||||
|
InviteDelete = 305,
|
||||||
|
|
||||||
|
MemberKick = 400,
|
||||||
|
MemberBan = 401,
|
||||||
|
MemberUnban = 402,
|
||||||
|
MemberUpdateNickname = 403,
|
||||||
|
MemberUpdateRoles = 404,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable, Selectable, Queryable, Serialize, Deserialize, Clone)]
|
||||||
|
#[diesel(table_name = audit_logs)]
|
||||||
|
#[diesel(check_for_backend(diesel::pg::Pg))]
|
||||||
|
pub struct AuditLog {
|
||||||
|
pub uuid: Uuid,
|
||||||
|
pub guild_uuid: Uuid,
|
||||||
|
pub action_id: i16,
|
||||||
|
pub by_uuid: Uuid,
|
||||||
|
pub channel_uuid: Option<Uuid>,
|
||||||
|
pub user_uuid: Option<Uuid>,
|
||||||
|
pub message_uuid: Option<Uuid>,
|
||||||
|
pub role_uuid: Option<Uuid>,
|
||||||
|
pub audit_message: Option<String>,
|
||||||
|
pub changed_from: Option<String>,
|
||||||
|
pub changed_to: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn new(
|
||||||
|
guild_uuid: Uuid,
|
||||||
|
action_id: i16,
|
||||||
|
by_uuid: Uuid,
|
||||||
|
channel_uuid: Option<Uuid>,
|
||||||
|
user_uuid: Option<Uuid>,
|
||||||
|
message_uuid: Option<Uuid>,
|
||||||
|
role_uuid: Option<Uuid>,
|
||||||
|
audit_message: Option<String>,
|
||||||
|
changed_from: Option<String>,
|
||||||
|
changed_to: Option<String>,
|
||||||
|
) -> AuditLog{
|
||||||
|
AuditLog {
|
||||||
|
uuid: Uuid::now_v7(),
|
||||||
|
guild_uuid,
|
||||||
|
action_id,
|
||||||
|
by_uuid,
|
||||||
|
channel_uuid,
|
||||||
|
user_uuid,
|
||||||
|
message_uuid,
|
||||||
|
role_uuid,
|
||||||
|
audit_message,
|
||||||
|
changed_from,
|
||||||
|
changed_to,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn push(self, conn: &mut Conn) -> Result<(), Error>{
|
||||||
|
insert_into(audit_logs::table)
|
||||||
|
.values(self.clone())
|
||||||
|
.execute(conn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -52,8 +52,8 @@ impl ChannelBuilder {
|
||||||
pub struct Channel {
|
pub struct Channel {
|
||||||
pub uuid: Uuid,
|
pub uuid: Uuid,
|
||||||
pub guild_uuid: Uuid,
|
pub guild_uuid: Uuid,
|
||||||
name: String,
|
pub name: String,
|
||||||
description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub is_above: Option<Uuid>,
|
pub is_above: Option<Uuid>,
|
||||||
pub permissions: Vec<ChannelPermission>,
|
pub permissions: Vec<ChannelPermission>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ use log::debug;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
mod auditlog;
|
||||||
mod bans;
|
mod bans;
|
||||||
mod channel;
|
mod channel;
|
||||||
mod email_token;
|
mod email_token;
|
||||||
|
@ -20,6 +21,8 @@ mod password_reset_token;
|
||||||
mod role;
|
mod role;
|
||||||
mod user;
|
mod user;
|
||||||
|
|
||||||
|
pub use auditlog::AuditLog;
|
||||||
|
pub use auditlog::AuditLogId;
|
||||||
pub use bans::GuildBan;
|
pub use bans::GuildBan;
|
||||||
pub use channel::Channel;
|
pub use channel::Channel;
|
||||||
pub use email_token::EmailToken;
|
pub use email_token::EmailToken;
|
||||||
|
|
|
@ -21,9 +21,9 @@ use super::{HasIsAbove, HasUuid, load_or_empty, member::MemberBuilder};
|
||||||
#[diesel(primary_key(uuid))]
|
#[diesel(primary_key(uuid))]
|
||||||
#[diesel(check_for_backend(diesel::pg::Pg))]
|
#[diesel(check_for_backend(diesel::pg::Pg))]
|
||||||
pub struct Role {
|
pub struct Role {
|
||||||
uuid: Uuid,
|
pub uuid: Uuid,
|
||||||
guild_uuid: Uuid,
|
guild_uuid: Uuid,
|
||||||
name: String,
|
pub name: String,
|
||||||
color: i32,
|
color: i32,
|
||||||
is_above: Option<Uuid>,
|
is_above: Option<Uuid>,
|
||||||
pub permissions: i64,
|
pub permissions: i64,
|
||||||
|
|
|
@ -11,6 +11,25 @@ diesel::table! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
audit_logs (uuid) {
|
||||||
|
uuid -> Uuid,
|
||||||
|
guild_uuid -> Uuid,
|
||||||
|
action_id -> Int2,
|
||||||
|
by_uuid -> Uuid,
|
||||||
|
channel_uuid -> Nullable<Uuid>,
|
||||||
|
user_uuid -> Nullable<Uuid>,
|
||||||
|
message_uuid -> Nullable<Uuid>,
|
||||||
|
role_uuid -> Nullable<Uuid>,
|
||||||
|
#[max_length = 200]
|
||||||
|
audit_message -> Nullable<Varchar>,
|
||||||
|
#[max_length = 200]
|
||||||
|
changed_from -> Nullable<Varchar>,
|
||||||
|
#[max_length = 200]
|
||||||
|
changed_to -> Nullable<Varchar>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
diesel::table! {
|
diesel::table! {
|
||||||
channel_permissions (channel_uuid, role_uuid) {
|
channel_permissions (channel_uuid, role_uuid) {
|
||||||
channel_uuid -> Uuid,
|
channel_uuid -> Uuid,
|
||||||
|
@ -163,6 +182,11 @@ diesel::table! {
|
||||||
|
|
||||||
diesel::joinable!(access_tokens -> refresh_tokens (refresh_token));
|
diesel::joinable!(access_tokens -> refresh_tokens (refresh_token));
|
||||||
diesel::joinable!(access_tokens -> users (uuid));
|
diesel::joinable!(access_tokens -> users (uuid));
|
||||||
|
diesel::joinable!(audit_logs -> channels (channel_uuid));
|
||||||
|
diesel::joinable!(audit_logs -> guild_members (by_uuid));
|
||||||
|
diesel::joinable!(audit_logs -> messages (message_uuid));
|
||||||
|
diesel::joinable!(audit_logs -> roles (role_uuid));
|
||||||
|
diesel::joinable!(audit_logs -> users (user_uuid));
|
||||||
diesel::joinable!(channel_permissions -> channels (channel_uuid));
|
diesel::joinable!(channel_permissions -> channels (channel_uuid));
|
||||||
diesel::joinable!(channel_permissions -> roles (role_uuid));
|
diesel::joinable!(channel_permissions -> roles (role_uuid));
|
||||||
diesel::joinable!(channels -> guilds (guild_uuid));
|
diesel::joinable!(channels -> guilds (guild_uuid));
|
||||||
|
@ -182,6 +206,7 @@ diesel::joinable!(roles -> guilds (guild_uuid));
|
||||||
|
|
||||||
diesel::allow_tables_to_appear_in_same_query!(
|
diesel::allow_tables_to_appear_in_same_query!(
|
||||||
access_tokens,
|
access_tokens,
|
||||||
|
audit_logs,
|
||||||
channel_permissions,
|
channel_permissions,
|
||||||
channels,
|
channels,
|
||||||
friend_requests,
|
friend_requests,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue