feat(spaces): add custom state event types for space roles
Define serde content types for m.space.roles, m.space.role.member, and m.space.role.room custom state events used by space permission cascading. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
dc8949f4d1
commit
c5ffc4963c
2 changed files with 101 additions and 0 deletions
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
pub mod event;
|
||||
pub mod pdu;
|
||||
pub mod space_roles;
|
||||
pub mod state_key;
|
||||
pub mod state_res;
|
||||
|
||||
|
|
|
|||
100
src/core/matrix/space_roles.rs
Normal file
100
src/core/matrix/space_roles.rs
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
//! Custom state event content types for space permission cascading.
|
||||
//!
|
||||
//! These events live in Space rooms and define roles, user-role assignments,
|
||||
//! and room-role requirements.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Content for `m.space.roles` (state key: "")
|
||||
///
|
||||
/// Defines available roles for a Space.
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct SpaceRolesEventContent {
|
||||
pub roles: BTreeMap<String, RoleDefinition>,
|
||||
}
|
||||
|
||||
/// A single role definition within a Space.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct RoleDefinition {
|
||||
pub description: String,
|
||||
|
||||
/// If present, users with this role receive this power level in child
|
||||
/// rooms.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub power_level: Option<i64>,
|
||||
}
|
||||
|
||||
/// Content for `m.space.role.member` (state key: user ID)
|
||||
///
|
||||
/// Assigns roles to a user within a Space.
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct SpaceRoleMemberEventContent {
|
||||
pub roles: Vec<String>,
|
||||
}
|
||||
|
||||
/// Content for `m.space.role.room` (state key: room ID)
|
||||
///
|
||||
/// Declares which roles a child room requires for access.
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct SpaceRoleRoomEventContent {
|
||||
pub required_roles: Vec<String>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn serialize_space_roles() {
|
||||
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.len(), 2);
|
||||
assert_eq!(deserialized.roles["admin"].power_level, Some(100));
|
||||
assert!(deserialized.roles["nsfw"].power_level.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_role_member() {
|
||||
let content = SpaceRoleMemberEventContent {
|
||||
roles: vec!["nsfw".to_owned(), "vip".to_owned()],
|
||||
};
|
||||
let json = serde_json::to_string(&content).unwrap();
|
||||
let deserialized: SpaceRoleMemberEventContent = serde_json::from_str(&json).unwrap();
|
||||
assert_eq!(deserialized.roles, vec!["nsfw", "vip"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_role_room() {
|
||||
let content = SpaceRoleRoomEventContent {
|
||||
required_roles: vec!["nsfw".to_owned()],
|
||||
};
|
||||
let json = serde_json::to_string(&content).unwrap();
|
||||
let deserialized: SpaceRoleRoomEventContent = serde_json::from_str(&json).unwrap();
|
||||
assert_eq!(deserialized.required_roles, vec!["nsfw"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_roles_deserialize() {
|
||||
let json = r#"{"roles":{}}"#;
|
||||
let content: SpaceRolesEventContent = serde_json::from_str(json).unwrap();
|
||||
assert!(content.roles.is_empty());
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue