Update mautrix-go

This commit is contained in:
Tulir Asokan
2020-05-08 22:32:22 +03:00
parent e0aea74abf
commit acc25a02e4
20 changed files with 454 additions and 465 deletions

View File

@ -1,5 +1,5 @@
// mautrix-whatsapp - A Matrix-WhatsApp puppeting bridge.
// Copyright (C) 2019 Tulir Asokan
// Copyright (C) 2020 Tulir Asokan
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@ -26,6 +26,7 @@ import (
log "maunium.net/go/maulogger/v2"
"maunium.net/go/mautrix-whatsapp/types"
"maunium.net/go/mautrix/id"
)
type MessageQuery struct {
@ -57,7 +58,7 @@ func (mq *MessageQuery) GetByJID(chat PortalKey, jid types.WhatsAppMessageID) *M
"FROM message WHERE chat_jid=$1 AND chat_receiver=$2 AND jid=$3", chat.JID, chat.Receiver, jid)
}
func (mq *MessageQuery) GetByMXID(mxid types.MatrixEventID) *Message {
func (mq *MessageQuery) GetByMXID(mxid id.EventID) *Message {
return mq.get("SELECT chat_jid, chat_receiver, jid, mxid, sender, timestamp, content " +
"FROM message WHERE mxid=$1", mxid)
}
@ -86,7 +87,7 @@ type Message struct {
Chat PortalKey
JID types.WhatsAppMessageID
MXID types.MatrixEventID
MXID id.EventID
Sender types.WhatsAppID
Timestamp uint64
Content *waProto.Message

View File

@ -1,5 +1,5 @@
// mautrix-whatsapp - A Matrix-WhatsApp puppeting bridge.
// Copyright (C) 2019 Tulir Asokan
// Copyright (C) 2020 Tulir Asokan
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@ -23,6 +23,7 @@ import (
log "maunium.net/go/maulogger/v2"
"maunium.net/go/mautrix-whatsapp/types"
"maunium.net/go/mautrix/id"
)
type PortalKey struct {
@ -74,7 +75,7 @@ func (pq *PortalQuery) GetByJID(key PortalKey) *Portal {
return pq.get("SELECT * FROM portal WHERE jid=$1 AND receiver=$2", key.JID, key.Receiver)
}
func (pq *PortalQuery) GetByMXID(mxid types.MatrixRoomID) *Portal {
func (pq *PortalQuery) GetByMXID(mxid id.RoomID) *Portal {
return pq.get("SELECT * FROM portal WHERE mxid=$1", mxid)
}
@ -107,12 +108,12 @@ type Portal struct {
log log.Logger
Key PortalKey
MXID types.MatrixRoomID
MXID id.RoomID
Name string
Topic string
Avatar string
AvatarURL string
AvatarURL id.ContentURI
}
func (portal *Portal) Scan(row Scannable) *Portal {
@ -124,12 +125,12 @@ func (portal *Portal) Scan(row Scannable) *Portal {
}
return nil
}
portal.MXID = mxid.String
portal.AvatarURL = avatarURL.String
portal.MXID = id.RoomID(mxid.String)
portal.AvatarURL, _ = id.ParseContentURI(avatarURL.String)
return portal
}
func (portal *Portal) mxidPtr() *string {
func (portal *Portal) mxidPtr() *id.RoomID {
if len(portal.MXID) > 0 {
return &portal.MXID
}
@ -138,19 +139,19 @@ func (portal *Portal) mxidPtr() *string {
func (portal *Portal) Insert() {
_, err := portal.db.Exec("INSERT INTO portal VALUES ($1, $2, $3, $4, $5, $6, $7)",
portal.Key.JID, portal.Key.Receiver, portal.mxidPtr(), portal.Name, portal.Topic, portal.Avatar, portal.AvatarURL)
portal.Key.JID, portal.Key.Receiver, portal.mxidPtr(), portal.Name, portal.Topic, portal.Avatar, portal.AvatarURL.String())
if err != nil {
portal.log.Warnfln("Failed to insert %s: %v", portal.Key, err)
}
}
func (portal *Portal) Update() {
var mxid *string
var mxid *id.RoomID
if len(portal.MXID) > 0 {
mxid = &portal.MXID
}
_, err := portal.db.Exec("UPDATE portal SET mxid=$1, name=$2, topic=$3, avatar=$4, avatar_url=$5 WHERE jid=$6 AND receiver=$7",
mxid, portal.Name, portal.Topic, portal.Avatar, portal.AvatarURL, portal.Key.JID, portal.Key.Receiver)
mxid, portal.Name, portal.Topic, portal.Avatar, portal.AvatarURL.String(), portal.Key.JID, portal.Key.Receiver)
if err != nil {
portal.log.Warnfln("Failed to update %s: %v", portal.Key, err)
}
@ -163,7 +164,7 @@ func (portal *Portal) Delete() {
}
}
func (portal *Portal) GetUserIDs() []types.MatrixUserID {
func (portal *Portal) GetUserIDs() []id.UserID {
rows, err := portal.db.Query(`SELECT "user".mxid FROM "user", user_portal
WHERE "user".jid=user_portal.user_jid
AND user_portal.portal_jid=$1
@ -173,9 +174,9 @@ func (portal *Portal) GetUserIDs() []types.MatrixUserID {
portal.log.Debugln("Failed to get portal user ids:", err)
return nil
}
var userIDs []types.MatrixUserID
var userIDs []id.UserID
for rows.Next() {
var userID types.MatrixUserID
var userID id.UserID
err = rows.Scan(&userID)
if err != nil {
portal.log.Warnln("Failed to scan row:", err)

View File

@ -1,5 +1,5 @@
// mautrix-whatsapp - A Matrix-WhatsApp puppeting bridge.
// Copyright (C) 2019 Tulir Asokan
// Copyright (C) 2020 Tulir Asokan
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@ -22,6 +22,7 @@ import (
log "maunium.net/go/maulogger/v2"
"maunium.net/go/mautrix-whatsapp/types"
"maunium.net/go/mautrix/id"
)
type PuppetQuery struct {
@ -56,7 +57,7 @@ func (pq *PuppetQuery) Get(jid types.WhatsAppID) *Puppet {
return pq.New().Scan(row)
}
func (pq *PuppetQuery) GetByCustomMXID(mxid types.MatrixUserID) *Puppet {
func (pq *PuppetQuery) GetByCustomMXID(mxid id.UserID) *Puppet {
row := pq.db.QueryRow("SELECT jid, avatar, avatar_url, displayname, name_quality, custom_mxid, access_token, next_batch FROM puppet WHERE custom_mxid=$1", mxid)
if row == nil {
return nil
@ -82,11 +83,11 @@ type Puppet struct {
JID types.WhatsAppID
Avatar string
AvatarURL string
AvatarURL id.ContentURI
Displayname string
NameQuality int8
CustomMXID string
CustomMXID id.UserID
AccessToken string
NextBatch string
}
@ -103,9 +104,9 @@ func (puppet *Puppet) Scan(row Scannable) *Puppet {
}
puppet.Displayname = displayname.String
puppet.Avatar = avatar.String
puppet.AvatarURL = avatarURL.String
puppet.AvatarURL, _ = id.ParseContentURI(avatarURL.String)
puppet.NameQuality = int8(quality.Int64)
puppet.CustomMXID = customMXID.String
puppet.CustomMXID = id.UserID(customMXID.String)
puppet.AccessToken = accessToken.String
puppet.NextBatch = nextBatch.String
return puppet
@ -113,7 +114,7 @@ func (puppet *Puppet) Scan(row Scannable) *Puppet {
func (puppet *Puppet) Insert() {
_, err := puppet.db.Exec("INSERT INTO puppet (jid, avatar, avatar_url, displayname, name_quality, custom_mxid, access_token, next_batch) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
puppet.JID, puppet.Avatar, puppet.AvatarURL, puppet.Displayname, puppet.NameQuality, puppet.CustomMXID, puppet.AccessToken, puppet.NextBatch)
puppet.JID, puppet.Avatar, puppet.AvatarURL.String(), puppet.Displayname, puppet.NameQuality, puppet.CustomMXID, puppet.AccessToken, puppet.NextBatch)
if err != nil {
puppet.log.Warnfln("Failed to insert %s: %v", puppet.JID, err)
}
@ -121,7 +122,7 @@ func (puppet *Puppet) Insert() {
func (puppet *Puppet) Update() {
_, err := puppet.db.Exec("UPDATE puppet SET displayname=$1, name_quality=$2, avatar=$3, avatar_url=$4, custom_mxid=$5, access_token=$6, next_batch=$7 WHERE jid=$8",
puppet.Displayname, puppet.NameQuality, puppet.Avatar, puppet.AvatarURL, puppet.CustomMXID, puppet.AccessToken, puppet.NextBatch, puppet.JID)
puppet.Displayname, puppet.NameQuality, puppet.Avatar, puppet.AvatarURL.String(), puppet.CustomMXID, puppet.AccessToken, puppet.NextBatch, puppet.JID)
if err != nil {
puppet.log.Warnfln("Failed to update %s->%s: %v", puppet.JID, err)
}

View File

@ -1,5 +1,5 @@
// mautrix-whatsapp - A Matrix-WhatsApp puppeting bridge.
// Copyright (C) 2019 Tulir Asokan
// Copyright (C) 2020 Tulir Asokan
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@ -24,8 +24,9 @@ import (
log "maunium.net/go/maulogger/v2"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix-appservice"
"maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
)
type SQLStateStore struct {
@ -34,7 +35,7 @@ type SQLStateStore struct {
db *Database
log log.Logger
Typing map[string]map[string]int64
Typing map[id.RoomID]map[id.UserID]int64
typingLock sync.RWMutex
}
@ -46,7 +47,7 @@ func NewSQLStateStore(db *Database) *SQLStateStore {
}
}
func (store *SQLStateStore) IsRegistered(userID string) bool {
func (store *SQLStateStore) IsRegistered(userID id.UserID) bool {
row := store.db.QueryRow("SELECT EXISTS(SELECT 1 FROM mx_registrations WHERE user_id=$1)", userID)
var isRegistered bool
err := row.Scan(&isRegistered)
@ -56,7 +57,7 @@ func (store *SQLStateStore) IsRegistered(userID string) bool {
return isRegistered
}
func (store *SQLStateStore) MarkRegistered(userID string) {
func (store *SQLStateStore) MarkRegistered(userID id.UserID) {
var err error
if store.db.dialect == "postgres" {
_, err = store.db.Exec("INSERT INTO mx_registrations (user_id) VALUES ($1) ON CONFLICT (user_id) DO NOTHING", userID)
@ -70,28 +71,28 @@ func (store *SQLStateStore) MarkRegistered(userID string) {
}
}
func (store *SQLStateStore) GetRoomMembers(roomID string) map[string]mautrix.Member {
members := make(map[string]mautrix.Member)
func (store *SQLStateStore) GetRoomMembers(roomID id.RoomID) map[id.UserID]*event.MemberEventContent {
members := make(map[id.UserID]*event.MemberEventContent)
rows, err := store.db.Query("SELECT user_id, membership, displayname, avatar_url FROM mx_user_profile WHERE room_id=$1", roomID)
if err != nil {
return members
}
var userID string
var member mautrix.Member
var userID id.UserID
var member event.MemberEventContent
for rows.Next() {
err := rows.Scan(&userID, &member.Membership, &member.Displayname, &member.AvatarURL)
if err != nil {
store.log.Warnfln("Failed to scan member in %s: %v", roomID, err)
} else {
members[userID] = member
members[userID] = &member
}
}
return members
}
func (store *SQLStateStore) GetMembership(roomID, userID string) mautrix.Membership {
func (store *SQLStateStore) GetMembership(roomID id.RoomID, userID id.UserID) event.Membership {
row := store.db.QueryRow("SELECT membership FROM mx_user_profile WHERE room_id=$1 AND user_id=$2", roomID, userID)
membership := mautrix.MembershipLeave
membership := event.MembershipLeave
err := row.Scan(&membership)
if err != nil && err != sql.ErrNoRows {
store.log.Warnfln("Failed to scan membership of %s in %s: %v", userID, roomID, err)
@ -99,33 +100,33 @@ func (store *SQLStateStore) GetMembership(roomID, userID string) mautrix.Members
return membership
}
func (store *SQLStateStore) GetMember(roomID, userID string) mautrix.Member {
func (store *SQLStateStore) GetMember(roomID id.RoomID, userID id.UserID) *event.MemberEventContent {
member, ok := store.TryGetMember(roomID, userID)
if !ok {
member.Membership = mautrix.MembershipLeave
member.Membership = event.MembershipLeave
}
return member
}
func (store *SQLStateStore) TryGetMember(roomID, userID string) (mautrix.Member, bool) {
func (store *SQLStateStore) TryGetMember(roomID id.RoomID, userID id.UserID) (*event.MemberEventContent, bool) {
row := store.db.QueryRow("SELECT membership, displayname, avatar_url FROM mx_user_profile WHERE room_id=$1 AND user_id=$2", roomID, userID)
var member mautrix.Member
var member event.MemberEventContent
err := row.Scan(&member.Membership, &member.Displayname, &member.AvatarURL)
if err != nil && err != sql.ErrNoRows {
store.log.Warnfln("Failed to scan member info of %s in %s: %v", userID, roomID, err)
}
return member, err == nil
return &member, err == nil
}
func (store *SQLStateStore) IsInRoom(roomID, userID string) bool {
func (store *SQLStateStore) IsInRoom(roomID id.RoomID, userID id.UserID) bool {
return store.IsMembership(roomID, userID, "join")
}
func (store *SQLStateStore) IsInvited(roomID, userID string) bool {
func (store *SQLStateStore) IsInvited(roomID id.RoomID, userID id.UserID) bool {
return store.IsMembership(roomID, userID, "join", "invite")
}
func (store *SQLStateStore) IsMembership(roomID, userID string, allowedMemberships ...mautrix.Membership) bool {
func (store *SQLStateStore) IsMembership(roomID id.RoomID, userID id.UserID, allowedMemberships ...event.Membership) bool {
membership := store.GetMembership(roomID, userID)
for _, allowedMembership := range allowedMemberships {
if allowedMembership == membership {
@ -135,7 +136,7 @@ func (store *SQLStateStore) IsMembership(roomID, userID string, allowedMembershi
return false
}
func (store *SQLStateStore) SetMembership(roomID, userID string, membership mautrix.Membership) {
func (store *SQLStateStore) SetMembership(roomID id.RoomID, userID id.UserID, membership event.Membership) {
var err error
if store.db.dialect == "postgres" {
_, err = store.db.Exec(`INSERT INTO mx_user_profile (room_id, user_id, membership) VALUES ($1, $2, $3)
@ -150,7 +151,7 @@ func (store *SQLStateStore) SetMembership(roomID, userID string, membership maut
}
}
func (store *SQLStateStore) SetMember(roomID, userID string, member mautrix.Member) {
func (store *SQLStateStore) SetMember(roomID id.RoomID, userID id.UserID, member *event.MemberEventContent) {
var err error
if store.db.dialect == "postgres" {
_, err = store.db.Exec(`INSERT INTO mx_user_profile (room_id, user_id, membership, displayname, avatar_url) VALUES ($1, $2, $3, $4, $5)
@ -166,7 +167,7 @@ func (store *SQLStateStore) SetMember(roomID, userID string, member mautrix.Memb
}
}
func (store *SQLStateStore) SetPowerLevels(roomID string, levels *mautrix.PowerLevels) {
func (store *SQLStateStore) SetPowerLevels(roomID id.RoomID, levels *event.PowerLevelsEventContent) {
levelsBytes, err := json.Marshal(levels)
if err != nil {
store.log.Errorfln("Failed to marshal power levels of %s: %v", roomID, err)
@ -185,7 +186,7 @@ func (store *SQLStateStore) SetPowerLevels(roomID string, levels *mautrix.PowerL
}
}
func (store *SQLStateStore) GetPowerLevels(roomID string) (levels *mautrix.PowerLevels) {
func (store *SQLStateStore) GetPowerLevels(roomID id.RoomID) (levels *event.PowerLevelsEventContent) {
row := store.db.QueryRow("SELECT power_levels FROM mx_room_state WHERE room_id=$1", roomID)
if row == nil {
return
@ -196,7 +197,7 @@ func (store *SQLStateStore) GetPowerLevels(roomID string) (levels *mautrix.Power
store.log.Errorln("Failed to scan power levels of %s: %v", roomID, err)
return
}
levels = &mautrix.PowerLevels{}
levels = &event.PowerLevelsEventContent{}
err = json.Unmarshal(data, levels)
if err != nil {
store.log.Errorln("Failed to parse power levels of %s: %v", roomID, err)
@ -205,7 +206,7 @@ func (store *SQLStateStore) GetPowerLevels(roomID string) (levels *mautrix.Power
return
}
func (store *SQLStateStore) GetPowerLevel(roomID, userID string) int {
func (store *SQLStateStore) GetPowerLevel(roomID id.RoomID, userID id.UserID) int {
if store.db.dialect == "postgres" {
row := store.db.QueryRow(`SELECT
COALESCE((power_levels->'users'->$2)::int, (power_levels->'users_default')::int, 0)
@ -224,7 +225,7 @@ func (store *SQLStateStore) GetPowerLevel(roomID, userID string) int {
return store.GetPowerLevels(roomID).GetUserLevel(userID)
}
func (store *SQLStateStore) GetPowerLevelRequirement(roomID string, eventType mautrix.EventType) int {
func (store *SQLStateStore) GetPowerLevelRequirement(roomID id.RoomID, eventType event.Type) int {
if store.db.dialect == "postgres" {
defaultType := "events_default"
defaultValue := 0
@ -249,7 +250,7 @@ func (store *SQLStateStore) GetPowerLevelRequirement(roomID string, eventType ma
return store.GetPowerLevels(roomID).GetEventLevel(eventType)
}
func (store *SQLStateStore) HasPowerLevel(roomID, userID string, eventType mautrix.EventType) bool {
func (store *SQLStateStore) HasPowerLevel(roomID id.RoomID, userID id.UserID, eventType event.Type) bool {
if store.db.dialect == "postgres" {
defaultType := "events_default"
defaultValue := 0

View File

@ -8,7 +8,7 @@ import (
"os"
"strings"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/event"
)
func init() {
@ -46,7 +46,7 @@ func init() {
return executeBatch(tx, valueStrings, values...)
}
migrateMemberships := func(tx *sql.Tx, rooms map[string]map[string]mautrix.Membership) error {
migrateMemberships := func(tx *sql.Tx, rooms map[string]map[string]event.Membership) error {
for roomID, members := range rooms {
if len(members) == 0 {
continue
@ -68,7 +68,7 @@ func init() {
return nil
}
migratePowerLevels := func(tx *sql.Tx, rooms map[string]*mautrix.PowerLevels) error {
migratePowerLevels := func(tx *sql.Tx, rooms map[string]*event.PowerLevelsEventContent) error {
if len(rooms) == 0 {
return nil
}
@ -106,9 +106,9 @@ func init() {
)`
type TempStateStore struct {
Registrations map[string]bool `json:"registrations"`
Members map[string]map[string]mautrix.Membership `json:"memberships"`
PowerLevels map[string]*mautrix.PowerLevels `json:"power_levels"`
Registrations map[string]bool `json:"registrations"`
Members map[string]map[string]event.Membership `json:"memberships"`
PowerLevels map[string]*event.PowerLevelsEventContent `json:"power_levels"`
}
upgrades[9] = upgrade{"Move state store to main DB", func(tx *sql.Tx, ctx context) error {

View File

@ -1,5 +1,5 @@
// mautrix-whatsapp - A Matrix-WhatsApp puppeting bridge.
// Copyright (C) 2019 Tulir Asokan
// Copyright (C) 2020 Tulir Asokan
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@ -28,6 +28,7 @@ import (
"maunium.net/go/mautrix-whatsapp/types"
"maunium.net/go/mautrix-whatsapp/whatsapp-ext"
"maunium.net/go/mautrix/id"
)
type UserQuery struct {
@ -54,7 +55,7 @@ func (uq *UserQuery) GetAll() (users []*User) {
return
}
func (uq *UserQuery) GetByMXID(userID types.MatrixUserID) *User {
func (uq *UserQuery) GetByMXID(userID id.UserID) *User {
row := uq.db.QueryRow(`SELECT mxid, jid, management_room, last_connection, client_id, client_token, server_token, enc_key, mac_key FROM "user" WHERE mxid=$1`, userID)
if row == nil {
return nil
@ -74,9 +75,9 @@ type User struct {
db *Database
log log.Logger
MXID types.MatrixUserID
MXID id.UserID
JID types.WhatsAppID
ManagementRoom types.MatrixRoomID
ManagementRoom id.RoomID
Session *whatsapp.Session
LastConnection uint64
}