Implement crypto.StateStore in appservice.SQLStateStore

This commit is contained in:
Tulir Asokan 2023-02-18 23:24:54 +02:00
commit 79d25715e4
5 changed files with 51 additions and 8 deletions

View file

@ -13,7 +13,6 @@ import (
"errors"
"sync"
"maunium.net/go/mautrix/appservice"
"maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
"maunium.net/go/mautrix/util/dbutil"
@ -37,8 +36,6 @@ type SQLStateStore struct {
typingLock sync.RWMutex
}
var _ appservice.StateStore = (*SQLStateStore)(nil)
func NewSQLStateStore(db *dbutil.Database, log dbutil.DatabaseLogger) *SQLStateStore {
return &SQLStateStore{
Database: db.Child(VersionTableName, UpgradeTable, log),
@ -172,6 +169,46 @@ func (store *SQLStateStore) SetMember(roomID id.RoomID, userID id.UserID, member
}
}
func (store *SQLStateStore) SetEncryptionEvent(roomID id.RoomID, content *event.EncryptionEventContent) {
contentBytes, err := json.Marshal(content)
if err != nil {
store.Log.Warn("Failed to marshal encryption config of %s: %v", roomID, err)
return
}
_, err = store.Exec(`
INSERT INTO mx_room_state (room_id, encryption) VALUES ($1, $2)
ON CONFLICT (room_id) DO UPDATE SET encryption=excluded.encryption
`, roomID, contentBytes)
if err != nil {
store.Log.Warn("Failed to store encryption config of %s: %v", roomID, err)
}
}
func (store *SQLStateStore) GetEncryptionEvent(roomID id.RoomID) *event.EncryptionEventContent {
var data []byte
err := store.
QueryRow("SELECT encryption FROM mx_room_state WHERE room_id=$1", roomID).
Scan(&data)
if err != nil {
if !errors.Is(err, sql.ErrNoRows) {
store.Log.Warn("Failed to scan encryption config of %s: %v", roomID, err)
}
return nil
}
content := &event.EncryptionEventContent{}
err = json.Unmarshal(data, content)
if err != nil {
store.Log.Warn("Failed to parse encryption config of %s: %v", roomID, err)
return nil
}
return content
}
func (store *SQLStateStore) IsEncrypted(roomID id.RoomID) bool {
cfg := store.GetEncryptionEvent(roomID)
return cfg != nil && cfg.Algorithm == id.AlgorithmMegolmV1
}
func (store *SQLStateStore) SetPowerLevels(roomID id.RoomID, levels *event.PowerLevelsEventContent) {
levelsBytes, err := json.Marshal(levels)
if err != nil {

View file

@ -1,4 +1,4 @@
-- v0 -> v3: Latest revision
-- v0 -> v4: Latest revision
CREATE TABLE mx_registrations (
user_id TEXT PRIMARY KEY
@ -18,5 +18,6 @@ CREATE TABLE mx_user_profile (
CREATE TABLE mx_room_state (
room_id TEXT PRIMARY KEY,
power_levels jsonb
power_levels jsonb,
encryption jsonb
);

View file

@ -0,0 +1,2 @@
-- v4: Store room encryption configuration
ALTER TABLE mx_room_state ADD COLUMN encryption jsonb;

View file

@ -25,6 +25,7 @@ import (
"maunium.net/go/mautrix/appservice"
"maunium.net/go/mautrix/appservice/sqlstatestore"
"maunium.net/go/mautrix/bridge/bridgeconfig"
"maunium.net/go/mautrix/crypto"
"maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
"maunium.net/go/mautrix/util/configupgrade"
@ -41,6 +42,9 @@ var ignoreUnsupportedDatabase = flag.Make().LongKey("ignore-unsupported-database
var ignoreForeignTables = flag.Make().LongKey("ignore-foreign-tables").Usage("Run even if the database contains tables from other programs (like Synapse)").Default("false").Bool()
var wantHelp, _ = flag.MakeHelpFlag()
var _ appservice.StateStore = (*sqlstatestore.SQLStateStore)(nil)
var _ crypto.StateStore = (*sqlstatestore.SQLStateStore)(nil)
type Portal interface {
IsEncrypted() bool
IsPrivateChat() bool

View file

@ -448,7 +448,6 @@ func (c *cryptoStateStore) FindSharedRooms(id id.UserID) []id.RoomID {
return c.bridge.StateStore.FindSharedRooms(id)
}
func (c *cryptoStateStore) GetEncryptionEvent(id.RoomID) *event.EncryptionEventContent {
// TODO implement
return nil
func (c *cryptoStateStore) GetEncryptionEvent(id id.RoomID) *event.EncryptionEventContent {
return c.bridge.StateStore.GetEncryptionEvent(id)
}