package web import ( "fmt" "gitlab.quimbo.fr/odwrtw/canape-sql/auth" "gitlab.quimbo.fr/odwrtw/canape-sql/config" "github.com/Sirupsen/logrus" "github.com/codegangsta/negroni" "github.com/gorilla/mux" "github.com/jmoiron/sqlx" "github.com/unrolled/render" ) // Env describes an environement object passed to all handlers type Env struct { Database *sqlx.DB Log *logrus.Entry Router *mux.Router Render *render.Render Auth *auth.Authorizer Config *config.Config loginRoute string } // EnvParams represents parameters for NewEnv type EnvParams struct { Database *sqlx.DB Auth *auth.Authorizer Log *logrus.Entry Config *config.Config TemplatesDir string } // NewEnv returns a new *Env func NewEnv(p EnvParams) *Env { e := &Env{ Database: p.Database, Log: p.Log, Router: mux.NewRouter(), Auth: p.Auth, Config: p.Config, } tmplFuncs = append(tmplFuncs, map[string]interface{}{ "URL": func(name string, pairs ...string) (string, error) { return e.GetURL(name, pairs...) }, }) e.Render = render.New(render.Options{ Directory: p.TemplatesDir, Layout: "layout", Funcs: tmplFuncs, DisableHTTPErrorRendering: true, RequirePartials: true, }) return e } type Route struct { env *Env mRoute *mux.Route } func (r *Route) Name(name string) *Route { r.mRoute.Name(name) return r } func (r *Route) Methods(methods ...string) *Route { r.mRoute.Methods(methods...) return r } func (r *Route) WithRole(role string) *Route { handler := r.mRoute.GetHandler() newHandler := negroni.New( auth.NewMiddlewareRole(r.env.Auth, r.env.GetLoginRouteGetter(), role), negroni.Wrap(handler)) r.mRoute.Handler(newHandler) return r } // Handle add route func (e *Env) Handle(route string, H HandlerFunc) *Route { mRoute := e.Router.Handle(route, Handler{e, H}) return &Route{ env: e, mRoute: mRoute, } } // GetURL returns URL string from URL name and params // Usefull for redirection and templates func (e *Env) GetURL(name string, pairs ...string) (string, error) { route := e.Router.Get(name) if route == nil { return "", fmt.Errorf("No route find for the given name: %s", name) } URL, err := route.URL(pairs...) if err != nil { return "", err } return URL.String(), nil } // 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 { 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 == "" { panic("Env: login route not set") } return e.loginRoute } }