From 76269e73583a88b22824494cd770ef1d686a151f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Z=C3=BCrcher?= Date: Wed, 12 Nov 2025 12:16:27 +0100 Subject: [PATCH] add enviroment variable for golang beckend close #6 --- backend/.gitignore | 1 + backend/env/env.go | 59 +++++++++++++++++++++++++++++++++++++ backend/example/example.env | 12 ++++++++ backend/go.mod | 3 +- backend/go.sum | 6 ++-- backend/main.go | 56 ++++++++++++++++++++--------------- backend/models/rights.go | 6 ---- backend/models/role.go | 11 ------- backend/models/settings.go | 11 ------- backend/models/user.go | 14 --------- 10 files changed, 110 insertions(+), 69 deletions(-) create mode 100644 backend/.gitignore create mode 100644 backend/env/env.go create mode 100644 backend/example/example.env delete mode 100644 backend/models/rights.go delete mode 100644 backend/models/role.go delete mode 100644 backend/models/settings.go delete mode 100644 backend/models/user.go diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 0000000..2eea525 --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1 @@ +.env \ No newline at end of file diff --git a/backend/env/env.go b/backend/env/env.go new file mode 100644 index 0000000..71bc8f2 --- /dev/null +++ b/backend/env/env.go @@ -0,0 +1,59 @@ +package env + +import ( + "os" + "strconv" + "strings" + + "github.com/joho/godotenv" +) + +type EnvKey string + +const ( + Env EnvKey = "ENV" + GinMode EnvKey = "GIN_MODE" + Debug EnvKey = "DEBUG" + PrivKey EnvKey = "PRIVKEY" + Fullchain EnvKey = "FULLCHAIN" + Https EnvKey = "HTTPS" + Url EnvKey = "URL" + Port EnvKey = "PORT" + WorkingDir EnvKey = "WORKING_DIR" + Spa EnvKey = "SPA" + AccessSecret EnvKey = "ACCESS_SECRET" + RefreshSecret EnvKey = "REFRESH_SECRET" +) + +const ( + EnvDevelopment = "development" + EnvProduction = "Prodction" +) + +func (key EnvKey) GetValue() string { + return os.Getenv(string(key)) +} + +func (key EnvKey) GetBoolValue() bool { + return strings.ToLower(os.Getenv(string(key))) == "true" +} + +func (key EnvKey) GetUIntValue() uint { + value, err := strconv.ParseUint(os.Getenv(string(key)), 10, 32) + if err != nil { + return 0 + } + return uint(value) +} + +func Load(file string) error { + return godotenv.Load(file) +} + +func InDevelopmentMode() bool { + return Env.GetValue() == EnvDevelopment +} + +func InDebugMode() bool { + return strings.ToLower(Debug.GetValue()) == "true" +} diff --git a/backend/example/example.env b/backend/example/example.env new file mode 100644 index 0000000..9122264 --- /dev/null +++ b/backend/example/example.env @@ -0,0 +1,12 @@ +ENV=development +GIN_MODE=release +DEBUG=false +SPA=directory_of_spa_files +WORKING_DIR=. +URL=your_local_url +PORT=your_local_port +HTTPS=true +PRIVKEY=your_certificate_key_file +FULLCHAIN=your_certificate_fullchain_file +ACCESS_SECRET=your_32bit_long_access_secret +REFRESH_SECRET=your_32bit_long_referesh_secret \ No newline at end of file diff --git a/backend/go.mod b/backend/go.mod index 51cc4a2..2db0fba 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -3,12 +3,13 @@ module backend go 1.24.5 require ( - gitea.tecamino.com/paadi/access-handler v1.0.19 + gitea.tecamino.com/paadi/access-handler v1.0.22 gitea.tecamino.com/paadi/memberDB v1.1.2 gitea.tecamino.com/paadi/tecamino-dbm v0.1.1 gitea.tecamino.com/paadi/tecamino-logger v0.2.1 github.com/gin-contrib/cors v1.7.6 github.com/gin-gonic/gin v1.11.0 + github.com/joho/godotenv v1.5.1 golang.org/x/crypto v0.43.0 ) diff --git a/backend/go.sum b/backend/go.sum index 819237b..7f1085d 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -1,5 +1,5 @@ -gitea.tecamino.com/paadi/access-handler v1.0.19 h1:L51Qg5RNjdIGeQsHwGUTV+ADRpUqPt3qdnu7A7UQbsw= -gitea.tecamino.com/paadi/access-handler v1.0.19/go.mod h1:wKsB5/Rvaj580gdg3+GbUf5V/0N00XN6cID+C/8135M= +gitea.tecamino.com/paadi/access-handler v1.0.22 h1:XFi2PQ1gWqe9YuSye4Ti1o5TpdV0AFpt4Fb58MFMagk= +gitea.tecamino.com/paadi/access-handler v1.0.22/go.mod h1:wKsB5/Rvaj580gdg3+GbUf5V/0N00XN6cID+C/8135M= gitea.tecamino.com/paadi/dbHandler v1.0.8 h1:ZWSBM/KFtLwTv2cBqwK1mOxWAxAfL0BcWEC3kJ9JALU= gitea.tecamino.com/paadi/dbHandler v1.0.8/go.mod h1:y/xn/POJg1DO++67uKvnO23lJQgh+XFQq7HZCS9Getw= gitea.tecamino.com/paadi/memberDB v1.1.2 h1:j/Tsr7JnzAkdOvgjG77TzTVBWd4vBrmEFzPXNpW7GYk= @@ -56,6 +56,8 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= diff --git a/backend/main.go b/backend/main.go index 90aea6a..372a7c2 100644 --- a/backend/main.go +++ b/backend/main.go @@ -1,6 +1,7 @@ package main import ( + "backend/env" "backend/models" "backend/server" "backend/utils" @@ -27,20 +28,27 @@ func main() { flag.Var(&allowOrigins, "allowOrigin", "Allowed origin (can repeat this flag)") - spa := flag.String("spa", "./dist/spa", "quasar spa files") - workingDir := flag.String("workingDirectory", ".", "quasar spa files") - ip := flag.String("ip", "0.0.0.0", "server listening ip") + envFile := flag.String("env", ".env", "enviroment file") organization := flag.String("organization", "", "self signed ciertificate organization") - port := flag.Uint("port", 9500, "server listening port") - https := flag.Bool("https", false, "serves as https needs flag -cert and -chain") - sslKey := flag.String("privkey", "", "ssl private key path") - sslFullchain := flag.String("fullchain", "", "ssl fullchain path") - debug := flag.Bool("debug", false, "log debug") flag.Parse() + // load enviroment file if exists + if err := env.Load(*envFile); err != nil { + fmt.Println("no .env found path: ", *envFile) + } + + devMode := env.InDevelopmentMode() + // set gin mode + if !devMode { + gin.SetMode(env.GinMode.GetValue()) + } + + workingDir := env.WorkingDir.GetValue() + spa := env.Spa.GetValue() + //change working directory only if value is given - if *workingDir != "." && *workingDir != "" { - os.Chdir(*workingDir) + if workingDir != "." && workingDir != "" { + os.Chdir(workingDir) } wd, err := os.Getwd() @@ -55,7 +63,7 @@ func main() { MaxSize: 1, MaxBackup: 3, MaxAge: 28, - Debug: *debug, + Debug: env.InDebugMode(), TerminalOut: true, }) if err != nil { @@ -82,11 +90,11 @@ func main() { //get local ip httpString := "http://" - if *https { + if env.Https.GetBoolValue() { httpString = "https://" } - allowOrigins = append(allowOrigins, httpString+"localhost:9000", httpString+"localhost:9500", httpString+"127.0.0.1:9500", httpString+"0.0.0.0:9500") + allowOrigins = append(allowOrigins, httpString+"localhost:9000", httpString+"localhost:9500", httpString+"127.0.0.1:9000", httpString+"0.0.0.0:9500") localIP, err := utils.GetLocalIP() if err != nil { @@ -153,7 +161,7 @@ func main() { api.POST("/login/refresh", accessHandler.Refresh) // Serve static files - s.Routes.StaticFS("/assets", gin.Dir(filepath.Join(*spa, "assets"), true)) + s.Routes.StaticFS("/assets", gin.Dir(filepath.Join(spa, "assets"), true)) s.Routes.NoRoute(func(c *gin.Context) { // Disallow fallback for /api paths if strings.HasPrefix(c.Request.URL.Path, "/api") { @@ -161,44 +169,44 @@ func main() { return } // Try to serve file from SPA directory - filePath := filepath.Join(*spa, c.Request.URL.Path) + filePath := filepath.Join(spa, c.Request.URL.Path) if _, err := os.Stat(filePath); err == nil { c.File(filePath) return } // Fallback to index.html for SPA routing - c.File(filepath.Join(*spa, "index.html")) + c.File(filepath.Join(spa, "index.html")) }) go func() { time.Sleep(500 * time.Millisecond) - if err := utils.OpenBrowser(fmt.Sprintf("%slocalhost:%d", httpString, *port), logger); err != nil { + if err := utils.OpenBrowser(fmt.Sprintf("%slocalhost:%s", httpString, env.Port.GetValue()), logger); err != nil { logger.Error("main", fmt.Sprintf("starting browser error : %s", err)) } }() - if *https { - if *sslFullchain == "" { + if env.Https.GetBoolValue() { + if env.Fullchain.GetValue() == "" { logger.Error("ssl certificate", "-cert flag not given for https server") log.Fatal("-cert flag not given for https server") } - if *sslKey == "" { + if env.PrivKey.GetValue() == "" { logger.Error("ssl key", "-chain flag not given for https server") log.Fatal("-chain flag not given for https server") } // start https server - logger.Info("main", fmt.Sprintf("https listen on ip: %s port: %d", *ip, *port)) - if err := s.ServeHttps(*ip, *port, cert.Cert{Organization: *organization, CertFile: *sslFullchain, KeyFile: *sslKey}); err != nil { + logger.Info("main", fmt.Sprintf("https listen on ip: %s port: %s", env.Url.GetValue(), env.Port.GetValue())) + if err := s.ServeHttps(env.Url.GetValue(), env.Port.GetUIntValue(), cert.Cert{Organization: *organization, CertFile: env.Fullchain.GetValue(), KeyFile: env.PrivKey.GetValue()}); err != nil { logger.Error("main", "error https server "+err.Error()) } return } // start http server - logger.Info("main", fmt.Sprintf("http listen on ip: %s port: %d", *ip, *port)) - if err := s.ServeHttp(*ip, *port); err != nil { + logger.Info("main", fmt.Sprintf("http listen on ip: %s port: %s", env.Url.GetValue(), env.Port.GetValue())) + if err := s.ServeHttp(env.Url.GetValue(), env.Port.GetUIntValue()); err != nil { logger.Error("main", "error http server "+err.Error()) } } diff --git a/backend/models/rights.go b/backend/models/rights.go deleted file mode 100644 index e93beec..0000000 --- a/backend/models/rights.go +++ /dev/null @@ -1,6 +0,0 @@ -package models - -// type Rights struct { -// Name string `json:"name"` -// Rights int `json:"rights"` -// } diff --git a/backend/models/role.go b/backend/models/role.go deleted file mode 100644 index 728d71e..0000000 --- a/backend/models/role.go +++ /dev/null @@ -1,11 +0,0 @@ -package models - -// type Role struct { -// Id int `json:"id"` -// Role string `json:"role"` -// Rights []Rights `json:"rights"` -// } - -// func (r *Role) IsValid() bool { -// return r.Role != "" -// } diff --git a/backend/models/settings.go b/backend/models/settings.go deleted file mode 100644 index 36ce147..0000000 --- a/backend/models/settings.go +++ /dev/null @@ -1,11 +0,0 @@ -package models - -// type Settings struct { -// PrimaryColor string `json:"primaryColor,omitempty"` -// PrimaryColorText string `json:"primaryColorText,omitempty"` -// SecondaryColor string `json:"secondaryColor,omitempty"` -// SecondaryColorText string `json:"secondaryColorText,omitempty"` -// Icon string `json:"icon,omitempty"` -// DatabaseName string `json:"databaseName,omitempty"` -// DatabaseToken string `json:"databaseToken,omitempty"` -// } diff --git a/backend/models/user.go b/backend/models/user.go deleted file mode 100644 index c09281a..0000000 --- a/backend/models/user.go +++ /dev/null @@ -1,14 +0,0 @@ -package models - -// type User struct { -// Id int `json:"id"` -// Name string `json:"user"` -// Email string `json:"email"` -// Role string `json:"role"` -// Password string `json:"password,omitempty"` -// Settings Settings `json:"settings"` -// } - -// func (u *User) IsValid() bool { -// return u.Name != "" -// }