mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
refactor: migrate to new config (resolve #54)
This commit is contained in:
parent
2ecbb3ea02
commit
660fefcca9
3
.gitignore
vendored
3
.gitignore
vendored
@ -5,4 +5,5 @@ wakapi
|
|||||||
.idea
|
.idea
|
||||||
build
|
build
|
||||||
*.exe
|
*.exe
|
||||||
*.db
|
*.db
|
||||||
|
config.yml
|
25
config.default.yml
Normal file
25
config.default.yml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
env: development
|
||||||
|
|
||||||
|
server:
|
||||||
|
listen: 127.0.0.1
|
||||||
|
port: 3000
|
||||||
|
base_path: /
|
||||||
|
|
||||||
|
app:
|
||||||
|
cleanup: false # only edit, if you know what you're doing
|
||||||
|
custom_languages:
|
||||||
|
vue: Vue
|
||||||
|
jsx: JSX
|
||||||
|
|
||||||
|
db:
|
||||||
|
host: # leave blank when using sqlite3
|
||||||
|
port: # leave blank when using sqlite3
|
||||||
|
user: # leave blank when using sqlite3
|
||||||
|
password: # leave blank when using sqlite3
|
||||||
|
name: wakapi_db.db # database name for mysql / postgres or file path for sqlite (e.g. /tmp/wakapi.db)
|
||||||
|
dialect: sqlite3 # mysql, postgres, sqlite3
|
||||||
|
max_conn: 2
|
||||||
|
|
||||||
|
security:
|
||||||
|
password_salt: # CHANGE !
|
||||||
|
insecure_cookies: false
|
178
config/config.go
178
config/config.go
@ -2,43 +2,48 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"flag"
|
||||||
"github.com/gorilla/securecookie"
|
"github.com/gorilla/securecookie"
|
||||||
|
"github.com/jinzhu/configor"
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
"github.com/joho/godotenv"
|
|
||||||
"github.com/muety/wakapi/models"
|
"github.com/muety/wakapi/models"
|
||||||
migrate "github.com/rubenv/sql-migrate"
|
migrate "github.com/rubenv/sql-migrate"
|
||||||
"gopkg.in/ini.v1"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cfg *Config
|
var cfg *Config
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Env string
|
Env string `default:"dev" env:"ENVIRONMENT"`
|
||||||
Version string
|
Version string
|
||||||
Port int
|
App struct {
|
||||||
Addr string
|
CleanUp bool `default:"false" env:"WAKAPI_CLEANUP"`
|
||||||
BasePath string
|
CustomLanguages map[string]string `yaml:"custom_languages"`
|
||||||
DbHost string
|
LanguageColors map[string]string
|
||||||
DbPort uint
|
}
|
||||||
DbUser string
|
Security struct {
|
||||||
DbPassword string
|
// this is actually a pepper (https://en.wikipedia.org/wiki/Pepper_(cryptography))
|
||||||
DbName string
|
PasswordSalt string `yaml:"password_salt" default:"" env:"WAKAPI_PASSWORD_SALT"`
|
||||||
DbDialect string
|
InsecureCookies bool `yaml:"insecure_cookies" default:"false" env:"WAKAPI_INSECURE_COOKIES"`
|
||||||
DbMaxConn uint
|
SecureCookie *securecookie.SecureCookie
|
||||||
CleanUp bool
|
}
|
||||||
// this is actually a pepper (https://en.wikipedia.org/wiki/Pepper_(cryptography))
|
Db struct {
|
||||||
PasswordSalt string
|
Host string `env:"WAKAPI_DB_HOST"`
|
||||||
SecureCookieHashKey string
|
Port uint `env:"WAKAPI_DB_PORT"`
|
||||||
SecureCookieBlockKey string
|
User string `env:"WAKAPI_DB_USER"`
|
||||||
InsecureCookies bool
|
Password string `env:"WAKAPI_DB_PASSWORD"`
|
||||||
CustomLanguages map[string]string
|
Name string `default:"wakapi_db.db" env:"WAKAPI_DB_PORT"`
|
||||||
LanguageColors map[string]string
|
Dialect string `default:"sqlite3" env:"WAKAPI_DB_TYPE"`
|
||||||
SecureCookie *securecookie.SecureCookie
|
MaxConn uint `yaml:"max_conn" default:"2" env:"WAKAPI_DB_MAX_CONNECTIONS"`
|
||||||
|
}
|
||||||
|
Server struct {
|
||||||
|
Port int `default:"3000" env:"WAKAPI_PORT"`
|
||||||
|
Addr string `default:"127.0.0.1" env:"WAKAPI_LISTEN_IPV4"`
|
||||||
|
BasePath string `yaml:"base_path" default:"/" env:"WAKAPI_BASE_PATH"`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) IsDev() bool {
|
func (c *Config) IsDev() bool {
|
||||||
@ -120,66 +125,7 @@ func readVersion() string {
|
|||||||
return string(bytes)
|
return string(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Set(config *Config) {
|
func readLanguageColors() map[string]string {
|
||||||
cfg = config
|
|
||||||
}
|
|
||||||
|
|
||||||
func Get() *Config {
|
|
||||||
return cfg
|
|
||||||
}
|
|
||||||
|
|
||||||
func Load() *Config {
|
|
||||||
if err := godotenv.Load(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
version := readVersion()
|
|
||||||
|
|
||||||
env := LookupFatal("ENV")
|
|
||||||
dbType := LookupFatal("WAKAPI_DB_TYPE")
|
|
||||||
dbUser := LookupFatal("WAKAPI_DB_USER")
|
|
||||||
dbPassword := LookupFatal("WAKAPI_DB_PASSWORD")
|
|
||||||
dbHost := LookupFatal("WAKAPI_DB_HOST")
|
|
||||||
dbName := LookupFatal("WAKAPI_DB_NAME")
|
|
||||||
dbPortStr := LookupFatal("WAKAPI_DB_PORT")
|
|
||||||
passwordSalt := LookupFatal("WAKAPI_PASSWORD_SALT")
|
|
||||||
dbPort, err := strconv.Atoi(dbPortStr)
|
|
||||||
|
|
||||||
cfg, err := ini.Load("config.ini")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Fail to read file: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if dbType == "" {
|
|
||||||
dbType = "mysql"
|
|
||||||
}
|
|
||||||
|
|
||||||
dbMaxConn := cfg.Section("database").Key("max_connections").MustUint(1)
|
|
||||||
addr := cfg.Section("server").Key("listen").MustString("127.0.0.1")
|
|
||||||
insecureCookies := IsDev(env) || cfg.Section("server").Key("insecure_cookies").MustBool(false)
|
|
||||||
port, err := strconv.Atoi(os.Getenv("PORT"))
|
|
||||||
if err != nil {
|
|
||||||
port = cfg.Section("server").Key("port").MustInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
basePathEnv, basePathEnvExists := os.LookupEnv("WAKAPI_BASE_PATH")
|
|
||||||
basePath := cfg.Section("server").Key("base_path").MustString("/")
|
|
||||||
if basePathEnvExists {
|
|
||||||
basePath = basePathEnv
|
|
||||||
}
|
|
||||||
if strings.HasSuffix(basePath, "/") {
|
|
||||||
basePath = basePath[:len(basePath)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanUp := cfg.Section("app").Key("cleanup").MustBool(false)
|
|
||||||
|
|
||||||
// Read custom languages
|
|
||||||
customLangs := make(map[string]string)
|
|
||||||
languageKeys := cfg.Section("languages").Keys()
|
|
||||||
for _, k := range languageKeys {
|
|
||||||
customLangs[k.Name()] = k.MustString("unknown")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read language colors
|
// Read language colors
|
||||||
// Source: https://raw.githubusercontent.com/ozh/github-colors/master/colors.json
|
// Source: https://raw.githubusercontent.com/ozh/github-colors/master/colors.json
|
||||||
var colors = make(map[string]string)
|
var colors = make(map[string]string)
|
||||||
@ -201,32 +147,54 @@ func Load() *Config {
|
|||||||
colors[strings.ToLower(k)] = v.Color
|
colors[strings.ToLower(k)] = v.Color
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return colors
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustReadConfigLocation() string {
|
||||||
|
var cFlag = flag.String("c", "config.yml", "config file location")
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if _, err := os.Stat(*cFlag); err != nil {
|
||||||
|
log.Fatalf("failed to find config file at '%s'\n", *cFlag)
|
||||||
|
}
|
||||||
|
|
||||||
|
return *cFlag
|
||||||
|
}
|
||||||
|
|
||||||
|
func Set(config *Config) {
|
||||||
|
cfg = config
|
||||||
|
}
|
||||||
|
|
||||||
|
func Get() *Config {
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
func Load() *Config {
|
||||||
|
config := &Config{}
|
||||||
|
|
||||||
|
if err := configor.New(&configor.Config{}).Load(config, mustReadConfigLocation()); err != nil {
|
||||||
|
log.Fatalf("failed to read config: %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
config.Version = readVersion()
|
||||||
|
config.App.LanguageColors = readLanguageColors()
|
||||||
// TODO: Read keys from env, so that users are not logged out every time the server is restarted
|
// TODO: Read keys from env, so that users are not logged out every time the server is restarted
|
||||||
secureCookie := securecookie.New(
|
config.Security.SecureCookie = securecookie.New(
|
||||||
securecookie.GenerateRandomKey(64),
|
securecookie.GenerateRandomKey(64),
|
||||||
securecookie.GenerateRandomKey(32),
|
securecookie.GenerateRandomKey(32),
|
||||||
)
|
)
|
||||||
|
|
||||||
Set(&Config{
|
if strings.HasSuffix(config.Server.BasePath, "/") {
|
||||||
Env: env,
|
config.Server.BasePath = config.Server.BasePath[:len(config.Server.BasePath)-1]
|
||||||
Version: version,
|
}
|
||||||
Port: port,
|
|
||||||
Addr: addr,
|
|
||||||
BasePath: basePath,
|
|
||||||
DbHost: dbHost,
|
|
||||||
DbPort: uint(dbPort),
|
|
||||||
DbUser: dbUser,
|
|
||||||
DbPassword: dbPassword,
|
|
||||||
DbName: dbName,
|
|
||||||
DbDialect: dbType,
|
|
||||||
DbMaxConn: dbMaxConn,
|
|
||||||
CleanUp: cleanUp,
|
|
||||||
InsecureCookies: insecureCookies,
|
|
||||||
SecureCookie: secureCookie,
|
|
||||||
PasswordSalt: passwordSalt,
|
|
||||||
CustomLanguages: customLangs,
|
|
||||||
LanguageColors: colors,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
for k, v := range config.App.CustomLanguages {
|
||||||
|
if v == "" {
|
||||||
|
config.App.CustomLanguages[k] = "unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set(config)
|
||||||
return Get()
|
return Get()
|
||||||
}
|
}
|
||||||
|
1
go.mod
1
go.mod
@ -8,6 +8,7 @@ require (
|
|||||||
github.com/gorilla/schema v1.1.0
|
github.com/gorilla/schema v1.1.0
|
||||||
github.com/gorilla/securecookie v1.1.1
|
github.com/gorilla/securecookie v1.1.1
|
||||||
github.com/jasonlvhit/gocron v0.0.0-20191106203602-f82992d443f4
|
github.com/jasonlvhit/gocron v0.0.0-20191106203602-f82992d443f4
|
||||||
|
github.com/jinzhu/configor v1.2.0
|
||||||
github.com/jinzhu/gorm v1.9.11
|
github.com/jinzhu/gorm v1.9.11
|
||||||
github.com/joho/godotenv v1.3.0
|
github.com/joho/godotenv v1.3.0
|
||||||
github.com/kr/pretty v0.2.0 // indirect
|
github.com/kr/pretty v0.2.0 // indirect
|
||||||
|
3
go.sum
3
go.sum
@ -1,6 +1,7 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
|
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
|
||||||
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||||
@ -154,6 +155,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt
|
|||||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||||
github.com/jasonlvhit/gocron v0.0.0-20191106203602-f82992d443f4 h1:UbQcOUL8J8EpnhYmLa2v6y5PSOPEdRRSVQxh7imPjHg=
|
github.com/jasonlvhit/gocron v0.0.0-20191106203602-f82992d443f4 h1:UbQcOUL8J8EpnhYmLa2v6y5PSOPEdRRSVQxh7imPjHg=
|
||||||
github.com/jasonlvhit/gocron v0.0.0-20191106203602-f82992d443f4/go.mod h1:1nXLkt6gXojCECs34KL3+LlZ3gTpZlkPUA8ejW3WeP0=
|
github.com/jasonlvhit/gocron v0.0.0-20191106203602-f82992d443f4/go.mod h1:1nXLkt6gXojCECs34KL3+LlZ3gTpZlkPUA8ejW3WeP0=
|
||||||
|
github.com/jinzhu/configor v1.2.0 h1:u78Jsrxw2+3sGbGMgpY64ObKU4xWCNmNRJIjGVqxYQA=
|
||||||
|
github.com/jinzhu/configor v1.2.0/go.mod h1:nX89/MOmDba7ZX7GCyU/VIaQ2Ar2aizBl2d3JLF/rDc=
|
||||||
github.com/jinzhu/gorm v1.9.11 h1:gaHGvE+UnWGlbWG4Y3FUwY1EcZ5n6S9WtqBA/uySMLE=
|
github.com/jinzhu/gorm v1.9.11 h1:gaHGvE+UnWGlbWG4Y3FUwY1EcZ5n6S9WtqBA/uySMLE=
|
||||||
github.com/jinzhu/gorm v1.9.11/go.mod h1:bu/pK8szGZ2puuErfU0RwyeNdsf3e6nCX/noXaVxkfw=
|
github.com/jinzhu/gorm v1.9.11/go.mod h1:bu/pK8szGZ2puuErfU0RwyeNdsf3e6nCX/noXaVxkfw=
|
||||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
|
20
main.go
20
main.go
@ -47,19 +47,19 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Show data loss warning
|
// Show data loss warning
|
||||||
if config.CleanUp {
|
if config.App.CleanUp {
|
||||||
promptAbort("`CLEANUP` is set to `true`, which may cause data loss. Are you sure to continue?", 5)
|
promptAbort("`CLEANUP` is set to `true`, which may cause data loss. Are you sure to continue?", 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect to database
|
// Connect to database
|
||||||
var err error
|
var err error
|
||||||
db, err = gorm.Open(config.DbDialect, utils.MakeConnectionString(config))
|
db, err = gorm.Open(config.Db.Dialect, utils.MakeConnectionString(config))
|
||||||
if config.DbDialect == "sqlite3" {
|
if config.Db.Dialect == "sqlite3" {
|
||||||
db.DB().Exec("PRAGMA foreign_keys = ON;")
|
db.DB().Exec("PRAGMA foreign_keys = ON;")
|
||||||
}
|
}
|
||||||
db.LogMode(config.IsDev())
|
db.LogMode(config.IsDev())
|
||||||
db.DB().SetMaxIdleConns(int(config.DbMaxConn))
|
db.DB().SetMaxIdleConns(int(config.Db.MaxConn))
|
||||||
db.DB().SetMaxOpenConns(int(config.DbMaxConn))
|
db.DB().SetMaxOpenConns(int(config.Db.MaxConn))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
log.Fatal("could not connect to database")
|
log.Fatal("could not connect to database")
|
||||||
@ -85,7 +85,7 @@ func main() {
|
|||||||
// Aggregate heartbeats to summaries and persist them
|
// Aggregate heartbeats to summaries and persist them
|
||||||
go aggregationService.Schedule()
|
go aggregationService.Schedule()
|
||||||
|
|
||||||
if config.CleanUp {
|
if config.App.CleanUp {
|
||||||
go heartbeatService.ScheduleCleanUp()
|
go heartbeatService.ScheduleCleanUp()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ func main() {
|
|||||||
router.PathPrefix("/assets").Handler(http.FileServer(http.Dir("./static")))
|
router.PathPrefix("/assets").Handler(http.FileServer(http.Dir("./static")))
|
||||||
|
|
||||||
// Listen HTTP
|
// Listen HTTP
|
||||||
portString := config.Addr + ":" + strconv.Itoa(config.Port)
|
portString := config.Server.Addr + ":" + strconv.Itoa(config.Server.Port)
|
||||||
s := &http.Server{
|
s := &http.Server{
|
||||||
Handler: router,
|
Handler: router,
|
||||||
Addr: portString,
|
Addr: portString,
|
||||||
@ -171,19 +171,19 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runDatabaseMigrations() {
|
func runDatabaseMigrations() {
|
||||||
if err := config.GetMigrationFunc(config.DbDialect)(db); err != nil {
|
if err := config.GetMigrationFunc(config.Db.Dialect)(db); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyFixtures() {
|
func applyFixtures() {
|
||||||
if err := config.GetFixturesFunc(config.DbDialect)(db); err != nil {
|
if err := config.GetFixturesFunc(config.Db.Dialect)(db); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func migrateLanguages() {
|
func migrateLanguages() {
|
||||||
for k, v := range config.CustomLanguages {
|
for k, v := range config.App.CustomLanguages {
|
||||||
result := db.Model(models.Heartbeat{}).
|
result := db.Model(models.Heartbeat{}).
|
||||||
Where("language = ?", "").
|
Where("language = ?", "").
|
||||||
Where("entity LIKE ?", "%."+k).
|
Where("entity LIKE ?", "%."+k).
|
||||||
|
@ -58,8 +58,8 @@ func (m *AuthenticateMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Reques
|
|||||||
if strings.HasPrefix(r.URL.Path, "/api") {
|
if strings.HasPrefix(r.URL.Path, "/api") {
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
} else {
|
} else {
|
||||||
utils.ClearCookie(w, models.AuthCookieKey, !m.config.InsecureCookies)
|
utils.ClearCookie(w, models.AuthCookieKey, !m.config.Security.InsecureCookies)
|
||||||
http.Redirect(w, r, fmt.Sprintf("%s/?error=unauthorized", m.config.BasePath), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("%s/?error=unauthorized", m.config.Server.BasePath), http.StatusFound)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@ func (m *AuthenticateMiddleware) tryGetUserByCookie(r *http.Request) (*models.Us
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !CheckAndMigratePassword(user, login, m.config.PasswordSalt, m.userSrvc) {
|
if !CheckAndMigratePassword(user, login, m.config.Security.PasswordSalt, m.userSrvc) {
|
||||||
return nil, errors.New("invalid password")
|
return nil, errors.New("invalid password")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ func (h *HeartbeatHandler) ApiPost(w http.ResponseWriter, r *http.Request) {
|
|||||||
hb.Machine = machineName
|
hb.Machine = machineName
|
||||||
hb.User = user
|
hb.User = user
|
||||||
hb.UserID = user.ID
|
hb.UserID = user.ID
|
||||||
hb.Augment(h.config.CustomLanguages)
|
hb.Augment(h.config.App.CustomLanguages)
|
||||||
|
|
||||||
if !hb.Valid() {
|
if !hb.Valid() {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
@ -36,7 +36,7 @@ func (h *IndexHandler) GetIndex(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cookie, err := r.Cookie(models.AuthCookieKey); err == nil && cookie.Value != "" {
|
if cookie, err := r.Cookie(models.AuthCookieKey); err == nil && cookie.Value != "" {
|
||||||
http.Redirect(w, r, fmt.Sprintf("%s/summary", h.config.BasePath), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("%s/summary", h.config.Server.BasePath), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ func (h *IndexHandler) PostLogin(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cookie, err := r.Cookie(models.AuthCookieKey); err == nil && cookie.Value != "" {
|
if cookie, err := r.Cookie(models.AuthCookieKey); err == nil && cookie.Value != "" {
|
||||||
http.Redirect(w, r, fmt.Sprintf("%s/summary", h.config.BasePath), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("%s/summary", h.config.Server.BasePath), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,12 +89,12 @@ func (h *IndexHandler) PostLogin(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: depending on middleware package here is a hack
|
// TODO: depending on middleware package here is a hack
|
||||||
if !middlewares.CheckAndMigratePassword(user, &login, h.config.PasswordSalt, h.userSrvc) {
|
if !middlewares.CheckAndMigratePassword(user, &login, h.config.Security.PasswordSalt, h.userSrvc) {
|
||||||
respondAlert(w, "invalid credentials", "", "", http.StatusUnauthorized)
|
respondAlert(w, "invalid credentials", "", "", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
encoded, err := h.config.SecureCookie.Encode(models.AuthCookieKey, login)
|
encoded, err := h.config.Security.SecureCookie.Encode(models.AuthCookieKey, login)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
respondAlert(w, "internal server error", "", "", http.StatusInternalServerError)
|
respondAlert(w, "internal server error", "", "", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
@ -107,11 +107,11 @@ func (h *IndexHandler) PostLogin(w http.ResponseWriter, r *http.Request) {
|
|||||||
Name: models.AuthCookieKey,
|
Name: models.AuthCookieKey,
|
||||||
Value: encoded,
|
Value: encoded,
|
||||||
Path: "/",
|
Path: "/",
|
||||||
Secure: !h.config.InsecureCookies,
|
Secure: !h.config.Security.InsecureCookies,
|
||||||
HttpOnly: true,
|
HttpOnly: true,
|
||||||
}
|
}
|
||||||
http.SetCookie(w, cookie)
|
http.SetCookie(w, cookie)
|
||||||
http.Redirect(w, r, fmt.Sprintf("%s/summary", h.config.BasePath), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("%s/summary", h.config.Server.BasePath), http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *IndexHandler) PostLogout(w http.ResponseWriter, r *http.Request) {
|
func (h *IndexHandler) PostLogout(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -119,8 +119,8 @@ func (h *IndexHandler) PostLogout(w http.ResponseWriter, r *http.Request) {
|
|||||||
loadTemplates()
|
loadTemplates()
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.ClearCookie(w, models.AuthCookieKey, !h.config.InsecureCookies)
|
utils.ClearCookie(w, models.AuthCookieKey, !h.config.Security.InsecureCookies)
|
||||||
http.Redirect(w, r, fmt.Sprintf("%s/", h.config.BasePath), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("%s/", h.config.Server.BasePath), http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *IndexHandler) GetSignup(w http.ResponseWriter, r *http.Request) {
|
func (h *IndexHandler) GetSignup(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -129,7 +129,7 @@ func (h *IndexHandler) GetSignup(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cookie, err := r.Cookie(models.AuthCookieKey); err == nil && cookie.Value != "" {
|
if cookie, err := r.Cookie(models.AuthCookieKey); err == nil && cookie.Value != "" {
|
||||||
http.Redirect(w, r, fmt.Sprintf("%s/summary", h.config.BasePath), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("%s/summary", h.config.Server.BasePath), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ func (h *IndexHandler) PostSignup(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cookie, err := r.Cookie(models.AuthCookieKey); err == nil && cookie.Value != "" {
|
if cookie, err := r.Cookie(models.AuthCookieKey); err == nil && cookie.Value != "" {
|
||||||
http.Redirect(w, r, fmt.Sprintf("%s/summary", h.config.BasePath), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("%s/summary", h.config.Server.BasePath), http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,5 +176,5 @@ func (h *IndexHandler) PostSignup(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
msg := url.QueryEscape("account created successfully")
|
msg := url.QueryEscape("account created successfully")
|
||||||
http.Redirect(w, r, fmt.Sprintf("%s/?success=%s", h.config.BasePath, msg), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("%s/?success=%s", h.config.Server.BasePath, msg), http.StatusFound)
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ func loadTemplates() {
|
|||||||
"title": strings.Title,
|
"title": strings.Title,
|
||||||
"capitalize": utils.Capitalize,
|
"capitalize": utils.Capitalize,
|
||||||
"getBasePath": func() string {
|
"getBasePath": func() string {
|
||||||
return config.Get().BasePath
|
return config.Get().Server.BasePath
|
||||||
},
|
},
|
||||||
"getVersion": func() string {
|
"getVersion": func() string {
|
||||||
return config.Get().Version
|
return config.Get().Version
|
||||||
|
@ -59,7 +59,7 @@ func (h *SettingsHandler) PostCredentials(w http.ResponseWriter, r *http.Request
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !utils.CheckPasswordBcrypt(user, credentials.PasswordOld, h.config.PasswordSalt) {
|
if !utils.CheckPasswordBcrypt(user, credentials.PasswordOld, h.config.Security.PasswordSalt) {
|
||||||
respondAlert(w, "invalid credentials", "", "settings.tpl.html", http.StatusUnauthorized)
|
respondAlert(w, "invalid credentials", "", "settings.tpl.html", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ func (h *SettingsHandler) PostCredentials(w http.ResponseWriter, r *http.Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
user.Password = credentials.PasswordNew
|
user.Password = credentials.PasswordNew
|
||||||
if err := utils.HashPassword(user, h.config.PasswordSalt); err != nil {
|
if err := utils.HashPassword(user, h.config.Security.PasswordSalt); err != nil {
|
||||||
respondAlert(w, "internal server error", "", "settings.tpl.html", http.StatusInternalServerError)
|
respondAlert(w, "internal server error", "", "settings.tpl.html", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ func (h *SettingsHandler) PostCredentials(w http.ResponseWriter, r *http.Request
|
|||||||
Username: user.ID,
|
Username: user.ID,
|
||||||
Password: user.Password,
|
Password: user.Password,
|
||||||
}
|
}
|
||||||
encoded, err := h.config.SecureCookie.Encode(models.AuthCookieKey, login)
|
encoded, err := h.config.Security.SecureCookie.Encode(models.AuthCookieKey, login)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
respondAlert(w, "internal server error", "", "settings.tpl.html", http.StatusInternalServerError)
|
respondAlert(w, "internal server error", "", "settings.tpl.html", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
@ -94,13 +94,13 @@ func (h *SettingsHandler) PostCredentials(w http.ResponseWriter, r *http.Request
|
|||||||
Name: models.AuthCookieKey,
|
Name: models.AuthCookieKey,
|
||||||
Value: encoded,
|
Value: encoded,
|
||||||
Path: "/",
|
Path: "/",
|
||||||
Secure: !h.config.InsecureCookies,
|
Secure: !h.config.Security.InsecureCookies,
|
||||||
HttpOnly: true,
|
HttpOnly: true,
|
||||||
}
|
}
|
||||||
http.SetCookie(w, cookie)
|
http.SetCookie(w, cookie)
|
||||||
|
|
||||||
msg := url.QueryEscape("password was updated successfully")
|
msg := url.QueryEscape("password was updated successfully")
|
||||||
http.Redirect(w, r, fmt.Sprintf("%s/settings?success=%s", h.config.BasePath, msg), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("%s/settings?success=%s", h.config.Server.BasePath, msg), http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *SettingsHandler) PostResetApiKey(w http.ResponseWriter, r *http.Request) {
|
func (h *SettingsHandler) PostResetApiKey(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -115,7 +115,7 @@ func (h *SettingsHandler) PostResetApiKey(w http.ResponseWriter, r *http.Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
msg := url.QueryEscape(fmt.Sprintf("your new api key is: %s", user.ApiKey))
|
msg := url.QueryEscape(fmt.Sprintf("your new api key is: %s", user.ApiKey))
|
||||||
http.Redirect(w, r, fmt.Sprintf("%s/settings?success=%s", h.config.BasePath, msg), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("%s/settings?success=%s", h.config.Server.BasePath, msg), http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *SettingsHandler) PostToggleBadges(w http.ResponseWriter, r *http.Request) {
|
func (h *SettingsHandler) PostToggleBadges(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -130,5 +130,5 @@ func (h *SettingsHandler) PostToggleBadges(w http.ResponseWriter, r *http.Reques
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
http.Redirect(w, r, fmt.Sprintf("%s/settings", h.config.BasePath), http.StatusFound)
|
http.Redirect(w, r, fmt.Sprintf("%s/settings", h.config.Server.BasePath), http.StatusFound)
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ func (h *SummaryHandler) GetIndex(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
vm := models.SummaryViewModel{
|
vm := models.SummaryViewModel{
|
||||||
Summary: summary,
|
Summary: summary,
|
||||||
LanguageColors: utils.FilterLanguageColors(h.config.LanguageColors, summary),
|
LanguageColors: utils.FilterLanguageColors(h.config.App.LanguageColors, summary),
|
||||||
ApiKey: user.ApiKey,
|
ApiKey: user.ApiKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ func (srv *AggregationService) Schedule() {
|
|||||||
go srv.summaryWorker(jobs, summaries)
|
go srv.summaryWorker(jobs, summaries)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < int(srv.Config.DbMaxConn); i++ {
|
for i := 0; i < int(srv.Config.Db.MaxConn); i++ {
|
||||||
go srv.persistWorker(summaries)
|
go srv.persistWorker(summaries)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ func (srv *UserService) CreateOrGet(signup *models.Signup) (*models.User, bool,
|
|||||||
Password: signup.Password,
|
Password: signup.Password,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := utils.HashPassword(u, srv.Config.PasswordSalt); err != nil {
|
if err := utils.HashPassword(u, srv.Config.Security.PasswordSalt); err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ func (srv *UserService) ToggleBadges(user *models.User) (*models.User, error) {
|
|||||||
|
|
||||||
func (srv *UserService) MigrateMd5Password(user *models.User, login *models.Login) (*models.User, error) {
|
func (srv *UserService) MigrateMd5Password(user *models.User, login *models.Login) (*models.User, error) {
|
||||||
user.Password = login.Password
|
user.Password = login.Password
|
||||||
if err := utils.HashPassword(user, srv.Config.PasswordSalt); err != nil {
|
if err := utils.HashPassword(user, srv.Config.Security.PasswordSalt); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ func ExtractCookieAuth(r *http.Request, config *config.Config) (login *models.Lo
|
|||||||
return nil, errors.New("missing authentication")
|
return nil, errors.New("missing authentication")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := config.SecureCookie.Decode(models.AuthCookieKey, cookie.Value, &login); err != nil {
|
if err := config.Security.SecureCookie.Decode(models.AuthCookieKey, cookie.Value, &login); err != nil {
|
||||||
return nil, errors.New("invalid parameters")
|
return nil, errors.New("invalid parameters")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ func ParseUserAgent(ua string) (string, string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func MakeConnectionString(config *config.Config) string {
|
func MakeConnectionString(config *config.Config) string {
|
||||||
switch config.DbDialect {
|
switch config.Db.Dialect {
|
||||||
case "mysql":
|
case "mysql":
|
||||||
return mysqlConnectionString(config)
|
return mysqlConnectionString(config)
|
||||||
case "postgres":
|
case "postgres":
|
||||||
@ -44,25 +44,25 @@ func MakeConnectionString(config *config.Config) string {
|
|||||||
func mysqlConnectionString(config *config.Config) string {
|
func mysqlConnectionString(config *config.Config) string {
|
||||||
//location, _ := time.LoadLocation("Local")
|
//location, _ := time.LoadLocation("Local")
|
||||||
return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=true&loc=%s&sql_mode=ANSI_QUOTES",
|
return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=true&loc=%s&sql_mode=ANSI_QUOTES",
|
||||||
config.DbUser,
|
config.Db.User,
|
||||||
config.DbPassword,
|
config.Db.Password,
|
||||||
config.DbHost,
|
config.Db.Host,
|
||||||
config.DbPort,
|
config.Db.Port,
|
||||||
config.DbName,
|
config.Db.Name,
|
||||||
"Local",
|
"Local",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func postgresConnectionString(config *config.Config) string {
|
func postgresConnectionString(config *config.Config) string {
|
||||||
return fmt.Sprintf("host=%s port=%d user=%s dbname=%s password=%s sslmode=disable",
|
return fmt.Sprintf("host=%s port=%d user=%s dbname=%s password=%s sslmode=disable",
|
||||||
config.DbHost,
|
config.Db.Host,
|
||||||
config.DbPort,
|
config.Db.Port,
|
||||||
config.DbUser,
|
config.Db.User,
|
||||||
config.DbName,
|
config.Db.Name,
|
||||||
config.DbPassword,
|
config.Db.Password,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sqliteConnectionString(config *config.Config) string {
|
func sqliteConnectionString(config *config.Config) string {
|
||||||
return config.DbName
|
return config.Db.Name
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user