brokkr-broker::dal::audit_logs
Rust
Data Access Layer for AuditLog operations.
This module provides functionality to interact with the audit_logs table. Audit logs are immutable - only create and query operations are supported.
Structs
Section titled “Structs”struct AuditLogsDAL<'a>
Section titled “struct AuditLogsDAL<'a>”pub
Data Access Layer for AuditLog operations.
Fields
Section titled “Fields”| Name | Type | Description |
|---|---|---|
dal |
&'a DAL |
Reference to the main DAL instance. |
Methods
Section titled “Methods”create
Section titled “create”pub
fn create( &self, new_log: &NewAuditLog,) -> Result<AuditLog, diesel::result::Error>Creates a new audit log entry.
Parameters:
| Name | Type | Description |
|---|---|---|
new_log |
&NewAuditLog |
The audit log entry to create. |
Returns:
Returns the created AuditLog record.
Source
pub fn create(&self, new_log: &NewAuditLog) -> Result<AuditLog, diesel::result::Error> { let conn = &mut self.dal.conn()?;
diesel::insert_into(audit_logs::table) .values(new_log) .get_result(conn) }create_batch
Section titled “create_batch”pub
fn create_batch( &self, logs: &[NewAuditLog],) -> Result<usize, diesel::result::Error>Creates multiple audit log entries in a batch.
Parameters:
| Name | Type | Description |
|---|---|---|
logs |
&[NewAuditLog] |
The audit log entries to create. |
Returns:
Returns the number of inserted rows.
Source
pub fn create_batch(&self, logs: &[NewAuditLog]) -> Result<usize, diesel::result::Error> { if logs.is_empty() { return Ok(0); }
let conn = &mut self.dal.conn()?;
diesel::insert_into(audit_logs::table) .values(logs) .execute(conn) }pub
fn get( &self, id: Uuid,) -> Result<Option<AuditLog>, diesel::result::Error>Gets an audit log entry by ID.
Parameters:
| Name | Type | Description |
|---|---|---|
id |
Uuid |
The audit log UUID. |
Returns:
Returns the audit log if found.
Source
pub fn get(&self, id: Uuid) -> Result<Option<AuditLog>, diesel::result::Error> { let conn = &mut self.dal.conn()?;
audit_logs::table .filter(audit_logs::id.eq(id)) .first(conn) .optional() }pub
fn list( &self, filter: Option<&AuditLogFilter>, limit: Option<i64>, offset: Option<i64>,) -> Result<Vec<AuditLog>, diesel::result::Error>Lists audit logs with optional filtering and pagination.
Parameters:
| Name | Type | Description |
|---|---|---|
filter |
Option<&AuditLogFilter> |
Optional filter criteria. |
limit |
Option<i64> |
Maximum number of results (default 100, max 1000). |
offset |
Option<i64> |
Number of results to skip. |
Returns:
Returns a list of audit logs ordered by timestamp descending.
Source
pub fn list( &self, filter: Option<&AuditLogFilter>, limit: Option<i64>, offset: Option<i64>, ) -> Result<Vec<AuditLog>, diesel::result::Error> { let conn = &mut self.dal.conn()?;
let mut query = audit_logs::table.into_boxed();
// Apply filters if let Some(f) = filter { if let Some(ref actor_type) = f.actor_type { query = query.filter(audit_logs::actor_type.eq(actor_type)); } if let Some(actor_id) = f.actor_id { query = query.filter(audit_logs::actor_id.eq(actor_id)); } if let Some(ref action) = f.action { // Support prefix matching with wildcard if action.ends_with('*') { let prefix = &action[..action.len() - 1]; query = query.filter(audit_logs::action.like(format!("{}%", prefix))); } else { query = query.filter(audit_logs::action.eq(action)); } } if let Some(ref resource_type) = f.resource_type { query = query.filter(audit_logs::resource_type.eq(resource_type)); } if let Some(resource_id) = f.resource_id { query = query.filter(audit_logs::resource_id.eq(resource_id)); } if let Some(from) = f.from { query = query.filter(audit_logs::timestamp.ge(from)); } if let Some(to) = f.to { query = query.filter(audit_logs::timestamp.lt(to)); } }
// Apply pagination let limit = limit.unwrap_or(100).min(1000); let offset = offset.unwrap_or(0);
query .order(audit_logs::timestamp.desc()) .limit(limit) .offset(offset) .load(conn) }pub
fn count( &self, filter: Option<&AuditLogFilter>,) -> Result<i64, diesel::result::Error>Counts audit logs matching the filter.
Parameters:
| Name | Type | Description |
|---|---|---|
filter |
Option<&AuditLogFilter> |
Optional filter criteria. |
Returns:
Returns the count of matching audit logs.
Source
pub fn count(&self, filter: Option<&AuditLogFilter>) -> Result<i64, diesel::result::Error> { let conn = &mut self.dal.conn()?;
let mut query = audit_logs::table.into_boxed();
// Apply same filters as list if let Some(f) = filter { if let Some(ref actor_type) = f.actor_type { query = query.filter(audit_logs::actor_type.eq(actor_type)); } if let Some(actor_id) = f.actor_id { query = query.filter(audit_logs::actor_id.eq(actor_id)); } if let Some(ref action) = f.action { if action.ends_with('*') { let prefix = &action[..action.len() - 1]; query = query.filter(audit_logs::action.like(format!("{}%", prefix))); } else { query = query.filter(audit_logs::action.eq(action)); } } if let Some(ref resource_type) = f.resource_type { query = query.filter(audit_logs::resource_type.eq(resource_type)); } if let Some(resource_id) = f.resource_id { query = query.filter(audit_logs::resource_id.eq(resource_id)); } if let Some(from) = f.from { query = query.filter(audit_logs::timestamp.ge(from)); } if let Some(to) = f.to { query = query.filter(audit_logs::timestamp.lt(to)); } }
query.count().get_result(conn) }cleanup_old_logs
Section titled “cleanup_old_logs”pub
fn cleanup_old_logs( &self, retention_days: i64,) -> Result<usize, diesel::result::Error>Deletes audit logs older than the specified retention period.
Parameters:
| Name | Type | Description |
|---|---|---|
retention_days |
i64 |
Number of days to retain logs. |
Returns:
Returns the number of deleted rows.
Source
pub fn cleanup_old_logs(&self, retention_days: i64) -> Result<usize, diesel::result::Error> { let conn = &mut self.dal.conn()?;
let cutoff = Utc::now() - Duration::days(retention_days);
diesel::delete(audit_logs::table.filter(audit_logs::created_at.lt(cutoff))).execute(conn) }get_resource_history
Section titled “get_resource_history”pub
fn get_resource_history( &self, resource_type: &str, resource_id: Uuid, limit: i64,) -> Result<Vec<AuditLog>, diesel::result::Error>Gets recent audit logs for a specific resource.
Parameters:
| Name | Type | Description |
|---|---|---|
resource_type |
&str |
The type of resource. |
resource_id |
Uuid |
The ID of the resource. |
limit |
i64 |
Maximum number of results. |
Returns:
Returns recent audit logs for the resource.
Source
pub fn get_resource_history( &self, resource_type: &str, resource_id: Uuid, limit: i64, ) -> Result<Vec<AuditLog>, diesel::result::Error> { let conn = &mut self.dal.conn()?;
audit_logs::table .filter(audit_logs::resource_type.eq(resource_type)) .filter(audit_logs::resource_id.eq(resource_id)) .order(audit_logs::timestamp.desc()) .limit(limit) .load(conn) }get_actor_history
Section titled “get_actor_history”pub
fn get_actor_history( &self, actor_type: &str, actor_id: Uuid, limit: i64,) -> Result<Vec<AuditLog>, diesel::result::Error>Gets recent audit logs for a specific actor.
Parameters:
| Name | Type | Description |
|---|---|---|
actor_type |
&str |
The type of actor. |
actor_id |
Uuid |
The ID of the actor. |
limit |
i64 |
Maximum number of results. |
Returns:
Returns recent audit logs for the actor.
Source
pub fn get_actor_history( &self, actor_type: &str, actor_id: Uuid, limit: i64, ) -> Result<Vec<AuditLog>, diesel::result::Error> { let conn = &mut self.dal.conn()?;
audit_logs::table .filter(audit_logs::actor_type.eq(actor_type)) .filter(audit_logs::actor_id.eq(actor_id)) .order(audit_logs::timestamp.desc()) .limit(limit) .load(conn) }get_failed_auth_attempts
Section titled “get_failed_auth_attempts”pub
fn get_failed_auth_attempts( &self, since: DateTime<Utc>, ip_address: Option<&str>,) -> Result<Vec<AuditLog>, diesel::result::Error>Gets failed authentication attempts within a time window.
Parameters:
| Name | Type | Description |
|---|---|---|
since |
DateTime<Utc> |
Start of the time window. |
ip_address |
Option<&str> |
Optional filter by IP address. |
Returns:
Returns failed auth audit logs.
Source
pub fn get_failed_auth_attempts( &self, since: DateTime<Utc>, ip_address: Option<&str>, ) -> Result<Vec<AuditLog>, diesel::result::Error> { use brokkr_models::models::audit_logs::ACTION_AUTH_FAILED;
let conn = &mut self.dal.conn()?;
let mut query = audit_logs::table .filter(audit_logs::action.eq(ACTION_AUTH_FAILED)) .filter(audit_logs::timestamp.ge(since)) .into_boxed();
if let Some(ip) = ip_address { query = query.filter(audit_logs::ip_address.eq(ip)); }
query.order(audit_logs::timestamp.desc()).load(conn) }