this repo has no description
1use chrono::{DateTime, Utc}; 2use serde::{Deserialize, Serialize}; 3use sqlx::PgPool; 4use uuid::Uuid; 5 6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, sqlx::Type)] 7#[sqlx(type_name = "delegation_action_type", rename_all = "snake_case")] 8pub enum DelegationActionType { 9 GrantCreated, 10 GrantRevoked, 11 ScopesModified, 12 TokenIssued, 13 RepoWrite, 14 BlobUpload, 15 AccountAction, 16} 17 18#[derive(Debug, Clone, Serialize, Deserialize)] 19pub struct AuditLogEntry { 20 pub id: Uuid, 21 pub delegated_did: String, 22 pub actor_did: String, 23 pub controller_did: Option<String>, 24 pub action_type: DelegationActionType, 25 pub action_details: Option<serde_json::Value>, 26 pub ip_address: Option<String>, 27 pub user_agent: Option<String>, 28 pub created_at: DateTime<Utc>, 29} 30 31pub async fn log_delegation_action( 32 pool: &PgPool, 33 delegated_did: &str, 34 actor_did: &str, 35 controller_did: Option<&str>, 36 action_type: DelegationActionType, 37 action_details: Option<serde_json::Value>, 38 ip_address: Option<&str>, 39 user_agent: Option<&str>, 40) -> Result<Uuid, sqlx::Error> { 41 let id = sqlx::query_scalar!( 42 r#" 43 INSERT INTO delegation_audit_log 44 (delegated_did, actor_did, controller_did, action_type, action_details, ip_address, user_agent) 45 VALUES ($1, $2, $3, $4, $5, $6, $7) 46 RETURNING id 47 "#, 48 delegated_did, 49 actor_did, 50 controller_did, 51 action_type as DelegationActionType, 52 action_details, 53 ip_address, 54 user_agent 55 ) 56 .fetch_one(pool) 57 .await?; 58 59 Ok(id) 60} 61 62pub async fn get_audit_log_for_account( 63 pool: &PgPool, 64 delegated_did: &str, 65 limit: i64, 66 offset: i64, 67) -> Result<Vec<AuditLogEntry>, sqlx::Error> { 68 let entries = sqlx::query_as!( 69 AuditLogEntry, 70 r#" 71 SELECT 72 id, 73 delegated_did, 74 actor_did, 75 controller_did, 76 action_type as "action_type: DelegationActionType", 77 action_details, 78 ip_address, 79 user_agent, 80 created_at 81 FROM delegation_audit_log 82 WHERE delegated_did = $1 83 ORDER BY created_at DESC 84 LIMIT $2 OFFSET $3 85 "#, 86 delegated_did, 87 limit, 88 offset 89 ) 90 .fetch_all(pool) 91 .await?; 92 93 Ok(entries) 94} 95 96pub async fn get_audit_log_by_controller( 97 pool: &PgPool, 98 controller_did: &str, 99 limit: i64, 100 offset: i64, 101) -> Result<Vec<AuditLogEntry>, sqlx::Error> { 102 let entries = sqlx::query_as!( 103 AuditLogEntry, 104 r#" 105 SELECT 106 id, 107 delegated_did, 108 actor_did, 109 controller_did, 110 action_type as "action_type: DelegationActionType", 111 action_details, 112 ip_address, 113 user_agent, 114 created_at 115 FROM delegation_audit_log 116 WHERE controller_did = $1 117 ORDER BY created_at DESC 118 LIMIT $2 OFFSET $3 119 "#, 120 controller_did, 121 limit, 122 offset 123 ) 124 .fetch_all(pool) 125 .await?; 126 127 Ok(entries) 128} 129 130pub async fn count_audit_log_entries( 131 pool: &PgPool, 132 delegated_did: &str, 133) -> Result<i64, sqlx::Error> { 134 let count = sqlx::query_scalar!( 135 r#"SELECT COUNT(*) as "count!" FROM delegation_audit_log WHERE delegated_did = $1"#, 136 delegated_did 137 ) 138 .fetch_one(pool) 139 .await?; 140 141 Ok(count) 142}