package api import ( "fmt" "io/ioutil" "log" "net/http" "path/filepath" "runtime/debug" jwtmiddleware "github.com/auth0/go-jwt-middleware" jwt "github.com/dgrijalva/jwt-go" "github.com/gorilla/mux" "github.com/gorilla/sessions" ) var ( signingKey = []byte("secret") store = sessions.NewCookieStore([]byte("something-very-secret")) jwtMiddleware = jwtmiddleware.New(jwtmiddleware.Options{ ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) { return signingKey, nil }, SigningMethod: jwt.SigningMethodHS256, Extractor: fromCookie, ErrorHandler: onError, }) ) type User struct { Name string Admin bool } func Handlers() *mux.Router { r := mux.NewRouter() // Authentication r.Handle("/login", loginHandler()) r.Handle("/logout", logoutHandler()) // Dashboard r.Handle("/", jwtMiddleware.Handler(recoverHandler(dashboardHandler()))) // School r.Handle("/school/{id}", jwtMiddleware.Handler(recoverHandler(schoolShowHandler()))) r.Handle("/school/{id}/update", jwtMiddleware.Handler(recoverHandler(schoolUpdateHandler()))).Methods("GET", "POST") // Teachers r.Handle("/teachers/check_username/{username}", jwtMiddleware.Handler(recoverHandler(teachersCheckUsernameHandler()))) r.Handle("/teachers", jwtMiddleware.Handler(recoverHandler(teachersHandler()))) r.Handle("/teachers/add", jwtMiddleware.Handler(recoverHandler(teachersAddHandler()))).Methods("GET", "POST") r.Handle("/teachers/{id}/delete", jwtMiddleware.Handler(recoverHandler(teachersDeleteHandler()))).Methods("DELETE") r.Handle("/teachers/{id}", jwtMiddleware.Handler(recoverHandler(teacherShowHandler()))).Methods("GET") r.Handle("/teachers/{id}/update", jwtMiddleware.Handler(recoverHandler(teacherUpdateHandler()))).Methods("GET", "POST") r.Handle("/teachers/import", jwtMiddleware.Handler(recoverHandler(teachersImportHandler()))).Methods("POST") // Teachers -> Subjects r.Handle("/teachers/{id}/subjects/add", jwtMiddleware.Handler(recoverHandler(teacherSubjectsAdd()))).Methods("GET") r.Handle("/teachers/{id}/subjects/add", jwtMiddleware.Handler(recoverHandler(teacherSubjectsAdd()))).Methods("POST") r.Handle("/teachers/{id}/subjects/{subject_id}/delete", jwtMiddleware.Handler(recoverHandler(teachersSubjectsDelete()))).Methods("DELETE") // Teachers -> Classes r.Handle("/teachers/{id}/classes/add", jwtMiddleware.Handler(recoverHandler(teacherClassesAdd()))).Methods("GET") r.Handle("/teachers/{id}/classes/add", jwtMiddleware.Handler(recoverHandler(teacherClassesAdd()))).Methods("POST") r.Handle("/teachers/{id}/classes/{class_id}/delete", jwtMiddleware.Handler(recoverHandler(teachersClassesDelete()))).Methods("DELETE") // Subjects r.Handle("/subjects", jwtMiddleware.Handler(recoverHandler(subjectsHandler()))) r.Handle("/subjects/add", jwtMiddleware.Handler(recoverHandler(subjectsAddHandler()))).Methods("GET", "POST") r.Handle("/subjects/{id}", jwtMiddleware.Handler(recoverHandler(subjectsShowHandler()))).Methods("GET") r.Handle("/subjects/{id}/update", jwtMiddleware.Handler(recoverHandler(subjectsUpdateHandler()))).Methods("GET", "POST") r.Handle("/subjects/{id}/delete", jwtMiddleware.Handler(recoverHandler(subjectsDeleteHandler()))).Methods("DELETE") r.Handle("/subjects/import", jwtMiddleware.Handler(recoverHandler(subjectsImportHandler()))).Methods("POST") // Activities r.Handle("/activities", jwtMiddleware.Handler(recoverHandler(activitiesHandler()))) r.Handle("/activities/add", jwtMiddleware.Handler(recoverHandler(activitiesAddHandler()))).Methods("GET", "POST") r.Handle("/activities/{id}/update", jwtMiddleware.Handler(recoverHandler(activitiesUpdateHandler()))).Methods("GET", "POST") r.Handle("/activities/{id}/delete", jwtMiddleware.Handler(recoverHandler(activitiesDeleteHandler()))).Methods("DELETE") // Classes r.Handle("/classes", jwtMiddleware.Handler(recoverHandler(classesHandler()))) r.Handle("/classes/add", jwtMiddleware.Handler(recoverHandler(classesAddHandler()))).Methods("GET", "POST") r.Handle("/classes/{id}", jwtMiddleware.Handler(recoverHandler(classesShowHandler()))).Methods("GET") r.Handle("/classes/{id}/update", jwtMiddleware.Handler(recoverHandler(classesUpdateHandler()))).Methods("GET", "POST") r.Handle("/classes/{id}/delete", jwtMiddleware.Handler(recoverHandler(classesDeleteHandler()))).Methods("DELETE") r.Handle("/classes/import", jwtMiddleware.Handler(recoverHandler(classesImportHandler()))).Methods("POST") // Documents r.Handle("/documents", jwtMiddleware.Handler(recoverHandler(documentsHandler()))) // Static file server r.PathPrefix("/").Handler(http.FileServer(http.Dir("./dist/"))) return r } func onError(w http.ResponseWriter, r *http.Request, err string) { http.Redirect(w, r, "/login", http.StatusTemporaryRedirect) } func respondWithStaticFile(w http.ResponseWriter, filename string) error { f, err := ioutil.ReadFile(filepath.Join("public/html", filename)) if err != nil { return err } w.Write(f) return nil } func fromCookie(r *http.Request) (string, error) { session, err := store.Get(r, "login-session") if err != nil { return "", nil } if session.Values["token"] == nil { return "", nil } token := session.Values["token"].([]uint8) return string(token), nil } func recoverHandler(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { defer func() { if err := recover(); err != nil { panicMsg := fmt.Sprintf("PANIC: %v\n\n== STACKTRACE ==\n%s", err, debug.Stack()) log.Print(panicMsg) http.Error(w, panicMsg, http.StatusInternalServerError) } }() next.ServeHTTP(w, r) } return http.HandlerFunc(fn) }