package routes import ( "encoding/gob" "encoding/json" "fmt" "net/http" "github.com/andreanidouglas/auth/model" "github.com/gorilla/securecookie" "github.com/gorilla/sessions" "golang.org/x/crypto/bcrypt" ) type user struct { Email string `json:"email"` Password string `jsob:"password"` } type authenticated struct { Email string Authenticated bool } const ( AUTH_KEY string = "session_id" USER_ID string = "user_id" ) var store *sessions.CookieStore type AuthRoutes struct{} func (a *AuthRoutes) Register(r *Routes) { AuthInit() Login(r) } func AuthInit() { auth_key := securecookie.GenerateRandomKey(64) encryption_key := securecookie.GenerateRandomKey(32) store = sessions.NewCookieStore( auth_key, encryption_key, ) store.Options = &sessions.Options{ Path: "/auth", MaxAge: 60 * 15, HttpOnly: true, } gob.Register(authenticated{}) } func getUser(s *sessions.Session) authenticated { val := s.Values["user"] var user = authenticated{} user, ok := val.(authenticated) if !ok { return authenticated{Authenticated: false} } return user } func AuthMiddleware(next http.HandlerFunc) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { fmt.Printf("got store: %v", store) session, err := store.Get(r, "cookie-name") if err != nil { w.WriteHeader(500) fmt.Fprintf(w, "Internal Server Error: %v", err) return } authed := getUser(session) if auth := authed.Authenticated; !auth { w.WriteHeader(403) fmt.Fprintf(w, "Unauthorized") return } next.ServeHTTP(w, r) } } func Login(route *Routes) { handler := func(w http.ResponseWriter, r *http.Request) { accepts := r.Header.Get("Content-Type") if accepts != "application/json" { w.WriteHeader(400) route.logger.Printf("[%s: %s]: 400 [Invalid headers]", r.RemoteAddr, r.RequestURI) fmt.Fprintf(w, "Could not process request. Invalid content type") return } sessions, err := store.Get(r, "cookie-name") if err != nil { w.WriteHeader(500) fmt.Fprintf(w, "Internal server error: %v", err) } var data user err = json.NewDecoder(r.Body).Decode(&data) if err != nil { w.WriteHeader(400) fmt.Fprintf(w, "Could not process request. Incorrect body format") return } var user model.User if !model.CheckEmail(data.Email, &user, &route.Pool) { w.WriteHeader(403) fmt.Fprintf(w, "Unauthorized") return } err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(data.Password)) if err != nil { w.WriteHeader(403) fmt.Fprintf(w, "Unauthorized") return } authed := authenticated{ Email: user.Email, Authenticated: true, } sessions.Values["user"] = authed err = sessions.Save(r, w) if err != nil { w.WriteHeader(500) fmt.Fprintf(w, "Internal Server Error: %v", err) } w.WriteHeader(200) fmt.Fprintf(w, "Authorized") } route.RegisterRoute("/api/login", "POST", false, handler) }