2020-09-29 19:55:07 +03:00
|
|
|
|
package config
|
2019-05-05 23:36:49 +03:00
|
|
|
|
|
2020-05-24 18:32:26 +03:00
|
|
|
|
import (
|
|
|
|
|
"encoding/json"
|
2020-10-04 11:37:38 +03:00
|
|
|
|
"flag"
|
2020-11-01 22:14:10 +03:00
|
|
|
|
"fmt"
|
2021-04-16 13:24:19 +03:00
|
|
|
|
"io/ioutil"
|
2021-04-11 13:42:43 +03:00
|
|
|
|
"net/http"
|
|
|
|
|
"os"
|
|
|
|
|
"strings"
|
2021-04-30 15:07:14 +03:00
|
|
|
|
"time"
|
2021-04-11 13:42:43 +03:00
|
|
|
|
|
2021-01-30 13:17:37 +03:00
|
|
|
|
"github.com/emvi/logbuch"
|
2020-05-24 18:32:26 +03:00
|
|
|
|
"github.com/gorilla/securecookie"
|
2020-10-04 11:37:38 +03:00
|
|
|
|
"github.com/jinzhu/configor"
|
2021-04-11 13:42:43 +03:00
|
|
|
|
"github.com/muety/wakapi/data"
|
2020-09-29 19:55:07 +03:00
|
|
|
|
"github.com/muety/wakapi/models"
|
2020-11-01 22:14:10 +03:00
|
|
|
|
"gorm.io/gorm"
|
2020-05-24 18:32:26 +03:00
|
|
|
|
)
|
|
|
|
|
|
2020-10-04 12:14:44 +03:00
|
|
|
|
const (
|
2021-02-03 00:52:13 +03:00
|
|
|
|
defaultConfigPath = "config.yml"
|
2020-11-06 19:20:26 +03:00
|
|
|
|
|
|
|
|
|
SQLDialectMysql = "mysql"
|
|
|
|
|
SQLDialectPostgres = "postgres"
|
|
|
|
|
SQLDialectSqlite = "sqlite3"
|
2021-01-17 11:24:09 +03:00
|
|
|
|
|
|
|
|
|
KeyLatestTotalTime = "latest_total_time"
|
|
|
|
|
KeyLatestTotalUsers = "latest_total_users"
|
2021-02-05 20:47:28 +03:00
|
|
|
|
KeyLastImportImport = "last_import"
|
2021-02-12 21:25:59 +03:00
|
|
|
|
|
|
|
|
|
SimpleDateFormat = "2006-01-02"
|
|
|
|
|
SimpleDateTimeFormat = "2006-01-02 15:04:05"
|
|
|
|
|
|
2021-02-13 13:23:58 +03:00
|
|
|
|
ErrUnauthorized = "401 unauthorized"
|
2021-08-07 11:16:50 +03:00
|
|
|
|
ErrBadRequest = "400 bad request"
|
2021-02-13 01:06:48 +03:00
|
|
|
|
ErrInternalServerError = "500 internal server error"
|
2020-10-04 12:14:44 +03:00
|
|
|
|
)
|
|
|
|
|
|
2021-01-30 12:54:54 +03:00
|
|
|
|
const (
|
2021-02-05 20:47:28 +03:00
|
|
|
|
WakatimeApiUrl = "https://wakatime.com/api/v1"
|
|
|
|
|
WakatimeApiUserUrl = "/users/current"
|
|
|
|
|
WakatimeApiAllTimeUrl = "/users/current/all_time_since_today"
|
|
|
|
|
WakatimeApiHeartbeatsUrl = "/users/current/heartbeats"
|
|
|
|
|
WakatimeApiHeartbeatsBulkUrl = "/users/current/heartbeats.bulk"
|
|
|
|
|
WakatimeApiUserAgentsUrl = "/users/current/user_agents"
|
2021-02-11 00:08:00 +03:00
|
|
|
|
WakatimeApiMachineNamesUrl = "/users/current/machine_names"
|
2021-01-30 12:54:54 +03:00
|
|
|
|
)
|
|
|
|
|
|
2021-04-05 23:57:57 +03:00
|
|
|
|
const (
|
2021-04-10 01:07:13 +03:00
|
|
|
|
MailProviderSmtp = "smtp"
|
2021-04-05 23:57:57 +03:00
|
|
|
|
MailProviderMailWhale = "mailwhale"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var emailProviders = []string{
|
2021-04-10 01:07:13 +03:00
|
|
|
|
MailProviderSmtp,
|
2021-04-05 23:57:57 +03:00
|
|
|
|
MailProviderMailWhale,
|
|
|
|
|
}
|
2021-04-05 17:25:13 +03:00
|
|
|
|
|
2020-11-08 12:12:49 +03:00
|
|
|
|
var cfg *Config
|
|
|
|
|
var cFlag = flag.String("config", defaultConfigPath, "config file location")
|
2021-04-16 13:24:19 +03:00
|
|
|
|
var env string
|
2020-05-24 14:41:19 +03:00
|
|
|
|
|
2020-10-04 12:14:44 +03:00
|
|
|
|
type appConfig struct {
|
2021-02-05 20:47:28 +03:00
|
|
|
|
AggregationTime string `yaml:"aggregation_time" default:"02:15" env:"WAKAPI_AGGREGATION_TIME"`
|
2021-04-30 15:07:14 +03:00
|
|
|
|
ReportTimeWeekly string `yaml:"report_time_weekly" default:"fri,18:00" env:"WAKAPI_REPORT_TIME_WEEKLY"`
|
2021-02-05 20:47:28 +03:00
|
|
|
|
ImportBackoffMin int `yaml:"import_backoff_min" default:"5" env:"WAKAPI_IMPORT_BACKOFF_MIN"`
|
2021-06-11 00:22:04 +03:00
|
|
|
|
ImportBatchSize int `yaml:"import_batch_size" default:"50" env:"WAKAPI_IMPORT_BATCH_SIZE"`
|
2021-02-13 01:06:48 +03:00
|
|
|
|
InactiveDays int `yaml:"inactive_days" default:"7" env:"WAKAPI_INACTIVE_DAYS"`
|
2021-06-27 13:08:11 +03:00
|
|
|
|
CountCacheTTLMin int `yaml:"count_cache_ttl_min" default:"30" env:"WAKAPI_COUNT_CACHE_TTL_MIN"`
|
2021-02-05 20:47:28 +03:00
|
|
|
|
CustomLanguages map[string]string `yaml:"custom_languages"`
|
|
|
|
|
Colors map[string]map[string]string `yaml:"-"`
|
2020-10-04 12:14:44 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type securityConfig struct {
|
2021-02-12 20:37:30 +03:00
|
|
|
|
AllowSignup bool `yaml:"allow_signup" default:"true" env:"WAKAPI_ALLOW_SIGNUP"`
|
|
|
|
|
ExposeMetrics bool `yaml:"expose_metrics" default:"false" env:"WAKAPI_EXPOSE_METRICS"`
|
2020-10-04 12:14:44 +03:00
|
|
|
|
// this is actually a pepper (https://en.wikipedia.org/wiki/Pepper_(cryptography))
|
|
|
|
|
PasswordSalt string `yaml:"password_salt" default:"" env:"WAKAPI_PASSWORD_SALT"`
|
|
|
|
|
InsecureCookies bool `yaml:"insecure_cookies" default:"false" env:"WAKAPI_INSECURE_COOKIES"`
|
2020-11-22 00:30:56 +03:00
|
|
|
|
CookieMaxAgeSec int `yaml:"cookie_max_age" default:"172800" env:"WAKAPI_COOKIE_MAX_AGE"`
|
2020-10-04 12:14:44 +03:00
|
|
|
|
SecureCookie *securecookie.SecureCookie `yaml:"-"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type dbConfig struct {
|
2021-04-18 12:03:54 +03:00
|
|
|
|
Host string `env:"WAKAPI_DB_HOST"`
|
|
|
|
|
Port uint `env:"WAKAPI_DB_PORT"`
|
|
|
|
|
User string `env:"WAKAPI_DB_USER"`
|
|
|
|
|
Password string `env:"WAKAPI_DB_PASSWORD"`
|
|
|
|
|
Name string `default:"wakapi_db.db" env:"WAKAPI_DB_NAME"`
|
|
|
|
|
Dialect string `yaml:"-"`
|
|
|
|
|
Charset string `default:"utf8mb4" env:"WAKAPI_DB_CHARSET"`
|
|
|
|
|
Type string `yaml:"dialect" default:"sqlite3" env:"WAKAPI_DB_TYPE"`
|
|
|
|
|
MaxConn uint `yaml:"max_conn" default:"2" env:"WAKAPI_DB_MAX_CONNECTIONS"`
|
|
|
|
|
Ssl bool `default:"false" env:"WAKAPI_DB_SSL"`
|
|
|
|
|
AutoMigrateFailSilently bool `yaml:"automigrate_fail_silently" default:"false" env:"WAKAPI_DB_AUTOMIGRATE_FAIL_SILENTLY"`
|
2020-10-04 12:14:44 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type serverConfig struct {
|
2021-06-23 18:22:51 +03:00
|
|
|
|
Port int `default:"3000" env:"WAKAPI_PORT"`
|
|
|
|
|
ListenIpV4 string `yaml:"listen_ipv4" default:"127.0.0.1" env:"WAKAPI_LISTEN_IPV4"`
|
|
|
|
|
ListenIpV6 string `yaml:"listen_ipv6" default:"::1" env:"WAKAPI_LISTEN_IPV6"`
|
|
|
|
|
ListenSocket string `yaml:"listen_socket" default:"" env:"WAKAPI_LISTEN_SOCKET"`
|
2021-06-24 22:56:47 +03:00
|
|
|
|
TimeoutSec int `yaml:"timeout_sec" default:"30" env:"WAKAPI_TIMEOUT_SEC"`
|
2021-06-23 18:22:51 +03:00
|
|
|
|
BasePath string `yaml:"base_path" default:"/" env:"WAKAPI_BASE_PATH"`
|
|
|
|
|
PublicUrl string `yaml:"public_url" default:"http://localhost:3000" env:"WAKAPI_PUBLIC_URL"`
|
|
|
|
|
TlsCertPath string `yaml:"tls_cert_path" default:"" env:"WAKAPI_TLS_CERT_PATH"`
|
|
|
|
|
TlsKeyPath string `yaml:"tls_key_path" default:"" env:"WAKAPI_TLS_KEY_PATH"`
|
2020-10-04 12:14:44 +03:00
|
|
|
|
}
|
|
|
|
|
|
2021-03-24 00:12:15 +03:00
|
|
|
|
type sentryConfig struct {
|
|
|
|
|
Dsn string `env:"WAKAPI_SENTRY_DSN"`
|
|
|
|
|
EnableTracing bool `yaml:"enable_tracing" env:"WAKAPI_SENTRY_TRACING"`
|
|
|
|
|
SampleRate float32 `yaml:"sample_rate" default:"0.75" env:"WAKAPI_SENTRY_SAMPLE_RATE"`
|
|
|
|
|
SampleRateHeartbeats float32 `yaml:"sample_rate_heartbeats" default:"0.1" env:"WAKAPI_SENTRY_SAMPLE_RATE_HEARTBEATS"`
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-05 17:25:13 +03:00
|
|
|
|
type mailConfig struct {
|
2021-04-12 23:57:52 +03:00
|
|
|
|
Enabled bool `env:"WAKAPI_MAIL_ENABLED" default:"true"`
|
|
|
|
|
Provider string `env:"WAKAPI_MAIL_PROVIDER" default:"smtp"`
|
|
|
|
|
MailWhale MailwhaleMailConfig `yaml:"mailwhale"`
|
|
|
|
|
Smtp SMTPMailConfig `yaml:"smtp"`
|
2021-04-30 16:14:29 +03:00
|
|
|
|
Sender string `env:"WAKAPI_MAIL_SENDER" yaml:"sender"`
|
2021-04-05 17:25:13 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type MailwhaleMailConfig struct {
|
|
|
|
|
Url string `env:"WAKAPI_MAIL_MAILWHALE_URL"`
|
|
|
|
|
ClientId string `yaml:"client_id" env:"WAKAPI_MAIL_MAILWHALE_CLIENT_ID"`
|
|
|
|
|
ClientSecret string `yaml:"client_secret" env:"WAKAPI_MAIL_MAILWHALE_CLIENT_SECRET"`
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-10 01:07:13 +03:00
|
|
|
|
type SMTPMailConfig struct {
|
|
|
|
|
Host string `env:"WAKAPI_MAIL_SMTP_HOST"`
|
|
|
|
|
Port uint `env:"WAKAPI_MAIL_SMTP_PORT"`
|
|
|
|
|
Username string `env:"WAKAPI_MAIL_SMTP_USER"`
|
|
|
|
|
Password string `env:"WAKAPI_MAIL_SMTP_PASS"`
|
|
|
|
|
TLS bool `env:"WAKAPI_MAIL_SMTP_TLS"`
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-05 23:36:49 +03:00
|
|
|
|
type Config struct {
|
2020-10-04 12:14:44 +03:00
|
|
|
|
Env string `default:"dev" env:"ENVIRONMENT"`
|
|
|
|
|
Version string `yaml:"-"`
|
|
|
|
|
App appConfig
|
|
|
|
|
Security securityConfig
|
|
|
|
|
Db dbConfig
|
|
|
|
|
Server serverConfig
|
2021-03-24 00:12:15 +03:00
|
|
|
|
Sentry sentryConfig
|
2021-04-05 17:25:13 +03:00
|
|
|
|
Mail mailConfig
|
2019-05-05 23:36:49 +03:00
|
|
|
|
}
|
2020-02-20 17:39:56 +03:00
|
|
|
|
|
2020-11-22 00:30:56 +03:00
|
|
|
|
func (c *Config) CreateCookie(name, value, path string) *http.Cookie {
|
|
|
|
|
return c.createCookie(name, value, path, c.Security.CookieMaxAgeSec)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Config) GetClearCookie(name, path string) *http.Cookie {
|
|
|
|
|
return c.createCookie(name, "", path, -1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Config) createCookie(name, value, path string, maxAge int) *http.Cookie {
|
|
|
|
|
return &http.Cookie{
|
|
|
|
|
Name: name,
|
|
|
|
|
Value: value,
|
|
|
|
|
Path: path,
|
|
|
|
|
MaxAge: maxAge,
|
|
|
|
|
Secure: !c.Security.InsecureCookies,
|
|
|
|
|
HttpOnly: true,
|
|
|
|
|
SameSite: http.SameSiteStrictMode,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-20 17:39:56 +03:00
|
|
|
|
func (c *Config) IsDev() bool {
|
2020-05-30 13:11:21 +03:00
|
|
|
|
return IsDev(c.Env)
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-13 00:07:00 +03:00
|
|
|
|
func (c *Config) UseTLS() bool {
|
|
|
|
|
return c.Server.TlsCertPath != "" && c.Server.TlsKeyPath != ""
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-29 19:55:07 +03:00
|
|
|
|
func (c *Config) GetMigrationFunc(dbDialect string) models.MigrationFunc {
|
2020-05-30 21:41:27 +03:00
|
|
|
|
switch dbDialect {
|
|
|
|
|
default:
|
|
|
|
|
return func(db *gorm.DB) error {
|
2021-04-18 12:03:54 +03:00
|
|
|
|
if err := db.AutoMigrate(&models.User{}); err != nil && !c.Db.AutoMigrateFailSilently {
|
2021-04-14 00:23:57 +03:00
|
|
|
|
return err
|
|
|
|
|
}
|
2021-04-18 12:03:54 +03:00
|
|
|
|
if err := db.AutoMigrate(&models.KeyStringValue{}); err != nil && !c.Db.AutoMigrateFailSilently {
|
2021-04-14 00:23:57 +03:00
|
|
|
|
return err
|
|
|
|
|
}
|
2021-04-18 12:03:54 +03:00
|
|
|
|
if err := db.AutoMigrate(&models.Alias{}); err != nil && !c.Db.AutoMigrateFailSilently {
|
2021-04-14 00:23:57 +03:00
|
|
|
|
return err
|
|
|
|
|
}
|
2021-04-18 12:03:54 +03:00
|
|
|
|
if err := db.AutoMigrate(&models.Heartbeat{}); err != nil && !c.Db.AutoMigrateFailSilently {
|
2021-04-14 00:23:57 +03:00
|
|
|
|
return err
|
|
|
|
|
}
|
2021-04-18 12:03:54 +03:00
|
|
|
|
if err := db.AutoMigrate(&models.Summary{}); err != nil && !c.Db.AutoMigrateFailSilently {
|
2021-04-14 00:23:57 +03:00
|
|
|
|
return err
|
|
|
|
|
}
|
2021-04-18 12:03:54 +03:00
|
|
|
|
if err := db.AutoMigrate(&models.SummaryItem{}); err != nil && !c.Db.AutoMigrateFailSilently {
|
2021-04-14 00:23:57 +03:00
|
|
|
|
return err
|
|
|
|
|
}
|
2021-04-18 12:03:54 +03:00
|
|
|
|
if err := db.AutoMigrate(&models.LanguageMapping{}); err != nil && !c.Db.AutoMigrateFailSilently {
|
2021-04-14 00:23:57 +03:00
|
|
|
|
return err
|
|
|
|
|
}
|
2021-06-11 21:59:34 +03:00
|
|
|
|
if err := db.AutoMigrate(&models.ProjectLabel{}); err != nil && !c.Db.AutoMigrateFailSilently {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2021-08-07 11:16:50 +03:00
|
|
|
|
if err := db.AutoMigrate(&models.Diagnostics{}); err != nil && !c.Db.AutoMigrateFailSilently {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2020-05-30 21:41:27 +03:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-07 12:52:49 +03:00
|
|
|
|
func (c *appConfig) GetCustomLanguages() map[string]string {
|
2021-01-30 11:51:36 +03:00
|
|
|
|
return cloneStringMap(c.CustomLanguages, false)
|
2021-01-07 12:52:49 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *appConfig) GetLanguageColors() map[string]string {
|
2021-01-30 11:51:36 +03:00
|
|
|
|
return cloneStringMap(c.Colors["languages"], true)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *appConfig) GetEditorColors() map[string]string {
|
|
|
|
|
return cloneStringMap(c.Colors["editors"], true)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *appConfig) GetOSColors() map[string]string {
|
|
|
|
|
return cloneStringMap(c.Colors["operating_systems"], true)
|
2021-01-07 12:52:49 +03:00
|
|
|
|
}
|
|
|
|
|
|
2021-04-30 15:07:14 +03:00
|
|
|
|
func (c *appConfig) GetWeeklyReportDay() time.Weekday {
|
|
|
|
|
s := strings.Split(c.ReportTimeWeekly, ",")[0]
|
|
|
|
|
return parseWeekday(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *appConfig) GetWeeklyReportTime() string {
|
|
|
|
|
return strings.Split(c.ReportTimeWeekly, ",")[1]
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-05 17:25:13 +03:00
|
|
|
|
func (c *serverConfig) GetPublicUrl() string {
|
|
|
|
|
return strings.TrimSuffix(c.PublicUrl, "/")
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-10 01:07:13 +03:00
|
|
|
|
func (c *SMTPMailConfig) ConnStr() string {
|
|
|
|
|
return fmt.Sprintf("%s:%d", c.Host, c.Port)
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-30 13:11:21 +03:00
|
|
|
|
func IsDev(env string) bool {
|
|
|
|
|
return env == "dev" || env == "development"
|
2020-02-20 17:39:56 +03:00
|
|
|
|
}
|
2020-05-24 18:32:26 +03:00
|
|
|
|
|
2021-01-30 11:51:36 +03:00
|
|
|
|
func readColors() map[string]map[string]string {
|
2020-05-24 18:32:26 +03:00
|
|
|
|
// Read language colors
|
2021-01-30 11:51:36 +03:00
|
|
|
|
// Source:
|
|
|
|
|
// – https://raw.githubusercontent.com/ozh/github-colors/master/colors.json
|
|
|
|
|
// – https://wakatime.com/colors/operating_systems
|
|
|
|
|
// - https://wakatime.com/colors/editors
|
|
|
|
|
// Extracted from Wakatime website with XPath (see below) and did a bit of regex magic after.
|
|
|
|
|
// – $x('//span[@class="editor-icon tip"]/@data-original-title').map(e => e.nodeValue)
|
|
|
|
|
// – $x('//span[@class="editor-icon tip"]/div[1]/text()').map(e => e.nodeValue)
|
2021-04-16 13:24:19 +03:00
|
|
|
|
|
|
|
|
|
raw := data.ColorsFile
|
|
|
|
|
if IsDev(env) {
|
|
|
|
|
raw, _ = ioutil.ReadFile("data/colors.json")
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-30 11:51:36 +03:00
|
|
|
|
var colors = make(map[string]map[string]string)
|
2021-04-16 13:24:19 +03:00
|
|
|
|
if err := json.Unmarshal(raw, &colors); err != nil {
|
2021-01-30 13:17:37 +03:00
|
|
|
|
logbuch.Fatal(err.Error())
|
2020-05-24 18:32:26 +03:00
|
|
|
|
}
|
|
|
|
|
|
2020-10-04 11:37:38 +03:00
|
|
|
|
return colors
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func mustReadConfigLocation() string {
|
|
|
|
|
if _, err := os.Stat(*cFlag); err != nil {
|
2021-01-30 13:17:37 +03:00
|
|
|
|
logbuch.Fatal("failed to find config file at '%s'", *cFlag)
|
2020-10-04 11:37:38 +03:00
|
|
|
|
}
|
|
|
|
|
return *cFlag
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-18 23:34:08 +03:00
|
|
|
|
func resolveDbDialect(dbType string) string {
|
|
|
|
|
if dbType == "cockroach" {
|
|
|
|
|
return "postgres"
|
|
|
|
|
}
|
|
|
|
|
return dbType
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-05 17:25:13 +03:00
|
|
|
|
func findString(needle string, haystack []string, defaultVal string) string {
|
|
|
|
|
for _, s := range haystack {
|
|
|
|
|
if s == needle {
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return defaultVal
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-30 15:07:14 +03:00
|
|
|
|
func parseWeekday(s string) time.Weekday {
|
|
|
|
|
switch strings.ToLower(s) {
|
|
|
|
|
case "mon", strings.ToLower(time.Monday.String()):
|
|
|
|
|
return time.Monday
|
|
|
|
|
case "tue", strings.ToLower(time.Tuesday.String()):
|
|
|
|
|
return time.Tuesday
|
|
|
|
|
case "wed", strings.ToLower(time.Wednesday.String()):
|
|
|
|
|
return time.Wednesday
|
|
|
|
|
case "thu", strings.ToLower(time.Thursday.String()):
|
|
|
|
|
return time.Thursday
|
|
|
|
|
case "fri", strings.ToLower(time.Friday.String()):
|
|
|
|
|
return time.Friday
|
|
|
|
|
case "sat", strings.ToLower(time.Saturday.String()):
|
|
|
|
|
return time.Saturday
|
|
|
|
|
case "sun", strings.ToLower(time.Sunday.String()):
|
|
|
|
|
return time.Sunday
|
|
|
|
|
}
|
|
|
|
|
return time.Monday
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-04 11:37:38 +03:00
|
|
|
|
func Set(config *Config) {
|
|
|
|
|
cfg = config
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Get() *Config {
|
|
|
|
|
return cfg
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-11 13:42:43 +03:00
|
|
|
|
func Load(version string) *Config {
|
2020-10-04 11:37:38 +03:00
|
|
|
|
config := &Config{}
|
|
|
|
|
|
2020-11-08 12:12:49 +03:00
|
|
|
|
flag.Parse()
|
|
|
|
|
|
2020-10-04 11:37:38 +03:00
|
|
|
|
if err := configor.New(&configor.Config{}).Load(config, mustReadConfigLocation()); err != nil {
|
2021-01-30 13:17:37 +03:00
|
|
|
|
logbuch.Fatal("failed to read config: %v", err)
|
2020-10-04 11:37:38 +03:00
|
|
|
|
}
|
|
|
|
|
|
2021-04-16 13:24:19 +03:00
|
|
|
|
env = config.Env
|
2021-04-11 13:42:43 +03:00
|
|
|
|
config.Version = strings.TrimSpace(version)
|
2021-01-30 11:51:36 +03:00
|
|
|
|
config.App.Colors = readColors()
|
2021-01-18 23:34:08 +03:00
|
|
|
|
config.Db.Dialect = resolveDbDialect(config.Db.Type)
|
2020-10-04 11:37:38 +03:00
|
|
|
|
config.Security.SecureCookie = securecookie.New(
|
2020-05-24 18:32:26 +03:00
|
|
|
|
securecookie.GenerateRandomKey(64),
|
|
|
|
|
securecookie.GenerateRandomKey(32),
|
|
|
|
|
)
|
|
|
|
|
|
2020-10-04 11:37:38 +03:00
|
|
|
|
if strings.HasSuffix(config.Server.BasePath, "/") {
|
|
|
|
|
config.Server.BasePath = config.Server.BasePath[:len(config.Server.BasePath)-1]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for k, v := range config.App.CustomLanguages {
|
|
|
|
|
if v == "" {
|
|
|
|
|
config.App.CustomLanguages[k] = "unknown"
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-29 19:55:07 +03:00
|
|
|
|
|
2021-05-04 22:04:11 +03:00
|
|
|
|
if config.Sentry.Dsn != "" {
|
|
|
|
|
logbuch.Info("enabling sentry integration")
|
|
|
|
|
initSentry(config.Sentry, config.IsDev())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// some validation checks
|
2021-06-23 18:22:51 +03:00
|
|
|
|
if config.Server.ListenIpV4 == "" && config.Server.ListenIpV6 == "" && config.Server.ListenSocket == "" {
|
|
|
|
|
logbuch.Fatal("either of listen_ipv4 or listen_ipv6 or listen_socket must be set")
|
2020-12-13 00:07:00 +03:00
|
|
|
|
}
|
2021-02-03 00:52:13 +03:00
|
|
|
|
if config.Db.MaxConn <= 0 {
|
|
|
|
|
logbuch.Fatal("you must allow at least one database connection")
|
|
|
|
|
}
|
2021-04-05 17:25:13 +03:00
|
|
|
|
if config.Mail.Provider != "" && findString(config.Mail.Provider, emailProviders, "") == "" {
|
|
|
|
|
logbuch.Fatal("unknown mail provider '%s'", config.Mail.Provider)
|
|
|
|
|
}
|
2021-05-04 22:04:11 +03:00
|
|
|
|
if _, err := time.Parse("15:04", config.App.GetWeeklyReportTime()); err != nil {
|
|
|
|
|
logbuch.Fatal("invalid interval set for report_time_weekly")
|
|
|
|
|
}
|
|
|
|
|
if _, err := time.Parse("15:04", config.App.AggregationTime); err != nil {
|
|
|
|
|
logbuch.Fatal("invalid interval set for aggregation_time")
|
|
|
|
|
}
|
2021-04-05 17:25:13 +03:00
|
|
|
|
|
2020-10-04 11:37:38 +03:00
|
|
|
|
Set(config)
|
2020-09-29 19:55:07 +03:00
|
|
|
|
return Get()
|
2020-05-24 18:32:26 +03:00
|
|
|
|
}
|