2020-02-16 15:26:55 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2020-02-16 21:07:41 +00:00
|
|
|
"fmt"
|
2020-02-16 18:30:49 +00:00
|
|
|
"crypto/rand"
|
|
|
|
"encoding/hex"
|
|
|
|
"flag"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
_"strings"
|
|
|
|
_ "time"
|
|
|
|
_ "fmt"
|
2020-02-16 15:26:55 +00:00
|
|
|
"log"
|
2020-02-16 18:30:49 +00:00
|
|
|
"encoding/json"
|
2020-02-16 15:26:55 +00:00
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
"git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib"
|
|
|
|
"git.deuxfleurs.fr/Deuxfleurs/easybridge/appservice"
|
2020-02-16 15:26:55 +00:00
|
|
|
"git.deuxfleurs.fr/Deuxfleurs/easybridge/connector"
|
|
|
|
"git.deuxfleurs.fr/Deuxfleurs/easybridge/connector/irc"
|
2020-02-16 16:53:31 +00:00
|
|
|
"git.deuxfleurs.fr/Deuxfleurs/easybridge/connector/xmpp"
|
2020-02-16 18:30:49 +00:00
|
|
|
"gopkg.in/yaml.v2"
|
2020-02-16 15:26:55 +00:00
|
|
|
)
|
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
type ConfigAccount struct {
|
|
|
|
Protocol string `json:"protocol"`
|
|
|
|
Rooms []string `json:"rooms"`
|
|
|
|
Config map[string]string `json:"config"`
|
2020-02-16 15:26:55 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
type ConfigFile struct {
|
|
|
|
HttpBindAddr string`json:"http_bind_addr"`
|
|
|
|
Registration string `json:"registration"`
|
|
|
|
Server string `json:"homeserver_url"`
|
|
|
|
DbType string `json:"db_type"`
|
|
|
|
DbPath string `json:"db_path"`
|
2020-02-16 21:07:41 +00:00
|
|
|
MatrixDomain string `json:"matrix_domain"`
|
2020-02-16 18:30:49 +00:00
|
|
|
Accounts map[string]map[string]ConfigAccount `json:"accounts"`
|
2020-02-16 15:26:55 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
var configFlag = flag.String("config", "./config.json", "Configuration file path")
|
2020-02-16 15:26:55 +00:00
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
var config *ConfigFile
|
|
|
|
var registration *mxlib.Registration
|
2020-02-16 15:26:55 +00:00
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
func readConfig() ConfigFile {
|
|
|
|
config_file := ConfigFile{
|
|
|
|
HttpBindAddr: "0.0.0.0:8321",
|
|
|
|
Registration: "./registration.yaml",
|
|
|
|
Server: "http://localhost:8008",
|
|
|
|
DbType: "sqlite3",
|
|
|
|
DbPath: "easybridge.db",
|
|
|
|
Accounts: map[string]map[string]ConfigAccount{},
|
2020-02-16 15:26:55 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
_, err := os.Stat(*configFlag)
|
|
|
|
if os.IsNotExist(err) {
|
|
|
|
// Generate default config file
|
|
|
|
log.Printf("Generating default config file as %s", *configFlag)
|
2020-02-16 15:26:55 +00:00
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
bytes, err := json.MarshalIndent(&config_file, "", " ")
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = ioutil.WriteFile(*configFlag, bytes, 0644)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return config_file
|
2020-02-16 15:26:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
2020-02-16 18:30:49 +00:00
|
|
|
log.Fatal(err)
|
2020-02-16 15:26:55 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
bytes, err := ioutil.ReadFile(*configFlag)
|
2020-02-16 15:26:55 +00:00
|
|
|
if err != nil {
|
2020-02-16 18:30:49 +00:00
|
|
|
log.Fatal(err)
|
2020-02-16 15:26:55 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
err = json.Unmarshal(bytes, &config_file)
|
2020-02-16 15:26:55 +00:00
|
|
|
if err != nil {
|
2020-02-16 18:30:49 +00:00
|
|
|
log.Fatal(err)
|
2020-02-16 15:26:55 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
return config_file
|
2020-02-16 15:26:55 +00:00
|
|
|
}
|
2020-02-16 16:53:31 +00:00
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
func readRegistration(file string) mxlib.Registration {
|
|
|
|
rnd := make([]byte, 64)
|
|
|
|
n, err := rand.Read(rnd)
|
|
|
|
if err != nil || n != 64 {
|
|
|
|
log.Fatal(err)
|
2020-02-16 16:53:31 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
reg := mxlib.Registration{
|
|
|
|
Id: "Easybridge",
|
|
|
|
Url: "http://localhost:8321",
|
|
|
|
AsToken: hex.EncodeToString(rnd[:32]),
|
|
|
|
HsToken: hex.EncodeToString(rnd[32:]),
|
|
|
|
SenderLocalpart: "_ezbr",
|
|
|
|
Namespaces: mxlib.RegistrationNamespaceSet{
|
|
|
|
Users: []mxlib.RegistrationNamespace{
|
|
|
|
mxlib.RegistrationNamespace{
|
|
|
|
Exclusive: true,
|
|
|
|
Regex: "@_ezbr_.*",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Aliases: []mxlib.RegistrationNamespace{
|
|
|
|
mxlib.RegistrationNamespace{
|
|
|
|
Exclusive: true,
|
|
|
|
Regex: "#_ezbr_.*",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Rooms: []mxlib.RegistrationNamespace{},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = os.Stat(file)
|
|
|
|
if os.IsNotExist(err) {
|
|
|
|
// Generate default config file
|
|
|
|
log.Printf("Generating default registration file as %s", file)
|
|
|
|
|
|
|
|
bytes, err := yaml.Marshal(®)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = ioutil.WriteFile(file, bytes, 0644)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return reg
|
2020-02-16 16:53:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
2020-02-16 18:30:49 +00:00
|
|
|
log.Fatal(err)
|
2020-02-16 16:53:31 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
bytes, err := ioutil.ReadFile(file)
|
2020-02-16 16:53:31 +00:00
|
|
|
if err != nil {
|
2020-02-16 18:30:49 +00:00
|
|
|
log.Fatal(err)
|
2020-02-16 16:53:31 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
err = yaml.Unmarshal(bytes, ®)
|
2020-02-16 16:53:31 +00:00
|
|
|
if err != nil {
|
2020-02-16 18:30:49 +00:00
|
|
|
log.Fatal(err)
|
2020-02-16 16:53:31 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
return reg
|
2020-02-16 16:53:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
2020-02-16 18:30:49 +00:00
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
config_file := readConfig()
|
|
|
|
config = &config_file
|
|
|
|
|
|
|
|
reg_file := readRegistration(config.Registration)
|
|
|
|
registration = ®_file
|
|
|
|
|
|
|
|
as_config := &appservice.Config{
|
|
|
|
HttpBindAddr: config.HttpBindAddr,
|
|
|
|
Server: config.Server,
|
|
|
|
DbType: config.DbType,
|
|
|
|
DbPath: config.DbPath,
|
2020-02-16 21:07:41 +00:00
|
|
|
MatrixDomain: config.MatrixDomain,
|
2020-02-16 18:30:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
errch, err := appservice.Start(registration, as_config)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for user, accounts := range config.Accounts {
|
|
|
|
for name, params := range accounts {
|
|
|
|
var conn connector.Connector
|
|
|
|
switch params.Protocol {
|
|
|
|
case "irc":
|
|
|
|
conn = &irc.IRC{}
|
|
|
|
case "xmpp":
|
|
|
|
conn = &xmpp.XMPP{}
|
|
|
|
}
|
|
|
|
account := &appservice.Account{
|
2020-02-16 21:07:41 +00:00
|
|
|
MatrixUser: fmt.Sprintf("@%s:%s", user, config.MatrixDomain),
|
2020-02-16 18:30:49 +00:00
|
|
|
AccountName: name,
|
|
|
|
Protocol: params.Protocol,
|
|
|
|
Conn: conn,
|
|
|
|
}
|
|
|
|
conn.SetHandler(account)
|
|
|
|
go connectAndJoin(conn, params)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
err = <-errch
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func connectAndJoin(conn connector.Connector, params ConfigAccount) {
|
|
|
|
log.Printf("Connecting to %s", params.Protocol)
|
|
|
|
err := conn.Configure(params.Config)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Could not connect to %s: %s\n", params.Protocol, err)
|
|
|
|
} else {
|
|
|
|
log.Printf("Connected to %s, now joining %#v`n", params.Protocol, params.Rooms)
|
|
|
|
for _, room := range params.Rooms {
|
|
|
|
err := conn.Join(connector.RoomID(room))
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Could not join %s: %s", room, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-02-16 16:53:31 +00:00
|
|
|
}
|