summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Chabowski <kevin@kch42.de>2013-08-30 15:11:50 +0200
committerKevin Chabowski <kevin@kch42.de>2013-08-30 15:11:50 +0200
commit3a501d85a560b2e2c5c5ded47cc431e4f1315d21 (patch)
tree4a339c9c992645d69b22e592b12ccb3e051a0d40
parentbf1207d7f3a4e95124c5f1498f96fad298e496a6 (diff)
downloadmailremind-3a501d85a560b2e2c5c5ded47cc431e4f1315d21.tar.gz
mailremind-3a501d85a560b2e2c5c5ded47cc431e4f1315d21.tar.bz2
mailremind-3a501d85a560b2e2c5c5ded47cc431e4f1315d21.zip
Defined own handler type to reduce repetive jobs.
-rw-r--r--activate.go26
-rw-r--r--handler.go65
-rw-r--r--login.go109
-rw-r--r--main.go10
-rw-r--r--register.go130
5 files changed, 164 insertions, 176 deletions
diff --git a/activate.go b/activate.go
index ae392d1..56ef897 100644
--- a/activate.go
+++ b/activate.go
@@ -1,18 +1,14 @@
package main
import (
+ "github.com/gorilla/sessions"
"kch42.de/gostuff/mailremind/model"
"log"
"net/http"
)
-func activate(rw http.ResponseWriter, req *http.Request) {
+func activate(user model.User, sess *sessions.Session, req *http.Request) interface{} {
outdata := &msgTpldata{Title: "Activate Account", Class: "error"}
- defer func() {
- if err := tplMsg.Execute(rw, outdata); err != nil {
- log.Printf("Could not execute template in activate: %s", err)
- }
- }()
req.ParseForm()
@@ -21,44 +17,44 @@ func activate(rw http.ResponseWriter, req *http.Request) {
if (_userid == "") || (code == "") {
outdata.Msg = "User or code invalid. Check, if the activation link was correctly copied from the mail."
- return
+ return outdata
}
userid, err := db.ParseDBID(_userid)
if err != nil {
outdata.Msg = "User or code invalid. Check, if the activation link was correctly copied from the mail."
- return
+ return outdata
}
- user, err := dbcon.UserByID(userid)
- switch err {
+ switch user, err = dbcon.UserByID(userid); err {
case nil:
case model.NotFound:
outdata.Msg = "User not found."
- return
+ return outdata
default:
log.Printf("Error while getting user by ID <%s>: %s", userid, err)
outdata.Msg = "An error occurred while loading user data. Send a message to the support, if this happens again."
- return
+ return outdata
}
if user.ActivationCode() != code {
outdata.Msg = "Wrong activation code."
- return
+ return outdata
}
if err := user.SetActivationCode(""); err != nil {
log.Printf("Error while resetting activation code: %s", err)
outdata.Msg = "An error occurred while activating the user. Send a message to the support, if this happens again."
- return
+ return outdata
}
if err := user.SetActive(true); err != nil {
log.Printf("Error while resetting activation code: %s", err)
outdata.Msg = "An error occurred while activating the user. Send a message to the support, if this happens again."
- return
+ return outdata
}
outdata.Class = "success"
outdata.Msg = "Account activated!"
+ return outdata
}
diff --git a/handler.go b/handler.go
new file mode 100644
index 0000000..d710b2a
--- /dev/null
+++ b/handler.go
@@ -0,0 +1,65 @@
+package main
+
+import (
+ "github.com/gorilla/sessions"
+ "html/template"
+ "kch42.de/gostuff/mailremind/model"
+ "log"
+ "net/http"
+)
+
+type Handler func(user model.User, sess *sessions.Session, req *http.Request) interface{}
+
+func getSess(req *http.Request) (*sessions.Session, error) {
+ sess, err := SessionStorage.Get(req, "mailremind-sess")
+ if err != nil {
+ sess, err = SessionStorage.New(req, "mailremind-sess")
+ }
+
+ return sess, err
+}
+
+func userFromSess(sess *sessions.Session) model.User {
+ _id, ok := sess.Values["uid"]
+ if !ok {
+ return nil
+ }
+
+ id, ok := _id.(string)
+ if !ok {
+ return nil
+ }
+
+ uid, err := db.ParseDBID(id)
+ if err != nil {
+ return nil
+ }
+
+ user, err := dbcon.UserByID(uid)
+ if err != nil {
+ return nil
+ }
+
+ return user
+}
+
+func mkHttpHandler(h Handler, tpl *template.Template) http.HandlerFunc {
+ return func(rw http.ResponseWriter, req *http.Request) {
+ sess, err := getSess(req)
+ if err != nil {
+ log.Printf("Error while getting session: %s", err)
+ rw.Write([]byte("Unable to create session")) // TODO: Better error message...
+ }
+
+ user := userFromSess(sess)
+ outdata := h(user, sess, req)
+
+ if err := sess.Save(req, rw); err != nil {
+ log.Printf("Error while saving session: %s", err)
+ }
+
+ if err := tpl.Execute(rw, outdata); err != nil {
+ log.Printf("Error executing template %s: %s", tpl.Name, err)
+ }
+ }
+}
diff --git a/login.go b/login.go
index e5d039d..459d2ff 100644
--- a/login.go
+++ b/login.go
@@ -16,79 +16,27 @@ type loginFormdata struct {
Mail, Password string
}
-func userFromSess(sess *sessions.Session) model.User {
- _id, ok := sess.Values["uid"]
- if !ok {
- return nil
- }
-
- id, ok := _id.(string)
- if !ok {
- return nil
- }
-
- uid, err := db.ParseDBID(id)
- if err != nil {
- return nil
- }
-
- user, err := dbcon.UserByID(uid)
- if err != nil {
- return nil
- }
-
- return user
-}
-
-func getSess(req *http.Request) (*sessions.Session, error) {
- sess, err := SessionStorage.Get(req, "mailremind-sess")
- if err != nil {
- sess, err = SessionStorage.New(req, "mailremind-sess")
- }
-
- return sess, err
-}
-
-func login(rw http.ResponseWriter, req *http.Request) {
+func login(user model.User, sess *sessions.Session, req *http.Request) interface{} {
outdata := &loginTpldata{}
- defer func() {
- if err := tplLogin.Execute(rw, outdata); err != nil {
- log.Printf("Error executing template in login: %s", err)
- }
- }()
- sess, err := getSess(req)
- if err != nil {
- outdata.Error = "Could not create a session. " + err.Error()
- return
- }
- defer func() {
- if err := sess.Save(req, rw); err != nil {
- log.Printf("Error while saving session: %s", err)
- outdata.Success = ""
- outdata.Error = "Error while saving session."
- return
- }
- }()
-
- if user := userFromSess(sess); user != nil {
+ if user != nil {
outdata.Success = "You are already logged in"
- return
+ return outdata
}
if req.Method != "POST" {
- return
+ return outdata
}
if err := req.ParseForm(); err != nil {
outdata.Error = "Data of form could not be understand. If this happens again, please contact support!"
- return
+ return outdata
}
indata := new(loginFormdata)
if err := formdec.Decode(indata, req.Form); (err != nil) || (indata.Mail == "") || (indata.Password == "") {
outdata.Error = "Input data wrong or missing. Please fill in all values."
- return
+ return outdata
}
user, err := dbcon.UserByMail(indata.Mail)
@@ -96,57 +44,32 @@ func login(rw http.ResponseWriter, req *http.Request) {
case nil:
case model.NotFound:
outdata.Error = "E-Mail or password was wrong."
- return
+ return outdata
default:
log.Printf("Error while loding user data (login): %s", err)
outdata.Error = "User data could not be loaded. Please contact support, if this happens again."
- return
+ return outdata
}
if bcrypt.CompareHashAndPassword(user.PWHash(), []byte(indata.Password)) != nil {
outdata.Error = "E-Mail or password was wrong."
- return
+ return outdata
}
sess.Values["uid"] = user.ID().String()
outdata.Success = "Login successful"
+ return outdata
}
-func logincheck(rw http.ResponseWriter, req *http.Request) {
- sess, _ := getSess(req)
- user := userFromSess(sess)
- outdata := new(msgTpldata)
- if user == nil {
- outdata.Msg = "<nil>"
- } else {
+func logincheck(user model.User, sess *sessions.Session, req *http.Request) interface{} {
+ outdata := &msgTpldata{Msg: "<nil>"}
+ if user != nil {
outdata.Msg = user.Email()
}
- tplMsg.Execute(rw, outdata)
+ return outdata
}
-func logout(rw http.ResponseWriter, req *http.Request) {
- outdata := &msgTpldata{Class: "error", Title: "Logout"}
- defer func() {
- if err := tplMsg.Execute(rw, outdata); err != nil {
- log.Printf("Error executing template in login: %s", err)
- }
- }()
-
- sess, err := getSess(req)
- if err != nil {
- outdata.Msg = "Could not create a session."
- return
- }
- defer func() {
- if err := sess.Save(req, rw); err != nil {
- log.Printf("Error while saving session: %s", err)
- outdata.Class = "error"
- outdata.Msg = "Error while saving session."
- return
- }
- }()
-
+func logout(user model.User, sess *sessions.Session, req *http.Request) interface{} {
delete(sess.Values, "uid")
- outdata.Class = "success"
- outdata.Msg = "Your are now logged out."
+ return &msgTpldata{Class: "success", Title: "Logout", Msg: "Your are now logged out."}
}
diff --git a/main.go b/main.go
index 0289256..7698b1e 100644
--- a/main.go
+++ b/main.go
@@ -76,11 +76,11 @@ func main() {
router := mux.NewRouter()
router.PathPrefix("/static").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(staticpath))))
- router.HandleFunc("/register", register)
- router.HandleFunc("/activate", activate)
- router.HandleFunc("/login", login)
- router.HandleFunc("/logincheck", logincheck)
- router.HandleFunc("/logout", logout)
+ router.HandleFunc("/register", mkHttpHandler(register, tplRegister))
+ router.HandleFunc("/activate", mkHttpHandler(activate, tplMsg))
+ router.HandleFunc("/login", mkHttpHandler(login, tplLogin))
+ router.HandleFunc("/logincheck", mkHttpHandler(logincheck, tplMsg))
+ router.HandleFunc("/logout", mkHttpHandler(logout, tplMsg))
http.Handle("/", router)
diff --git a/register.go b/register.go
index 936f540..38f7b97 100644
--- a/register.go
+++ b/register.go
@@ -2,6 +2,7 @@ package main
import (
"code.google.com/p/go.crypto/bcrypt"
+ "github.com/gorilla/sessions"
"kch42.de/gostuff/mailremind/model"
"log"
"math/rand"
@@ -33,69 +34,72 @@ func genAcCode() string {
return string(code)
}
-func register(rw http.ResponseWriter, req *http.Request) {
+func register(user model.User, sess *sessions.Session, req *http.Request) interface{} {
outdata := &registerData{Timezones: &timeLocs}
- defer func() {
- if err := tplRegister.Execute(rw, outdata); err != nil {
- log.Printf("Exec tplRegister: %s", err)
- }
- }()
-
- if req.Method == "POST" {
- if err := req.ParseForm(); err != nil {
- outdata.Error = "Data of form could not be understand. If this happens again, please contact support!"
- return
- }
-
- indata := new(registerFormdata)
- if err := formdec.Decode(indata, req.Form); (err != nil) || (indata.Mail == "") || (indata.Timezone.Loc == nil) {
- outdata.Error = "Input data wrong or missing. Please fill in all values and make sure to provide a valid E-Mail address."
- return
- }
-
- if indata.Password == "" {
- outdata.Error = "Empty passwords are not allowed."
- return
- }
-
- if indata.Password != indata.RetypePassword {
- outdata.Error = "Passwords are not identical."
- return
- }
-
- mail := string(indata.Mail)
-
- switch _, err := dbcon.UserByMail(mail); err {
- case nil:
- outdata.Error = "This E-Mail address is already used."
- return
- case model.NotFound:
- default:
- log.Printf("Error while checking, if mail is used: %s", err)
- outdata.Error = "Internal error, sorry. If this happens again, please contact support!"
- return
- }
-
- acCode := genAcCode()
- pwhash, err := bcrypt.GenerateFromPassword([]byte(indata.Password), bcrypt.DefaultCost)
- if err != nil {
- log.Printf("Error while hashing password: %s", err)
- outdata.Error = "Internal error, sorry. If this happens again, please contact support!"
- return
- }
-
- user, err := dbcon.AddUser(mail, pwhash, indata.Timezone.Loc, false, acCode)
- if err != nil {
- log.Printf("Could not create user (%s): %s", indata.Mail, err)
- outdata.Error = "Internal error, sorry. If this happens again, please contact support!"
- return
- }
-
- if !SendActivationcode(mail, acCode, user.ID()) {
- outdata.Error = "We could not send you a mail with your confirmation code."
- return
- }
-
- outdata.Success = "Account created successfully! We sent you an E-Mail that contains a link to activate your account."
+
+ if user != nil {
+ outdata.Success = "You are already logged in. To register a new account, first log out."
+ return outdata
+ }
+
+ if req.Method != "POST" {
+ return outdata
+ }
+
+ if err := req.ParseForm(); err != nil {
+ outdata.Error = "Data of form could not be understand. If this happens again, please contact support!"
+ return outdata
+ }
+
+ indata := new(registerFormdata)
+ if err := formdec.Decode(indata, req.Form); (err != nil) || (indata.Mail == "") || (indata.Timezone.Loc == nil) {
+ outdata.Error = "Input data wrong or missing. Please fill in all values and make sure to provide a valid E-Mail address."
+ return outdata
+ }
+
+ if indata.Password == "" {
+ outdata.Error = "Empty passwords are not allowed."
+ return outdata
+ }
+
+ if indata.Password != indata.RetypePassword {
+ outdata.Error = "Passwords are not identical."
+ return outdata
+ }
+
+ mail := string(indata.Mail)
+
+ switch _, err := dbcon.UserByMail(mail); err {
+ case nil:
+ outdata.Error = "This E-Mail address is already used."
+ return outdata
+ case model.NotFound:
+ default:
+ log.Printf("Error while checking, if mail is used: %s", err)
+ outdata.Error = "Internal error, sorry. If this happens again, please contact support!"
+ return outdata
+ }
+
+ acCode := genAcCode()
+ pwhash, err := bcrypt.GenerateFromPassword([]byte(indata.Password), bcrypt.DefaultCost)
+ if err != nil {
+ log.Printf("Error while hashing password: %s", err)
+ outdata.Error = "Internal error, sorry. If this happens again, please contact support!"
+ return outdata
}
+
+ user, err = dbcon.AddUser(mail, pwhash, indata.Timezone.Loc, false, acCode)
+ if err != nil {
+ log.Printf("Could not create user (%s): %s", indata.Mail, err)
+ outdata.Error = "Internal error, sorry. If this happens again, please contact support!"
+ return outdata
+ }
+
+ if !SendActivationcode(mail, acCode, user.ID()) {
+ outdata.Error = "We could not send you a mail with your confirmation code."
+ return outdata
+ }
+
+ outdata.Success = "Account created successfully! We sent you an E-Mail that contains a link to activate your account."
+ return outdata
}