github.com/ngocphuongnb/tetua@v0.0.7-alpha/app/config/config.go (about) 1 package config 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "io/ioutil" 8 mathrand "math/rand" 9 "os" 10 "path" 11 "path/filepath" 12 "runtime" 13 "strings" 14 15 "github.com/ngocphuongnb/tetua/app/fs" 16 ) 17 18 type SmtpConfig struct { 19 Secure bool `json:"secure"` 20 Host string `json:"host"` 21 Port int `json:"port"` 22 User string `json:"user"` 23 Pass string `json:"pass"` 24 } 25 26 type MailConfig struct { 27 Sender string `json:"sender"` 28 Smtp *SmtpConfig `json:"smtp"` 29 } 30 31 type AuthConfig struct { 32 EnabledProviders []string `json:"enabled_providers"` 33 Providers map[string]map[string]string `json:"providers"` 34 } 35 36 type ConfigFile struct { 37 APP_ENV string `json:"app_env"` 38 APP_KEY string `json:"app_key"` 39 APP_TOKEN_KEY string `json:"app_token_key,omitempty"` 40 APP_PORT string `json:"app_port"` 41 APP_THEME string `json:"app_theme,omitempty"` 42 DB_DSN string `json:"db_dsn"` 43 COOKIE_UUID string `json:"cookie_uuid,omitempty"` 44 SHOW_TETUA_BLOCK bool `json:"show_tetua_block,omitempty"` 45 DB_QUERY_LOGGING bool `json:"db_query_logging"` 46 STORAGES *fs.StorageConfig `json:"storage,omitempty"` 47 Mail *MailConfig `json:"mail,omitempty"` 48 Auth *AuthConfig `json:"auth,omitempty"` 49 } 50 51 var ( 52 WD = "." 53 DEVELOPMENT = false 54 APP_VERSION = "0.0.1" 55 STORAGES = &fs.StorageConfig{} 56 APP_ENV = "" 57 APP_KEY = "" 58 APP_TOKEN_KEY = "token" 59 APP_PORT = "3000" 60 APP_THEME = "default" 61 DB_DSN = "" 62 DB_QUERY_LOGGING = false 63 ROOT_DIR = "" 64 PUBLIC_DIR = "public" 65 PRIVATE_DIR = "private" 66 COOKIE_UUID = "uuid" 67 SHOW_TETUA_BLOCK = false 68 ) 69 70 var Mail *MailConfig 71 var Auth *AuthConfig 72 73 func ConfigError(name string) { 74 panic(fmt.Sprintf( 75 "%s is not set, please set it in config.json or setting the environment variable.\n", 76 name, 77 )) 78 } 79 80 func Init(workingDir string) { 81 WD = workingDir 82 PUBLIC_DIR = path.Join(WD, "public") 83 PRIVATE_DIR = path.Join(WD, "private") 84 85 parseConfigFile() 86 parseENV() 87 DEVELOPMENT = APP_ENV == "development" 88 89 if DEVELOPMENT { 90 _, mainFile, _, _ := runtime.Caller(2) 91 ROOT_DIR = filepath.Dir(mainFile) 92 } 93 94 if APP_KEY == "" { 95 ConfigError("APP_KEY") 96 } 97 98 if DB_DSN == "" { 99 ConfigError("DB_DSN") 100 } 101 } 102 103 func CreateConfigFile(workingDir string) (err error) { 104 configFile := path.Join(workingDir, "config.json") 105 106 if _, err := os.Stat(configFile); err == nil { 107 fmt.Println("config.json already exists", configFile) 108 return nil 109 } 110 111 cfg := &ConfigFile{} 112 cfg.APP_ENV = "production" 113 cfg.SHOW_TETUA_BLOCK = false 114 cfg.APP_PORT = APP_PORT 115 116 letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") 117 randBytes := make([]rune, 32) 118 119 for i := range randBytes { 120 randBytes[i] = letters[mathrand.Intn(len(letters))] 121 } 122 123 cfg.APP_KEY = string(randBytes) 124 125 file, err := json.MarshalIndent(cfg, "", " ") 126 if err != nil { 127 return err 128 } 129 130 if err = ioutil.WriteFile(configFile, file, 0644); err != nil { 131 return err 132 } 133 134 fmt.Println("Config file created at", configFile) 135 136 return nil 137 } 138 139 func parseConfigFile() { 140 configFile := path.Join(WD, "config.json") 141 cfg := &ConfigFile{} 142 143 if _, err := os.Stat(configFile); !errors.Is(err, os.ErrNotExist) { 144 file, _ := ioutil.ReadFile(configFile) 145 146 if err := json.Unmarshal([]byte(file), cfg); err != nil { 147 panic(err) 148 } 149 150 Mail = cfg.Mail 151 Auth = cfg.Auth 152 153 if cfg.APP_ENV != "" { 154 APP_ENV = cfg.APP_ENV 155 } 156 157 if cfg.APP_PORT != "" { 158 APP_PORT = cfg.APP_PORT 159 } 160 161 if cfg.DB_DSN != "" { 162 DB_DSN = cfg.DB_DSN 163 } 164 165 if cfg.APP_KEY != "" { 166 APP_KEY = cfg.APP_KEY 167 } 168 169 if cfg.APP_TOKEN_KEY != "" { 170 APP_TOKEN_KEY = cfg.APP_TOKEN_KEY 171 } 172 173 if cfg.APP_THEME != "" { 174 APP_THEME = cfg.APP_THEME 175 } 176 177 if cfg.COOKIE_UUID != "" { 178 COOKIE_UUID = cfg.COOKIE_UUID 179 } 180 181 SHOW_TETUA_BLOCK = cfg.SHOW_TETUA_BLOCK 182 DB_QUERY_LOGGING = cfg.DB_QUERY_LOGGING 183 STORAGES = &fs.StorageConfig{ 184 DefaultDisk: "local_public", 185 DiskConfigs: []*fs.DiskConfig{{ 186 Name: "local_public", 187 Driver: "local", 188 Root: path.Join(PUBLIC_DIR, "files"), 189 BaseUrlFn: func() string { 190 return Setting("file_base_url") + "/files" 191 }, 192 }, { 193 Name: "local_private", 194 Driver: "local", 195 Root: path.Join(PRIVATE_DIR, "storage"), 196 }}, 197 } 198 199 if cfg.STORAGES != nil { 200 if cfg.STORAGES.DefaultDisk != "" { 201 STORAGES.DefaultDisk = cfg.STORAGES.DefaultDisk 202 } 203 204 if cfg.STORAGES.DiskConfigs != nil && len(cfg.STORAGES.DiskConfigs) > 0 { 205 for _, disk := range cfg.STORAGES.DiskConfigs { 206 diskExisted := false 207 for _, currentDisk := range STORAGES.DiskConfigs { 208 if currentDisk.Name == disk.Name { 209 diskExisted = true 210 break 211 } 212 } 213 214 if !diskExisted { 215 STORAGES.DiskConfigs = append(STORAGES.DiskConfigs, disk) 216 } 217 } 218 } 219 } 220 } 221 } 222 223 func parseENV() { 224 if os.Getenv("APP_ENV") != "" { 225 APP_ENV = os.Getenv("APP_ENV") 226 } 227 228 if os.Getenv("APP_PORT") != "" { 229 APP_PORT = os.Getenv("APP_PORT") 230 } 231 232 if os.Getenv("DB_DSN") != "" { 233 DB_DSN = os.Getenv("DB_DSN") 234 } 235 236 if os.Getenv("APP_KEY") != "" { 237 APP_KEY = os.Getenv("APP_KEY") 238 } 239 240 if os.Getenv("APP_TOKEN_KEY") != "" { 241 APP_TOKEN_KEY = os.Getenv("APP_TOKEN_KEY") 242 } 243 244 if os.Getenv("APP_THEME") != "" { 245 APP_THEME = os.Getenv("APP_THEME") 246 } 247 248 if os.Getenv("COOKIE_UUID") != "" { 249 COOKIE_UUID = os.Getenv("COOKIE_UUID") 250 } 251 252 if os.Getenv("DB_QUERY_LOGGING") != "" { 253 DB_QUERY_LOGGING = strings.ToLower(os.Getenv("DB_QUERY_LOGGING")) == "true" 254 } 255 256 if os.Getenv("SHOW_TETUA_BLOCK") != "" { 257 SHOW_TETUA_BLOCK = strings.ToLower(os.Getenv("SHOW_TETUA_BLOCK")) == "true" 258 } 259 }