Skip to content

Commit bb0964d

Browse files
feat: add teams, general rework of permissions
Signed-off-by: Henry <mail@henrygressmann.de>
1 parent 86aeaeb commit bb0964d

61 files changed

Lines changed: 1670 additions & 600 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.cargo/config.toml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
[build]
2-
31
[alias]
42
dev = "run -- dev"
53

4+
[build]
5+
66
[env]
7-
DUCKDB_STATIC = "1"
87
DUCKDB_DISABLE_EXTENSION_LOAD = "1"
98
DUCKDB_DISABLE_JEMALLOC = "1"
9+
DUCKDB_STATIC = "1"
1010

1111
[target.x86_64-unknown-linux-musl]
1212
rustflags = ["-C", "target_cpu=x86-64-v3"]

‎CHANGELOG.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ Since this is not a library, this changelog focuses on the changes that are rele
2727
- Added left and right arrow keyboard shortcuts for navigating dashboard date ranges
2828
- Added authenticated batch event ingestion endpoint
2929
- Added API key management UI
30+
- Added teams for assigning project read access to groups of users and internal projects visible to signed-in users
31+
32+
### ⚠️ Breaking Changes
33+
34+
- Direct per-user project assignments no longer grant access. Reassign users to teams to restore private-project access.
3035

3136
## [v1.7.0] - 2026-09-13
3237

‎Cargo.lock‎

Lines changed: 1 addition & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ homepage = "https://liwan.dev"
1111
repository = "https://github.com/explodingcamera/liwan"
1212
license = "Apache-2.0"
1313

14+
[workspace.lints.rust]
15+
unsafe_code = "forbid"
16+
17+
[workspace.lints.clippy]
18+
too_many_arguments = "allow"
19+
1420
[profile.dev]
1521
opt-level = 1
1622

‎crates/api/Cargo.toml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,6 @@ url = "2"
4444
[dev-dependencies]
4545
axum = "0.8"
4646
tokio = { version = "1", features = ["macros", "rt-multi-thread", "time", "sync"] }
47+
48+
[lints]
49+
workspace = true

‎crates/api/src/client.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,20 +336,28 @@ async fn send_batch<T: Transport>(config: &Builder<T>, entity_id: &str, events:
336336
/// A client error.
337337
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
338338
pub enum Error {
339+
/// The event queue has reached its capacity.
339340
#[error("event queue is full")]
340341
QueueFull,
342+
/// The client is no longer accepting events.
341343
#[error("client is closed")]
342344
Closed,
345+
/// Liwan rejected the API key.
343346
#[error("Liwan rejected the API key")]
344347
Authentication,
348+
/// Liwan rejected the event batch.
345349
#[error("Liwan rejected the event batch")]
346350
InvalidRequest,
351+
/// Delivery failed after all retries.
347352
#[error("event delivery retries were exhausted")]
348353
RetriesExhausted,
354+
/// The background worker stopped before completing the operation.
349355
#[error("event delivery worker stopped")]
350356
WorkerStopped,
357+
/// Liwan returned an unexpected HTTP status.
351358
#[error("Liwan returned HTTP status {0}")]
352359
Response(StatusCode),
360+
/// A client setting is invalid.
353361
#[error("{0}")]
354362
InvalidConfiguration(&'static str),
355363
}

‎crates/api/src/event.rs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@ use serde::Serialize;
77
/// Metadata captured from an HTTP request.
88
#[derive(Debug, Clone, Default)]
99
pub struct RequestMetadata {
10+
/// The full URL of the request.
1011
pub url: String,
12+
/// The referrer, if supplied.
1113
pub referrer: Option<String>,
14+
/// The resolved client IP, if available.
1215
pub ip: Option<IpAddr>,
16+
/// The user-agent header, if supplied.
1317
pub user_agent: Option<String>,
1418
}
1519

@@ -105,6 +109,7 @@ impl Event {
105109

106110
/// Converts supported timestamp types to RFC 3339.
107111
pub trait IntoTimestamp {
112+
/// Formats this timestamp as an RFC 3339 string.
108113
fn into_timestamp(self) -> String;
109114
}
110115

‎crates/api/src/lib.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! A framework-neutral client for the Liwan API.
22

3-
#![forbid(unsafe_code)]
3+
#![deny(missing_docs)]
44

55
mod client;
66
mod client_ip;

‎crates/liwan/Cargo.toml‎

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,12 @@ name = "reports"
2121
[dependencies]
2222
# async/concurrency
2323
arc-swap = "1.9"
24-
futures-lite = { version = "2.6", default-features = false, features = ["alloc"] }
24+
futures-util = { version = "0.3", default-features = false, features = ["std"] }
2525
quick_cache = { version = "0.7" }
26-
tokio = { version = "1.53", default-features = false, features = ["macros", "rt-multi-thread", "signal", "sync"] }
26+
tokio = { version = "1.53", default-features = false, features = ["macros", "net", "rt-multi-thread", "signal", "sync", "time"] }
2727
tokio-util = { version = "0.7", features = ["io", "time"] }
2828

2929
# encoding
30-
hex = { version = "0.4" }
3130
md-5 = { version = "0.11.0" }
3231
serde = { version = "1.0", features = ["derive"] }
3332
serde_json = { version = "1.0" }
@@ -67,12 +66,13 @@ axum = { version = "0.8", default-features = false, features = [
6766
"tokio",
6867
] }
6968
axum-extra = { version = "0.12", default-features = false, features = ["cookie", "typed-header"] }
69+
base64 = "0.23"
7070
headers = "0.4"
7171
http = "1.5"
7272
ipnet = "2.12"
7373
oauth2 = { git = "https://github.com/explodingcamera-contrib/oauth2-rs", default-features = false }
7474
openidconnect = { git = "https://github.com/explodingcamera-contrib/openidconnect-rs", default-features = false }
75-
reqwest = { version = "0.13", default-features = false, features = ["charset", "json", "rustls", "stream"] }
75+
reqwest = { version = "0.13", default-features = false, features = ["json", "rustls", "stream"] }
7676
rust-embed = { version = "8.12", features = ["mime-guess"] }
7777
schemars = { version = "1.2", features = ["chrono04", "derive"] }
7878
tower = { version = "0.5", default-features = false }
@@ -96,11 +96,9 @@ refinery = { version = "0.9", default-features = false }
9696
refinery-core = { version = "0.9", default-features = false }
9797
rsntp = { version = "4.1.2", default-features = false, features = ["async"] }
9898
rusqlite = { version = "0.40", features = ["bundled", "chrono", "modern_sqlite"] }
99-
base64 = "0.23"
10099

101100
[dev-dependencies]
102101
axum-test = { version = "21" }
103-
cookie = { version = "*", default-features = false }
104102
criterion = { version = "0.8", default-features = false }
105103
tempfile = { version = "3" }
106104
tower = { version = "*", features = ["util"] }
@@ -109,5 +107,5 @@ tower = { version = "*", features = ["util"] }
109107
default = ["geoip"]
110108
geoip = ["dep:maxminddb"]
111109

112-
[lints.clippy]
113-
too_many_arguments = "allow"
110+
[lints]
111+
workspace = true

‎crates/liwan/src/app/core.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod projects;
77
pub mod reports;
88
mod sessions;
99
mod settings;
10+
mod teams;
1011
mod users;
1112

1213
pub use api_keys::{ApiKeyAccess, LiwanApiKeys};
@@ -19,6 +20,7 @@ pub use onboarding::LiwanOnboarding;
1920
pub use projects::LiwanProjects;
2021
pub use sessions::LiwanSessions;
2122
pub use settings::{LiwanProjectSettings, LiwanSettings};
23+
pub use teams::LiwanTeams;
2224
pub use users::LiwanUsers;
2325

2426
#[cfg(feature = "geoip")]

0 commit comments

Comments
 (0)