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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
@ -15,22 +16,63 @@ type Account struct {
|
||||||
AccountName string
|
AccountName string
|
||||||
Protocol string
|
Protocol string
|
||||||
Config map[string]string
|
Config map[string]string
|
||||||
Conn Connector
|
|
||||||
|
|
||||||
|
Conn Connector
|
||||||
JoinedRooms map[RoomID]bool
|
JoinedRooms map[RoomID]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var accountsLock sync.Mutex
|
var accountsLock sync.Mutex
|
||||||
var registeredAccounts = map[string]map[string]*Account{}
|
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()
|
accountsLock.Lock()
|
||||||
defer accountsLock.Unlock()
|
defer accountsLock.Unlock()
|
||||||
|
|
||||||
if _, ok := registeredAccounts[a.MatrixUser]; !ok {
|
if _, ok := registeredAccounts[mxid]; !ok {
|
||||||
registeredAccounts[a.MatrixUser] = make(map[string]*Account)
|
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 {
|
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{}) {
|
func (a *Account) ezbrMessagef(format string, args ...interface{}) {
|
||||||
|
@ -78,10 +138,10 @@ func (a *Account) ezbrMessagef(format string, args ...interface{}) {
|
||||||
ezbrSystemSend(a.MatrixUser, msg)
|
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)
|
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 {
|
if err != nil {
|
||||||
ezbrSystemSendf(a.MatrixUser, "%s (%s) cannot connect: %s", a.AccountName, a.Protocol, err.Error())
|
ezbrSystemSendf(a.MatrixUser, "%s (%s) cannot connect: %s", a.AccountName, a.Protocol, err.Error())
|
||||||
return
|
return
|
||||||
|
|
34
main.go
34
main.go
|
@ -15,10 +15,6 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"gopkg.in/yaml.v2"
|
"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"
|
"git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -174,22 +170,9 @@ func main() {
|
||||||
StartWeb()
|
StartWeb()
|
||||||
|
|
||||||
for user, accounts := range config.Accounts {
|
for user, accounts := range config.Accounts {
|
||||||
|
mxid := fmt.Sprintf("@%s:%s", user, config.MatrixDomain)
|
||||||
for name, params := range accounts {
|
for name, params := range accounts {
|
||||||
conn := createConnector(params.Protocol)
|
SetAccount(mxid, name, params.Protocol, params.Config)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,16 +181,3 @@ func main() {
|
||||||
log.Fatal(err)
|
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"
|
"golang.org/x/crypto/nacl/secretbox"
|
||||||
|
|
||||||
. "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector"
|
. "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 = "✯◡✯"
|
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)
|
err = json.Unmarshal(decoded, &config)
|
||||||
return config, err
|
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"
|
"github.com/gorilla/sessions"
|
||||||
"golang.org/x/crypto/argon2"
|
"golang.org/x/crypto/argon2"
|
||||||
|
|
||||||
"git.deuxfleurs.fr/Deuxfleurs/easybridge/connector"
|
|
||||||
"git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib"
|
"git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -81,7 +80,7 @@ func checkLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
|
||||||
|
|
||||||
type HomeData struct {
|
type HomeData struct {
|
||||||
Login *LoginInfo
|
Login *LoginInfo
|
||||||
Accounts map[string]*Account
|
Accounts []*Account
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleHome(w http.ResponseWriter, r *http.Request) {
|
func handleHome(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -92,11 +91,9 @@ func handleHome(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
accountsLock.Lock()
|
|
||||||
defer accountsLock.Unlock()
|
|
||||||
templateHome.Execute(w, &HomeData{
|
templateHome.Execute(w, &HomeData{
|
||||||
Login: login,
|
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)
|
key_slice := argon2.IDKey([]byte(password), []byte("EZBRIDGE account store"), 3, 64*1024, 4, 32)
|
||||||
copy(key[:], key_slice[:])
|
copy(key[:], key_slice[:])
|
||||||
userKeys[mxid] = key
|
userKeys[mxid] = key
|
||||||
syncDbAccounts(mxid, key)
|
|
||||||
|
SaveDbAccounts(mxid, key)
|
||||||
|
LoadDbAccounts(mxid, key)
|
||||||
|
|
||||||
// Successfully logged in, save it to session
|
// Successfully logged in, save it to session
|
||||||
session, err := sessionsStore.Get(r, SESSION_NAME)
|
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) {
|
func LoadDbAccounts(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
|
var allAccounts []DbAccountConfig
|
||||||
db.Where(&DbAccountConfig{MxUserID: mxid}).Find(&allAccounts)
|
db.Where(&DbAccountConfig{MxUserID: mxid}).Find(&allAccounts)
|
||||||
for _, acct := range allAccounts {
|
for _, acct := range allAccounts {
|
||||||
if _, ok := accounts[acct.Name]; !ok {
|
config, err := decryptAccountConfig(acct.Config, key)
|
||||||
config, err := decryptAccountConfig(acct.Config, key)
|
if err != nil {
|
||||||
if err != nil {
|
ezbrSystemSendf("Could not decrypt stored configuration for account %s", acct.Name)
|
||||||
ezbrSystemSendf("Could not decrypt stored configuration for account %s", acct.Name)
|
continue
|
||||||
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
|
err = SetAccount(mxid, acct.Name, acct.Protocol, config)
|
||||||
|
if err != nil {
|
||||||
go account.connect(config)
|
ezbrSystemSendf("Could not setup account %s: %s", acct.Name, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue