summary refs log tree commit diff
path: root/vendor/maunium.net/go/mautrix/event/powerlevels.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/maunium.net/go/mautrix/event/powerlevels.go')
-rw-r--r--vendor/maunium.net/go/mautrix/event/powerlevels.go199
1 files changed, 199 insertions, 0 deletions
diff --git a/vendor/maunium.net/go/mautrix/event/powerlevels.go b/vendor/maunium.net/go/mautrix/event/powerlevels.go
new file mode 100644
index 0000000..2f4d457
--- /dev/null
+++ b/vendor/maunium.net/go/mautrix/event/powerlevels.go
@@ -0,0 +1,199 @@
+// 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 event
+
+import (
+	"sync"
+
+	"go.mau.fi/util/ptr"
+	"golang.org/x/exp/maps"
+
+	"maunium.net/go/mautrix/id"
+)
+
+// PowerLevelsEventContent represents the content of a m.room.power_levels state event content.
+// https://spec.matrix.org/v1.5/client-server-api/#mroompower_levels
+type PowerLevelsEventContent struct {
+	usersLock    sync.RWMutex
+	Users        map[id.UserID]int `json:"users,omitempty"`
+	UsersDefault int               `json:"users_default,omitempty"`
+
+	eventsLock    sync.RWMutex
+	Events        map[string]int `json:"events,omitempty"`
+	EventsDefault int            `json:"events_default,omitempty"`
+
+	Notifications *NotificationPowerLevels `json:"notifications,omitempty"`
+
+	StateDefaultPtr *int `json:"state_default,omitempty"`
+
+	InvitePtr *int `json:"invite,omitempty"`
+	KickPtr   *int `json:"kick,omitempty"`
+	BanPtr    *int `json:"ban,omitempty"`
+	RedactPtr *int `json:"redact,omitempty"`
+}
+
+func (pl *PowerLevelsEventContent) Clone() *PowerLevelsEventContent {
+	if pl == nil {
+		return nil
+	}
+	return &PowerLevelsEventContent{
+		Users:           maps.Clone(pl.Users),
+		UsersDefault:    pl.UsersDefault,
+		Events:          maps.Clone(pl.Events),
+		EventsDefault:   pl.EventsDefault,
+		StateDefaultPtr: ptr.Clone(pl.StateDefaultPtr),
+
+		Notifications: pl.Notifications.Clone(),
+
+		InvitePtr: ptr.Clone(pl.InvitePtr),
+		KickPtr:   ptr.Clone(pl.KickPtr),
+		BanPtr:    ptr.Clone(pl.BanPtr),
+		RedactPtr: ptr.Clone(pl.RedactPtr),
+	}
+}
+
+type NotificationPowerLevels struct {
+	RoomPtr *int `json:"room,omitempty"`
+}
+
+func (npl *NotificationPowerLevels) Clone() *NotificationPowerLevels {
+	if npl == nil {
+		return nil
+	}
+	return &NotificationPowerLevels{
+		RoomPtr: ptr.Clone(npl.RoomPtr),
+	}
+}
+
+func (npl *NotificationPowerLevels) Room() int {
+	if npl != nil && npl.RoomPtr != nil {
+		return *npl.RoomPtr
+	}
+	return 50
+}
+
+func (pl *PowerLevelsEventContent) Invite() int {
+	if pl.InvitePtr != nil {
+		return *pl.InvitePtr
+	}
+	return 0
+}
+
+func (pl *PowerLevelsEventContent) Kick() int {
+	if pl.KickPtr != nil {
+		return *pl.KickPtr
+	}
+	return 50
+}
+
+func (pl *PowerLevelsEventContent) Ban() int {
+	if pl.BanPtr != nil {
+		return *pl.BanPtr
+	}
+	return 50
+}
+
+func (pl *PowerLevelsEventContent) Redact() int {
+	if pl.RedactPtr != nil {
+		return *pl.RedactPtr
+	}
+	return 50
+}
+
+func (pl *PowerLevelsEventContent) StateDefault() int {
+	if pl.StateDefaultPtr != nil {
+		return *pl.StateDefaultPtr
+	}
+	return 50
+}
+
+func (pl *PowerLevelsEventContent) GetUserLevel(userID id.UserID) int {
+	pl.usersLock.RLock()
+	defer pl.usersLock.RUnlock()
+	level, ok := pl.Users[userID]
+	if !ok {
+		return pl.UsersDefault
+	}
+	return level
+}
+
+func (pl *PowerLevelsEventContent) SetUserLevel(userID id.UserID, level int) {
+	pl.usersLock.Lock()
+	defer pl.usersLock.Unlock()
+	if level == pl.UsersDefault {
+		delete(pl.Users, userID)
+	} else {
+		if pl.Users == nil {
+			pl.Users = make(map[id.UserID]int)
+		}
+		pl.Users[userID] = level
+	}
+}
+
+func (pl *PowerLevelsEventContent) EnsureUserLevel(target id.UserID, level int) bool {
+	return pl.EnsureUserLevelAs("", target, level)
+}
+
+func (pl *PowerLevelsEventContent) EnsureUserLevelAs(actor, target id.UserID, level int) bool {
+	existingLevel := pl.GetUserLevel(target)
+	if actor != "" {
+		actorLevel := pl.GetUserLevel(actor)
+		if actorLevel <= existingLevel || actorLevel < level {
+			return false
+		}
+	}
+	if existingLevel != level {
+		pl.SetUserLevel(target, level)
+		return true
+	}
+	return false
+}
+
+func (pl *PowerLevelsEventContent) GetEventLevel(eventType Type) int {
+	pl.eventsLock.RLock()
+	defer pl.eventsLock.RUnlock()
+	level, ok := pl.Events[eventType.String()]
+	if !ok {
+		if eventType.IsState() {
+			return pl.StateDefault()
+		}
+		return pl.EventsDefault
+	}
+	return level
+}
+
+func (pl *PowerLevelsEventContent) SetEventLevel(eventType Type, level int) {
+	pl.eventsLock.Lock()
+	defer pl.eventsLock.Unlock()
+	if (eventType.IsState() && level == pl.StateDefault()) || (!eventType.IsState() && level == pl.EventsDefault) {
+		delete(pl.Events, eventType.String())
+	} else {
+		if pl.Events == nil {
+			pl.Events = make(map[string]int)
+		}
+		pl.Events[eventType.String()] = level
+	}
+}
+
+func (pl *PowerLevelsEventContent) EnsureEventLevel(eventType Type, level int) bool {
+	return pl.EnsureEventLevelAs("", eventType, level)
+}
+
+func (pl *PowerLevelsEventContent) EnsureEventLevelAs(actor id.UserID, eventType Type, level int) bool {
+	existingLevel := pl.GetEventLevel(eventType)
+	if actor != "" {
+		actorLevel := pl.GetUserLevel(actor)
+		if existingLevel > actorLevel || level > actorLevel {
+			return false
+		}
+	}
+	if existingLevel != level {
+		pl.SetEventLevel(eventType, level)
+		return true
+	}
+	return false
+}