package main import ( "crypto/rand" "encoding/hex" "encoding/json" "flag" "fmt" _ "fmt" "io/ioutil" "os" _ "strings" _ "time" log "github.com/sirupsen/logrus" "gopkg.in/yaml.v2" "git.deuxfleurs.fr/Deuxfleurs/easybridge/appservice" "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector" "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector/irc" "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector/xmpp" "git.deuxfleurs.fr/Deuxfleurs/easybridge/connector/mattermost" "git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib" ) type ConfigAccount struct { Protocol string `json:"protocol"` Rooms []string `json:"rooms"` Config map[string]string `json:"config"` } 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"` MatrixDomain string `json:"matrix_domain"` Accounts map[string]map[string]ConfigAccount `json:"accounts"` } var configFlag = flag.String("config", "./config.json", "Configuration file path") var config *ConfigFile var registration *mxlib.Registration 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{}, } _, err := os.Stat(*configFlag) if os.IsNotExist(err) { // Generate default config file log.Printf("Generating default config file as %s", *configFlag) 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 } if err != nil { log.Fatal(err) } bytes, err := ioutil.ReadFile(*configFlag) if err != nil { log.Fatal(err) } err = json.Unmarshal(bytes, &config_file) if err != nil { log.Fatal(err) } return config_file } func readRegistration(file string) mxlib.Registration { rnd := make([]byte, 64) n, err := rand.Read(rnd) if err != nil || n != 64 { log.Fatal(err) } 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 } if err != nil { log.Fatal(err) } bytes, err := ioutil.ReadFile(file) if err != nil { log.Fatal(err) } err = yaml.Unmarshal(bytes, ®) if err != nil { log.Fatal(err) } return reg } func main() { log.SetLevel(log.DebugLevel) 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, MatrixDomain: config.MatrixDomain, } 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{} case "mattermost": conn = &mattermost.Mattermost{} default: log.Fatalf("Invalid protocol %s", params.Protocol) } account := &appservice.Account{ MatrixUser: fmt.Sprintf("@%s:%s", user, config.MatrixDomain), AccountName: name, Protocol: params.Protocol, Conn: conn, JoinedRooms: map[connector.RoomID]bool{}, } conn.SetHandler(account) appservice.AddAccount(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", params.Protocol, err) } else { log.Printf("Connected to %s, now joining %#v", 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) } } } }