Add moderation policy events

This commit is contained in:
q-b 2020-10-09 13:29:11 +02:00 committed by GitHub
parent 87b0846201
commit 524782e992
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 208 additions and 1 deletions

View File

@ -38,6 +38,12 @@ Improvements:
* `MessageEventContent::text_html` * `MessageEventContent::text_html`
* `MessageEventContent::notice_plain` * `MessageEventContent::notice_plain`
* `MessageEventContent::notice_html` * `MessageEventContent::notice_html`
* Add policy rule entities:
* `policy::rule::room`
* `policy::rule::server`
* `policy::rule::user`
* Add policy rule recommendation:
* `Recommendation::Ban`
# 0.21.3 # 0.21.3

View File

@ -48,6 +48,9 @@ event_enum! {
/// Any state event. /// Any state event.
kind: State, kind: State,
events: [ events: [
"m.policy.rule.room",
"m.policy.rule.server",
"m.policy.rule.user",
"m.room.aliases", "m.room.aliases",
"m.room.avatar", "m.room.avatar",
"m.room.canonical_alias", "m.room.canonical_alias",

View File

@ -55,6 +55,15 @@ pub enum EventType {
/// m.ignored_user_list /// m.ignored_user_list
IgnoredUserList, IgnoredUserList,
/// m.policy.rule.room
PolicyRuleRoom,
/// m.policy.rule.server
PolicyRuleServer,
/// m.policy.rule.user
PolicyRuleUser,
/// m.presence /// m.presence
Presence, Presence,
@ -162,6 +171,9 @@ impl EventType {
EventType::KeyVerificationRequest => "m.key.verification.request", EventType::KeyVerificationRequest => "m.key.verification.request",
EventType::KeyVerificationStart => "m.key.verification.start", EventType::KeyVerificationStart => "m.key.verification.start",
EventType::IgnoredUserList => "m.ignored_user_list", EventType::IgnoredUserList => "m.ignored_user_list",
EventType::PolicyRuleRoom => "m.policy.rule.room",
EventType::PolicyRuleServer => "m.policy.rule.server",
EventType::PolicyRuleUser => "m.policy.rule.user",
EventType::Presence => "m.presence", EventType::Presence => "m.presence",
EventType::PushRules => "m.push_rules", EventType::PushRules => "m.push_rules",
EventType::Receipt => "m.receipt", EventType::Receipt => "m.receipt",
@ -222,6 +234,9 @@ where
"m.key.verification.request" => EventType::KeyVerificationRequest, "m.key.verification.request" => EventType::KeyVerificationRequest,
"m.key.verification.start" => EventType::KeyVerificationStart, "m.key.verification.start" => EventType::KeyVerificationStart,
"m.ignored_user_list" => EventType::IgnoredUserList, "m.ignored_user_list" => EventType::IgnoredUserList,
"m.policy.rule.room" => EventType::PolicyRuleRoom,
"m.policy.rule.server" => EventType::PolicyRuleServer,
"m.policy.rule.user" => EventType::PolicyRuleUser,
"m.presence" => EventType::Presence, "m.presence" => EventType::Presence,
"m.push_rules" => EventType::PushRules, "m.push_rules" => EventType::PushRules,
"m.receipt" => EventType::Receipt, "m.receipt" => EventType::Receipt,
@ -286,6 +301,9 @@ mod tests {
serde_json_eq(EventType::KeyVerificationRequest, json!("m.key.verification.request")); serde_json_eq(EventType::KeyVerificationRequest, json!("m.key.verification.request"));
serde_json_eq(EventType::KeyVerificationStart, json!("m.key.verification.start")); serde_json_eq(EventType::KeyVerificationStart, json!("m.key.verification.start"));
serde_json_eq(EventType::IgnoredUserList, json!("m.ignored_user_list")); serde_json_eq(EventType::IgnoredUserList, json!("m.ignored_user_list"));
serde_json_eq(EventType::PolicyRuleRoom, json!("m.policy.rule.room"));
serde_json_eq(EventType::PolicyRuleServer, json!("m.policy.rule.server"));
serde_json_eq(EventType::PolicyRuleUser, json!("m.policy.rule.user"));
serde_json_eq(EventType::Presence, json!("m.presence")); serde_json_eq(EventType::Presence, json!("m.presence"));
serde_json_eq(EventType::PushRules, json!("m.push_rules")); serde_json_eq(EventType::PushRules, json!("m.push_rules"));
serde_json_eq(EventType::Receipt, json!("m.receipt")); serde_json_eq(EventType::Receipt, json!("m.receipt"));

View File

@ -167,6 +167,7 @@ pub mod fully_read;
pub mod ignored_user_list; pub mod ignored_user_list;
pub mod key; pub mod key;
pub mod pdu; pub mod pdu;
pub mod policy;
pub mod presence; pub mod presence;
pub mod push_rules; pub mod push_rules;
pub mod receipt; pub mod receipt;

View File

@ -0,0 +1,3 @@
//! Modules for events in the *m.policy* namespace.
pub mod rule;

View File

@ -0,0 +1,60 @@
//! Modules and types for events in the *m.policy.rule* namespace.
use std::fmt::{Display, Formatter, Result as FmtResult};
use serde::{Deserialize, Serialize};
pub mod room;
pub mod server;
pub mod user;
/// The payload for policy rule events.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct PolicyRuleEventContent {
/// The entity affected by this rule. Glob characters * and ? can be used to match zero or more and one or more characters respectively.
pub entity: String,
/// The suggested action to take.
pub recommendation: Recommendation,
/// The human-readable description for the recommendation.
pub reason: String,
}
impl PolicyRuleEventContent {
/// Creates a new `PolicyRuleEventContent` with the given entity, recommendation and reason.
pub fn new(entity: String, recommendation: Recommendation, reason: String) -> Self {
Self { entity, recommendation, reason }
}
}
/// Rules recommendations
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub enum Recommendation {
/// Entities affected by the rule should be banned from participation where possible.
#[serde(rename = "m.ban")]
Ban,
}
impl Recommendation {
/// Creates a string slice from this `Recommendation`.
pub fn as_str(&self) -> &str {
match *self {
Recommendation::Ban => "m.ban",
}
}
}
impl Display for Recommendation {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.write_str(self.as_str())
}
}
impl From<Recommendation> for String {
fn from(recommendation: Recommendation) -> String {
recommendation.to_string()
}
}

View File

@ -0,0 +1,88 @@
//! Types for the *m.policy.rule.room* event.
use ruma_events_macros::StateEventContent;
use serde::{Deserialize, Serialize};
use crate::{policy::rule::PolicyRuleEventContent, StateEvent};
/// This event type is used to apply rules to room entities.
pub type RoomEvent = StateEvent<RoomEventContent>;
/// The payload for `RoomEvent`.
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
#[ruma_event(type = "m.policy.rule.room")]
pub struct RoomEventContent(pub PolicyRuleEventContent);
#[cfg(test)]
mod tests {
use std::time::{Duration, UNIX_EPOCH};
use ruma_common::Raw;
use ruma_identifiers::{event_id, room_id, user_id};
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
use super::{RoomEvent, RoomEventContent};
use crate::{
policy::rule::{PolicyRuleEventContent, Recommendation},
Unsigned,
};
#[test]
fn serialization() {
let room_event = RoomEvent {
event_id: event_id!("$143273582443PhrSn:example.org"),
sender: user_id!("@example:example.org"),
origin_server_ts: UNIX_EPOCH + Duration::from_millis(1_432_735_824_653),
room_id: room_id!("!jEsUZKDJdhlrceRyVU:example.org"),
state_key: "rule:#*:example.org".into(),
prev_content: None,
unsigned: Unsigned { age: Some(1234.into()), transaction_id: None },
content: RoomEventContent(PolicyRuleEventContent {
entity: "#*:example.org".into(),
reason: "undesirable content".into(),
recommendation: Recommendation::Ban,
}),
};
let json = json!({
"content": {
"entity": "#*:example.org",
"reason": "undesirable content",
"recommendation": "m.ban"
},
"event_id": "$143273582443PhrSn:example.org",
"origin_server_ts": 1432735824653u64,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"state_key": "rule:#*:example.org",
"type": "m.policy.rule.room",
"unsigned": {
"age": 1234
}
});
assert_eq!(to_json_value(room_event).unwrap(), json);
}
#[test]
fn deserialization() {
let json = json!({
"content": {
"entity": "#*:example.org",
"reason": "undesirable content",
"recommendation": "m.ban"
},
"event_id": "$143273582443PhrSn:example.org",
"origin_server_ts": 1432735824653u64,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"state_key": "rule:#*:example.org",
"type": "m.policy.rule.room",
"unsigned": {
"age": 1234
}
});
assert!(from_json_value::<Raw<RoomEvent>>(json).unwrap().deserialize().is_ok());
}
}

View File

@ -0,0 +1,14 @@
//! Types for the *m.policy.rule.server* event.
use ruma_events_macros::StateEventContent;
use serde::{Deserialize, Serialize};
use crate::{policy::rule::PolicyRuleEventContent, StateEvent};
/// This event type is used to apply rules to server entities.
pub type ServerEvent = StateEvent<ServerEventContent>;
/// The payload for `ServerEvent`.
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
#[ruma_event(type = "m.policy.rule.server")]
pub struct ServerEventContent(pub PolicyRuleEventContent);

View File

@ -0,0 +1,14 @@
//! Types for the *m.policy.rule.user* event.
use ruma_events_macros::StateEventContent;
use serde::{Deserialize, Serialize};
use crate::{policy::rule::PolicyRuleEventContent, StateEvent};
/// This event type is used to apply rules to user entities.
pub type UserEvent = StateEvent<UserEventContent>;
/// The payload for `UserEvent`.
#[derive(Clone, Debug, Deserialize, Serialize, StateEventContent)]
#[ruma_event(type = "m.policy.rule.user")]
pub struct UserEventContent(pub PolicyRuleEventContent);

View File

@ -1,4 +1,4 @@
//! Types for the the *m.push_rules* event. //! Types for the *m.push_rules* event.
use ruma_common::push::Ruleset; use ruma_common::push::Ruleset;
use ruma_events_macros::BasicEventContent; use ruma_events_macros::BasicEventContent;