From 30341f27c708dae954f4e7bcb65f95139e54fa97 Mon Sep 17 00:00:00 2001 From: Bernhard B Date: Fri, 4 Mar 2022 20:34:11 +0100 Subject: [PATCH] make json-rpc mode work with linked devices see #224 --- src/scripts/jsonrpc2-helper.go | 120 +++++++++++++++++++++++---------- 1 file changed, 84 insertions(+), 36 deletions(-) diff --git a/src/scripts/jsonrpc2-helper.go b/src/scripts/jsonrpc2-helper.go index 9d230ee..09c1fc9 100644 --- a/src/scripts/jsonrpc2-helper.go +++ b/src/scripts/jsonrpc2-helper.go @@ -10,6 +10,8 @@ import ( "path/filepath" "strconv" "strings" + "github.com/gabriel-vasile/mimetype" + "encoding/json" ) const supervisorctlConfigTemplate = ` @@ -30,7 +32,38 @@ stdout_logfile_backups=10 numprocs=1 ` +func isSignalCliLinkedNumberConfigFile(filename string) (bool, error) { + fileExtension := filepath.Ext(filename) + if fileExtension != "" { + return false, nil + } + mimetype, err := mimetype.DetectFile(filename) + if err != nil { + return false, err + } + if mimetype.String() == "application/json" { + return true, nil + } + return false, nil +} + + +func getUsernameFromLinkedNumberConfigFile(filename string) (string, error) { + type LinkedNumberConfigFile struct { + Username string `json:"username"` + } + bytes, err := ioutil.ReadFile(filename) + if err != nil { + return "", err + } + var linkedNumberConfigFile LinkedNumberConfigFile + err = json.Unmarshal(bytes, &linkedNumberConfigFile) + if err != nil { + return "", err + } + return linkedNumberConfigFile.Username, nil +} func main() { signalCliConfigDir := "/home/.local/share/signal-cli/" signalCliConfigDirEnv := utils.GetEnv("SIGNAL_CLI_CONFIG_DIR", "") @@ -58,47 +91,62 @@ func main() { continue } filename := filepath.Base(item.Name()) - if strings.HasPrefix(filename, "+") { + isSignalCliLinkedNumberConfigFile, err := isSignalCliLinkedNumberConfigFile(signalCliConfigDataDir + "/" + filename) + if err != nil { + log.Error("Couldn't determine whether file ", filename, " is a signal-cli config file: ", err.Error()) + continue + } + + if strings.HasPrefix(filename, "+") || isSignalCliLinkedNumberConfigFile { + var number string = "" if utils.IsPhoneNumber(filename) { - number := filename - fifoPathname := fifoBasePathName + strconv.FormatInt(ctr, 10) - tcpPort := tcpBasePort + ctr - jsonRpc2ClientConfig.AddEntry(number, utils.ConfigEntry{TcpPort: tcpPort, FifoPathname: fifoPathname}) - ctr += 1 - - os.Remove(fifoPathname) //remove any existing named pipe - - _, err = exec.Command("mkfifo", fifoPathname).Output() + number = filename + } else if isSignalCliLinkedNumberConfigFile { + number, err = getUsernameFromLinkedNumberConfigFile(signalCliConfigDataDir + "/" + filename) if err != nil { - log.Fatal("Couldn't create fifo with name ", fifoPathname, ": ", err.Error()) - } - - uid := utils.GetEnv("SIGNAL_CLI_UID", "1000") - gid := utils.GetEnv("SIGNAL_CLI_GID", "1000") - _, err = exec.Command("chown", uid + ":" + gid, fifoPathname).Output() - if err != nil { - log.Fatal("Couldn't change permissions of fifo with name ", fifoPathname, ": ", err.Error()) - } - - supervisorctlProgramName := "signal-cli-json-rpc-" + strconv.FormatInt(ctr, 10) - supervisorctlLogFolder := "/var/log/" + supervisorctlProgramName - _, err = exec.Command("mkdir", "-p", supervisorctlLogFolder).Output() - if err != nil { - log.Fatal("Couldn't create log folder ", supervisorctlLogFolder, ": ", err.Error()) - } - - log.Info("Found number ", number, " and added it to jsonrpc2.yml") - - //write supervisorctl config - supervisorctlConfigFilename := "/etc/supervisor/conf.d/" + "signal-cli-json-rpc-" + strconv.FormatInt(ctr, 10) + ".conf" - supervisorctlConfig := fmt.Sprintf(supervisorctlConfigTemplate, supervisorctlProgramName, supervisorctlProgramName, - tcpPort, fifoPathname, number, signalCliConfigDir, fifoPathname, supervisorctlProgramName, supervisorctlProgramName) - err = ioutil.WriteFile(supervisorctlConfigFilename, []byte(supervisorctlConfig), 0644) - if err != nil { - log.Fatal("Couldn't write ", supervisorctlConfigFilename, ": ", err.Error()) + log.Debug("Skipping ", filename, " as it is not a valid signal-cli config file: ", err.Error()) + continue } } else { log.Error("Skipping ", filename, " as it is not a valid phone number!") + continue + } + + fifoPathname := fifoBasePathName + strconv.FormatInt(ctr, 10) + tcpPort := tcpBasePort + ctr + jsonRpc2ClientConfig.AddEntry(number, utils.ConfigEntry{TcpPort: tcpPort, FifoPathname: fifoPathname}) + ctr += 1 + + os.Remove(fifoPathname) //remove any existing named pipe + + _, err = exec.Command("mkfifo", fifoPathname).Output() + if err != nil { + log.Fatal("Couldn't create fifo with name ", fifoPathname, ": ", err.Error()) + } + + uid := utils.GetEnv("SIGNAL_CLI_UID", "1000") + gid := utils.GetEnv("SIGNAL_CLI_GID", "1000") + _, err = exec.Command("chown", uid + ":" + gid, fifoPathname).Output() + if err != nil { + log.Fatal("Couldn't change permissions of fifo with name ", fifoPathname, ": ", err.Error()) + } + + supervisorctlProgramName := "signal-cli-json-rpc-" + strconv.FormatInt(ctr, 10) + supervisorctlLogFolder := "/var/log/" + supervisorctlProgramName + _, err = exec.Command("mkdir", "-p", supervisorctlLogFolder).Output() + if err != nil { + log.Fatal("Couldn't create log folder ", supervisorctlLogFolder, ": ", err.Error()) + } + + log.Info("Found number ", number, " and added it to jsonrpc2.yml") + + //write supervisorctl config + supervisorctlConfigFilename := "/etc/supervisor/conf.d/" + "signal-cli-json-rpc-" + strconv.FormatInt(ctr, 10) + ".conf" + supervisorctlConfig := fmt.Sprintf(supervisorctlConfigTemplate, supervisorctlProgramName, supervisorctlProgramName, + tcpPort, fifoPathname, number, signalCliConfigDir, fifoPathname, supervisorctlProgramName, supervisorctlProgramName) + err = ioutil.WriteFile(supervisorctlConfigFilename, []byte(supervisorctlConfig), 0644) + if err != nil { + log.Fatal("Couldn't write ", supervisorctlConfigFilename, ": ", err.Error()) } } }