add enviroment variable for golang beckend close #6
This commit is contained in:
1
backend/.gitignore
vendored
Normal file
1
backend/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.env
|
||||
59
backend/env/env.go
vendored
Normal file
59
backend/env/env.go
vendored
Normal file
@@ -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"
|
||||
}
|
||||
12
backend/example/example.env
Normal file
12
backend/example/example.env
Normal file
@@ -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
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
package models
|
||||
|
||||
// type Rights struct {
|
||||
// Name string `json:"name"`
|
||||
// Rights int `json:"rights"`
|
||||
// }
|
||||
@@ -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 != ""
|
||||
// }
|
||||
@@ -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"`
|
||||
// }
|
||||
@@ -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 != ""
|
||||
// }
|
||||
Reference in New Issue
Block a user