package main import ( "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/postgres" "log" "github.com/gorilla/mux" "io/ioutil" "net/http" "os" "path/filepath" ) type Tapit struct { db *gorm.DB globalSettings GlobalSettings campaignChan chan CampaignComms } type GlobalSettings struct { secretRegistrationCode string threadsPerCampaign int bcryptCost int maxRequestRetries int waitBeforeRetry int } func generateFileHandler(path string) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { r.Header.Add("Cache-Control", "private, max-age=604800") // 7 days //r.Header.Add("Cache-Control", "private, max-age=1") // 1 sec -- debug http.ServeFile(w, r, path) } } func iterateStatic(r *mux.Router, path string, startWebPath string) { files, err := ioutil.ReadDir(path) if err!=nil { log.Fatal(err) } for _, f := range files { if !f.IsDir() && f.Name()[0] != '.' { r.HandleFunc(startWebPath + f.Name(), generateFileHandler(path+"/"+f.Name())) log.Println(startWebPath + f.Name()+" added to path") } else if f.IsDir() && f.Name()[0] != '.' { iterateStatic(r, path + "/" + string(f.Name()), startWebPath + string(f.Name() + "/")) } } } func generateRoutes(r *mux.Router, indexPath string, routes []string) { for _, route := range routes { r.HandleFunc(route, generateFileHandler(indexPath)) log.Println(route+" added as route") } } func main() { // Setting up DB host := "postgres-tapit" db, err := gorm.Open("postgres", "sslmode=disable host=" + host + " port=5432 user=tapit dbname=tapit password=secret-tapit-password") if err != nil { log.Fatal(err) } defer db.Close() // DB Migrations db.AutoMigrate(&Session{}) db.AutoMigrate(&User{}) db.AutoMigrate(&TextTemplate{}) db.AutoMigrate(&TwilioProvider{}) db.AutoMigrate(&Phonebook{}) db.AutoMigrate(&PhoneRecord{}) db.AutoMigrate(&Campaign{}) db.AutoMigrate(&Job{}) // Setting up Tapit app var tapit Tapit tapit.db = db tapit.globalSettings.secretRegistrationCode = "Super-Secret-Code" tapit.globalSettings.threadsPerCampaign = 2 tapit.globalSettings.bcryptCost = 12 tapit.globalSettings.maxRequestRetries = 5 tapit.globalSettings.waitBeforeRetry = 1000 // Clear running campaigns & starting background jobs tapit.clearRunningCampaigns() go tapit.workerTwilioChecker() tapit.campaignChan = make(chan CampaignComms, 10) // Setting up mux r := mux.NewRouter() // Get current dir dir, err := filepath.Abs(filepath.Dir(os.Args[0])) if err != nil { log.Fatal(err) } // Setting up static routes (frontend) iterateStatic(r, dir + "/static/", "/") routes := []string{ "/", "/login", "/register", "/profile", "/campaign", "/campaign/new", "/campaign/{id}/view", "/phonebook", "/phonebook/new", "/phonebook/{id}/edit", "/text-template", "/text-template/new", "/text-template/{id}/edit", "/provider", } indexPath := dir + "/static/index.html" generateRoutes(r, indexPath, routes) // Setting up API routes r.HandleFunc("/api/login", tapit.login) r.HandleFunc("/api/logout", tapit.logout) r.HandleFunc("/api/register", tapit.register) r.HandleFunc("/api/myself", tapit.authenticationHandler(tapit.myselfHandler)) r.Handle("/api/text-template",tapit.authenticationHandler(tapit.handleTextTemplate)) r.Handle("/api/text-template/{id}",tapit.authenticationHandler(tapit.handleSpecificTextTemplate)) r.Handle("/api/provider/twilio",tapit.authenticationHandler(tapit.handleTwilioProvider)) r.Handle("/api/phonebook",tapit.authenticationHandler(tapit.handlePhonebook)) r.Handle("/api/phonebook/{id}",tapit.authenticationHandler(tapit.handleSpecificPhonebook)) r.Handle("/api/import-phonebook",tapit.authenticationHandler(tapit.importPhonebook)) r.Handle("/api/campaign",tapit.authenticationHandler(tapit.handleCampaign)) r.Handle("/api/campaign/{id}",tapit.authenticationHandler(tapit.handleSpecificCampaign)) r.Handle("/api/campaign/{id}/start",tapit.authenticationHandler(tapit.handleStartCampaign)) r.Handle("/api/campaign/{id}/pause",tapit.authenticationHandler(tapit.handleStopCampaign)) // Starting web server http.Handle("/", r) log.Println("Starting web server...") http.ListenAndServe(":8000", nil) }