The main server, and probably only repository in this org.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
1.7 KiB

5 years ago
  1. package middlewares
  2. import (
  3. "net/http"
  4. "strings"
  5. "time"
  6. "git.aiterp.net/lucifer/lucifer/internal/httperr"
  7. "git.aiterp.net/lucifer/lucifer/models"
  8. "github.com/gorilla/mux"
  9. )
  10. // Session is a middleware that adds a Session to the request context if there
  11. // is one.
  12. func Session(sessions models.SessionRepository, users models.UserRepository) mux.MiddlewareFunc {
  13. clearCookie := &http.Cookie{
  14. Name: "lucifer_session",
  15. Value: "",
  16. Path: "/",
  17. Expires: time.Unix(0, 0),
  18. HttpOnly: true,
  19. }
  20. redirectFailure := func(next http.Handler, w http.ResponseWriter, r *http.Request) {
  21. if !strings.HasPrefix(r.URL.Path, "/api/") || strings.HasPrefix(r.URL.Path, "/api/user/") {
  22. next.ServeHTTP(w, r)
  23. } else {
  24. httperr.Respond(w, httperr.ErrLoginRequired)
  25. }
  26. }
  27. return func(next http.Handler) http.Handler {
  28. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  29. ctx := r.Context()
  30. // Find cookie
  31. cookie, err := r.Cookie("lucifer_session")
  32. if err != nil || cookie == nil {
  33. redirectFailure(next, w, r)
  34. return
  35. }
  36. // Check session existence
  37. session, err := sessions.FindByID(r.Context(), cookie.Value)
  38. if err != nil {
  39. http.SetCookie(w, clearCookie)
  40. redirectFailure(next, w, r)
  41. return
  42. }
  43. ctx = session.InContext(ctx)
  44. user, err := users.FindByID(r.Context(), session.UserID)
  45. if err != nil {
  46. http.SetCookie(w, clearCookie)
  47. redirectFailure(next, w, r)
  48. return
  49. }
  50. ctx = user.InContext(ctx)
  51. // Check if session has expired
  52. if session.Expired() {
  53. http.SetCookie(w, clearCookie)
  54. redirectFailure(next, w, r)
  55. return
  56. }
  57. // Proceed.
  58. next.ServeHTTP(w, r.WithContext(ctx))
  59. })
  60. }
  61. }