aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kavon <hawk@alexkavon.com>2023-11-30 01:43:08 -0500
committerAlexander Kavon <hawk@alexkavon.com>2023-11-30 01:43:08 -0500
commit218cd643550ed00d26b6e9772d8a64875b5abf2e (patch)
tree36b943ea5f73f290dcd0ed3aeacdb0b83852bc5c
parent59bfd1219d36db6ae7b6833aef4f0c71b7b19b74 (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.go7
-rw-r--r--src/server/router.go15
-rw-r--r--src/server/server.go32
-rw-r--r--src/server/session.go9
-rw-r--r--src/sessions/middleware.go36
-rw-r--r--src/sessions/sessions.go35
-rw-r--r--src/user/routes.go8
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."})
}