Skip to main content

revolt_database/models/audit_logs/ops/
mongodb.rs

1use mongodb::options::FindOptions;
2use revolt_result::Result;
3
4use crate::{AuditLogEntry, AuditLogQuery, MongoDb};
5
6use super::AbstractAuditLogs;
7
8static COL: &str = "audit_logs";
9
10#[async_trait]
11impl AbstractAuditLogs for MongoDb {
12    /// Inserts an entry into the server's audit log
13    async fn insert_audit_log_entry(&self, entry: &AuditLogEntry) -> Result<()> {
14        query!(self, insert_one, COL, entry).map(|_| ())
15    }
16
17    /// Fetches a server's audit logs using the provided query options
18    async fn get_server_audit_logs(
19        &self,
20        server: &str,
21        query: AuditLogQuery,
22    ) -> Result<Vec<AuditLogEntry>> {
23        let mut filter = doc! {
24            "server": server
25        };
26
27        if let Some(user) = query.user {
28            filter.insert("user", user);
29        };
30
31        if let Some(target) = query.target {
32            filter.insert("target", target);
33        }
34
35        if let Some(types) = query.r#type {
36            filter.insert("action.type", doc! { "$in": types });
37        };
38
39        if let Some(doc) = match (query.before, query.after) {
40            (Some(before), Some(after)) => Some(doc! {
41                "$lt": before,
42                "$gt": after
43            }),
44            (Some(before), _) => Some(doc! {
45                "$lt": before
46            }),
47            (_, Some(after)) => Some(doc! {
48                "$gt": after
49            }),
50            _ => None,
51        } {
52            filter.insert("_id", doc);
53        };
54
55        self.find_with_options(
56            COL,
57            filter,
58            FindOptions::builder()
59                .limit(query.limit)
60                .sort(doc! { "_id": -1 })
61                .build(),
62        )
63        .await
64        .map_err(|_| create_database_error!("find", COL))
65    }
66}