Re-work loading of configuration, introduce a loader for start up & and custom logging wrapper.
This commit is contained in:
30
bootstrap/loader.go
Normal file
30
bootstrap/loader.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"synlotto-website/models"
|
||||
)
|
||||
|
||||
type AppState struct {
|
||||
Config *models.Config
|
||||
}
|
||||
|
||||
func LoadAppState(configPath string) (*AppState, error) {
|
||||
file, err := os.Open(configPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("open config: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var config models.Config
|
||||
if err := json.NewDecoder(file).Decode(&config); err != nil {
|
||||
return nil, fmt.Errorf("decode config: %w", err)
|
||||
}
|
||||
|
||||
return &AppState{
|
||||
Config: &config,
|
||||
}, nil
|
||||
}
|
||||
22
config/config.go
Normal file
22
config/config.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"synlotto-website/models"
|
||||
)
|
||||
|
||||
var (
|
||||
appConfig *models.Config
|
||||
once sync.Once
|
||||
)
|
||||
|
||||
func Init(config *models.Config) {
|
||||
once.Do(func() {
|
||||
appConfig = config
|
||||
})
|
||||
}
|
||||
|
||||
func Get() *models.Config {
|
||||
return appConfig
|
||||
}
|
||||
24
logging/config.go
Normal file
24
logging/config.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package logging
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
|
||||
"synlotto-website/models"
|
||||
)
|
||||
|
||||
func LogConfig(config *models.Config) {
|
||||
safeConfig := *config
|
||||
safeConfig.CSRF.CSRFKey = "[REDACTED]"
|
||||
safeConfig.Session.SessionAuthKey = "[REDACTED]"
|
||||
safeConfig.Session.SessionEncryptionKey = "[REDACTED]"
|
||||
|
||||
cfg, err := json.MarshalIndent(safeConfig, "", " ")
|
||||
if err != nil {
|
||||
log.Println("Failed to log config:", err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Println("App starting with config:")
|
||||
log.Println(string(cfg))
|
||||
}
|
||||
13
logging/messages.go
Normal file
13
logging/messages.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package logging
|
||||
|
||||
import (
|
||||
"log"
|
||||
)
|
||||
|
||||
func Info(msg string, args ...any) {
|
||||
log.Printf("[INFO] "+msg, args...)
|
||||
}
|
||||
|
||||
func Error(msg string, args ...any) {
|
||||
log.Printf("[ERROR] "+msg, args...)
|
||||
}
|
||||
14
main.go
14
main.go
@@ -3,8 +3,11 @@ package main
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"synlotto-website/bootstrap"
|
||||
"synlotto-website/config"
|
||||
"synlotto-website/handlers"
|
||||
"synlotto-website/helpers"
|
||||
"synlotto-website/logging"
|
||||
"synlotto-website/middleware"
|
||||
"synlotto-website/models"
|
||||
"synlotto-website/routes"
|
||||
@@ -14,11 +17,16 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
appState, err := bootstrap.LoadAppState("config/config.json")
|
||||
if err != nil {
|
||||
logging.Error("Failed to load app state: %v", err)
|
||||
}
|
||||
config.Init(appState.Config)
|
||||
logging.LogConfig(appState.Config)
|
||||
|
||||
db := storage.InitDB("synlotto.db")
|
||||
models.SetDB(db) // Should be in storage not models.
|
||||
|
||||
var isProduction = false
|
||||
|
||||
csrfMiddleware := csrf.Protect(
|
||||
[]byte("abcdefghijklmnopqrstuvwx12345678"), // TodO: Make Global
|
||||
csrf.Secure(true),
|
||||
@@ -35,7 +43,7 @@ func main() {
|
||||
mux.HandleFunc("/", handlers.Home(db))
|
||||
|
||||
wrapped := helpers.RateLimit(csrfMiddleware(mux))
|
||||
wrapped = middleware.EnforceHTTPS(wrapped, isProduction)
|
||||
wrapped = middleware.EnforceHTTPS(wrapped, appState.Config.HttpServer.ProductionMode)
|
||||
wrapped = middleware.SecureHeaders(wrapped)
|
||||
wrapped = middleware.Recover(wrapped)
|
||||
|
||||
|
||||
19
models/config.go
Normal file
19
models/config.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package models
|
||||
|
||||
type Config struct {
|
||||
HttpServer struct {
|
||||
Port int `json:"port"`
|
||||
Address string `json:"address"`
|
||||
ProductionMode bool `json:"productionMode"`
|
||||
} `json:"httpServer"`
|
||||
|
||||
CSRF struct {
|
||||
CSRFKey string `json:"csrfKey"`
|
||||
} `json:"csrf"`
|
||||
|
||||
Session struct {
|
||||
SessionAuthKey string `json:"authKey"`
|
||||
SessionEncryptionKey string `json:"encryptionKey"`
|
||||
SessionName string `json:"sessionName"`
|
||||
} `json:"session"`
|
||||
}
|
||||
Reference in New Issue
Block a user