aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--account.go74
-rw-r--r--main.go34
-rw-r--r--util.go18
-rw-r--r--web.go67
4 files changed, 101 insertions, 92 deletions
diff --git a/account.go b/account.go
index c17fb2f..6785fb7 100644
--- a/account.go
+++ b/account.go
@@ -2,6 +2,7 @@ package main
import (
"fmt"
+ "reflect"
"strings"
"sync"
@@ -15,22 +16,63 @@ type Account struct {
AccountName string
Protocol string
Config map[string]string
- Conn Connector
+ Conn Connector
JoinedRooms map[RoomID]bool
}
var accountsLock sync.Mutex
var registeredAccounts = map[string]map[string]*Account{}
-func AddAccount(a *Account) {
+func SetAccount(mxid string, name string, protocol string, config map[string]string) error {
accountsLock.Lock()
defer accountsLock.Unlock()
- if _, ok := registeredAccounts[a.MatrixUser]; !ok {
- registeredAccounts[a.MatrixUser] = make(map[string]*Account)
+ if _, ok := registeredAccounts[mxid]; !ok {
+ registeredAccounts[mxid] = make(map[string]*Account)
}
- registeredAccounts[a.MatrixUser][a.AccountName] = a
+ accounts := registeredAccounts[mxid]
+
+ if prev_acct, ok := accounts[name]; ok {
+ if protocol != prev_acct.Protocol {
+ return fmt.Errorf("Wrong protocol")
+ }
+ if !reflect.DeepEqual(config, prev_acct.Config) {
+ prev_acct.Config = config
+ go prev_acct.connect()
+ }
+ } else {
+ conn := createConnector(protocol)
+ if conn == nil {
+ return fmt.Errorf("Could not create connector for protocol %s", protocol)
+ }
+ account := &Account{
+ MatrixUser: mxid,
+ AccountName: name,
+ Protocol: protocol,
+ Config: config,
+ Conn: conn,
+ JoinedRooms: map[RoomID]bool{},
+ }
+ conn.SetHandler(account)
+
+ accounts[name] = account
+ go account.connect()
+ }
+ return nil
+}
+
+func ListAccounts(mxUser string) []*Account {
+ accountsLock.Lock()
+ defer accountsLock.Unlock()
+
+ ret := []*Account{}
+ if accts, ok := registeredAccounts[mxUser]; ok {
+ for _, acct := range accts {
+ ret = append(ret, acct)
+ }
+ }
+ return ret
}
func FindAccount(mxUser string, name string) *Account {
@@ -70,6 +112,24 @@ func RemoveAccount(mxUser string, name string) {
}
}
+func SaveDbAccounts(mxid string, key *[32]byte) {
+ accountsLock.Lock()
+ defer accountsLock.Unlock()
+
+ if accounts, ok := registeredAccounts[mxid]; ok {
+ for name, acct := range accounts {
+ var entry DbAccountConfig
+ db.Where(&DbAccountConfig{
+ MxUserID: mxid,
+ Name: name,
+ }).Assign(&DbAccountConfig{
+ Protocol: acct.Protocol,
+ Config: encryptAccountConfig(acct.Config, key),
+ }).FirstOrCreate(&entry)
+ }
+ }
+}
+
// ----
func (a *Account) ezbrMessagef(format string, args ...interface{}) {
@@ -78,10 +138,10 @@ func (a *Account) ezbrMessagef(format string, args ...interface{}) {
ezbrSystemSend(a.MatrixUser, msg)
}
-func (a *Account) connect(config map[string]string) {
+func (a *Account) connect() {
ezbrSystemSendf(a.MatrixUser, "Connecting to account %s (%s)", a.AccountName, a.Protocol)
- err := a.Conn.Configure(config)
+ err := a.Conn.Configure(a.Config)
if err != nil {
ezbrSystemSendf(a.MatrixUser, "%s (%s) cannot connect: %s", a.AccountName, a.Protocol, err.Error())
return
diff --git a/main.go b/main.go
index a8a349c..5448e89 100644
--- a/main.go
+++ b/main.go
@@ -15,10 +15,6 @@ import (
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
- "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector"
- "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector/irc"
- "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector/mattermost"
- "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector/xmpp"
"git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib"
)
@@ -174,22 +170,9 @@ func main() {
StartWeb()
for user, accounts := range config.Accounts {
+ mxid := fmt.Sprintf("@%s:%s", user, config.MatrixDomain)
for name, params := range accounts {
- conn := createConnector(params.Protocol)
- if conn == nil {
- log.Fatalf("Could not create connector for protocol %s", params.Protocol)
- }
- account := &Account{
- MatrixUser: fmt.Sprintf("@%s:%s", user, config.MatrixDomain),
- AccountName: name,
- Protocol: params.Protocol,
- Config: params.Config,
- Conn: conn,
- JoinedRooms: map[connector.RoomID]bool{},
- }
- conn.SetHandler(account)
- AddAccount(account)
- go account.connect(params.Config)
+ SetAccount(mxid, name, params.Protocol, params.Config)
}
}
@@ -198,16 +181,3 @@ func main() {
log.Fatal(err)
}
}
-
-func createConnector(protocol string) connector.Connector {
- switch protocol {
- case "irc":
- return &irc.IRC{}
- case "xmpp":
- return &xmpp.XMPP{}
- case "mattermost":
- return &mattermost.Mattermost{}
- default:
- return nil
- }
-}
diff --git a/util.go b/util.go
index 323f99d..6193d4d 100644
--- a/util.go
+++ b/util.go
@@ -11,6 +11,9 @@ import (
"golang.org/x/crypto/nacl/secretbox"
. "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector"
+ "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector/irc"
+ "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector/mattermost"
+ "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector/xmpp"
)
const EASYBRIDGE_SYSTEM_PROTOCOL string = "✯◡✯"
@@ -98,3 +101,18 @@ func decryptAccountConfig(data string, key *[32]byte) (map[string]string, error)
err = json.Unmarshal(decoded, &config)
return config, err
}
+
+// ----
+
+func createConnector(protocol string) Connector {
+ switch protocol {
+ case "irc":
+ return &irc.IRC{}
+ case "xmpp":
+ return &xmpp.XMPP{}
+ case "mattermost":
+ return &mattermost.Mattermost{}
+ default:
+ return nil
+ }
+}
diff --git a/web.go b/web.go
index bff8acc..74dd1f8 100644
--- a/web.go
+++ b/web.go
@@ -11,7 +11,6 @@ import (
"github.com/gorilla/sessions"
"golang.org/x/crypto/argon2"
- "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector"
"git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib"
)
@@ -81,7 +80,7 @@ func checkLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
type HomeData struct {
Login *LoginInfo
- Accounts map[string]*Account
+ Accounts []*Account
}
func handleHome(w http.ResponseWriter, r *http.Request) {
@@ -92,11 +91,9 @@ func handleHome(w http.ResponseWriter, r *http.Request) {
return
}
- accountsLock.Lock()
- defer accountsLock.Unlock()
templateHome.Execute(w, &HomeData{
Login: login,
- Accounts: registeredAccounts[login.MxId],
+ Accounts: ListAccounts(login.MxId),
})
}
@@ -154,7 +151,9 @@ func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
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)
+
+ SaveDbAccounts(mxid, key)
+ LoadDbAccounts(mxid, key)
// Successfully logged in, save it to session
session, err := sessionsStore.Get(r, SESSION_NAME)
@@ -179,57 +178,19 @@ func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
}
}
-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
+func LoadDbAccounts(mxid string, key *[32]byte) {
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
+ config, err := decryptAccountConfig(acct.Config, key)
+ if err != nil {
+ ezbrSystemSendf("Could not decrypt stored configuration for account %s", acct.Name)
+ continue
+ }
- go account.connect(config)
+ err = SetAccount(mxid, acct.Name, acct.Protocol, config)
+ if err != nil {
+ ezbrSystemSendf("Could not setup account %s: %s", acct.Name, err.Error())
}
}
}