ecodash/config.go
2022-10-15 19:58:44 +02:00

110 lines
2.7 KiB
Go

package main
import (
"crypto/sha256"
"encoding/json"
"errors"
"fmt"
"github.com/gofiber/fiber/v2"
"os"
"regexp"
"strings"
)
type Config struct {
HomeAssistant HomeAssistant `json:"home_assistant"`
Sensors Sensors `json:"sensors"`
Administrator Administrator `json:"administrator"`
Dashboard Dashboard `json:"dashboard"`
}
type HomeAssistant struct {
BaseURL string `json:"base_url"`
ApiKey string `json:"api_key"`
}
type Sensors struct {
PolledSmartEnergySummation string `json:"polled_smart_energy_summation"`
FossilPercentage string `json:"fossil_percentage"`
}
type Administrator struct {
Username string `json:"username"`
PasswordHash string `json:"password_hash"`
}
type Dashboard struct {
Name string `json:"name"`
Theme string `json:"theme"`
FooterLinks []Link `json:"footer_links"`
HeaderLinks []Link `json:"header_links"`
}
func formatURL(url string) (string, error) {
// the URL we want is: protocol://hostname[:port] without a final /
if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
url = "http://" + url
}
if strings.HasSuffix(url, "/") {
url = url[0 : len(url)-1]
}
test := regexp.MustCompile(`(?m)https?:\/\/[^/]*`).ReplaceAllString(url, "")
if test != "" {
return "", errors.New("HomeAssistant base URL is badly formatted")
}
return url, nil
}
func loadConfig() (config Config, err error, isFirstRun bool) {
var defaultConfig = Config{}
defaultConfig.Dashboard.Theme = "default"
defaultConfig.Dashboard.Name = "EcoDash"
defaultConfig.Dashboard.HeaderLinks = append(defaultConfig.Dashboard.HeaderLinks, Link{
Label: "Admin",
Destination: "/admin",
}, Link{
Label: "Docs",
Destination: "https://gitea.massivebox.net/massivebox/ecodash",
NewTab: true,
Primary: true,
})
data, err := os.ReadFile("config.json")
if err != nil {
// if the data file doesn't exist, we consider it a first run
if os.IsNotExist(err) {
return defaultConfig, nil, true
}
return Config{}, err, false
}
// if the data file is empty, we consider it as a first run
if string(data) == "" {
return defaultConfig, nil, true
}
var conf Config
err = json.Unmarshal(data, &conf)
if err != nil {
return Config{}, err, false
}
return conf, nil, false
}
// just a little utility function to SHA256 strings (for hashing passwords)
func hash(toHash string) string {
return fmt.Sprintf("%x", sha256.Sum256([]byte(toHash)))
}
func (config Config) isAuthorized(c *fiber.Ctx) bool {
if config.Administrator.PasswordHash == "" {
return true
}
return c.Cookies("admin_username") == config.Administrator.Username && c.Cookies("admin_password_hash") == config.Administrator.PasswordHash
}