From f675ba57e400d378088d29c08bd5d0bd9126c74b Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Wed, 26 Feb 2020 20:21:32 +0100 Subject: Implement account configuration save/load from db --- web.go | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'web.go') diff --git a/web.go b/web.go index dafb8b1..bff8acc 100644 --- a/web.go +++ b/web.go @@ -9,13 +9,16 @@ import ( "github.com/gorilla/mux" "github.com/gorilla/sessions" + "golang.org/x/crypto/argon2" + "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector" "git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib" ) const SESSION_NAME = "easybridge_session" var sessionsStore sessions.Store = nil +var userKeys = map[string]*[32]byte{} func StartWeb() { session_key := make([]byte, 32) @@ -147,6 +150,12 @@ func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo { return nil } + key := new([32]byte) + key_slice := argon2.IDKey([]byte(password), []byte("EZBRIDGE account store"), 3, 64*1024, 4, 32) + copy(key[:], key_slice[:]) + userKeys[mxid] = key + syncDbAccounts(mxid, key) + // Successfully logged in, save it to session session, err := sessionsStore.Get(r, SESSION_NAME) if err != nil { @@ -169,3 +178,58 @@ func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo { return nil } } + +func syncDbAccounts(mxid string, key *[32]byte) { + accountsLock.Lock() + defer accountsLock.Unlock() + + // 1. Save all accounts that we have + var accounts map[string]*Account + if accts, ok := registeredAccounts[mxid]; ok { + accounts = accts + for name, acct := range accts { + var entry DbAccountConfig + db.Where(&DbAccountConfig{ + MxUserID: mxid, + Name: name, + }).Assign(&DbAccountConfig{ + Protocol: acct.Protocol, + Config: encryptAccountConfig(acct.Config, key), + }).FirstOrCreate(&entry) + } + } else { + accounts = make(map[string]*Account) + registeredAccounts[mxid] = accounts + } + + // 2. Load and start missing accounts + var allAccounts []DbAccountConfig + db.Where(&DbAccountConfig{MxUserID: mxid}).Find(&allAccounts) + for _, acct := range allAccounts { + if _, ok := accounts[acct.Name]; !ok { + config, err := decryptAccountConfig(acct.Config, key) + if err != nil { + ezbrSystemSendf("Could not decrypt stored configuration for account %s", acct.Name) + continue + } + conn := createConnector(acct.Protocol) + if conn == nil { + ezbrSystemSendf("Could not create connector for protocol %s", acct.Protocol) + continue + } + account := &Account{ + MatrixUser: mxid, + AccountName: acct.Name, + Protocol: acct.Protocol, + Config: config, + Conn: conn, + JoinedRooms: map[connector.RoomID]bool{}, + } + conn.SetHandler(account) + + accounts[acct.Name] = account + + go account.connect(config) + } + } +} -- cgit v1.2.3