diff --git a/handlers/handlers.go b/handlers/handlers.go index 70a68f3e..ac0b588c 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -30,6 +30,19 @@ type PathPattern struct { Permission int } +type Handlers struct { + Models []interface{} + + Login func() http.Handler + Logout func() http.Handler + Home func() http.Handler + GetToken func() http.Handler + Static func() http.Handler + Recover func(next http.Handler) http.Handler + + Router *mux.Router +} + var ( permissions map[string]map[string]bool ) @@ -62,7 +75,7 @@ func pluralizedModelName(s interface{}) string { } // Generate CRUD handlers for models -func generateHandler(r *mux.Router, model interface{}) { +func (h *Handlers) generateModelHandlers(r *mux.Router, model interface{}) { var ( patterns []PathPattern = []PathPattern{ PathPattern{"/%s", "", []string{"GET"}, PermissionReadAll}, @@ -89,8 +102,8 @@ func generateHandler(r *mux.Router, model interface{}) { pluralizedModelName(model), ), jwtCookie.Handler( - recoverHandler( - modelHandler( + h.Recover( + h.modelHandler( pluralizedModelName(model), pattern, )))).Methods(pattern.Methods...) @@ -103,8 +116,8 @@ func generateHandler(r *mux.Router, model interface{}) { pluralizedModelName(model), ), jwtHeader.Handler( - recoverHandler( - modelHandler( + h.Recover( + h.modelHandler( pluralizedModelName(model), pattern, )))).Methods(pattern.Methods...) @@ -141,31 +154,40 @@ func generateHandler(r *mux.Router, model interface{}) { } -func Handlers(models []interface{}) *mux.Router { +func NewHandlers(models []interface{}) *Handlers { + + handlers := new(Handlers) + + handlers.Login = DefaultLoginHandler + handlers.Logout = DefaultLogoutHandler + handlers.Recover = DefaultRecoverHandler + handlers.Home = DefaultHomeHandler + handlers.GetToken = DefaultGetTokenHandler + r := mux.NewRouter() // Authentication - r.Handle("/login", loginHandler()) - r.Handle("/logout", logoutHandler()) + r.Handle("/login", handlers.Login()) + r.Handle("/logout", handlers.Logout()) // School subscription - r.Handle("/subscribe", loginHandler()) + r.Handle("/subscribe", handlers.Login()) - // Dashboard + // Home - r.Handle("/", jwtCookie.Handler(recoverHandler(homeHandler()))) + r.Handle("/", jwtCookie.Handler(handlers.Recover(handlers.Home()))) // Generate CRUD handlers for _, model := range models { - generateHandler(r, model) + handlers.generateModelHandlers(r, model) } // Token handling - r.Handle("/get_token", tokenHandler()) + r.Handle("/get_token", handlers.GetToken()) // Static file server @@ -202,7 +224,7 @@ func fromCookie(r *http.Request) (string, error) { return string(token), nil } -func recoverHandler(next http.Handler) http.Handler { +func DefaultRecoverHandler(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { defer func() { if err := recover(); err != nil { @@ -337,7 +359,7 @@ func respondWithError(w http.ResponseWriter, r *http.Request, err error) { renderer.Render[respFormat](w, r, err) } -func modelHandler(model string, pattern PathPattern) http.Handler { +func (h *Handlers) modelHandler(model string, pattern PathPattern) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { // Replace "api" prefix @@ -358,7 +380,7 @@ func modelHandler(model string, pattern PathPattern) http.Handler { return http.HandlerFunc(fn) } -func homeHandler() http.Handler { +func DefaultHomeHandler() http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { claims := r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims) diff --git a/handlers/login.go b/handlers/login.go index 23cbd7da..2fdd232a 100644 --- a/handlers/login.go +++ b/handlers/login.go @@ -43,7 +43,7 @@ var ( }) ) -func logoutHandler() http.Handler { +func DefaultLogoutHandler() http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { session, err := store.Get(r, "login-session") if err != nil { @@ -60,7 +60,7 @@ func logoutHandler() http.Handler { return http.HandlerFunc(fn) } -func loginHandler() http.Handler { +func DefaultLoginHandler() http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { renderer.Render["html"](w, r, nil, r.URL.Query()) @@ -156,7 +156,7 @@ func getToken(username string, password string) ([]byte, error) { } // FIXME: Refactor the functions above please!!! -func tokenHandler() http.Handler { +func DefaultGetTokenHandler() http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { username, password, _ := r.BasicAuth()