summary refs log tree commit diff
path: root/vendor/maunium.net/go/mautrix/pushrules/rule.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/maunium.net/go/mautrix/pushrules/rule.go')
-rw-r--r--vendor/maunium.net/go/mautrix/pushrules/rule.go177
1 files changed, 177 insertions, 0 deletions
diff --git a/vendor/maunium.net/go/mautrix/pushrules/rule.go b/vendor/maunium.net/go/mautrix/pushrules/rule.go
new file mode 100644
index 0000000..ee6d33c
--- /dev/null
+++ b/vendor/maunium.net/go/mautrix/pushrules/rule.go
@@ -0,0 +1,177 @@
+// Copyright (c) 2020 Tulir Asokan
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package pushrules
+
+import (
+	"encoding/gob"
+
+	"go.mau.fi/util/glob"
+
+	"maunium.net/go/mautrix/event"
+	"maunium.net/go/mautrix/id"
+)
+
+func init() {
+	gob.Register(PushRuleArray{})
+	gob.Register(PushRuleMap{})
+}
+
+type PushRuleCollection interface {
+	GetMatchingRule(room Room, evt *event.Event) *PushRule
+	GetActions(room Room, evt *event.Event) PushActionArray
+}
+
+type PushRuleArray []*PushRule
+
+func (rules PushRuleArray) SetType(typ PushRuleType) PushRuleArray {
+	for _, rule := range rules {
+		rule.Type = typ
+	}
+	return rules
+}
+
+func (rules PushRuleArray) GetMatchingRule(room Room, evt *event.Event) *PushRule {
+	for _, rule := range rules {
+		if !rule.Match(room, evt) {
+			continue
+		}
+		return rule
+	}
+	return nil
+}
+
+func (rules PushRuleArray) GetActions(room Room, evt *event.Event) PushActionArray {
+	return rules.GetMatchingRule(room, evt).GetActions()
+}
+
+type PushRuleMap struct {
+	Map  map[string]*PushRule
+	Type PushRuleType
+}
+
+func (rules PushRuleArray) SetTypeAndMap(typ PushRuleType) PushRuleMap {
+	data := PushRuleMap{
+		Map:  make(map[string]*PushRule),
+		Type: typ,
+	}
+	for _, rule := range rules {
+		rule.Type = typ
+		data.Map[rule.RuleID] = rule
+	}
+	return data
+}
+
+func (ruleMap PushRuleMap) GetMatchingRule(room Room, evt *event.Event) *PushRule {
+	var rule *PushRule
+	var found bool
+	switch ruleMap.Type {
+	case RoomRule:
+		rule, found = ruleMap.Map[string(evt.RoomID)]
+	case SenderRule:
+		rule, found = ruleMap.Map[string(evt.Sender)]
+	}
+	if found && rule.Match(room, evt) {
+		return rule
+	}
+	return nil
+}
+
+func (ruleMap PushRuleMap) GetActions(room Room, evt *event.Event) PushActionArray {
+	return ruleMap.GetMatchingRule(room, evt).GetActions()
+}
+
+func (ruleMap PushRuleMap) Unmap() PushRuleArray {
+	array := make(PushRuleArray, len(ruleMap.Map))
+	index := 0
+	for _, rule := range ruleMap.Map {
+		array[index] = rule
+		index++
+	}
+	return array
+}
+
+type PushRuleType string
+
+const (
+	OverrideRule  PushRuleType = "override"
+	ContentRule   PushRuleType = "content"
+	RoomRule      PushRuleType = "room"
+	SenderRule    PushRuleType = "sender"
+	UnderrideRule PushRuleType = "underride"
+)
+
+type PushRule struct {
+	// The type of this rule.
+	Type PushRuleType `json:"-"`
+	// The ID of this rule.
+	// For room-specific rules and user-specific rules, this is the room or user ID (respectively)
+	// For other types of rules, this doesn't affect anything.
+	RuleID string `json:"rule_id"`
+	// The actions this rule should trigger when matched.
+	Actions PushActionArray `json:"actions"`
+	// Whether this is a default rule, or has been set explicitly.
+	Default bool `json:"default"`
+	// Whether or not this push rule is enabled.
+	Enabled bool `json:"enabled"`
+	// The conditions to match in order to trigger this rule.
+	// Only applicable to generic underride/override rules.
+	Conditions []*PushCondition `json:"conditions,omitempty"`
+	// Pattern for content-specific push rules
+	Pattern string `json:"pattern,omitempty"`
+}
+
+func (rule *PushRule) GetActions() PushActionArray {
+	if rule == nil {
+		return nil
+	}
+	return rule.Actions
+}
+
+func (rule *PushRule) Match(room Room, evt *event.Event) bool {
+	if rule == nil || !rule.Enabled {
+		return false
+	}
+	if rule.RuleID == ".m.rule.contains_display_name" || rule.RuleID == ".m.rule.contains_user_name" || rule.RuleID == ".m.rule.roomnotif" {
+		if _, containsMentions := evt.Content.Raw["m.mentions"]; containsMentions {
+			// Disable legacy mention push rules when the event contains the new mentions key
+			return false
+		}
+	}
+	switch rule.Type {
+	case OverrideRule, UnderrideRule:
+		return rule.matchConditions(room, evt)
+	case ContentRule:
+		return rule.matchPattern(room, evt)
+	case RoomRule:
+		return id.RoomID(rule.RuleID) == evt.RoomID
+	case SenderRule:
+		return id.UserID(rule.RuleID) == evt.Sender
+	default:
+		return false
+	}
+}
+
+func (rule *PushRule) matchConditions(room Room, evt *event.Event) bool {
+	for _, cond := range rule.Conditions {
+		if !cond.Match(room, evt) {
+			return false
+		}
+	}
+	return true
+}
+
+func (rule *PushRule) matchPattern(room Room, evt *event.Event) bool {
+	pattern := glob.CompileWithImplicitContains(rule.Pattern)
+	if pattern == nil {
+		return false
+	}
+	msg, ok := evt.Content.Raw["body"].(string)
+	if !ok {
+		return false
+	}
+	return pattern.Match(msg)
+}