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  }