transmet/main.go

125 lines
2.8 KiB
Go

package main
import (
"database/sql"
"encoding/json"
"flag"
"fmt"
"github.com/gorilla/csrf"
"github.com/gorilla/sessions"
_ "github.com/lib/pq"
"net/http"
"os"
)
const (
VERSION = "0.1"
MAX_DB_CONNS = 10 // already excessive for personal app
)
type Config struct {
Sql struct {
Host string
Dbname string
Username string
Password string
}
Port string
Url string
}
const (
flash_err = "_flash_err"
flash_info = "_flash_info"
)
var (
config Config
db *sql.DB
store = sessions.NewCookieStore([]byte("key-store-auth-secret"))
)
func loadConfig(env string) {
file, err := os.Open("config/" + env + ".json")
if err != nil {
fmt.Println("Error: cannot open config file: config/" + env + ".json")
os.Exit(-1)
}
defer file.Close()
decoder := json.NewDecoder(file)
err = decoder.Decode(&config)
if err != nil {
fmt.Println("Error: cannot decode config file: ", err)
os.Exit(-1)
}
}
func dbConnect() {
var err error
db, err = sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=require", config.Sql.Username, config.Sql.Password, config.Sql.Host, config.Sql.Dbname))
if err != nil {
fmt.Println("DB ERROR: ", err)
}
db.SetMaxIdleConns(MAX_DB_CONNS)
err = db.Ping()
if err != nil {
fmt.Println("DB Error on Ping(): ", err)
os.Exit(-1)
}
}
func csrfSecret() string {
file, err := os.Open("csrf-secret.txt")
if err != nil {
fmt.Println("Error: cannot open csrf-secret.txt (run gen-csrf.sh to generate)")
os.Exit(-1)
}
defer file.Close()
var bytes []byte = make([]byte, 32)
n, err := file.Read(bytes)
if err != nil || n != 32 {
fmt.Println("Error: cannot open csrf-secret.txt (run gen-csrf.sh to generate)")
}
return string(bytes)
}
type CSRFErrorHandler struct{}
func (self CSRFErrorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Println("csrf Failure: ")
fmt.Println(csrf.FailureReason(r))
fmt.Println("-----")
}
func main() {
fmt.Println("transmet ", VERSION)
envFlag := flag.String("env", "local", "load config/{env}.json")
flag.Parse()
fmt.Println("Loading...")
loadConfig(*envFlag)
dbConnect()
initTemplates()
muxRouter := init_route_handlers()
//errHandler := csrf.ErrorHandler( CSRFErrorHandler{} )
// Terrible. TODO: Get SSL for prod, and then wrap in if(dev) { {
//csrfSecurityOption := csrf.Secure(false)
//csrfMaxTimeOption := csrf.MaxAge(3600 * 24 * 3) // 3 Days - a little more wiggle room
fmt.Println("Listening on", config.Port, "...")
// Disabled CSRF until SSL (and sorting why the popup is throwing CSRF errs
// for tor and FF with ublock + https everywhere)
//err := http.ListenAndServe(":"+config.Port, csrf.Protect([]byte(csrfSecret()), errHandler, csrfSecurityOption, csrfMaxTimeOption)(muxRouter))
err := http.ListenAndServe(":"+config.Port, muxRouter)
if err != nil {
fmt.Println("Fatal Error: ", err)
}
db.Close()
}