Add four custom Matrix state event content types for space role management: space roles definitions, per-user role assignments, per-room role requirements, and per-space cascading override. Add server config options: space_permission_cascading (default false) as the server-wide toggle, and space_roles_cache_flush_threshold (default 1000) for cache management.
81 lines
2.4 KiB
Rust
81 lines
2.4 KiB
Rust
use std::collections::BTreeMap;
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
pub const SPACE_ROLES_EVENT_TYPE: &str = "com.continuwuity.space.roles";
|
|
pub const SPACE_ROLE_MEMBER_EVENT_TYPE: &str = "com.continuwuity.space.role.member";
|
|
pub const SPACE_ROLE_ROOM_EVENT_TYPE: &str = "com.continuwuity.space.role.room";
|
|
pub const SPACE_CASCADING_EVENT_TYPE: &str = "com.continuwuity.space.cascading";
|
|
|
|
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
|
|
pub struct SpaceRolesEventContent {
|
|
pub roles: BTreeMap<String, RoleDefinition>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
|
pub struct RoleDefinition {
|
|
pub description: String,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub power_level: Option<i64>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
|
|
pub struct SpaceRoleMemberEventContent {
|
|
pub roles: Vec<String>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
|
|
pub struct SpaceRoleRoomEventContent {
|
|
pub required_roles: Vec<String>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
|
pub struct SpaceCascadingEventContent {
|
|
pub enabled: bool,
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn space_roles_roundtrip() {
|
|
let mut roles = BTreeMap::new();
|
|
roles.insert("admin".to_owned(), RoleDefinition {
|
|
description: "Space administrator".to_owned(),
|
|
power_level: Some(100),
|
|
});
|
|
roles.insert("nsfw".to_owned(), RoleDefinition {
|
|
description: "NSFW access".to_owned(),
|
|
power_level: None,
|
|
});
|
|
let content = SpaceRolesEventContent { roles };
|
|
let json = serde_json::to_string(&content).unwrap();
|
|
let deserialized: SpaceRolesEventContent = serde_json::from_str(&json).unwrap();
|
|
assert_eq!(deserialized.roles["admin"].power_level, Some(100));
|
|
assert!(deserialized.roles["nsfw"].power_level.is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn power_level_omitted_in_serialization_when_none() {
|
|
let role = RoleDefinition {
|
|
description: "Test".to_owned(),
|
|
power_level: None,
|
|
};
|
|
let json = serde_json::to_string(&role).unwrap();
|
|
assert!(!json.contains("power_level"));
|
|
}
|
|
|
|
#[test]
|
|
fn negative_power_level() {
|
|
let json = r#"{"description":"Restricted","power_level":-10}"#;
|
|
let role: RoleDefinition = serde_json::from_str(json).unwrap();
|
|
assert_eq!(role.power_level, Some(-10));
|
|
}
|
|
|
|
#[test]
|
|
fn missing_description_fails() {
|
|
let json = r#"{"power_level":100}"#;
|
|
serde_json::from_str::<RoleDefinition>(json).unwrap_err();
|
|
}
|
|
}
|