feat: Add ListUsers operation

This commit is contained in:
selfhoster selfhoster 2026-09-08 16:39:50 +02:00
commit dba07912d2
9 changed files with 166 additions and 28 deletions

View file

@ -1,13 +1,49 @@
use serde::Serialize;
use std::fmt;
use crate::db::{Operation, Role};
/// A requested user/domain combo for login, lowercased.
///
/// Domain may be empty, but a value with more than one
/// `@` is considered invalid.
#[derive(Clone, Debug)]
pub struct UserRef {
pub username: String,
pub domain: Option<String>,
}
#[derive(Clone, Debug)]
pub struct InvalidUserRef(pub String);
impl std::error::Error for InvalidUserRef {}
impl fmt::Display for InvalidUserRef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Invalid username: {}", self.0)
}
}
impl UserRef {
pub fn from_user_maybe_domain(value: &str) -> Result<Self, InvalidUserRef> {
let value = value.to_lowercase();
let mut parts = value.split('@');
let username = parts.next().unwrap();
let domain = parts.next();
if parts.next().is_some() {
return Err(InvalidUserRef(value.clone()));
}
Ok(Self {
username: username.to_string(),
domain: domain.map(Into::into),
})
}
}
impl fmt::Display for UserRef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(domain) = &self.domain {
@ -18,7 +54,7 @@ impl fmt::Display for UserRef {
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Serialize)]
pub struct User {
/// Username, without the domain part. Once set, cannot be edited.
pub username: String,
@ -41,7 +77,6 @@ impl User {
}
}
#[expect(unused)]
pub fn can_perform(&self, operation: &Operation) -> bool {
self.role.can_perform(operation)
}