Refactor
This commit is contained in:
parent
f675ba57e4
commit
775fc7b217
4 changed files with 101 additions and 92 deletions
74
account.go
74
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
|
||||
|
|
34
main.go
34
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
|
||||
}
|
||||
}
|
||||
|
|
18
util.go
18
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
|
||||
}
|
||||
}
|
||||
|
|
67
web.go
67
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)
|
||||
config, err := decryptAccountConfig(acct.Config, key)
|
||||
if err != nil {
|
||||
ezbrSystemSendf("Could not decrypt stored configuration for account %s", acct.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
accounts[acct.Name] = account
|
||||
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue