aboutsummaryrefslogblamecommitdiff
path: root/main.go
blob: 0f8f3f0e408f730dc56f5b08060f7d9ee43b092a (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12


            
             







                      
             
                       
 

                                                            

                                                               
                                                                
                          

 



                                                

 





                                                  
                                                  
                                                                      

 
                                                                                  
 

                                    
 







                                                                
         
 



                                                                               
 










                                                                        

         
                       
                              

         
                                                  
                       
                              

         
                                                 
                       
                              

         
                          
 
 




                                                       
         
 






































                                                                              

         
                       
                              

         
                                           
                       
                              

         
                                         
                       
                              

         
                  


             












                                                         
                                                  
















                                                               
                                                                                             




























                                                                                               
 
package main

import (
	"fmt"
	"crypto/rand"
	"encoding/hex"
	"flag"
	"io/ioutil"
	"os"
	_"strings"
	_ "time"
	_ "fmt"
	"log"
	"encoding/json"

	"git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib"
	"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"
	"gopkg.in/yaml.v2"
)

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(&reg)
		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, &reg)
	if err != nil {
		log.Fatal(err)
	}

	return reg
}

func main() {
	flag.Parse()

	config_file := readConfig()
	config = &config_file

	reg_file := readRegistration(config.Registration)
	registration = &reg_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{}
			}
			account := &appservice.Account{
				MatrixUser: fmt.Sprintf("@%s:%s", user, config.MatrixDomain),
				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)
			}
		}
	}
}