api.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package api
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "log"
  6. "net/http"
  7. "path/filepath"
  8. "runtime/debug"
  9. jwtmiddleware "github.com/auth0/go-jwt-middleware"
  10. jwt "github.com/dgrijalva/jwt-go"
  11. "github.com/gorilla/mux"
  12. "github.com/gorilla/sessions"
  13. )
  14. var (
  15. signingKey = []byte("secret")
  16. store = sessions.NewCookieStore([]byte("something-very-secret"))
  17. jwtMiddleware = jwtmiddleware.New(jwtmiddleware.Options{
  18. ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
  19. return signingKey, nil
  20. },
  21. SigningMethod: jwt.SigningMethodHS256,
  22. Extractor: fromCookie,
  23. ErrorHandler: onError,
  24. })
  25. )
  26. type User struct {
  27. Name string
  28. Admin bool
  29. }
  30. func Handlers() *mux.Router {
  31. r := mux.NewRouter()
  32. // Authentication
  33. r.Handle("/login", loginHandler())
  34. r.Handle("/logout", logoutHandler())
  35. // Dashboard
  36. r.Handle("/", jwtMiddleware.Handler(recoverHandler(dashboardHandler())))
  37. // School
  38. r.Handle("/school/{id}", jwtMiddleware.Handler(recoverHandler(schoolShowHandler())))
  39. r.Handle("/school/{id}/update", jwtMiddleware.Handler(recoverHandler(schoolUpdateHandler()))).Methods("GET", "POST")
  40. // Teachers
  41. r.Handle("/teachers/check_username/{username}", jwtMiddleware.Handler(recoverHandler(teachersCheckUsernameHandler())))
  42. r.Handle("/teachers", jwtMiddleware.Handler(recoverHandler(teachersHandler())))
  43. r.Handle("/teachers/add", jwtMiddleware.Handler(recoverHandler(teachersAddHandler()))).Methods("GET", "POST")
  44. r.Handle("/teachers/{id}/delete", jwtMiddleware.Handler(recoverHandler(teachersDeleteHandler()))).Methods("DELETE")
  45. r.Handle("/teachers/{id}", jwtMiddleware.Handler(recoverHandler(teacherShowHandler()))).Methods("GET")
  46. r.Handle("/teachers/{id}/update", jwtMiddleware.Handler(recoverHandler(teacherUpdateHandler()))).Methods("GET", "POST")
  47. r.Handle("/teachers/import", jwtMiddleware.Handler(recoverHandler(teachersImportHandler()))).Methods("POST")
  48. // Teachers -> Subjects
  49. r.Handle("/teachers/{id}/subjects/add", jwtMiddleware.Handler(recoverHandler(teacherSubjectsAdd()))).Methods("GET")
  50. r.Handle("/teachers/{id}/subjects/add", jwtMiddleware.Handler(recoverHandler(teacherSubjectsAdd()))).Methods("POST")
  51. r.Handle("/teachers/{id}/subjects/{subject_id}/delete", jwtMiddleware.Handler(recoverHandler(teachersSubjectsDelete()))).Methods("DELETE")
  52. // Teachers -> Classes
  53. r.Handle("/teachers/{id}/classes/add", jwtMiddleware.Handler(recoverHandler(teacherClassesAdd()))).Methods("GET")
  54. r.Handle("/teachers/{id}/classes/add", jwtMiddleware.Handler(recoverHandler(teacherClassesAdd()))).Methods("POST")
  55. r.Handle("/teachers/{id}/classes/{class_id}/delete", jwtMiddleware.Handler(recoverHandler(teachersClassesDelete()))).Methods("DELETE")
  56. // Subjects
  57. r.Handle("/subjects", jwtMiddleware.Handler(recoverHandler(subjectsHandler())))
  58. r.Handle("/subjects/add", jwtMiddleware.Handler(recoverHandler(subjectsAddHandler()))).Methods("GET", "POST")
  59. r.Handle("/subjects/{id}", jwtMiddleware.Handler(recoverHandler(subjectsShowHandler()))).Methods("GET")
  60. r.Handle("/subjects/{id}/update", jwtMiddleware.Handler(recoverHandler(subjectsUpdateHandler()))).Methods("GET", "POST")
  61. r.Handle("/subjects/{id}/delete", jwtMiddleware.Handler(recoverHandler(subjectsDeleteHandler()))).Methods("DELETE")
  62. r.Handle("/subjects/import", jwtMiddleware.Handler(recoverHandler(subjectsImportHandler()))).Methods("POST")
  63. // Activities
  64. r.Handle("/activities", jwtMiddleware.Handler(recoverHandler(activitiesHandler())))
  65. r.Handle("/activities/add", jwtMiddleware.Handler(recoverHandler(activitiesAddHandler()))).Methods("GET", "POST")
  66. r.Handle("/activities/{id}/update", jwtMiddleware.Handler(recoverHandler(activitiesUpdateHandler()))).Methods("GET", "POST")
  67. r.Handle("/activities/{id}/delete", jwtMiddleware.Handler(recoverHandler(activitiesDeleteHandler()))).Methods("DELETE")
  68. // Classes
  69. r.Handle("/classes", jwtMiddleware.Handler(recoverHandler(classesHandler())))
  70. r.Handle("/classes/add", jwtMiddleware.Handler(recoverHandler(classesAddHandler()))).Methods("GET", "POST")
  71. r.Handle("/classes/{id}", jwtMiddleware.Handler(recoverHandler(classesShowHandler()))).Methods("GET")
  72. r.Handle("/classes/{id}/update", jwtMiddleware.Handler(recoverHandler(classesUpdateHandler()))).Methods("GET", "POST")
  73. r.Handle("/classes/{id}/delete", jwtMiddleware.Handler(recoverHandler(classesDeleteHandler()))).Methods("DELETE")
  74. r.Handle("/classes/import", jwtMiddleware.Handler(recoverHandler(classesImportHandler()))).Methods("POST")
  75. // Static file server
  76. r.PathPrefix("/").Handler(http.FileServer(http.Dir("./dist/")))
  77. return r
  78. }
  79. func onError(w http.ResponseWriter, r *http.Request, err string) {
  80. http.Redirect(w, r, "/login", http.StatusTemporaryRedirect)
  81. }
  82. func respondWithStaticFile(w http.ResponseWriter, filename string) error {
  83. f, err := ioutil.ReadFile(filepath.Join("public/html", filename))
  84. if err != nil {
  85. return err
  86. }
  87. w.Write(f)
  88. return nil
  89. }
  90. func fromCookie(r *http.Request) (string, error) {
  91. session, err := store.Get(r, "login-session")
  92. if err != nil {
  93. return "", nil
  94. }
  95. if session.Values["token"] == nil {
  96. return "", nil
  97. }
  98. token := session.Values["token"].([]uint8)
  99. return string(token), nil
  100. }
  101. func recoverHandler(next http.Handler) http.Handler {
  102. fn := func(w http.ResponseWriter, r *http.Request) {
  103. defer func() {
  104. if err := recover(); err != nil {
  105. panicMsg := fmt.Sprintf("PANIC: %v\n\n== STACKTRACE ==\n%s", err, debug.Stack())
  106. log.Print(panicMsg)
  107. http.Error(w, panicMsg, http.StatusInternalServerError)
  108. }
  109. }()
  110. next.ServeHTTP(w, r)
  111. }
  112. return http.HandlerFunc(fn)
  113. }