Some code clean

This commit is contained in:
Nicolas Duhamel 2016-04-30 21:32:54 +02:00
parent 0e2733086e
commit 827ab41df5
7 changed files with 83 additions and 84 deletions

View File

@ -91,6 +91,7 @@ func (a *Authorizer) Login(rw http.ResponseWriter, req *http.Request, username,
return nil 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 { func (a *Authorizer) RegenSecret(user User, w http.ResponseWriter, r *http.Request) error {
cookie, err := a.cookiejar.Get(r, a.cookieName) cookie, err := a.cookiejar.Get(r, a.cookieName)
if err != nil { if err != nil {

View File

@ -34,10 +34,10 @@ func main() {
env := web.NewEnv(db, authorizer, log, "./templates") env := web.NewEnv(db, authorizer, log, "./templates")
authMiddleware := auth.NewMiddleware(env.Auth) authMiddleware := auth.NewMiddleware(env.Auth)
env.Handle("users.login", "/users/login", users.Login) env.Handle("users.login", "/users/login", users.LoginHandler)
env.Handle("users.logout", "/users/logout", users.Logout) env.Handle("users.logout", "/users/logout", users.LogoutHandler)
env.HandleRole("users.details", "/users/details", users.Details, users.UserRole) env.HandleRole("users.details", "/users/details", users.DetailsHandler, users.UserRole)
env.HandleRole("users.edit", "/users/edit", users.Edit, users.UserRole) env.HandleRole("users.edit", "/users/edit", users.EditHandler, users.UserRole)
env.HandleRole("movies.polochon", "/movies/polochon", movies.FromPolochon, users.UserRole) env.HandleRole("movies.polochon", "/movies/polochon", movies.FromPolochon, users.UserRole)

View File

@ -12,8 +12,8 @@ import (
"gitlab.quimbo.fr/odwrtw/canape-sql/web" "gitlab.quimbo.fr/odwrtw/canape-sql/web"
) )
// Login login user // LoginHandler login user
func Login(e *web.Env, w http.ResponseWriter, r *http.Request) error { func LoginHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error {
if r.Method == "GET" { if r.Method == "GET" {
return e.Rends(w, r, "users/login") 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 return nil
} }
// Logout just logout // LogoutHandler just logout
func Logout(e *web.Env, w http.ResponseWriter, r *http.Request) error { func LogoutHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error {
e.Auth.Logout(w, r) e.Auth.Logout(w, r)
route := e.GetLoginRouteGetter()() route := e.GetLoginRouteGetter()()
http.Redirect(w, r, route, http.StatusTemporaryRedirect) http.Redirect(w, r, route, http.StatusTemporaryRedirect)
return nil return nil
} }
// Details show user details // DetailsHandler show user details
func Details(env *web.Env, w http.ResponseWriter, r *http.Request) error { func DetailsHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error {
v := auth.GetCurrentUser(r) v := auth.GetCurrentUser(r)
user, ok := v.(*User) user, ok := v.(*User)
if !ok { 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, "user", user)
web.SetData(r, "polochon", polochonConfig) 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 // EditHandler allow editing user info and configuration
func Edit(env *web.Env, w http.ResponseWriter, r *http.Request) error { func EditHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error {
v := auth.GetCurrentUser(r) v := auth.GetCurrentUser(r)
user, ok := v.(*User) user, ok := v.(*User)
if !ok { if !ok {
@ -99,7 +99,7 @@ func Edit(env *web.Env, w http.ResponseWriter, r *http.Request) error {
if r.Method == "GET" { if r.Method == "GET" {
web.SetData(r, "user", user) web.SetData(r, "user", user)
web.SetData(r, "polochon", polochonConfig) web.SetData(r, "polochon", polochonConfig)
return env.Rends(w, r, "users/edit") return e.Rends(w, r, "users/edit")
} }
type editForm struct { type editForm struct {
@ -133,24 +133,28 @@ func Edit(env *web.Env, w http.ResponseWriter, r *http.Request) error {
if form.Password != form.PasswordVerify { if form.Password != form.PasswordVerify {
// TODO: manage form error // TODO: manage form error
} }
user.Hash, err = env.Auth.GenHash(form.Password) user.Hash, err = e.Auth.GenHash(form.Password)
if err != nil { if err != nil {
return err return err
} }
} }
err = user.Update(env.Database) err = user.Update(e.Database)
if err != nil { if err != nil {
pretty.Println(err) pretty.Println(err)
return err return err
} }
err = env.Auth.RegenSecret(user, w, r) err = e.Auth.RegenSecret(user, w, r)
if err != nil { if err != nil {
return err return err
} }
web.SetData(r, "user", user) url, err := e.GetURL("users.details")
web.SetData(r, "polochon", polochonConfig) if err != nil {
return env.Rends(w, r, "users/edit") return err
}
http.Redirect(w, r, url, http.StatusTemporaryRedirect)
return nil
} }

View File

@ -6,14 +6,14 @@ import (
"github.com/gorilla/context" "github.com/gorilla/context"
) )
type contextKey int type key int
// RespData is key for access to response data in context // dKey is key for access to response data in context
const respData contextKey = 0 const dKey key = 0
// GetAllData return response's data // GetAllData return response's data
func GetAllData(r *http.Request) map[string]interface{} { func GetAllData(r *http.Request) map[string]interface{} {
data, ok := context.GetOk(r, respData) data, ok := context.GetOk(r, dKey)
if !ok { if !ok {
return nil return nil
} }
@ -26,11 +26,11 @@ func GetAllData(r *http.Request) map[string]interface{} {
// SetData sets some response's data for access in template // SetData sets some response's data for access in template
func SetData(r *http.Request, key string, val interface{}) { func SetData(r *http.Request, key string, val interface{}) {
data, ok := context.GetOk(r, respData) data, ok := context.GetOk(r, dKey)
if !ok { if !ok {
context.Set(r, respData, make(map[string]interface{})) context.Set(r, dKey, make(map[string]interface{}))
data = make(map[string]interface{}) data = make(map[string]interface{})
} }
data.(map[string]interface{})[key] = val data.(map[string]interface{})[key] = val
context.Set(r, respData, data) context.Set(r, dKey, data)
} }

View File

@ -2,7 +2,6 @@ package web
import ( import (
"fmt" "fmt"
"net/http"
"gitlab.quimbo.fr/odwrtw/canape-sql/auth" "gitlab.quimbo.fr/odwrtw/canape-sql/auth"
@ -13,14 +12,6 @@ import (
"github.com/unrolled/render" "github.com/unrolled/render"
) )
type Mode string
const (
ProductionMode Mode = "production"
DeveloppementMode = "developpement"
TestMode = "test"
)
// Env describes an environement object passed to all handlers // Env describes an environement object passed to all handlers
type Env struct { type Env struct {
Database *sqlx.DB Database *sqlx.DB
@ -28,7 +19,6 @@ type Env struct {
Router *mux.Router Router *mux.Router
Render *render.Render Render *render.Render
Auth *auth.Authorizer Auth *auth.Authorizer
Mode Mode
loginRoute string loginRoute string
} }
@ -39,7 +29,6 @@ func NewEnv(db *sqlx.DB, auth *auth.Authorizer, log *logrus.Entry, templatesDir
Log: log, Log: log,
Router: mux.NewRouter(), Router: mux.NewRouter(),
Auth: auth, Auth: auth,
Mode: ProductionMode,
} }
tmplFuncs = append(tmplFuncs, map[string]interface{}{ tmplFuncs = append(tmplFuncs, map[string]interface{}{
@ -58,13 +47,17 @@ func NewEnv(db *sqlx.DB, auth *auth.Authorizer, log *logrus.Entry, templatesDir
return e return e
} }
func (e *Env) SetLoginRoute(name string) error { // Handle add route
route, err := e.GetURL(name) func (e *Env) Handle(name, route string, H HandlerFunc) {
if err != nil { e.Router.Handle(route, Handler{e, H}).Name(name)
return err }
}
e.loginRoute = route // HandleRole add route and take care of user's role
return nil 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 // 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 return URL.String(), nil
} }
type HandlerFunc func(e *Env, w http.ResponseWriter, r *http.Request) error // SetLoginRoute sets the route name of login page for further use
// with GetLoginRouteGetter
func (e *Env) Handle(name, route string, H HandlerFunc) { func (e *Env) SetLoginRoute(name string) error {
e.Router.Handle(route, Handler{e, H}).Name(name) route, err := e.GetURL(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)
if err != nil { if err != nil {
// Any error types we don't specifically look out for default return err
// to serving a HTTP 500
h.Env.Log.Errorf(err.Error())
http.Error(w, http.StatusText(http.StatusInternalServerError),
http.StatusInternalServerError)
} }
e.loginRoute = route
return nil
} }
// GetLoginRouteGetter allow some code parts like middleware access
// to login route name
func (e *Env) GetLoginRouteGetter() func() string { func (e *Env) GetLoginRouteGetter() func() string {
return func() string { return func() string {
if e.loginRoute == "" { if e.loginRoute == "" {

25
web/handler.go Normal file
View File

@ -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)
}
}

View File

@ -26,26 +26,21 @@ func AddTmplFunc(name string, f interface{}) error {
// TemplateData represents object passed to template renderer // TemplateData represents object passed to template renderer
type TemplateData struct { type TemplateData struct {
Env *Env `json:"-"`
RouteName string RouteName string
Data map[string]interface{} Data map[string]interface{}
} }
// Rends a view // Rends a view
func (e *Env) Rends(w http.ResponseWriter, r *http.Request, template string) error { func (e *Env) Rends(w http.ResponseWriter, r *http.Request, template string) error {
if e.Mode == ProductionMode { if r.Header.Get("Accept") == "application/json" {
return e.Render.HTML(w, http.StatusOK, template, TemplateData{
Env: e,
RouteName: mux.CurrentRoute(r).GetName(),
Data: GetAllData(r),
})
}
if e.Mode == TestMode {
return e.Render.JSON(w, http.StatusOK, TemplateData{ return e.Render.JSON(w, http.StatusOK, TemplateData{
Env: e,
RouteName: mux.CurrentRoute(r).GetName(), RouteName: mux.CurrentRoute(r).GetName(),
Data: GetAllData(r), Data: GetAllData(r),
}) })
} }
return nil
return e.Render.HTML(w, http.StatusOK, template, TemplateData{
RouteName: mux.CurrentRoute(r).GetName(),
Data: GetAllData(r),
})
} }