add vendoring
This commit is contained in:
236
vendor/maunium.net/go/mautrix/appservice/statestore.go
generated
vendored
Normal file
236
vendor/maunium.net/go/mautrix/appservice/statestore.go
generated
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
// 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 appservice
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"maunium.net/go/mautrix/event"
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
type StateStore interface {
|
||||
IsRegistered(userID id.UserID) bool
|
||||
MarkRegistered(userID id.UserID)
|
||||
|
||||
IsTyping(roomID id.RoomID, userID id.UserID) bool
|
||||
SetTyping(roomID id.RoomID, userID id.UserID, timeout time.Duration)
|
||||
|
||||
IsInRoom(roomID id.RoomID, userID id.UserID) bool
|
||||
IsInvited(roomID id.RoomID, userID id.UserID) bool
|
||||
IsMembership(roomID id.RoomID, userID id.UserID, allowedMemberships ...event.Membership) bool
|
||||
GetMember(roomID id.RoomID, userID id.UserID) *event.MemberEventContent
|
||||
TryGetMember(roomID id.RoomID, userID id.UserID) (*event.MemberEventContent, bool)
|
||||
SetMembership(roomID id.RoomID, userID id.UserID, membership event.Membership)
|
||||
SetMember(roomID id.RoomID, userID id.UserID, member *event.MemberEventContent)
|
||||
|
||||
SetPowerLevels(roomID id.RoomID, levels *event.PowerLevelsEventContent)
|
||||
GetPowerLevels(roomID id.RoomID) *event.PowerLevelsEventContent
|
||||
GetPowerLevel(roomID id.RoomID, userID id.UserID) int
|
||||
GetPowerLevelRequirement(roomID id.RoomID, eventType event.Type) int
|
||||
HasPowerLevel(roomID id.RoomID, userID id.UserID, eventType event.Type) bool
|
||||
}
|
||||
|
||||
func (as *AppService) UpdateState(evt *event.Event) {
|
||||
switch content := evt.Content.Parsed.(type) {
|
||||
case *event.MemberEventContent:
|
||||
as.StateStore.SetMember(evt.RoomID, id.UserID(evt.GetStateKey()), content)
|
||||
case *event.PowerLevelsEventContent:
|
||||
as.StateStore.SetPowerLevels(evt.RoomID, content)
|
||||
}
|
||||
}
|
||||
|
||||
type TypingStateStore struct {
|
||||
typing map[id.RoomID]map[id.UserID]time.Time
|
||||
typingLock sync.RWMutex
|
||||
}
|
||||
|
||||
func NewTypingStateStore() *TypingStateStore {
|
||||
return &TypingStateStore{
|
||||
typing: make(map[id.RoomID]map[id.UserID]time.Time),
|
||||
}
|
||||
}
|
||||
|
||||
func (store *TypingStateStore) IsTyping(roomID id.RoomID, userID id.UserID) bool {
|
||||
store.typingLock.RLock()
|
||||
defer store.typingLock.RUnlock()
|
||||
roomTyping, ok := store.typing[roomID]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
typingEndsAt := roomTyping[userID]
|
||||
return typingEndsAt.After(time.Now())
|
||||
}
|
||||
|
||||
func (store *TypingStateStore) SetTyping(roomID id.RoomID, userID id.UserID, timeout time.Duration) {
|
||||
store.typingLock.Lock()
|
||||
defer store.typingLock.Unlock()
|
||||
roomTyping, ok := store.typing[roomID]
|
||||
if !ok {
|
||||
if timeout >= 0 {
|
||||
roomTyping = map[id.UserID]time.Time{
|
||||
userID: time.Now().Add(timeout),
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if timeout >= 0 {
|
||||
roomTyping[userID] = time.Now().Add(timeout)
|
||||
} else {
|
||||
delete(roomTyping, userID)
|
||||
}
|
||||
}
|
||||
store.typing[roomID] = roomTyping
|
||||
}
|
||||
|
||||
type BasicStateStore struct {
|
||||
registrationsLock sync.RWMutex `json:"-"`
|
||||
Registrations map[id.UserID]bool `json:"registrations"`
|
||||
membersLock sync.RWMutex `json:"-"`
|
||||
Members map[id.RoomID]map[id.UserID]*event.MemberEventContent `json:"memberships"`
|
||||
powerLevelsLock sync.RWMutex `json:"-"`
|
||||
PowerLevels map[id.RoomID]*event.PowerLevelsEventContent `json:"power_levels"`
|
||||
|
||||
*TypingStateStore
|
||||
}
|
||||
|
||||
func NewBasicStateStore() StateStore {
|
||||
return &BasicStateStore{
|
||||
Registrations: make(map[id.UserID]bool),
|
||||
Members: make(map[id.RoomID]map[id.UserID]*event.MemberEventContent),
|
||||
PowerLevels: make(map[id.RoomID]*event.PowerLevelsEventContent),
|
||||
TypingStateStore: NewTypingStateStore(),
|
||||
}
|
||||
}
|
||||
|
||||
func (store *BasicStateStore) IsRegistered(userID id.UserID) bool {
|
||||
store.registrationsLock.RLock()
|
||||
defer store.registrationsLock.RUnlock()
|
||||
registered, ok := store.Registrations[userID]
|
||||
return ok && registered
|
||||
}
|
||||
|
||||
func (store *BasicStateStore) MarkRegistered(userID id.UserID) {
|
||||
store.registrationsLock.Lock()
|
||||
defer store.registrationsLock.Unlock()
|
||||
store.Registrations[userID] = true
|
||||
}
|
||||
|
||||
func (store *BasicStateStore) GetRoomMembers(roomID id.RoomID) map[id.UserID]*event.MemberEventContent {
|
||||
store.membersLock.RLock()
|
||||
members, ok := store.Members[roomID]
|
||||
store.membersLock.RUnlock()
|
||||
if !ok {
|
||||
members = make(map[id.UserID]*event.MemberEventContent)
|
||||
store.membersLock.Lock()
|
||||
store.Members[roomID] = members
|
||||
store.membersLock.Unlock()
|
||||
}
|
||||
return members
|
||||
}
|
||||
|
||||
func (store *BasicStateStore) GetMembership(roomID id.RoomID, userID id.UserID) event.Membership {
|
||||
return store.GetMember(roomID, userID).Membership
|
||||
}
|
||||
|
||||
func (store *BasicStateStore) GetMember(roomID id.RoomID, userID id.UserID) *event.MemberEventContent {
|
||||
member, ok := store.TryGetMember(roomID, userID)
|
||||
if !ok {
|
||||
member = &event.MemberEventContent{Membership: event.MembershipLeave}
|
||||
}
|
||||
return member
|
||||
}
|
||||
|
||||
func (store *BasicStateStore) TryGetMember(roomID id.RoomID, userID id.UserID) (member *event.MemberEventContent, ok bool) {
|
||||
store.membersLock.RLock()
|
||||
defer store.membersLock.RUnlock()
|
||||
members, membersOk := store.Members[roomID]
|
||||
if !membersOk {
|
||||
return
|
||||
}
|
||||
member, ok = members[userID]
|
||||
return
|
||||
}
|
||||
|
||||
func (store *BasicStateStore) IsInRoom(roomID id.RoomID, userID id.UserID) bool {
|
||||
return store.IsMembership(roomID, userID, "join")
|
||||
}
|
||||
|
||||
func (store *BasicStateStore) IsInvited(roomID id.RoomID, userID id.UserID) bool {
|
||||
return store.IsMembership(roomID, userID, "join", "invite")
|
||||
}
|
||||
|
||||
func (store *BasicStateStore) IsMembership(roomID id.RoomID, userID id.UserID, allowedMemberships ...event.Membership) bool {
|
||||
membership := store.GetMembership(roomID, userID)
|
||||
for _, allowedMembership := range allowedMemberships {
|
||||
if allowedMembership == membership {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (store *BasicStateStore) SetMembership(roomID id.RoomID, userID id.UserID, membership event.Membership) {
|
||||
store.membersLock.Lock()
|
||||
members, ok := store.Members[roomID]
|
||||
if !ok {
|
||||
members = map[id.UserID]*event.MemberEventContent{
|
||||
userID: {Membership: membership},
|
||||
}
|
||||
} else {
|
||||
member, ok := members[userID]
|
||||
if !ok {
|
||||
members[userID] = &event.MemberEventContent{Membership: membership}
|
||||
} else {
|
||||
member.Membership = membership
|
||||
members[userID] = member
|
||||
}
|
||||
}
|
||||
store.Members[roomID] = members
|
||||
store.membersLock.Unlock()
|
||||
}
|
||||
|
||||
func (store *BasicStateStore) SetMember(roomID id.RoomID, userID id.UserID, member *event.MemberEventContent) {
|
||||
store.membersLock.Lock()
|
||||
members, ok := store.Members[roomID]
|
||||
if !ok {
|
||||
members = map[id.UserID]*event.MemberEventContent{
|
||||
userID: member,
|
||||
}
|
||||
} else {
|
||||
members[userID] = member
|
||||
}
|
||||
store.Members[roomID] = members
|
||||
store.membersLock.Unlock()
|
||||
}
|
||||
|
||||
func (store *BasicStateStore) SetPowerLevels(roomID id.RoomID, levels *event.PowerLevelsEventContent) {
|
||||
store.powerLevelsLock.Lock()
|
||||
store.PowerLevels[roomID] = levels
|
||||
store.powerLevelsLock.Unlock()
|
||||
}
|
||||
|
||||
func (store *BasicStateStore) GetPowerLevels(roomID id.RoomID) (levels *event.PowerLevelsEventContent) {
|
||||
store.powerLevelsLock.RLock()
|
||||
levels = store.PowerLevels[roomID]
|
||||
store.powerLevelsLock.RUnlock()
|
||||
return
|
||||
}
|
||||
|
||||
func (store *BasicStateStore) GetPowerLevel(roomID id.RoomID, userID id.UserID) int {
|
||||
return store.GetPowerLevels(roomID).GetUserLevel(userID)
|
||||
}
|
||||
|
||||
func (store *BasicStateStore) GetPowerLevelRequirement(roomID id.RoomID, eventType event.Type) int {
|
||||
return store.GetPowerLevels(roomID).GetEventLevel(eventType)
|
||||
}
|
||||
|
||||
func (store *BasicStateStore) HasPowerLevel(roomID id.RoomID, userID id.UserID, eventType event.Type) bool {
|
||||
return store.GetPowerLevel(roomID, userID) >= store.GetPowerLevelRequirement(roomID, eventType)
|
||||
}
|
||||
Reference in New Issue
Block a user