mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-09 00:04:10 +00:00
* Migrate audit log page to svelte 5 * Add email and span cols to audit table * Add token_prefixs to audit logs (into AuditAuthorable trait) * Add audit logs graph (wip) * Add audit span on push and jwt * Unify same job audit into the same audit span * Improve the graph visually * Fix typo * functioning graph with svelte issue * Fix leak * feat: migrate AuditLogsTable from DataTable to VirtualList for performance - Replace DataTable component with VirtualList for handling thousands of rows - Migrate to Svelte 5 runes ($props, $bindable, $derived, $state) - Implement flattenLogs() for virtual scrolling with grouped date headers - Add sticky indices and dynamic height calculation - Update parent component to use callback prop pattern instead of events - Preserve all existing functionality: filtering, selection, pagination - Follows RunsTable.svelte implementation pattern Resolves performance issues when displaying large audit log datasets. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Ruben Fiszel <rubenfiszel@users.noreply.github.com> * Fix remaining virtual list issues * WIP graph * Fix chart styling * Fix npm check * Fix missing audit_span arguments * Update sqlx * use varchar 255 for email as in other tables * Remove syntax inconsistency * Match struct with ee crate * Update ee-repo-ref.txt * Update worker_flow.rs * Remove redefinition of trait to prevent shadowing * Re add trait on oss but only when no `private` flag --------- Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> Co-authored-by: Ruben Fiszel <rubenfiszel@users.noreply.github.com> Co-authored-by: GitHub Action <action@github.com> Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
127 lines
3.0 KiB
Rust
127 lines
3.0 KiB
Rust
use sqlx::{Pool, Postgres, Transaction};
|
|
|
|
pub type DB = Pool<Postgres>;
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct Authed {
|
|
pub email: String,
|
|
pub username: String,
|
|
pub is_admin: bool,
|
|
pub is_operator: bool,
|
|
pub groups: Vec<String>,
|
|
// (folder name, can write, is owner)
|
|
pub folders: Vec<(String, bool, bool)>,
|
|
pub scopes: Option<Vec<String>>,
|
|
pub token_prefix: Option<String>,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct UserDB {
|
|
db: DB,
|
|
}
|
|
|
|
pub trait Authable {
|
|
fn email(&self) -> &str;
|
|
fn username(&self) -> &str;
|
|
fn is_admin(&self) -> bool;
|
|
fn is_operator(&self) -> bool;
|
|
fn groups(&self) -> &[String];
|
|
fn folders(&self) -> &[(String, bool, bool)];
|
|
fn scopes(&self) -> Option<&[String]>;
|
|
}
|
|
|
|
impl Authable for Authed {
|
|
fn is_admin(&self) -> bool {
|
|
self.is_admin
|
|
}
|
|
|
|
fn is_operator(&self) -> bool {
|
|
self.is_operator
|
|
}
|
|
|
|
fn groups(&self) -> &[String] {
|
|
&self.groups
|
|
}
|
|
|
|
fn folders(&self) -> &[(String, bool, bool)] {
|
|
&self.folders
|
|
}
|
|
|
|
fn scopes(&self) -> Option<&[std::string::String]> {
|
|
self.scopes.as_ref().map(|x| x.as_slice())
|
|
}
|
|
|
|
fn email(&self) -> &str {
|
|
&self.email
|
|
}
|
|
|
|
fn username(&self) -> &str {
|
|
&self.username
|
|
}
|
|
}
|
|
|
|
lazy_static::lazy_static! {
|
|
pub static ref PG_SCHEMA: Option<String> = std::env::var("PG_SCHEMA").ok();
|
|
}
|
|
|
|
impl UserDB {
|
|
pub fn new(db: DB) -> Self {
|
|
Self { db }
|
|
}
|
|
|
|
pub async fn begin<T>(self, authed: &T) -> Result<Transaction<'static, Postgres>, sqlx::Error>
|
|
where
|
|
T: Authable,
|
|
{
|
|
let (folders_write, folders_read): &(Vec<_>, Vec<_>) =
|
|
&authed.folders().into_iter().partition(|x| x.1);
|
|
|
|
let mut folders_read = folders_read.clone();
|
|
folders_read.extend(folders_write.clone());
|
|
|
|
// tracing::debug!(
|
|
// "Setting role to {} {:?} {:?} {:?} {:?}",
|
|
// user,
|
|
// authed.username(),
|
|
// authed.groups(),
|
|
// folders_read,
|
|
// folders_write
|
|
// );
|
|
|
|
let mut tx = self.db.begin().await?;
|
|
|
|
if let Some(schema) = PG_SCHEMA.as_ref() {
|
|
sqlx::query(&format!("SET LOCAL search_path TO {}", schema))
|
|
.execute(&mut *tx)
|
|
.await?;
|
|
}
|
|
|
|
sqlx::query!(
|
|
"SELECT set_session_context($1, $2, $3, $4, $5, $6)",
|
|
authed.is_admin(),
|
|
authed.username(),
|
|
authed.groups().join(","),
|
|
authed
|
|
.groups()
|
|
.iter()
|
|
.map(|x| format!("g/{}", x))
|
|
.collect::<Vec<_>>()
|
|
.join(","),
|
|
folders_read
|
|
.iter()
|
|
.map(|x| x.0.clone())
|
|
.collect::<Vec<_>>()
|
|
.join(","),
|
|
folders_write
|
|
.iter()
|
|
.map(|x| x.0.clone())
|
|
.collect::<Vec<_>>()
|
|
.join(",")
|
|
)
|
|
.execute(&mut *tx)
|
|
.await?;
|
|
|
|
Ok(tx)
|
|
}
|
|
}
|