From 5f9930988d864259ea3666f1da392309ad1da834 Mon Sep 17 00:00:00 2001 From: Rene Date: Tue, 27 Sep 2022 17:15:22 -0600 Subject: [PATCH] feature/25 :: Added basic auth to webUI --- README.md | 1 + src/getconfig.go | 8 +++--- src/main.go | 69 ++++++++++++++++++++++++------------------------ src/web-index.go | 51 ++++++++++++++++++++++++----------- 4 files changed, 77 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index cd1822a..639c6df 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ Configuration can be done through config file or environment variables | DBPATH | Path to Database | /data/db.sqlite | | GUIIP | Address for web GUI | localhost (127.0.0.1) | | GUIPORT | Port for web GUI | 8840 | +| GUIAUTH | Basic auth credentials for web GUI, e.g.: GUIAUTH=user:pass | (empty - no auth) | | TIMEOUT | Time between scans (seconds) | 60 (1 minute) | | SHOUTRRR_URL | Url to any notification service supported by [Shoutrrr](https://github.com/containrrr/shoutrrr/tree/main/docs/services) (gotify, email, telegram and others) | "" | | THEME | Any theme name from https://bootswatch.com in lowcase | solar | diff --git a/src/getconfig.go b/src/getconfig.go index cb80354..526b341 100644 --- a/src/getconfig.go +++ b/src/getconfig.go @@ -11,13 +11,14 @@ func get_config() (config Conf) { viper.SetDefault("DBPATH", "/data/db.sqlite") viper.SetDefault("GUIIP", "localhost") viper.SetDefault("GUIPORT", "8840") + viper.SetDefault("GUIAUTH", "") viper.SetDefault("TIMEOUT", "60") viper.SetDefault("SHOUTRRR_URL", "") viper.SetDefault("THEME", "solar") - viper.SetConfigFile(configPath) + viper.SetConfigFile(configPath) viper.SetConfigType("env") - viper.ReadInConfig() + viper.ReadInConfig() viper.AutomaticEnv() // Get ENVIRONMENT variables @@ -25,6 +26,7 @@ func get_config() (config Conf) { config.DbPath = viper.Get("DBPATH").(string) config.GuiIP = viper.Get("GUIIP").(string) config.GuiPort = viper.Get("GUIPORT").(string) + config.GuiAuth = viper.Get("GUIAUTH").(string) config.Timeout = viper.GetInt("TIMEOUT") config.ShoutUrl = viper.Get("SHOUTRRR_URL").(string) config.Theme = viper.Get("THEME").(string) @@ -37,4 +39,4 @@ func write_config() { viper.SetConfigType("env") viper.Set("THEME", AppConfig.Theme) viper.WriteConfig() -} \ No newline at end of file +} diff --git a/src/main.go b/src/main.go index e64c974..cac36a9 100644 --- a/src/main.go +++ b/src/main.go @@ -1,54 +1,55 @@ package main import ( - "time" + "time" ) type Host struct { - Id uint16 - Name string - Ip string - Mac string - Hw string - Date string - Known uint16 - Now uint16 + Id uint16 + Name string + Ip string + Mac string + Hw string + Date string + Known uint16 + Now uint16 } type Conf struct { - Iface string - DbPath string - GuiIP string - GuiPort string - Timeout int - ShoutUrl string - Theme string + Iface string + DbPath string + GuiIP string + GuiPort string + GuiAuth string + ShoutUrl string + Theme string + Timeout int } var AppConfig Conf var AllHosts []Host func scan_and_compare() { - var foundHosts []Host - var dbHosts []Host - for { // Endless - foundHosts = arp_scan() // Scan interfaces - dbHosts = db_select() // Select everything from DB - db_setnow() // Mark hosts in DB as offline - hosts_compare(foundHosts, dbHosts) // Compare hosts online and in DB - // and add them to DB - AllHosts = db_select() - time.Sleep(time.Duration(AppConfig.Timeout) * time.Second) // Timeout - } + var foundHosts []Host + var dbHosts []Host + for { // Endless + foundHosts = arp_scan() // Scan interfaces + dbHosts = db_select() // Select everything from DB + db_setnow() // Mark hosts in DB as offline + hosts_compare(foundHosts, dbHosts) // Compare hosts online and in DB + // and add them to DB + AllHosts = db_select() + time.Sleep(time.Duration(AppConfig.Timeout) * time.Second) // Timeout + } } func main() { - AllHosts = []Host{} - AppConfig = get_config() // Get config from Defaults, Config file, Env + AllHosts = []Host{} + AppConfig = get_config() // Get config from Defaults, Config file, Env - db_create() // Check if DB exists. Create if not - - go scan_and_compare() + db_create() // Check if DB exists. Create if not - webgui() // Start web GUI -} \ No newline at end of file + go scan_and_compare() + + webgui() // Start web GUI +} diff --git a/src/web-index.go b/src/web-index.go index e026ada..7ffad97 100644 --- a/src/web-index.go +++ b/src/web-index.go @@ -1,17 +1,17 @@ package main import ( - "fmt" - "log" - "net/http" - "html/template" - "strconv" + "fmt" + "html/template" + "log" + "net/http" + "strconv" ) func index(w http.ResponseWriter, r *http.Request) { type allData struct { Config Conf - Hosts []Host + Hosts []Host } var guiData allData guiData.Config = AppConfig @@ -48,6 +48,27 @@ func update_host(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, r.Header.Get("Referer"), 302) } +func basicAuth(next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + if AppConfig.GuiAuth == "" { + next.ServeHTTP(w, r) + return + } + + username, password, ok := r.BasicAuth() + if ok { + userCredentials := fmt.Sprintf(`%s:%s`, username, password) + if userCredentials == AppConfig.GuiAuth { + next.ServeHTTP(w, r) + return + } + } + + w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`) + http.Error(w, "Unauthorized", http.StatusUnauthorized) + } +} + func webgui() { // fmt.Println(FoundHosts) address := AppConfig.GuiIP + ":" + AppConfig.GuiPort @@ -56,13 +77,13 @@ func webgui() { log.Println(fmt.Sprintf("Web GUI at http://%s", address)) log.Println("=================================== ") - http.HandleFunc("/", index) - http.HandleFunc("/home/", home) - http.HandleFunc("/offline/", offline) - http.HandleFunc("/online/", online) - http.HandleFunc("/search_hosts/", search_hosts) - http.HandleFunc("/sort_hosts/", sort_hosts) - http.HandleFunc("/theme/", theme) - http.HandleFunc("/update_host/", update_host) + http.HandleFunc("/", basicAuth(index)) + http.HandleFunc("/home/", basicAuth(home)) + http.HandleFunc("/offline/", basicAuth(offline)) + http.HandleFunc("/online/", basicAuth(online)) + http.HandleFunc("/search_hosts/", basicAuth(search_hosts)) + http.HandleFunc("/sort_hosts/", basicAuth(sort_hosts)) + http.HandleFunc("/theme/", basicAuth(theme)) + http.HandleFunc("/update_host/", basicAuth(update_host)) http.ListenAndServe(address, nil) -} \ No newline at end of file +}