load config from environment variables and .env files

pull/6/head
Namekuji 2022-12-03 12:44:11 -05:00
rodzic 7e5eac4509
commit 429844799f
7 zmienionych plików z 142 dodań i 44 usunięć

7
.env.development 100644
Wyświetl plik

@ -0,0 +1,7 @@
LOCAL_DOMAIN="localhost:1323"
SESSION_SECRET="dev"
DB_HOST="localhost"
DB_PORT=27017
DB_NAME="audon"
DB_USER="root"
DB_PASS="example"

9
.vscode/launch.json vendored
Wyświetl plik

@ -12,14 +12,7 @@
"cwd": "${workspaceFolder}",
"program": ".",
"env": {
"LOCAL_DOMAIN": "localhost:1323",
"SESSION_SECRET": "dev",
"DB_HOST": "localhost",
"DB_PORT": "27017",
"DB_NAME": "audon",
"DB_USER": "root",
"DB_PASS": "example",
"APP_ENV": "development"
"AUDON_ENV": "development"
}
}
]

105
config.go 100644
Wyświetl plik

@ -0,0 +1,105 @@
package main
import (
"fmt"
"net/url"
"os"
"strconv"
"github.com/joho/godotenv"
)
type (
AppConfig struct {
AppConfigBase
Livekit *LivekitConfig
MongoURL *url.URL
}
AppConfigBase struct {
DBName string `validate:"required,alphabum"`
SeesionSecret string `validate:"required,ascii"`
LocalDomain string `validate:"required,hostname|hostname_port`
}
LivekitConfig struct {
LivekitAPIKey string `validate:"required,alphanum"`
LivekitAPISecret string `validate:"required,alphanum"`
}
DBConfig struct {
User string `validate:"required,alphanum"`
Password string `validate:"required,ascii"`
Host string `validare:"required,hostname"`
Port int `validate:"required,gt=20000"`
Name string `validate:"required,alphanum"`
}
)
const (
SESSION_NAME = "session"
SESSION_DATASTORE_NAME = "data"
)
func loadConfig(envname string) (*AppConfig, error) {
if envname == "" {
envname = "development"
}
// Set values in .env files to environment variables
if err := godotenv.Load(".env." + envname); err != nil {
return nil, err
}
if err := godotenv.Load(".env"); err != nil {
return nil, err
}
var appConf AppConfig
// Setup base config
basicConf := AppConfigBase{
DBName: os.Getenv("DB_NAME"),
SeesionSecret: os.Getenv("SESSION_SECRET"),
LocalDomain: os.Getenv("LOCAL_DOMAIN"),
}
if basicConf.SeesionSecret == "" {
basicConf.SeesionSecret = "dev"
}
if err := mainValidator.Struct(&basicConf); err != nil {
return nil, err
}
appConf.AppConfigBase = basicConf
// Setup MongoDB config
dbport, err := strconv.Atoi(os.Getenv("DB_PORT"))
if err != nil {
return nil, err
}
dbconf := &DBConfig{
User: os.Getenv("DB_USER"),
Password: os.Getenv("DB_PASS"),
Host: os.Getenv("DB_HOST"),
Port: dbport,
}
if err := mainValidator.Struct(dbconf); err != nil {
return nil, err
}
mongoURL := &url.URL{
Scheme: "mongodb",
User: url.UserPassword(dbconf.User, dbconf.Password),
Host: fmt.Sprintf("%s:%d", dbconf.Host, dbconf.Port),
}
appConf.MongoURL = mongoURL
// Setup LiveKit config
lkConf := &LivekitConfig{
LivekitAPIKey: os.Getenv("LIVEKIT_API_KEY"),
LivekitAPISecret: os.Getenv("LIVEKIT_API_SECRET"),
}
if err := mainValidator.Struct(lkConf); err != nil {
return nil, err
}
appConf.Livekit = lkConf
return &appConf, nil
}

1
go.mod
Wyświetl plik

@ -24,6 +24,7 @@ require (
github.com/gorilla/context v1.1.1 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/joho/godotenv v1.4.0 // indirect
github.com/klauspost/compress v1.13.6 // indirect
github.com/labstack/gommon v0.4.0 // indirect
github.com/leodido/go-urn v1.2.1 // indirect

2
go.sum
Wyświetl plik

@ -61,6 +61,8 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/jaevor/go-nanoid v1.3.0 h1:nD+iepesZS6pr3uOVf20vR9GdGgJW1HPaR46gtrxzkg=
github.com/jaevor/go-nanoid v1.3.0/go.mod h1:SI+jFaPuddYkqkVQoNGHs81navCtH388TcrH0RqFKgY=
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/jxskiss/base62 v1.1.0 h1:A5zbF8v8WXx2xixnAKD2w+abC+sIzYJX+nxmhA6HWFw=
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=

Wyświetl plik

@ -6,7 +6,7 @@ import (
"time"
"github.com/gorilla/sessions"
nanoid "github.com/jaevor/go-nanoid"
"github.com/jaevor/go-nanoid"
"github.com/labstack/echo/v4"
mastodon "github.com/mattn/go-mastodon"
"go.mongodb.org/mongo-driver/mongo"
@ -121,7 +121,8 @@ func oauthHandler(c echo.Context) (err error) {
coll := mainDB.Collection(COLLECTION_USER)
if result, dbErr := findUserByRemote(c.Request().Context(), string(acc.ID), acc.URL); dbErr == mongo.ErrNoDocuments {
canonic, err := nanoid.Standard(21)
// Create user if not yet registered
canonic, err := nanoid.Standard(21) // Should AudonID be sortable?
if err != nil {
c.Logger().Error(err)
return echo.NewHTTPError(http.StatusInternalServerError)
@ -141,6 +142,7 @@ func oauthHandler(c echo.Context) (err error) {
c.Logger().Error(dbErr)
return echo.NewHTTPError(http.StatusInternalServerError)
} else if result != nil {
// Set setssion's Audon ID if already registered
data.AudonID = result.AudonID
}

Wyświetl plik

@ -4,7 +4,6 @@ import (
"context"
"encoding/gob"
"errors"
"fmt"
"html/template"
"io"
"log"
@ -34,16 +33,12 @@ type (
M map[string]interface{}
)
const (
SESSION_NAME = "session"
SESSION_DATASTORE_NAME = "data"
)
var (
err_invalid_cookie error = errors.New("invalid cookie")
mastAppConfigBase *mastodon.AppConfig = nil
mainDB *mongo.Database = nil
mainValidator = validator.New()
mainConfig *AppConfig
)
func init() {
@ -52,24 +47,28 @@ func init() {
}
func main() {
mongoURI := &url.URL{
Scheme: "mongodb",
User: url.UserPassword(os.Getenv("DB_USER"), os.Getenv("DB_PASS")),
Host: fmt.Sprintf("%s:%s", os.Getenv("DB_HOST"), os.Getenv("DB_PORT")),
}
dbContext, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
dbClient, err := mongo.Connect(dbContext, options.Client().ApplyURI(mongoURI.String()))
var err error
// Load config from environment variables and .env
mainConfig, err = loadConfig(os.Getenv("AUDON_ENV"))
if err != nil {
log.Fatalln(err)
os.Exit(1)
}
mainDB = dbClient.Database(os.Getenv("DB_NAME"))
err = createIndexes(dbContext)
dbContext, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
dbClient, err := mongo.Connect(dbContext, options.Client().ApplyURI(mainConfig.MongoURL.String()))
if err != nil {
log.Fatalln(err)
os.Exit(2)
}
mainDB = dbClient.Database(mainConfig.DBName)
err = createIndexes(dbContext)
if err != nil {
log.Fatalln(err)
os.Exit(3)
}
e := echo.New()
defer e.Close()
@ -79,11 +78,7 @@ func main() {
}
e.Renderer = t
e.Validator = &CustomValidator{validator: mainValidator}
secret := os.Getenv("SESSION_SECRET")
if secret == "" {
secret = "dev"
}
e.Use(session.Middleware(sessions.NewCookieStore([]byte(secret))))
e.Use(session.Middleware(sessions.NewCookieStore([]byte(mainConfig.SeesionSecret))))
// e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
// CookiePath: "/",
// TokenLookup: "header:X-CSRF-Token,form:csrf",
@ -135,21 +130,14 @@ func getAppConfig(server string) (*mastodon.AppConfig, error) {
}, nil
}
localDomain := os.Getenv("LOCAL_DOMAIN")
redirectURI := "urn:ietf:wg:oauth:2.0:oob"
if localDomain != "" {
err := mainValidator.Var(localDomain, "hostname|hostname_port")
if err != nil {
return nil, err
}
u := &url.URL{
Host: localDomain,
Scheme: "http",
Path: "/",
}
u = u.JoinPath("app", "oauth")
redirectURI = u.String()
u := &url.URL{
Host: mainConfig.LocalDomain,
Scheme: "http",
Path: "/",
}
u = u.JoinPath("app", "oauth")
redirectURI = u.String()
conf := &mastodon.AppConfig{
ClientName: "Audon",