From f334c93c0364d14a2b55641b155ad58f715a4b39 Mon Sep 17 00:00:00 2001 From: horus_arch Date: Thu, 19 Mar 2015 13:39:37 +0100 Subject: Rewriting from scratch. --- Makefile | 133 + app/controllers/app.go | 63 - app/controllers/db.go | 138 - app/controllers/email.db | Bin 10240 -> 0 bytes app/controllers/init.go | 10 - app/controllers/utilities.go | 98 - app/init.go | 38 - app/views/App/DomainRegister.html | 50 - app/views/App/Index.html | 13 - app/views/App/Index.html.bak | 23 - app/views/App/Register.html | 78 - app/views/debug.html | 64 - app/views/errors/404.html | 20 - app/views/errors/500.html | 16 - app/views/flash.html | 18 - app/views/footer.html | 19 - app/views/header.html | 19 - app/views/navbar.html | 23 - conf/app.conf | 161 - conf/routes | 30 - config.go | 49 + db.go | 39 + email.go | 29 + email_test.go | 37 + env.sh | 23 + main.go | 49 + messages/sample.en | 7 - public/css/bootstrap.css | 5774 ----------------------------- public/img/favicon.png | Bin 5639 -> 0 bytes public/img/glyphicons-halflings-white.png | Bin 8777 -> 0 bytes public/img/glyphicons-halflings.png | Bin 12799 -> 0 bytes public/js/jquery-1.9.1.min.js | 5 - roadmap.txt | 13 + struct.go | 43 + tests/apptest.go | 21 - views/email/index.html | 0 views/index.html | 0 37 files changed, 415 insertions(+), 6688 deletions(-) create mode 100644 Makefile delete mode 100644 app/controllers/app.go delete mode 100644 app/controllers/db.go delete mode 100644 app/controllers/email.db delete mode 100644 app/controllers/init.go delete mode 100644 app/controllers/utilities.go delete mode 100644 app/init.go delete mode 100644 app/views/App/DomainRegister.html delete mode 100644 app/views/App/Index.html delete mode 100644 app/views/App/Index.html.bak delete mode 100644 app/views/App/Register.html delete mode 100644 app/views/debug.html delete mode 100644 app/views/errors/404.html delete mode 100644 app/views/errors/500.html delete mode 100644 app/views/flash.html delete mode 100644 app/views/footer.html delete mode 100644 app/views/header.html delete mode 100644 app/views/navbar.html delete mode 100644 conf/app.conf delete mode 100644 conf/routes create mode 100644 config.go create mode 100644 db.go create mode 100644 email.go create mode 100644 email_test.go create mode 100755 env.sh create mode 100644 main.go delete mode 100644 messages/sample.en delete mode 100644 public/css/bootstrap.css delete mode 100644 public/img/favicon.png delete mode 100644 public/img/glyphicons-halflings-white.png delete mode 100644 public/img/glyphicons-halflings.png delete mode 100644 public/js/jquery-1.9.1.min.js create mode 100644 roadmap.txt create mode 100644 struct.go delete mode 100644 tests/apptest.go create mode 100644 views/email/index.html create mode 100644 views/index.html diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4e92af6 --- /dev/null +++ b/Makefile @@ -0,0 +1,133 @@ +# Modify env.sh and uncomment to change config. +include env.sh + +# Start the race detector with "TEST_RACE=1 make test" on the command line. +ifdef TEST_RACE + RACE:=-race +else + RACE:= +endif + +# To be verbose while testing use TEST_VERBOSE=1. +ifdef TEST_VERBOSE + VERBOSE:=-v +else + VERBOSE:= +endif + +IMPORT_FILE:=./import.go +APP:=mailer + +# Include the sqlit3 database in archiv. +ifeq ($(FREEMAIL_DB_DRIVER), sqlite3) + FREEMAIL_DB_DIR:=db +else + FREEMAIL_DB_DIR:= +endif + +# Start targets +all: kill build run + +clean: kill + @(rm $(IMPORT_FILE) 2>/dev/null && echo "Removing import file..." ) || true + @(rm $(FREEMAIL_DB_CREDENTIALS) 2>/dev/null echo && "Removing sqlite3 database..." ) || true +# @(rm ../$(APP).tar.gz 1>&2 2>/dev/null && echo "Removing tar archiv...") || true + @(rm _env.sh 1>&2 2>/dev/null && echo "Removing _env.sh...") || true + @(rm $(APP) 2>/dev/null && echo "Removing binary ($(APP))...") || true +# @(rm ../start.sh 1>&2 2>/dev/null && echo "Removing startup script...") || true + @echo "Done." + +build: import + go build -o $(APP) + +run: _test_build + ./$(APP) & + +kill: + @echo "Killing running instances..." + @pkill $(APP) || true + +create_import: + @if [ ! -f $(IMPORT_FILE) ] ; \ + then \ + echo "package main" > $(IMPORT_FILE) ; \ + fi + +import: + @if [ ! -f $(IMPORT_FILE) ] ; \ + then \ + echo "package main" > $(IMPORT_FILE) ; \ + echo "import _ \"$(FREEMAIL_DB_IMPORT_DRIVER)\"" >> $(IMPORT_FILE) ; \ + fi + +sqlite3: create_import + @echo "import _ \"github.com/mattn/go-sqlite3\"" >> $(IMPORT_FILE) + +mysql: create_import + @echo "import _ \"github.com/go-sql-driver/mysql\"" >> $(IMPORT_FILE) + +postgresql: create_import + @echo "import _ \"github.com/lib/pq\"" >> $(IMPORT_FILE) + +database_all: sqlite3 mysql postgresql + @echo "Created import file for all databases." + +pack: gen_config + @cd .. && \ + echo "#!/bin/sh" > start.sh && \ + echo "cd app && . ./_env.sh && ./$(APP)" >> start.sh && \ + chmod +x start.sh && \ + tar czf $(APP).tar.gz start.sh app/$(APP) app/_env.sh views static $(FREEMAIL_DB_DIR) 2>/dev/null && \ + rm start.sh 2>/dev/null && \ + echo "\n../$(APP).tar.gz is ready." || \ + (echo "Run \"make build\" first." && exit 1) + +test: import + FREEMAIL_DB_CREDENTIALS=":memory:" go test $(RACE) $(VERBOSE) #-tags general + make clean + +test_all: import + FREEMAIL_DB_CREDENTIALS=":memory:" go test $(RACE) $(VERBOSE) -v -tags all + +test_dependencies: import + FREEMAIL_DB_CREDENTIALS=":memory:" go test $(RACE) $(VERBOSE) -tags dep + +benchmark: + FREEMAIL_DB_CREDENTIALS=":memory:" go test $(VERBOSE) -bench=".*" -tags general + +benchmark_dependencies: import + export DB_FREEMAIL_LOG=false + FREEMAIL_DB_CREDENTIALS=":memory:" go test $(VERBOSE) -bench=".*" -tags dep + +_test_build: + @if [ ! -f ./$(APP) ] || [ ! -x ./$(APP) ]; then \ + echo "No executable binary found." 1>&2; \ + echo "Run \"make build\" first." 1>&2; \ + echo ""; \ + exit 1; \ + fi + +gen_config: _test_build + @echo "Generating config file!\n" + echo "#!/bin/sh" > _env.sh + @echo "# Database" >> _env.sh + echo "export FREEMAIL_DB_DRIVER=$(FREEMAIL_DB_DRIVER)" >> _env.sh + echo "export FREEMAIL_DB_CREDENTIALS=$(FREEMAIL_DB_CREDENTIALS)" >> _env.sh + echo "export FREEMAIL_DB_IMPORT_DRIVER=$(FREEMAIL_DB_IMPORT_DRIVER)" >> _env.sh + echo "export FREEMAIL_DB_LOG=$(FREEMAIL_DB_LOG)\n" >> _env.sh + @echo "" + @echo "# Redis" >> _env.sh + echo "export FREEMAIL_REDIS_SERVER=$(FREEMAIL_REDIS_SERVER)" >> _env.sh + echo "export FREEMAIL_REDIS_PORT=$(FREEMAIL_REDIS_PORT)\n" >> _env.sh + @echo "" + @echo "# Http" >> _env.sh + echo "export FREEMAIL_HTTP_IP=$(FREEMAIL_HTTP_IP)" >> _env.sh + echo "export FREEMAIL_HTTP_PORT=$(FREEMAIL_HTTP_PORT)" >> _env.sh + @echo "" + echo "export FREEMAIL_SECRET=$(FREEMAIL_SECRET)" >> _env.sh + @echo "" + @echo "# Smtp" >> _env.sh + echo "export FREEMAIL_SMTP_MAILER=$(FREEMAIL_SMTP_MAILER)" >> _env.sh + echo "export FREEMAIL_SMTP_PASSWORD=$(FREEMAIL_SMTP_PASSWORD)" >> _env.sh + echo "export FREEMAIL_SMTP_ADRESS=$(FREEMAIL_SMTP_ADRESS)" >> _env.sh + @chmod +x _env.sh diff --git a/app/controllers/app.go b/app/controllers/app.go deleted file mode 100644 index 2b8945c..0000000 --- a/app/controllers/app.go +++ /dev/null @@ -1,63 +0,0 @@ -package controllers - -import ( - _ "github.com/jinzhu/gorm" - _ "github.com/mattn/go-sqlite3" - "github.com/revel/revel" -) - -type App struct { - //*revel.Controller - GormController -} - -func (c App) Index() revel.Result { - return c.Render() -} - -func (c App) DoRegister(name, email, confirmEmail, password, confirmPassword string) revel.Result { - c.Validation.Required(name).Message("Please provide a user name.") - c.Validation.Required(email).Message("Please provide a mail adress.") - c.Validation.Required(email == confirmEmail).Message("Mail adresses do not match.") - c.Validation.Required(password).Message("Please provide a password.") - c.Validation.Required(password == confirmPassword).Message("Passwords do not match.") - - if c.Validation.HasErrors() { - c.Validation.Keep() - c.FlashParams() - return c.Redirect(App.Register) - } - - hash := HashPassword(password) - revel.INFO.Printf("%s \n", hash) - user := User{Name: name, Email: email, Password: hash} - - //c.Validation.Required(c.Db.NewRecord(user)).Message("User name already used.") - /* - if !c.Db.NewRecord(user) { - revel.ERROR.Println("User name already in use.") - } - */ - - revel.INFO.Printf("%s", c.Gdb) - c.Gdb.Debug().NewRecord(user) - c.Gdb.Debug().Save(&user) - //c.Db.Debug().NewRecord(user) - //c.Db.Debug().Save(&user) - //c.Db.Create(&user) - - /* - if c.Validation.HasErrors() { - c.Validation.Keep() - c.FlashParams() - return c.Redirect(App.Register) - } - */ - - //return c.Render() - return c.Redirect(App.Register) -} - -func (c App) Register() revel.Result { - return c.Render() -} diff --git a/app/controllers/db.go b/app/controllers/db.go deleted file mode 100644 index 5b7dd97..0000000 --- a/app/controllers/db.go +++ /dev/null @@ -1,138 +0,0 @@ -package controllers - -import ( - "github.com/jinzhu/gorm" - // _ "github.com/mattn/go-sqlite3" - "database/sql" - "github.com/revel/revel" - "time" -) - -// Website user -type User struct { - Id int64 - Name string - Email string - Password string - // Domains []Domain - CreatedAt time.Time - UpdatedAt time.Time - DeletedAt time.Time -} - -/* -type Domain struct { - Id int64 - UserId int64 - Domain string - CreatedAt time.Time - UpdatedAt time.Time - DeletedAt time.Time -} -*/ - -// Domains for which we do E-Mail hosting -type VirtualDomain struct { - Id int64 - User User - UserId int64 - Name string -} - -// User for postfix -type VirtualUser struct { - Id int64 - UserId int64 - VirtualDomain VirtualDomain - VirtualDomainId int64 - Password string - Email string -} - -// E-Mail aliase for postfix -type VirtualAliase struct { - Id int64 - VirtualDomain VirtualDomain - VirtualDomainId int64 - Source string - Destination string -} - -type GormController struct { - *revel.Controller - Gdb *gorm.DB -} - -var Gdb gorm.DB - -func InitDB() { - // db.Init() - Gdb, err := gorm.Open(revel.Config.StringDefault("db.driver", "sqlite3"), revel.Config.StringDefault("db.spec", "email.db")) - if err != nil { - revel.ERROR.Printf("%s", err) - } - Gdb.LogMode(true) - Gdb.SetLogger(gorm.Logger{revel.TRACE}) - - user := User{} - Gdb.AutoMigrate(&user) - Gdb.Model(&user).AddUniqueIndex("idx_user_name", "name") - Gdb.Model(&user).AddUniqueIndex("idx_user_email", "email") - - /* - domain := Domain{} - Gdb.AutoMigrate(&domain) - Gdb.Model(&domain).AddUniqueIndex("idx_domain_name", "domain") - */ - - vu := VirtualUser{} - Gdb.AutoMigrate(&vu) - Gdb.Model(&vu).AddUniqueIndex("idx_virtual_user_email", "email") - Gdb.Debug().Model(&vu).Related(&user) - Gdb.Debug().Model(&user).Related(&vu) - - vd := VirtualDomain{} - Gdb.AutoMigrate(&vd) - - va := VirtualAliase{} - Gdb.AutoMigrate(&va) -} - -// transactions - -// This method fills the c.Gdb before each transaction -func (c *GormController) Begin() revel.Result { - txn := Gdb.Begin() - if txn.Error != nil { - //panic(txn.Error) - revel.ERROR.Printf("%s \n", txn.Error) - } - c.Gdb = txn - return nil -} - -// This method clears the c.Gdb after each transaction -func (c *GormController) Commit() revel.Result { - if c.Gdb == nil { - return nil - } - c.Gdb.Commit() - if err := c.Gdb.Error; err != nil && err != sql.ErrTxDone { - panic(err) - } - c.Gdb = nil - return nil -} - -// This method clears the c.Gdb after each transaction, too -func (c *GormController) Rollback() revel.Result { - if c.Gdb == nil { - return nil - } - c.Gdb.Rollback() - if err := c.Gdb.Error; err != nil && err != sql.ErrTxDone { - panic(err) - } - c.Gdb = nil - return nil -} diff --git a/app/controllers/email.db b/app/controllers/email.db deleted file mode 100644 index 4a4cefc..0000000 Binary files a/app/controllers/email.db and /dev/null differ diff --git a/app/controllers/init.go b/app/controllers/init.go deleted file mode 100644 index a5c9096..0000000 --- a/app/controllers/init.go +++ /dev/null @@ -1,10 +0,0 @@ -package controllers - -import "github.com/revel/revel" - -func init() { - revel.OnAppStart(InitDB) // invoke InitDB function before - revel.InterceptMethod((*GormController).Begin, revel.BEFORE) - revel.InterceptMethod((*GormController).Commit, revel.AFTER) - revel.InterceptMethod((*GormController).Rollback, revel.FINALLY) -} diff --git a/app/controllers/utilities.go b/app/controllers/utilities.go deleted file mode 100644 index 693a459..0000000 --- a/app/controllers/utilities.go +++ /dev/null @@ -1,98 +0,0 @@ -package controllers - -import ( - "crypto/md5" - "fmt" - // "github.com/garyburd/redigo/redis" - "github.com/revel/revel" - "golang.org/x/crypto/bcrypt" - "io" - "io/ioutil" - "math/rand" - "net/http" - // "time" -) - -// Returns the content of a webpage as string -func HttpGet(url string) (http.Header, string, error) { - response, err := http.Get(url) - if err != nil { - return nil, "Get request failed.", err - } - - defer response.Body.Close() - contents, err := ioutil.ReadAll(response.Body) - if err != nil { - return nil, "Reading body failed.", err - } - - return response.Header, string(contents), nil -} - -// Hashs and returns a string (md5) -func Hash(content string) string { - h := md5.New() - io.WriteString(h, content) - hash := fmt.Sprintf("%x", h.Sum(nil)) - - return hash -} - -// Creates a random string -func RandomKey() string { - letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") - key := make([]rune, 40) - for i := range key { - key[i] = letters[rand.Intn(len(letters))] - } - - return string(key) -} - -//var pool = newPool() - -/* -// Creates a pool with connections to Redis -func newPool() *redis.Pool { - return &redis.Pool{ - MaxIdle: 3, - IdleTimeout: 240 * time.Second, - Dial: func() (redis.Conn, error) { - //c, err := redis.Dial("tcp", ":6379") - c, err := redis.Dial("tcp", revel.Config.StringDefault("redis.server", "127.0.0.1")+":"+revel.Config.StringDefault("redis.port", "6379")) - if err != nil { - return nil, err - } - return c, err - }, - TestOnBorrow: func(c redis.Conn, t time.Time) error { - _, err := c.Do("PING") - return err - }, - } -} -*/ - -// Hashs password with bcrypt and returns the string -func HashPassword(password string) string { - if password == "" { - return "" - } - p := []byte(password) - hash, err := bcrypt.GenerateFromPassword(p, 10) - if err != nil { - revel.ERROR.Printf("%s \n", err) - return "" - } - return string(hash) -} - -// Verify password and hash -func VerifyPassword(password, hash string) bool { - err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) - if err != nil { - revel.ERROR.Printf("%s \n", err) - return false - } - return true -} diff --git a/app/init.go b/app/init.go deleted file mode 100644 index 2305d73..0000000 --- a/app/init.go +++ /dev/null @@ -1,38 +0,0 @@ -package app - -import "github.com/revel/revel" - -func init() { - // Filters is the default set of global filters. - revel.Filters = []revel.Filter{ - revel.PanicFilter, // Recover from panics and display an error page instead. - revel.RouterFilter, // Use the routing table to select the right Action - revel.FilterConfiguringFilter, // A hook for adding or removing per-Action filters. - revel.ParamsFilter, // Parse parameters into Controller.Params. - revel.SessionFilter, // Restore and write the session cookie. - revel.FlashFilter, // Restore and write the flash cookie. - revel.ValidationFilter, // Restore kept validation errors and save new ones from cookie. - revel.I18nFilter, // Resolve the requested language - HeaderFilter, // Add some security based headers - revel.InterceptorFilter, // Run interceptors around the action. - revel.CompressFilter, // Compress the result. - revel.ActionInvoker, // Invoke the action. - } - - // register startup functions with OnAppStart - // ( order dependent ) - // revel.OnAppStart(InitDB) - // revel.OnAppStart(FillCache) -} - -// TODO turn this into revel.HeaderFilter -// should probably also have a filter for CSRF -// not sure if it can go in the same filter or not -var HeaderFilter = func(c *revel.Controller, fc []revel.Filter) { - // Add some common security headers - c.Response.Out.Header().Add("X-Frame-Options", "SAMEORIGIN") - c.Response.Out.Header().Add("X-XSS-Protection", "1; mode=block") - c.Response.Out.Header().Add("X-Content-Type-Options", "nosniff") - - fc[0](c, fc[1:]) // Execute the next filter stage. -} diff --git a/app/views/App/DomainRegister.html b/app/views/App/DomainRegister.html deleted file mode 100644 index 9c8683c..0000000 --- a/app/views/App/DomainRegister.html +++ /dev/null @@ -1,50 +0,0 @@ -{{set . "title" "Register"}} -{{template "header.html" .}} -{{template "navbar.html" .}} - -
- {{.Description}} -
- {{end}} -{{end}} - - diff --git a/app/views/errors/500.html b/app/views/errors/500.html deleted file mode 100644 index 0cef4de..0000000 --- a/app/views/errors/500.html +++ /dev/null @@ -1,16 +0,0 @@ - - - -- This exception has been logged. -
- {{end}} - - diff --git a/app/views/flash.html b/app/views/flash.html deleted file mode 100644 index 9c9ade9..0000000 --- a/app/views/flash.html +++ /dev/null @@ -1,18 +0,0 @@ -{{if .flash.success}} -