diff --git a/args/args.go b/args/args.go index 5403154..a859ea2 100644 --- a/args/args.go +++ b/args/args.go @@ -3,21 +3,13 @@ package args /* This file manages declaration of, parsing of, and returning copies of command line arguments. */ -import ( - "flag" - "os" -) +import "flag" /* Method to trigger flag parsing. Can be called multiple times safely. */ func Parse() { if (flagsParsed) {return} flag.Parse(); flagsParsed = true; - - // Process DBUS socket location - if socketLocation == nil || *socketLocation == "" { - *socketLocation = os.Getenv("DBUS_SYSTEM_BUS_ADDRESS"); - } } /* module-specific variable to avoid re-parsing flags */ var flagsParsed bool = false; @@ -28,28 +20,4 @@ var confLocation = flag.String("conf", "./config.txt", "Config file to read from func GetConfLocation() (location string, set bool) { if confLocation == nil {return "", false} return *confLocation, true; -} - -/* TCP port to bind to */ -var httpPort = flag.Int("port", 11938, "Port number to bind to") -/* @return set boolean will be true if argument is not nil */ -func GetHTTPPort() (port int, set bool) { - if httpPort == nil {return -1, false} - return *httpPort, true; -} - -/* Listen on a UNIX socket */ -var socketLocation = flag.String("socket", "", "Location of UNIX socket to listen on. Setting will disable TCP.") -/* @return set boolean will be true if argument is not nil */ -func GetSocketLocation() (port string, set bool) { - if socketLocation == nil {return "", false} - return *socketLocation, true; -} - -/* Where the signal-cli binary is */ -var binaryLocation = flag.String("binary", "/usr/local/bin/signal-cli", "Location of the signal-cli binary.") -/* @return set boolean will be true if argument is not nil */ -func GetBinaryLocation() (port string, set bool) { - if binaryLocation == nil {return "", false} - return *binaryLocation, true; } \ No newline at end of file diff --git a/conf/conf.go b/conf/conf.go index fb81fb7..5356b37 100644 --- a/conf/conf.go +++ b/conf/conf.go @@ -10,14 +10,13 @@ import ( "strings" ) +// import "fmt" + /* Object to handle what is in a JSON config */ type Config struct { configData map[string][]string; } -/* Default Config object */ -var GlobalConfig * Config; - /* Opens and reads a file at the path */ func NewConfig(filePath string) (newConfig *Config, err error) { // Open file @@ -31,7 +30,8 @@ func NewConfig(filePath string) (newConfig *Config, err error) { // Read lines into newConfigData scanner := bufio.NewScanner(file) for scanner.Scan() { - parts := strings.SplitN(scanner.Text(), " ", 2); + line := scanner.Text() + parts := strings.SplitN(line, " ", 2); if len(parts) != 2 {err = errors.New("Bad config file!"); return;} newConfigData[parts[0]] = append(newConfigData[parts[0]], parts[1]); } @@ -41,21 +41,4 @@ func NewConfig(filePath string) (newConfig *Config, err error) { } /* Gets a reference copy to the config data */ -func (config * Config) GetConfigData() map[string][]string { - return config.configData; -} - -/* Returns if a bearer key is authorized for the path in this Config object - @return false for any situation that isn't a valid match */ -func (config * Config) ValidateBearerKey(bearerKey string, request string) bool { - paths, exists := config.configData[bearerKey]; - if !exists {return false} - - for _, matchTo := range paths { - if match(request, matchTo) { - return true; - } - } - - return false; -} \ No newline at end of file +func (config Config) GetConfigData() map[string][]string {return config.configData;} \ No newline at end of file diff --git a/conf/regex.go b/conf/regex.go index 32524df..4a1fb0a 100644 --- a/conf/regex.go +++ b/conf/regex.go @@ -13,8 +13,16 @@ func splitPath(path string) []string { /* Attempts to match a request path to a set of whitelisted paths @return false for anything other than a valid match */ -func match(request string, matchTo string) bool { - return matchSegments(splitPath(request), splitPath(matchTo)); +func match(request string, matchTo []string) bool { + requestSplit := splitPath(request) + for _, matchToAttempt := range matchTo { + matchToAttemptSplit := splitPath(matchToAttempt); + if matchSegments(requestSplit, matchToAttemptSplit) { + return true; + } + } + + return false; } /* Returns false for anything other than a valid match */ diff --git a/http/listen.go b/http/listen.go deleted file mode 100644 index 1a0934e..0000000 --- a/http/listen.go +++ /dev/null @@ -1,64 +0,0 @@ -package http - -/* This file handles listening to HTTP requests */ - -import ( - "signal-cli-http/conf" - "signal-cli-http/subprocess" - - "fmt" - "io" - "log" - "net/http" -) - -func StartWebserver(port int) { - http.HandleFunc("/", getRoot) - - err := http.ListenAndServe(":"+fmt.Sprint(port), nil) - fmt.Println(err) -} - -func getRoot(w http.ResponseWriter, r *http.Request) { - // Check that Authentication header exists - authArr, ok := r.Header["Authentication"] - if (!ok) || (len(authArr) == 0) { - w.WriteHeader(400); - w.Write([]byte("Authentication header missing\n")) - return; - } - bearer := authArr[0]; - - // Check that the request is allowed for the path - if !conf.GlobalConfig.ValidateBearerKey(bearer, r.URL.Path) { - w.WriteHeader(403); - w.Write([]byte("Bearer key not whitelisted for this path\n")) - return; - } - - // OK authentication wise - - body, err := io.ReadAll(r.Body) - if err != nil { - w.WriteHeader(500); - w.Write([]byte("Error reading body\n")) - return; - } - - // Call subprocess - status, bodyContent, err := subprocess.Run(r.URL.Path, body) - - // Error - if err != nil { - w.WriteHeader(500); - w.Write([]byte("Internal server error: " + err.Error() + "\n")); - return - } - - // Respond to client with status - w.WriteHeader(status); - w.Write(bodyContent); - - // Log the request - log.Default().Print("HTTP Request: ", bearer, " " , r.URL.Path, " ", status) -} \ No newline at end of file diff --git a/main.go b/main.go index 006eec7..1e18720 100644 --- a/main.go +++ b/main.go @@ -5,8 +5,8 @@ package main import ( "signal-cli-http/args" "signal-cli-http/conf" - "signal-cli-http/http" - + + "fmt" "log" ) @@ -14,14 +14,11 @@ func main() { // Read arguments args.Parse(); configLocation, confLocationSet := args.GetConfLocation(); - if !confLocationSet {log.Default().Print("No config value!"); return} + if !confLocationSet {log.Default().Print("No config value!"); return;} log.Default().Print("Reading config value from ", configLocation); // Set up config - conf.GlobalConfig, _ = conf.NewConfig(configLocation); - if conf.GlobalConfig == nil {log.Default().Print("Error reading config"); return} - - port, portSet := args.GetHTTPPort(); - if !portSet {log.Default().Print("No port value!"); return;} - http.StartWebserver(port) + config, err := conf.NewConfig(configLocation); + if err != nil {log.Default().Print("Error reading config: ", err); return;} + fmt.Println(config.GetConfigData()) } \ No newline at end of file diff --git a/readme.md b/readme.md index 36814b9..ace0a89 100644 --- a/readme.md +++ b/readme.md @@ -7,9 +7,4 @@ Very simple HTTP frontend to [signal-cli](https://github.com/AsamK/signal-cli). Please also read the following README files for the individual modules: * [args](args/readme.md) - handles command line arguments. -* [conf](conf/readme.md) - handles the config file. - -Too be implemented: - -* subprocess - handles running the binaries which communicate with the daemon. -* web - handles the incoming http requests. \ No newline at end of file +* [conf](conf/readme.md) - handles the config file. \ No newline at end of file diff --git a/subprocess/command.go b/subprocess/command.go deleted file mode 100644 index 2b53020..0000000 --- a/subprocess/command.go +++ /dev/null @@ -1,21 +0,0 @@ -package subprocess - -/* This file manages creating the command line arguments to the subprocess */ - -/* Method which module http calls to create the subprocess */ -func Run(path string, body []byte) (status int, bodyContents []byte, err error) { - arguments := getArguments(path, body); - - // Don't know what to do with this request - if arguments == nil {return 404, []byte("Unknown request\n"), nil;} - - // Call subprocess - status, bodyContents, err = runCommand(arguments); - - return -} - -/* Converts a request into the correct binary arguments */ -func getArguments(path string, body []byte) []string { - return nil // For now -} \ No newline at end of file diff --git a/subprocess/subprocess.go b/subprocess/subprocess.go deleted file mode 100644 index a1ea05f..0000000 --- a/subprocess/subprocess.go +++ /dev/null @@ -1,44 +0,0 @@ -package subprocess - -import ( - "signal-cli-http/args" - - "errors" - "os/exec" - "strings" -) - -/* This file manages calling signal-cli */ - -/* Runs the command */ -func runCommand(arguments []string) (returnStatus int, bodyContent []byte, err error) { - // Get binary location - binary, ok := args.GetBinaryLocation(); - if !ok { - err = errors.New("Binary cannot be found!"); - return; - } - - // Create command using binary location and arguments - command := exec.Command(binary, strings.Join(arguments, " ")); - - // Duplicate pointer into command.Stdout - //command.Stdout = &bodyContent; - - // Run the command - err = command.Run(); - if err != nil {return} - - // Extract exit code if possible - if exitError, ok := err.(*exec.ExitError); ok { - returnStatus = exitError.ExitCode(); - } else { - err = errors.New("Cannot get exit code!"); - } - - // Get output - bodyContent, err = command.Output(); - - // Named return values allow this - return; -} \ No newline at end of file