auth.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package routes
  2. import (
  3. "encoding/gob"
  4. "encoding/json"
  5. "fmt"
  6. "net/http"
  7. "github.com/andreanidouglas/auth/model"
  8. "github.com/gorilla/securecookie"
  9. "github.com/gorilla/sessions"
  10. "golang.org/x/crypto/bcrypt"
  11. )
  12. type user struct {
  13. Email string `json:"email"`
  14. Password string `jsob:"password"`
  15. }
  16. type authenticated struct {
  17. Email string
  18. Authenticated bool
  19. }
  20. const (
  21. AUTH_KEY string = "session_id"
  22. USER_ID string = "user_id"
  23. )
  24. var store *sessions.CookieStore
  25. type AuthRoutes struct{}
  26. func (a *AuthRoutes) Register(r *Routes) {
  27. AuthInit()
  28. Login(r)
  29. }
  30. func AuthInit() {
  31. auth_key := securecookie.GenerateRandomKey(64)
  32. encryption_key := securecookie.GenerateRandomKey(32)
  33. store = sessions.NewCookieStore(
  34. auth_key,
  35. encryption_key,
  36. )
  37. store.Options = &sessions.Options{
  38. Path: "/auth",
  39. MaxAge: 60 * 15,
  40. HttpOnly: true,
  41. }
  42. gob.Register(authenticated{})
  43. }
  44. func getUser(s *sessions.Session) authenticated {
  45. val := s.Values["user"]
  46. var user = authenticated{}
  47. user, ok := val.(authenticated)
  48. if !ok {
  49. return authenticated{Authenticated: false}
  50. }
  51. return user
  52. }
  53. func AuthMiddleware(next http.HandlerFunc) func(http.ResponseWriter, *http.Request) {
  54. return func(w http.ResponseWriter, r *http.Request) {
  55. fmt.Printf("got store: %v", store)
  56. session, err := store.Get(r, "cookie-name")
  57. if err != nil {
  58. w.WriteHeader(500)
  59. fmt.Fprintf(w, "Internal Server Error: %v", err)
  60. return
  61. }
  62. authed := getUser(session)
  63. if auth := authed.Authenticated; !auth {
  64. w.WriteHeader(403)
  65. fmt.Fprintf(w, "Unauthorized")
  66. return
  67. }
  68. next.ServeHTTP(w, r)
  69. }
  70. }
  71. func Login(route *Routes) {
  72. handler := func(w http.ResponseWriter, r *http.Request) {
  73. accepts := r.Header.Get("Content-Type")
  74. if accepts != "application/json" {
  75. w.WriteHeader(400)
  76. route.logger.Printf("[%s: %s]: 400 [Invalid headers]", r.RemoteAddr, r.RequestURI)
  77. fmt.Fprintf(w, "Could not process request. Invalid content type")
  78. return
  79. }
  80. sessions, err := store.Get(r, "cookie-name")
  81. if err != nil {
  82. w.WriteHeader(500)
  83. fmt.Fprintf(w, "Internal server error: %v", err)
  84. }
  85. var data user
  86. err = json.NewDecoder(r.Body).Decode(&data)
  87. if err != nil {
  88. w.WriteHeader(400)
  89. fmt.Fprintf(w, "Could not process request. Incorrect body format")
  90. return
  91. }
  92. var user model.User
  93. if !model.CheckEmail(data.Email, &user, &route.Pool) {
  94. w.WriteHeader(403)
  95. fmt.Fprintf(w, "Unauthorized")
  96. return
  97. }
  98. err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(data.Password))
  99. if err != nil {
  100. w.WriteHeader(403)
  101. fmt.Fprintf(w, "Unauthorized")
  102. return
  103. }
  104. authed := authenticated{
  105. Email: user.Email,
  106. Authenticated: true,
  107. }
  108. sessions.Values["user"] = authed
  109. err = sessions.Save(r, w)
  110. if err != nil {
  111. w.WriteHeader(500)
  112. fmt.Fprintf(w, "Internal Server Error: %v", err)
  113. }
  114. w.WriteHeader(200)
  115. fmt.Fprintf(w, "Authorized")
  116. }
  117. route.RegisterRoute("/api/login", "POST", false, handler)
  118. }