Update dependencies. Closes #9

This commit is contained in:
Tulir Asokan
2018-09-22 18:27:16 +03:00
parent f658c61951
commit fa3105d058
73 changed files with 9299 additions and 287 deletions

View File

@ -2,12 +2,62 @@ package gomatrix
import (
"encoding/json"
"strings"
"sync"
)
type EventTypeClass int
const (
// Normal message events
MessageEventType EventTypeClass = iota
// State events
StateEventType
// Ephemeral events
EphemeralEventType
// Account data events
AccountDataEventType
// Unknown events
UnknownEventType
)
type EventType struct {
Type string
IsState bool
Type string
Class EventTypeClass
}
func NewEventType(name string) EventType {
evtType := EventType{Type: name}
evtType.Class = evtType.GuessClass()
return evtType
}
func (et *EventType) IsState() bool {
return et.Class == StateEventType
}
func (et *EventType) IsEphemeral() bool {
return et.Class == EphemeralEventType
}
func (et *EventType) IsCustom() bool {
return !strings.HasPrefix(et.Type, "m.")
}
func (et *EventType) GuessClass() EventTypeClass {
switch et.Type {
case StateAliases.Type, StateCanonicalAlias.Type, StateCreate.Type, StateJoinRules.Type, StateMember.Type,
StatePowerLevels.Type, StateRoomName.Type, StateRoomAvatar.Type, StateTopic.Type, StatePinnedEvents.Type:
return StateEventType
case EphemeralEventReceipt.Type, EphemeralEventTyping.Type:
return EphemeralEventType
case AccountDataDirectChats.Type, AccountDataPushRules.Type, AccountDataRoomTags.Type:
return AccountDataEventType
case EventRedaction.Type, EventMessage.Type, EventSticker.Type:
return MessageEventType
default:
return UnknownEventType
}
}
func (et *EventType) UnmarshalJSON(data []byte) error {
@ -15,14 +65,7 @@ func (et *EventType) UnmarshalJSON(data []byte) error {
if err != nil {
return err
}
switch et.Type {
case StateAliases.Type, StateCanonicalAlias.Type, StateCreate.Type, StateJoinRules.Type, StateMember.Type,
StatePowerLevels.Type, StateRoomName.Type, StateRoomAvatar.Type, StateTopic.Type, StatePinnedEvents.Type:
et.IsState = true
default:
et.IsState = false
}
et.Class = et.GuessClass()
return nil
}
@ -34,29 +77,42 @@ func (et *EventType) String() string {
return et.Type
}
type MessageType string
// State events
var (
StateAliases = EventType{"m.room.aliases", true}
StateCanonicalAlias = EventType{"m.room.canonical_alias", true}
StateCreate = EventType{"m.room.create", true}
StateJoinRules = EventType{"m.room.join_rules", true}
StateMember = EventType{"m.room.member", true}
StatePowerLevels = EventType{"m.room.power_levels", true}
StateRoomName = EventType{"m.room.name", true}
StateTopic = EventType{"m.room.topic", true}
StateRoomAvatar = EventType{"m.room.avatar", true}
StatePinnedEvents = EventType{"m.room.pinned_events", true}
StateAliases = EventType{"m.room.aliases", StateEventType}
StateCanonicalAlias = EventType{"m.room.canonical_alias", StateEventType}
StateCreate = EventType{"m.room.create", StateEventType}
StateJoinRules = EventType{"m.room.join_rules", StateEventType}
StateMember = EventType{"m.room.member", StateEventType}
StatePowerLevels = EventType{"m.room.power_levels", StateEventType}
StateRoomName = EventType{"m.room.name", StateEventType}
StateTopic = EventType{"m.room.topic", StateEventType}
StateRoomAvatar = EventType{"m.room.avatar", StateEventType}
StatePinnedEvents = EventType{"m.room.pinned_events", StateEventType}
)
// Message events
var (
EventRedaction = EventType{"m.room.redaction", false}
EventMessage = EventType{"m.room.message", false}
EventSticker = EventType{"m.sticker", false}
EventRedaction = EventType{"m.room.redaction", MessageEventType}
EventMessage = EventType{"m.room.message", MessageEventType}
EventSticker = EventType{"m.sticker", MessageEventType}
)
// Ephemeral events
var (
EphemeralEventReceipt = EventType{"m.receipt", EphemeralEventType}
EphemeralEventTyping = EventType{"m.typing", EphemeralEventType}
)
// Account data events
var (
AccountDataDirectChats = EventType{"m.direct", AccountDataEventType}
AccountDataPushRules = EventType{"m.push_rules", AccountDataEventType}
AccountDataRoomTags = EventType{"m.tag", AccountDataEventType}
)
type MessageType string
// Msgtypes
const (
MsgText MessageType = "m.text"
@ -105,10 +161,21 @@ type StrippedState struct {
}
type Unsigned struct {
PrevContent map[string]interface{} `json:"prev_content,omitempty"`
PrevSender string `json:"prev_sender,omitempty"`
ReplacesState string `json:"replaces_state,omitempty"`
Age int64 `json:"age,omitempty"`
PrevContent *Content `json:"prev_content,omitempty"`
PrevSender string `json:"prev_sender,omitempty"`
ReplacesState string `json:"replaces_state,omitempty"`
Age int64 `json:"age,omitempty"`
PassiveCommand map[string]*MatchedPassiveCommand `json:"m.passive_command,omitempty"`
}
type MatchedPassiveCommand struct {
// Matched string `json:"matched"`
// Value string `json:"value"`
Captured [][]string `json:"captured"`
BackCompatCommand string `json:"command"`
BackCompatArguments map[string]string `json:"arguments"`
}
type Content struct {
@ -124,28 +191,48 @@ type Content struct {
URL string `json:"url,omitempty"`
// Membership key for easy access in m.room.member events
Membership string `json:"membership,omitempty"`
Membership Membership `json:"membership,omitempty"`
RelatesTo *RelatesTo `json:"m.relates_to,omitempty"`
RelatesTo *RelatesTo `json:"m.relates_to,omitempty"`
Command *MatchedCommand `json:"m.command,omitempty"`
PowerLevels
Member
Aliases
Aliases []string `json:"aliases,omitempty"`
CanonicalAlias
RoomName
RoomTopic
RoomTags Tags `json:"tags,omitempty"`
TypingUserIDs []string `json:"user_ids,omitempty"`
}
type serializableContent Content
var DisableFancyEventParsing = false
func (content *Content) UnmarshalJSON(data []byte) error {
content.VeryRaw = data
if err := json.Unmarshal(data, &content.Raw); err != nil {
if err := json.Unmarshal(data, &content.Raw); err != nil || DisableFancyEventParsing {
return err
}
return json.Unmarshal(data, (*serializableContent)(content))
}
func (content *Content) GetCommand() *MatchedCommand {
if content.Command == nil {
content.Command = &MatchedCommand{}
}
return content.Command
}
func (content *Content) GetRelatesTo() *RelatesTo {
if content.RelatesTo == nil {
content.RelatesTo = &RelatesTo{}
}
return content.RelatesTo
}
func (content *Content) UnmarshalPowerLevels() (pl PowerLevels, err error) {
err = json.Unmarshal(content.VeryRaw, &pl)
return
@ -156,11 +243,6 @@ func (content *Content) UnmarshalMember() (m Member, err error) {
return
}
func (content *Content) UnmarshalAliases() (a Aliases, err error) {
err = json.Unmarshal(content.VeryRaw, &a)
return
}
func (content *Content) UnmarshalCanonicalAlias() (ca CanonicalAlias, err error) {
err = json.Unmarshal(content.VeryRaw, &ca)
return
@ -173,6 +255,10 @@ func (content *Content) GetInfo() *FileInfo {
return content.Info
}
type Tags map[string]struct {
Order string `json:"order"`
}
type RoomName struct {
Name string `json:"name,omitempty"`
}
@ -181,11 +267,24 @@ type RoomTopic struct {
Topic string `json:"topic,omitempty"`
}
// Membership is an enum specifying the membership state of a room member.
type Membership string
// The allowed membership states as specified in spec section 10.5.5.
const (
MembershipJoin Membership = "join"
MembershipLeave Membership = "leave"
MembershipInvite Membership = "invite"
MembershipBan Membership = "ban"
MembershipKnock Membership = "knock"
)
type Member struct {
Membership string `json:"membership,omitempty"`
Membership Membership `json:"membership,omitempty"`
AvatarURL string `json:"avatar_url,omitempty"`
Displayname string `json:"displayname,omitempty"`
ThirdPartyInvite *ThirdPartyInvite `json:"third_party_invite,omitempty"`
Reason string `json:"reason,omitempty"`
}
type ThirdPartyInvite struct {
@ -197,10 +296,6 @@ type ThirdPartyInvite struct {
}
}
type Aliases struct {
Aliases []string `json:"aliases,omitempty"`
}
type CanonicalAlias struct {
Alias string `json:"alias,omitempty"`
}
@ -210,9 +305,9 @@ type PowerLevels struct {
Users map[string]int `json:"users,omitempty"`
UsersDefault int `json:"users_default,omitempty"`
eventsLock sync.RWMutex `json:"-"`
eventsLock sync.RWMutex `json:"-"`
Events map[string]int `json:"events,omitempty"`
EventsDefault int `json:"events_default,omitempty"`
EventsDefault int `json:"events_default,omitempty"`
StateDefaultPtr *int `json:"state_default,omitempty"`
@ -291,7 +386,7 @@ func (pl *PowerLevels) GetEventLevel(eventType EventType) int {
defer pl.eventsLock.RUnlock()
level, ok := pl.Events[eventType.String()]
if !ok {
if eventType.IsState {
if eventType.IsState() {
return pl.StateDefault()
}
return pl.EventsDefault
@ -302,7 +397,7 @@ func (pl *PowerLevels) GetEventLevel(eventType EventType) int {
func (pl *PowerLevels) SetEventLevel(eventType EventType, level int) {
pl.eventsLock.Lock()
defer pl.eventsLock.Unlock()
if (eventType.IsState && level == pl.StateDefault()) || (!eventType.IsState && level == pl.EventsDefault) {
if (eventType.IsState() && level == pl.StateDefault()) || (!eventType.IsState() && level == pl.EventsDefault) {
delete(pl.Events, eventType.String())
} else {
pl.Events[eventType.String()] = level
@ -344,3 +439,9 @@ type InReplyTo struct {
// Not required, just for future-proofing
RoomID string `json:"room_id,omitempty"`
}
type MatchedCommand struct {
Target string `json:"target"`
Matched string `json:"matched"`
Arguments map[string]string `json:"arguments"`
}

View File

@ -2,8 +2,8 @@ package format
import (
"gopkg.in/russross/blackfriday.v2"
"strings"
"maunium.net/go/gomatrix"
"strings"
)
func RenderMarkdown(text string) gomatrix.Content {

View File

@ -31,7 +31,7 @@ type ReqCreateRoom struct {
Invite []string `json:"invite,omitempty"`
Invite3PID []ReqInvite3PID `json:"invite_3pid,omitempty"`
CreationContent map[string]interface{} `json:"creation_content,omitempty"`
InitialState []*Event `json:"initial_state,omitempty"`
InitialState []*Event `json:"initial_state,omitempty"`
Preset string `json:"preset,omitempty"`
IsDirect bool `json:"is_direct,omitempty"`
}
@ -79,4 +79,4 @@ type ReqTyping struct {
type ReqPresence struct {
Presence string `json:"presence"`
}
}

View File

@ -63,9 +63,9 @@ type RespJoinedMembers struct {
// RespMessages is the JSON response for https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-messages
type RespMessages struct {
Start string `json:"start"`
Chunk []Event `json:"chunk"`
End string `json:"end"`
Start string `json:"start"`
Chunk []*Event `json:"chunk"`
End string `json:"end"`
}
// RespSendEvent is the JSON response for http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid
@ -146,8 +146,8 @@ type RespSync struct {
} `json:"state"`
Timeline struct {
Events []*Event `json:"events"`
Limited bool `json:"limited"`
PrevBatch string `json:"prev_batch"`
Limited bool `json:"limited"`
PrevBatch string `json:"prev_batch"`
} `json:"timeline"`
} `json:"leave"`
Join map[string]struct {
@ -156,14 +156,14 @@ type RespSync struct {
} `json:"state"`
Timeline struct {
Events []*Event `json:"events"`
Limited bool `json:"limited"`
PrevBatch string `json:"prev_batch"`
Limited bool `json:"limited"`
PrevBatch string `json:"prev_batch"`
} `json:"timeline"`
Ephemeral struct {
Events []*Event `json:"events"`
Events []*Event `json:"events"`
} `json:"ephemeral"`
AccountData struct {
Events []*Event `json:"events"`
Events []*Event `json:"events"`
} `json:"account_data"`
} `json:"join"`
Invite map[string]struct {

View File

@ -25,8 +25,8 @@ func (room Room) GetStateEvent(eventType EventType, stateKey string) *Event {
// GetMembershipState returns the membership state of the given user ID in this room. If there is
// no entry for this member, 'leave' is returned for consistency with left users.
func (room Room) GetMembershipState(userID string) string {
state := "leave"
func (room Room) GetMembershipState(userID string) Membership {
state := MembershipLeave
event := room.GetStateEvent(StateMember, userID)
if event != nil {
state = event.Content.Membership

View File

@ -125,6 +125,6 @@ func ExtractUserLocalpart(userID string) (string, error) {
}
return strings.TrimPrefix(
strings.SplitN(userID, ":", 2)[0], // @foo:bar:8448 => [ "@foo", "bar:8448" ]
"@", // remove "@" prefix
"@", // remove "@" prefix
), nil
}

View File

@ -2,7 +2,6 @@ package appservice
import (
"maunium.net/go/gomatrix"
"strings"
"sync"
"time"
)
@ -16,8 +15,8 @@ type StateStore interface {
IsInRoom(roomID, userID string) bool
IsInvited(roomID, userID string) bool
IsMembership(roomID, userID string, allowedMemberships ...string) bool
SetMembership(roomID, userID, membership string)
IsMembership(roomID, userID string, allowedMemberships ...gomatrix.Membership) bool
SetMembership(roomID, userID string, membership gomatrix.Membership)
SetPowerLevels(roomID string, levels *gomatrix.PowerLevels)
GetPowerLevels(roomID string) *gomatrix.PowerLevels
@ -36,12 +35,12 @@ func (as *AppService) UpdateState(evt *gomatrix.Event) {
}
type BasicStateStore struct {
registrationsLock sync.RWMutex `json:"-"`
Registrations map[string]bool `json:"registrations"`
membershipsLock sync.RWMutex `json:"-"`
Memberships map[string]map[string]string `json:"memberships"`
powerLevelsLock sync.RWMutex `json:"-"`
PowerLevels map[string]*gomatrix.PowerLevels `json:"power_levels"`
registrationsLock sync.RWMutex `json:"-"`
Registrations map[string]bool `json:"registrations"`
membershipsLock sync.RWMutex `json:"-"`
Memberships map[string]map[string]gomatrix.Membership `json:"memberships"`
powerLevelsLock sync.RWMutex `json:"-"`
PowerLevels map[string]*gomatrix.PowerLevels `json:"power_levels"`
Typing map[string]map[string]int64 `json:"-"`
typingLock sync.RWMutex `json:"-"`
@ -50,7 +49,7 @@ type BasicStateStore struct {
func NewBasicStateStore() StateStore {
return &BasicStateStore{
Registrations: make(map[string]bool),
Memberships: make(map[string]map[string]string),
Memberships: make(map[string]map[string]gomatrix.Membership),
PowerLevels: make(map[string]*gomatrix.PowerLevels),
Typing: make(map[string]map[string]int64),
}
@ -102,12 +101,12 @@ func (store *BasicStateStore) SetTyping(roomID, userID string, timeout int64) {
store.Typing[roomID] = roomTyping
}
func (store *BasicStateStore) GetRoomMemberships(roomID string) map[string]string {
func (store *BasicStateStore) GetRoomMemberships(roomID string) map[string]gomatrix.Membership {
store.membershipsLock.RLock()
memberships, ok := store.Memberships[roomID]
store.membershipsLock.RUnlock()
if !ok {
memberships = make(map[string]string)
memberships = make(map[string]gomatrix.Membership)
store.membershipsLock.Lock()
store.Memberships[roomID] = memberships
store.membershipsLock.Unlock()
@ -115,16 +114,16 @@ func (store *BasicStateStore) GetRoomMemberships(roomID string) map[string]strin
return memberships
}
func (store *BasicStateStore) GetMembership(roomID, userID string) string {
func (store *BasicStateStore) GetMembership(roomID, userID string) gomatrix.Membership {
store.membershipsLock.RLock()
defer store.membershipsLock.RUnlock()
memberships, ok := store.Memberships[roomID]
if !ok {
return "leave"
return gomatrix.MembershipLeave
}
membership, ok := memberships[userID]
if !ok {
return "leave"
return gomatrix.MembershipLeave
}
return membership
}
@ -137,7 +136,7 @@ func (store *BasicStateStore) IsInvited(roomID, userID string) bool {
return store.IsMembership(roomID, userID, "join", "invite")
}
func (store *BasicStateStore) IsMembership(roomID, userID string, allowedMemberships ...string) bool {
func (store *BasicStateStore) IsMembership(roomID, userID string, allowedMemberships ...gomatrix.Membership) bool {
membership := store.GetMembership(roomID, userID)
for _, allowedMembership := range allowedMemberships {
if allowedMembership == membership {
@ -147,15 +146,15 @@ func (store *BasicStateStore) IsMembership(roomID, userID string, allowedMembers
return false
}
func (store *BasicStateStore) SetMembership(roomID, userID, membership string) {
func (store *BasicStateStore) SetMembership(roomID, userID string, membership gomatrix.Membership) {
store.membershipsLock.Lock()
memberships, ok := store.Memberships[roomID]
if !ok {
memberships = map[string]string{
userID: strings.ToLower(membership),
memberships = map[string]gomatrix.Membership{
userID: membership,
}
} else {
memberships[userID] = strings.ToLower(membership)
memberships[userID] = membership
}
store.Memberships[roomID] = memberships
store.membershipsLock.Unlock()