2020-02-16 15:26:55 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2020-03-02 20:51:13 +00:00
|
|
|
"context"
|
2020-02-16 18:30:49 +00:00
|
|
|
"crypto/rand"
|
|
|
|
"encoding/hex"
|
2020-02-17 18:02:26 +00:00
|
|
|
"encoding/json"
|
2020-02-16 18:30:49 +00:00
|
|
|
"flag"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
2020-03-01 13:14:18 +00:00
|
|
|
"os/signal"
|
|
|
|
"syscall"
|
2020-03-02 20:51:13 +00:00
|
|
|
"time"
|
2020-02-16 15:26:55 +00:00
|
|
|
|
2020-02-17 08:41:08 +00:00
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
"gopkg.in/yaml.v2"
|
|
|
|
|
2020-02-17 18:02:26 +00:00
|
|
|
"git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib"
|
2020-02-16 15:26:55 +00:00
|
|
|
)
|
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
type ConfigFile struct {
|
2020-02-29 09:51:09 +00:00
|
|
|
LogLevel string `json:"log_level"`
|
|
|
|
|
2020-02-27 09:44:28 +00:00
|
|
|
Registration string `json:"registration"`
|
2020-02-29 09:51:09 +00:00
|
|
|
ASBindAddr string `json:"appservice_bind_addr"`
|
2020-02-27 09:44:28 +00:00
|
|
|
Server string `json:"homeserver_url"`
|
|
|
|
MatrixDomain string `json:"matrix_domain"`
|
2020-02-29 09:51:09 +00:00
|
|
|
NameFormat string `json:"name_format"`
|
|
|
|
|
|
|
|
WebBindAddr string `json:"web_bind_addr"`
|
|
|
|
WebURL string `json:"web_url"`
|
|
|
|
SessionKey string `json:"web_session_key"`
|
|
|
|
|
|
|
|
DbType string `json:"db_type"`
|
|
|
|
DbPath string `json:"db_path"`
|
|
|
|
|
|
|
|
AvatarFile string `json:"easybridge_avatar"`
|
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 {
|
2020-02-28 16:20:32 +00:00
|
|
|
defaultKey := make([]byte, 32)
|
|
|
|
rand.Read(defaultKey)
|
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
config_file := ConfigFile{
|
2020-02-27 09:44:28 +00:00
|
|
|
LogLevel: "info",
|
2020-02-26 15:30:10 +00:00
|
|
|
ASBindAddr: "0.0.0.0:8321",
|
2020-02-26 16:45:25 +00:00
|
|
|
WebBindAddr: "0.0.0.0:8281",
|
2020-02-16 18:30:49 +00:00
|
|
|
Registration: "./registration.yaml",
|
2020-02-17 18:02:26 +00:00
|
|
|
Server: "http://localhost:8008",
|
2020-02-29 09:51:09 +00:00
|
|
|
NameFormat: "{}_ezbr_",
|
2020-02-17 18:02:26 +00:00
|
|
|
DbType: "sqlite3",
|
|
|
|
DbPath: "easybridge.db",
|
2020-02-28 19:07:47 +00:00
|
|
|
AvatarFile: "./easybridge.jpg",
|
2020-02-28 16:20:32 +00:00
|
|
|
SessionKey: hex.EncodeToString(defaultKey),
|
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{
|
2020-02-17 18:02:26 +00:00
|
|
|
Id: "Easybridge",
|
|
|
|
Url: "http://localhost:8321",
|
|
|
|
AsToken: hex.EncodeToString(rnd[:32]),
|
|
|
|
HsToken: hex.EncodeToString(rnd[32:]),
|
2020-02-17 14:30:01 +00:00
|
|
|
SenderLocalpart: "_ezbr_",
|
2020-02-23 19:24:50 +00:00
|
|
|
RateLimited: false,
|
2020-02-16 18:30:49 +00:00
|
|
|
Namespaces: mxlib.RegistrationNamespaceSet{
|
|
|
|
Users: []mxlib.RegistrationNamespace{
|
|
|
|
mxlib.RegistrationNamespace{
|
|
|
|
Exclusive: true,
|
2020-02-29 09:51:09 +00:00
|
|
|
Regex: "@.*_ezbr_",
|
2020-02-16 18:30:49 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
Aliases: []mxlib.RegistrationNamespace{
|
|
|
|
mxlib.RegistrationNamespace{
|
|
|
|
Exclusive: true,
|
2020-02-29 09:51:09 +00:00
|
|
|
Regex: "#.*_ezbr_",
|
2020-02-16 18:30:49 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
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()
|
|
|
|
|
2020-02-28 16:42:15 +00:00
|
|
|
// Read configuration
|
2020-02-16 18:30:49 +00:00
|
|
|
config_file := readConfig()
|
|
|
|
config = &config_file
|
|
|
|
|
2020-02-27 09:44:28 +00:00
|
|
|
log_level, err := log.ParseLevel(config.LogLevel)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
log.SetLevel(log_level)
|
|
|
|
|
2020-02-16 18:30:49 +00:00
|
|
|
reg_file := readRegistration(config.Registration)
|
|
|
|
registration = ®_file
|
|
|
|
|
2020-02-28 16:42:15 +00:00
|
|
|
// Start appservice and web management interface
|
|
|
|
errch := make(chan error)
|
2020-03-01 13:14:18 +00:00
|
|
|
sigch := make(chan os.Signal)
|
|
|
|
signal.Notify(sigch, os.Interrupt, syscall.SIGTERM)
|
|
|
|
|
2020-03-02 20:51:13 +00:00
|
|
|
as_server, err := StartAppService(errch)
|
2020-02-28 19:07:47 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2020-03-02 20:51:13 +00:00
|
|
|
web_server := StartWeb(errch)
|
2020-02-26 16:45:25 +00:00
|
|
|
|
2020-03-01 13:14:18 +00:00
|
|
|
// Wait for an error somewhere or interrupt signal
|
|
|
|
select {
|
|
|
|
case err = <-errch:
|
|
|
|
if err != nil {
|
|
|
|
log.Error(err)
|
|
|
|
}
|
|
|
|
case sig := <-sigch:
|
|
|
|
log.Warnf("Got signal %s", sig.String())
|
2020-02-16 18:30:49 +00:00
|
|
|
}
|
2020-03-01 13:14:18 +00:00
|
|
|
|
2020-03-02 20:51:13 +00:00
|
|
|
// Shut down, hopefully this is not a too bad way to do it
|
2020-03-01 13:14:18 +00:00
|
|
|
log.Warn("Shuttind down")
|
2020-03-02 20:51:13 +00:00
|
|
|
delay := 2 * time.Second
|
|
|
|
|
|
|
|
ctx1, _ := context.WithTimeout(context.TODO(), delay)
|
|
|
|
go as_server.Shutdown(ctx1)
|
|
|
|
|
|
|
|
ctx2, _ := context.WithTimeout(context.TODO(), delay)
|
|
|
|
go web_server.Shutdown(ctx2)
|
|
|
|
|
|
|
|
time.Sleep(delay)
|
2020-03-01 13:14:18 +00:00
|
|
|
CloseAllAcountsForShutdown()
|
2020-03-02 20:51:13 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
os.Exit(1)
|
|
|
|
} else {
|
|
|
|
os.Exit(0)
|
|
|
|
}
|
2020-02-16 18:30:49 +00:00
|
|
|
}
|