Add basic end-to-bridge encryption support

Still missing persisting sync tokens and crypto state in DB
This commit is contained in:
Tulir Asokan
2020-05-09 02:03:59 +03:00
parent edd91510f1
commit baae66ed04
12 changed files with 460 additions and 38 deletions

View File

@ -22,8 +22,9 @@ import (
log "maunium.net/go/maulogger/v2"
"maunium.net/go/mautrix-whatsapp/types"
"maunium.net/go/mautrix/id"
"maunium.net/go/mautrix-whatsapp/types"
)
type PortalKey struct {
@ -114,11 +115,12 @@ type Portal struct {
Topic string
Avatar string
AvatarURL id.ContentURI
Encrypted bool
}
func (portal *Portal) Scan(row Scannable) *Portal {
var mxid, avatarURL sql.NullString
err := row.Scan(&portal.Key.JID, &portal.Key.Receiver, &mxid, &portal.Name, &portal.Topic, &portal.Avatar, &avatarURL)
err := row.Scan(&portal.Key.JID, &portal.Key.Receiver, &mxid, &portal.Name, &portal.Topic, &portal.Avatar, &avatarURL, &portal.Encrypted)
if err != nil {
if err != sql.ErrNoRows {
portal.log.Errorln("Database scan failed:", err)
@ -138,8 +140,8 @@ func (portal *Portal) mxidPtr() *id.RoomID {
}
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.String())
_, err := portal.db.Exec("INSERT INTO portal (jid, receiver, mxid, name, topic, avatar, avatar_url, encrypted) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
portal.Key.JID, portal.Key.Receiver, portal.mxidPtr(), portal.Name, portal.Topic, portal.Avatar, portal.AvatarURL.String(), portal.Encrypted)
if err != nil {
portal.log.Warnfln("Failed to insert %s: %v", portal.Key, err)
}
@ -150,8 +152,8 @@ func (portal *Portal) Update() {
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.String(), portal.Key.JID, portal.Key.Receiver)
_, err := portal.db.Exec("UPDATE portal SET mxid=$1, name=$2, topic=$3, avatar=$4, avatar_url=$5, encrypted=$6 WHERE jid=$7 AND receiver=$8",
mxid, portal.Name, portal.Topic, portal.Avatar, portal.AvatarURL.String(), portal.Encrypted, portal.Key.JID, portal.Key.Receiver)
if err != nil {
portal.log.Warnfln("Failed to update %s: %v", portal.Key, err)
}

View File

@ -90,6 +90,24 @@ func (store *SQLStateStore) GetRoomMembers(roomID id.RoomID) map[id.UserID]*even
return members
}
func (store *SQLStateStore) GetRoomMemberList(roomID id.RoomID) (members []id.UserID, err error) {
var rows *sql.Rows
rows, err = store.db.Query("SELECT user_id FROM mx_user_profile WHERE room_id=$1", roomID)
if err != nil {
return
}
for rows.Next() {
var userID id.UserID
err := rows.Scan(&userID)
if err != nil {
store.log.Warnfln("Failed to scan member in %s: %v", roomID, err)
} else {
members = append(members, userID)
}
}
return
}
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 := event.MembershipLeave
@ -118,6 +136,26 @@ func (store *SQLStateStore) TryGetMember(roomID id.RoomID, userID id.UserID) (*e
return &member, err == nil
}
func (store *SQLStateStore) FindSharedRooms(userID id.UserID) (rooms []id.RoomID) {
rows, err := store.db.Query(`
SELECT room_id FROM mx_user_profile WHERE user_id=$2 AND portal.encrypted=true
LEFT JOIN portal WHEN portal.mxid=mx_user_profile.room_id`, userID)
if err != nil {
store.log.Warnfln("Failed to query shared rooms with %s: %v", userID, err)
return
}
for rows.Next() {
var roomID id.RoomID
err := rows.Scan(&roomID)
if err != nil {
store.log.Warnfln("Failed to scan room ID: %v", err)
} else {
rooms = append(rooms, roomID)
}
}
return
}
func (store *SQLStateStore) IsInRoom(roomID id.RoomID, userID id.UserID) bool {
return store.IsMembership(roomID, userID, "join")
}

View File

@ -0,0 +1,12 @@
package upgrades
import (
"database/sql"
)
func init() {
upgrades[12] = upgrade{"Add encryption status to portal table", func(tx *sql.Tx, ctx context) error {
_, err := tx.Exec(`ALTER TABLE portal ADD COLUMN encrypted BOOLEAN NOT NULL DEFAULT false`)
return err
}}
}

View File

@ -28,7 +28,7 @@ type upgrade struct {
fn upgradeFunc
}
const NumberOfUpgrades = 12
const NumberOfUpgrades = 13
var upgrades [NumberOfUpgrades]upgrade