From 827ab41df596bad461dceac4c24fce1c91274f2d Mon Sep 17 00:00:00 2001 From: Nicolas Duhamel Date: Sat, 30 Apr 2016 21:32:54 +0200 Subject: [PATCH] Some code clean --- auth/auth.go | 1 + main.go | 8 +++--- users/handlers.go | 36 ++++++++++++++------------ web/data.go | 14 +++++----- web/env.go | 66 ++++++++++++++--------------------------------- web/handler.go | 25 ++++++++++++++++++ web/templates.go | 17 +++++------- 7 files changed, 83 insertions(+), 84 deletions(-) create mode 100644 web/handler.go diff --git a/auth/auth.go b/auth/auth.go index be689d3..41f2b8b 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -91,6 +91,7 @@ func (a *Authorizer) Login(rw http.ResponseWriter, req *http.Request, username, return nil } +// RegenSecret update secret in cookie with user info, usefull when updating password func (a *Authorizer) RegenSecret(user User, w http.ResponseWriter, r *http.Request) error { cookie, err := a.cookiejar.Get(r, a.cookieName) if err != nil { diff --git a/main.go b/main.go index 840e3c3..8762ee8 100644 --- a/main.go +++ b/main.go @@ -34,10 +34,10 @@ func main() { env := web.NewEnv(db, authorizer, log, "./templates") authMiddleware := auth.NewMiddleware(env.Auth) - env.Handle("users.login", "/users/login", users.Login) - env.Handle("users.logout", "/users/logout", users.Logout) - env.HandleRole("users.details", "/users/details", users.Details, users.UserRole) - env.HandleRole("users.edit", "/users/edit", users.Edit, users.UserRole) + env.Handle("users.login", "/users/login", users.LoginHandler) + env.Handle("users.logout", "/users/logout", users.LogoutHandler) + env.HandleRole("users.details", "/users/details", users.DetailsHandler, users.UserRole) + env.HandleRole("users.edit", "/users/edit", users.EditHandler, users.UserRole) env.HandleRole("movies.polochon", "/movies/polochon", movies.FromPolochon, users.UserRole) diff --git a/users/handlers.go b/users/handlers.go index b3e5796..438c178 100644 --- a/users/handlers.go +++ b/users/handlers.go @@ -12,8 +12,8 @@ import ( "gitlab.quimbo.fr/odwrtw/canape-sql/web" ) -// Login login user -func Login(e *web.Env, w http.ResponseWriter, r *http.Request) error { +// LoginHandler login user +func LoginHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error { if r.Method == "GET" { return e.Rends(w, r, "users/login") } @@ -56,16 +56,16 @@ func Login(e *web.Env, w http.ResponseWriter, r *http.Request) error { return nil } -// Logout just logout -func Logout(e *web.Env, w http.ResponseWriter, r *http.Request) error { +// LogoutHandler just logout +func LogoutHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error { e.Auth.Logout(w, r) route := e.GetLoginRouteGetter()() http.Redirect(w, r, route, http.StatusTemporaryRedirect) return nil } -// Details show user details -func Details(env *web.Env, w http.ResponseWriter, r *http.Request) error { +// DetailsHandler show user details +func DetailsHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error { v := auth.GetCurrentUser(r) user, ok := v.(*User) if !ok { @@ -80,11 +80,11 @@ func Details(env *web.Env, w http.ResponseWriter, r *http.Request) error { web.SetData(r, "user", user) web.SetData(r, "polochon", polochonConfig) - return env.Rends(w, r, "users/details") + return e.Rends(w, r, "users/details") } -// Edit allow editing user info and configuration -func Edit(env *web.Env, w http.ResponseWriter, r *http.Request) error { +// EditHandler allow editing user info and configuration +func EditHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error { v := auth.GetCurrentUser(r) user, ok := v.(*User) if !ok { @@ -99,7 +99,7 @@ func Edit(env *web.Env, w http.ResponseWriter, r *http.Request) error { if r.Method == "GET" { web.SetData(r, "user", user) web.SetData(r, "polochon", polochonConfig) - return env.Rends(w, r, "users/edit") + return e.Rends(w, r, "users/edit") } type editForm struct { @@ -133,24 +133,28 @@ func Edit(env *web.Env, w http.ResponseWriter, r *http.Request) error { if form.Password != form.PasswordVerify { // TODO: manage form error } - user.Hash, err = env.Auth.GenHash(form.Password) + user.Hash, err = e.Auth.GenHash(form.Password) if err != nil { return err } } - err = user.Update(env.Database) + err = user.Update(e.Database) if err != nil { pretty.Println(err) return err } - err = env.Auth.RegenSecret(user, w, r) + err = e.Auth.RegenSecret(user, w, r) if err != nil { return err } - web.SetData(r, "user", user) - web.SetData(r, "polochon", polochonConfig) - return env.Rends(w, r, "users/edit") + url, err := e.GetURL("users.details") + if err != nil { + return err + } + + http.Redirect(w, r, url, http.StatusTemporaryRedirect) + return nil } diff --git a/web/data.go b/web/data.go index 1f53915..78c8416 100644 --- a/web/data.go +++ b/web/data.go @@ -6,14 +6,14 @@ import ( "github.com/gorilla/context" ) -type contextKey int +type key int -// RespData is key for access to response data in context -const respData contextKey = 0 +// dKey is key for access to response data in context +const dKey key = 0 // GetAllData return response's data func GetAllData(r *http.Request) map[string]interface{} { - data, ok := context.GetOk(r, respData) + data, ok := context.GetOk(r, dKey) if !ok { return nil } @@ -26,11 +26,11 @@ func GetAllData(r *http.Request) map[string]interface{} { // SetData sets some response's data for access in template func SetData(r *http.Request, key string, val interface{}) { - data, ok := context.GetOk(r, respData) + data, ok := context.GetOk(r, dKey) if !ok { - context.Set(r, respData, make(map[string]interface{})) + context.Set(r, dKey, make(map[string]interface{})) data = make(map[string]interface{}) } data.(map[string]interface{})[key] = val - context.Set(r, respData, data) + context.Set(r, dKey, data) } diff --git a/web/env.go b/web/env.go index 8724c63..434ef2f 100644 --- a/web/env.go +++ b/web/env.go @@ -2,7 +2,6 @@ package web import ( "fmt" - "net/http" "gitlab.quimbo.fr/odwrtw/canape-sql/auth" @@ -13,14 +12,6 @@ import ( "github.com/unrolled/render" ) -type Mode string - -const ( - ProductionMode Mode = "production" - DeveloppementMode = "developpement" - TestMode = "test" -) - // Env describes an environement object passed to all handlers type Env struct { Database *sqlx.DB @@ -28,7 +19,6 @@ type Env struct { Router *mux.Router Render *render.Render Auth *auth.Authorizer - Mode Mode loginRoute string } @@ -39,7 +29,6 @@ func NewEnv(db *sqlx.DB, auth *auth.Authorizer, log *logrus.Entry, templatesDir Log: log, Router: mux.NewRouter(), Auth: auth, - Mode: ProductionMode, } tmplFuncs = append(tmplFuncs, map[string]interface{}{ @@ -58,13 +47,17 @@ func NewEnv(db *sqlx.DB, auth *auth.Authorizer, log *logrus.Entry, templatesDir return e } -func (e *Env) SetLoginRoute(name string) error { - route, err := e.GetURL(name) - if err != nil { - return err - } - e.loginRoute = route - return nil +// Handle add route +func (e *Env) Handle(name, route string, H HandlerFunc) { + e.Router.Handle(route, Handler{e, H}).Name(name) +} + +// HandleRole add route and take care of user's role +func (e *Env) HandleRole(name, route string, H HandlerFunc, role string) { + e.Router.Handle(route, negroni.New( + auth.NewMiddlewareRole(e.Auth, e.GetLoginRouteGetter(), role), + negroni.Wrap(Handler{e, H}), + )).Name(name) } // GetURL returns URL string from URL name and params @@ -81,38 +74,19 @@ func (e *Env) GetURL(name string, pairs ...string) (string, error) { return URL.String(), nil } -type HandlerFunc func(e *Env, w http.ResponseWriter, r *http.Request) error - -func (e *Env) Handle(name, route string, H HandlerFunc) { - e.Router.Handle(route, Handler{e, H}).Name(name) -} - -func (e *Env) HandleRole(name, route string, H HandlerFunc, role string) { - e.Router.Handle(route, negroni.New( - auth.NewMiddlewareRole(e.Auth, e.GetLoginRouteGetter(), role), - negroni.Wrap(Handler{e, H}), - )).Name(name) -} - -// The Handler struct that takes a configured Env and a function matching our -// handler signature -type Handler struct { - *Env - H func(e *Env, w http.ResponseWriter, r *http.Request) error -} - -// ServeHTTP allows our Handler type to satisfy http.Handler. -func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - err := h.H(h.Env, w, r) +// SetLoginRoute sets the route name of login page for further use +// with GetLoginRouteGetter +func (e *Env) SetLoginRoute(name string) error { + route, err := e.GetURL(name) if err != nil { - // Any error types we don't specifically look out for default - // to serving a HTTP 500 - h.Env.Log.Errorf(err.Error()) - http.Error(w, http.StatusText(http.StatusInternalServerError), - http.StatusInternalServerError) + return err } + e.loginRoute = route + return nil } +// GetLoginRouteGetter allow some code parts like middleware access +// to login route name func (e *Env) GetLoginRouteGetter() func() string { return func() string { if e.loginRoute == "" { diff --git a/web/handler.go b/web/handler.go new file mode 100644 index 0000000..54a76e4 --- /dev/null +++ b/web/handler.go @@ -0,0 +1,25 @@ +package web + +import "net/http" + +// HandlerFunc is our handler signature +type HandlerFunc func(e *Env, w http.ResponseWriter, r *http.Request) error + +// The Handler struct that takes a configured Env and a function matching our +// handler signature +type Handler struct { + *Env + H HandlerFunc +} + +// ServeHTTP allows our Handler type to satisfy http.Handler. +func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + err := h.H(h.Env, w, r) + if err != nil { + // Any error types we don't specifically look out for default + // to serving a HTTP 500 + h.Env.Log.Errorf(err.Error()) + http.Error(w, http.StatusText(http.StatusInternalServerError), + http.StatusInternalServerError) + } +} diff --git a/web/templates.go b/web/templates.go index 8e15f51..1b494da 100644 --- a/web/templates.go +++ b/web/templates.go @@ -26,26 +26,21 @@ func AddTmplFunc(name string, f interface{}) error { // TemplateData represents object passed to template renderer type TemplateData struct { - Env *Env `json:"-"` RouteName string Data map[string]interface{} } // Rends a view func (e *Env) Rends(w http.ResponseWriter, r *http.Request, template string) error { - if e.Mode == ProductionMode { - return e.Render.HTML(w, http.StatusOK, template, TemplateData{ - Env: e, - RouteName: mux.CurrentRoute(r).GetName(), - Data: GetAllData(r), - }) - } - if e.Mode == TestMode { + if r.Header.Get("Accept") == "application/json" { return e.Render.JSON(w, http.StatusOK, TemplateData{ - Env: e, RouteName: mux.CurrentRoute(r).GetName(), Data: GetAllData(r), }) } - return nil + + return e.Render.HTML(w, http.StatusOK, template, TemplateData{ + RouteName: mux.CurrentRoute(r).GetName(), + Data: GetAllData(r), + }) }