diff options
| author | Alexander Kavon <hawk@alexkavon.com> | 2023-11-30 01:43:08 -0500 |
|---|---|---|
| committer | Alexander Kavon <hawk@alexkavon.com> | 2023-11-30 01:43:08 -0500 |
| commit | 218cd643550ed00d26b6e9772d8a64875b5abf2e (patch) | |
| tree | 36b943ea5f73f290dcd0ed3aeacdb0b83852bc5c | |
| parent | 59bfd1219d36db6ae7b6833aef4f0c71b7b19b74 (diff) | |
initial sessions support via sessions pkg, includes session middleware for setting sessions, guest sessions, method to return array of middlewares
| -rw-r--r-- | src/server/middleware.go | 7 | ||||
| -rw-r--r-- | src/server/router.go | 15 | ||||
| -rw-r--r-- | src/server/server.go | 32 | ||||
| -rw-r--r-- | src/server/session.go | 9 | ||||
| -rw-r--r-- | src/sessions/middleware.go | 36 | ||||
| -rw-r--r-- | src/sessions/sessions.go | 35 | ||||
| -rw-r--r-- | src/user/routes.go | 8 |
7 files changed, 100 insertions, 42 deletions
diff --git a/src/server/middleware.go b/src/server/middleware.go new file mode 100644 index 0000000..7b5b58b --- /dev/null +++ b/src/server/middleware.go @@ -0,0 +1,7 @@ +package server + +import "net/http" + +func NewMiddlewares(middlewares ...func(http.Handler) http.Handler) []func(http.Handler) http.Handler { + return middlewares +} diff --git a/src/server/router.go b/src/server/router.go index c8ca0fa..6b33a7d 100644 --- a/src/server/router.go +++ b/src/server/router.go @@ -6,18 +6,18 @@ import ( "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "gitlab.com/alexkavon/newsstand/src/conf" + "gitlab.com/alexkavon/newsstand/src/sessions" ) type HandlerFunc func(s *Server) http.HandlerFunc type Route struct { - Name string - Method string - Path string - AuthRequired bool - HandlerFunc HandlerFunc - UiPageName string - UiTemplateName string + Name string + Method string + Path string + AuthRequired bool + HandlerFunc HandlerFunc + Middlewares []func(http.Handler) http.Handler } type Routes []Route @@ -25,5 +25,6 @@ type Routes []Route func NewRouter(config *conf.Conf) *chi.Mux { r := chi.NewRouter() r.Use(middleware.Logger) + r.Use(sessions.SetSession) return r } diff --git a/src/server/server.go b/src/server/server.go index c483069..eb5f785 100644 --- a/src/server/server.go +++ b/src/server/server.go @@ -4,26 +4,23 @@ import ( "net/http" "github.com/go-chi/chi/v5" - "github.com/google/uuid" "gitlab.com/alexkavon/newsstand/src/conf" "gitlab.com/alexkavon/newsstand/src/db" ) type Server struct { - Router *chi.Mux - Db *db.Database - Config *conf.Conf - Ui Ui - Sessions map[string]session + Router *chi.Mux + Db *db.Database + Config *conf.Conf + Ui Ui } func NewServer(config *conf.Conf, database *db.Database) *Server { return &Server{ - Router: NewRouter(config), - Db: database, - Config: config, - Ui: NewUi(config), - Sessions: map[string]session{}, + Router: NewRouter(config), + Db: database, + Config: config, + Ui: NewUi(config), } } @@ -33,6 +30,7 @@ func (s *Server) BuildUi() { func (s *Server) RegisterRoutes(routes Routes) { for _, r := range routes { + s.Router.Use(r.Middlewares...) s.Router.Method(r.Method, r.Path, r.HandlerFunc(s)) } } @@ -40,15 +38,3 @@ func (s *Server) RegisterRoutes(routes Routes) { func (s *Server) Serve() { http.ListenAndServe(":"+s.Config.Server.Port, s.Router) } - -func (s *Server) NewSession(w http.ResponseWriter, username string) { - token := uuid.NewString() - s.Sessions[token] = session{ - username: username, - } - - http.SetCookie(w, &http.Cookie{ - Name: "session_token", - Value: token, - }) -} diff --git a/src/server/session.go b/src/server/session.go deleted file mode 100644 index 3a12215..0000000 --- a/src/server/session.go +++ /dev/null @@ -1,9 +0,0 @@ -package server - -type session struct { - username string -} - -func (s *session) Username() string { - return s.username -} diff --git a/src/sessions/middleware.go b/src/sessions/middleware.go new file mode 100644 index 0000000..238047e --- /dev/null +++ b/src/sessions/middleware.go @@ -0,0 +1,36 @@ +package sessions + +import ( + "context" + "net/http" +) + +func SetSession(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + scookie, err := r.Cookie("session_token") + if err != nil || scookie.Value == "" { + // no session value or cookie + next.ServeHTTP(w, r) + } + cvalue := scookie.Value + vsession, ok := Sessions[cvalue] + if !ok { + // no session + next.ServeHTTP(w, r) + } + // set session + ctx := context.WithValue(r.Context(), SessionCtxKey("session"), vsession) + next.ServeHTTP(w, r.WithContext(ctx)) + }) +} + +func GuestSession(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // if SessionKey does not exist then this is a valid guest request + if _, ok := r.Context().Value(SessionCtxKey("session")).(session); !ok { + next.ServeHTTP(w, r) + } + // else redirect to `/` as this is an auth session + http.Redirect(w, r, "/", http.StatusSeeOther) + }) +} diff --git a/src/sessions/sessions.go b/src/sessions/sessions.go new file mode 100644 index 0000000..d2acab6 --- /dev/null +++ b/src/sessions/sessions.go @@ -0,0 +1,35 @@ +package sessions + +import ( + "net/http" + + "github.com/google/uuid" +) + +type SessionMgr struct { + key string + Values map[string]string +} + +type session map[string]any + +type SessionCtxKey string + +var sessions map[string]session + +func (sm *SessionMgr) NewSession(w http.ResponseWriter, r http.Request) { + token := uuid.NewString() + + // set secure cookie in http.ResponseWriter + // TODO make secure + http.SetCookie(w, &http.Cookie{ + Name: "session_token", + Value: token, + }) + + sessions[token] = session{ + "username": username, + } + // set request context + +} diff --git a/src/user/routes.go b/src/user/routes.go index 64018d0..636daa6 100644 --- a/src/user/routes.go +++ b/src/user/routes.go @@ -6,6 +6,7 @@ import ( "github.com/go-playground/validator/v10" "gitlab.com/alexkavon/newsstand/src/server" + "gitlab.com/alexkavon/newsstand/src/sessions" ) var Routes = server.Routes{ @@ -14,6 +15,7 @@ var Routes = server.Routes{ Method: "GET", Path: "/u/create", HandlerFunc: Create, + Middlewares: server.NewMiddlewares(sessions.GuestSession), }, server.Route{ Name: "Store", @@ -24,7 +26,7 @@ var Routes = server.Routes{ server.Route{ Name: "LoginForm", Method: "GET", - Path: "/u/auth", + Path: "/u/login", HandlerFunc: LoginForm, }, server.Route{ @@ -78,7 +80,7 @@ func Store(s *server.Server) http.HandlerFunc { } // Send email validation // Create cookie session - s.NewSession(w, user.Username) + sessions.Store(w, user.Username) // Redirect to user profile http.Redirect(w, r, "/u/me", http.StatusSeeOther) } @@ -100,7 +102,7 @@ func Show(s *server.Server) http.HandlerFunc { if err != nil { s.Ui.Render(w, "user/login", &struct{ Message string }{"You are not logged in! Missing Cookie"}) } - session, ok := s.Sessions[token.Value] + session, ok := sessions.NewSession(w, r, token.Value) if !ok { s.Ui.Render(w, "user/login", &struct{ Message string }{"You are not logged in! With Session."}) } |
