aboutsummaryrefslogblamecommitdiff
path: root/main.go
blob: 50f8bc71fd4aa5a10174dd4425751d1a81f6de29 (plain) (tree)
1
2
3
4
5
6
7
8
9


            

                      
                       
              

               

                   
                   
                
 


                                        
                                                            

                                                               
                                                                
                                                                      
                                                       

 
                           


                                                    

 
                        






                                                                                

 
                                                                                  
 

                                    
 



                                                    



                                                                    
         
 



                                                                               
 










                                                                        

         
                       
                              

         
                                                  
                       
                              

         
                                                 
                       
                              

         
                          
 
 




                                                       
         
 
                                  



                                                              
                                          



                                                             
                                                               




                                                               
                                                               





















                                                                              

         
                       
                              

         
                                           
                       
                              

         
                                         
                       
                              

         
                  


             

                                    









                                                         


                                            
                                                  














                                                               

                                                               

                                                                                  

                                                       
                                                                                              
                                                  

                                                             
                                                                         

                                                
                                                      













                                                                     
                                                                               
                
                                                                                             






                                                                              
 
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(&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() {
	log.SetLevel(log.DebugLevel)

	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{}
			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)
			}
		}
	}
}