feat: create-room handler, with middleware
This commit is contained in:
parent
850b6c693b
commit
f8eb11c53e
@ -10,14 +10,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Person struct {
|
type Person struct {
|
||||||
PersonId int64
|
PersonId int
|
||||||
Name string
|
Name string
|
||||||
PasswordHash string
|
PasswordHash string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Room struct {
|
type Room struct {
|
||||||
Name string // will be unique ID
|
Name string // will be unique ID
|
||||||
AdminIds []int64
|
AdminIds []int
|
||||||
PasswordHash string
|
PasswordHash string
|
||||||
Paricipants []Person
|
Paricipants []Person
|
||||||
// TODO hands, for each type of hand?
|
// TODO hands, for each type of hand?
|
||||||
|
@ -1,29 +1,82 @@
|
|||||||
package routes
|
package routes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"embed"
|
"embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"log"
|
"log"
|
||||||
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"sunshine.industries/some-automoderation/rooms"
|
"sunshine.industries/some-automoderation/rooms"
|
||||||
"sunshine.industries/some-automoderation/sessions"
|
"sunshine.industries/some-automoderation/sessions"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const authCookieName = "auth"
|
||||||
|
const loginPath = "/login"
|
||||||
|
type contextKey string
|
||||||
|
|
||||||
|
// checks sessionId from cookie
|
||||||
|
// when non-zero session found - pass to next http.Hander
|
||||||
|
// when no session available - render same as login page and redirect to /
|
||||||
|
func authedPageMiddleware(
|
||||||
|
sessionsM sessions.SessionManagement, next http.Handler,
|
||||||
|
) http.Handler {
|
||||||
|
|
||||||
|
returnNoAccess := func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Printf("auth middle > restricting access to %s", r.URL.Path)
|
||||||
|
w.Header().Add("HX-Replace-Url", loginPath)
|
||||||
|
renderLoginPage(w)
|
||||||
|
}
|
||||||
|
rerturnSuccess := func(w http.ResponseWriter, r *http.Request, session sessions.SessionData) {
|
||||||
|
ctx := context.WithValue(r.Context(), contextKey("session"), session)
|
||||||
|
log.Printf("auth middle > allowing access to %s for %+v", r.URL.Path, session)
|
||||||
|
next.ServeHTTP(w, r.WithContext(ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
sessionCookie, err := r.Cookie(authCookieName)
|
||||||
|
if err != nil {
|
||||||
|
returnNoAccess(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// TODO log here, why i get 'error readin 0'
|
||||||
|
sessionId, err := strconv.Atoi(sessionCookie.Value)
|
||||||
|
if err != nil {
|
||||||
|
returnNoAccess(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
session := sessionsM.Get(sessionId)
|
||||||
|
if session == (sessions.SessionData{}) {
|
||||||
|
returnNoAccess(w, r)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
rerturnSuccess(w, r, session)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderLoginPage(w http.ResponseWriter) {
|
||||||
|
var templFile = "templates/login.gohtml"
|
||||||
|
tmpl := template.Must(template.ParseFS(templateFs, templFile))
|
||||||
|
err := tmpl.Execute(w, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("my error in executing template, huh\n %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// function to register all http routes for servicing auth pages and logic
|
||||||
func registerLoginRoutes(
|
func registerLoginRoutes(
|
||||||
templateFs *embed.FS,
|
templateFs *embed.FS,
|
||||||
sessionSM sessions.SessionManagement,
|
sessionSM sessions.SessionManagement,
|
||||||
roomsM rooms.RoomManager,
|
roomsM rooms.RoomManager,
|
||||||
) {
|
) {
|
||||||
// login page
|
// login page
|
||||||
http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc(loginPath, func(w http.ResponseWriter, r *http.Request) {
|
||||||
var templFile = "templates/login.gohtml"
|
renderLoginPage(w)
|
||||||
tmpl := template.Must(template.ParseFS(templateFs, templFile))
|
|
||||||
err := tmpl.Execute(w, nil)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("my error in executing template, huh\n %s", err)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// when the room exists - attempt to join
|
// when the room exists - attempt to join
|
||||||
@ -49,7 +102,7 @@ func registerLoginRoutes(
|
|||||||
roomId := "room-name-actually" // would be taken from rooms interface from redis
|
roomId := "room-name-actually" // would be taken from rooms interface from redis
|
||||||
// would be either taken from room info on correct person pass or created
|
// would be either taken from room info on correct person pass or created
|
||||||
personId := 111
|
personId := 111
|
||||||
id, err := sessionSM.Save(roomId, int64(personId))
|
id, err := sessionSM.Save(roomId, personId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("/login/submit > error saving session %s", err)
|
log.Printf("/login/submit > error saving session %s", err)
|
||||||
}
|
}
|
||||||
@ -75,33 +128,37 @@ func registerLoginRoutes(
|
|||||||
_, exists, _ := roomsM.Get(roomName)
|
_, exists, _ := roomsM.Get(roomName)
|
||||||
if exists {
|
if exists {
|
||||||
// TODO return anouther error notice
|
// TODO return anouther error notice
|
||||||
log.Printf("error, room name occupied", roomName)
|
log.Printf("error, room name occupied %s", roomName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
person := rooms.Person{
|
||||||
|
PersonId: rand.Int(),
|
||||||
|
Name: r.PostFormValue("personalName"),
|
||||||
|
PasswordHash: r.PostFormValue("personalPassword"), // TODO hash the password, not to store
|
||||||
|
}
|
||||||
newRoom := rooms.Room{
|
newRoom := rooms.Room{
|
||||||
Name: roomName,
|
Name: roomName,
|
||||||
PasswordHash: r.PostFormValue("roomPassword"), // TODO hash the password, not to store
|
PasswordHash: r.PostFormValue("roomPassword"), // TODO hash the password, not to store
|
||||||
AdminIds: []int64{1},
|
AdminIds: []int{person.PersonId},
|
||||||
Paricipants: []rooms.Person{
|
Paricipants: []rooms.Person{person},
|
||||||
{
|
|
||||||
PersonId: 1,
|
|
||||||
Name: r.PostFormValue("personalName"),
|
|
||||||
PasswordHash: r.PostFormValue("personalPassword"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
err = roomsM.Save(newRoom)
|
err = roomsM.Save(newRoom)
|
||||||
http.SetCookie(w, &http.Cookie{
|
|
||||||
Name: "auth",
|
|
||||||
Value: "session-id",
|
|
||||||
Secure: true,
|
|
||||||
HttpOnly: true,
|
|
||||||
Path: "/",
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("what am i to do? error saving room %s", err)
|
log.Printf("what am i to do? error saving room %s", err)
|
||||||
// todo return error notice somehow
|
// todo return error notice somehow
|
||||||
}
|
}
|
||||||
|
newSessionId, err := sessionSM.Save(newRoom.Name, person.PersonId)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("what am i to do? error saving session %s", err)
|
||||||
|
// todo return error notice somehow
|
||||||
|
}
|
||||||
|
http.SetCookie(w, &http.Cookie{
|
||||||
|
Name: authCookieName,
|
||||||
|
Value: fmt.Sprint(newSessionId),
|
||||||
|
Secure: true,
|
||||||
|
HttpOnly: true,
|
||||||
|
Path: "/",
|
||||||
|
})
|
||||||
var templFile = "templates/index.gohtml"
|
var templFile = "templates/index.gohtml"
|
||||||
tmpl := template.Must(template.ParseFS(templateFs, templFile))
|
tmpl := template.Must(template.ParseFS(templateFs, templFile))
|
||||||
w.Header().Add("HX-Retarget", "body")
|
w.Header().Add("HX-Retarget", "body")
|
||||||
|
@ -21,14 +21,16 @@ func RegisterRoutes(sessions sessions.SessionManagement, rooms rooms.RoomManager
|
|||||||
registerLoginRoutes(&templateFs, sessions, rooms)
|
registerLoginRoutes(&templateFs, sessions, rooms)
|
||||||
|
|
||||||
// main page template
|
// main page template
|
||||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
http.Handle("/", authedPageMiddleware(
|
||||||
var templFile = "templates/index.gohtml"
|
sessions,
|
||||||
tmpl := template.Must(template.ParseFS(templateFs, templFile))
|
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
err := tmpl.Execute(w, nil)
|
var templFile = "templates/index.gohtml"
|
||||||
if err != nil {
|
tmpl := template.Must(template.ParseFS(templateFs, templFile))
|
||||||
log.Printf("my error in executing template, huh\n %s", err)
|
err := tmpl.Execute(w, nil)
|
||||||
}
|
if err != nil {
|
||||||
})
|
log.Printf("my error in executing template, huh\n %s", err)
|
||||||
|
}
|
||||||
|
})))
|
||||||
|
|
||||||
// static resources route
|
// static resources route
|
||||||
http.Handle("/static/",
|
http.Handle("/static/",
|
||||||
|
@ -10,21 +10,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type SessionData struct {
|
type SessionData struct {
|
||||||
SessionId int64 `redis:"session_id"`
|
SessionId int `redis:"session_id"`
|
||||||
RoomId string `redis:"room_id"`
|
RoomId string `redis:"room_id"`
|
||||||
PersonId int64 `redis:"person_id"`
|
PersonId int `redis:"person_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SessionManagement interface {
|
type SessionManagement interface {
|
||||||
Get(sessionId int64) SessionData
|
Get(sessionId int) SessionData
|
||||||
Save(roomId string, personId int64) (int64, error)
|
Save(roomName string, personId int) (int, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
var ctx = context.Background()
|
var ctx = context.Background()
|
||||||
|
|
||||||
const sessionPrefix = "session"
|
const sessionPrefix = "session"
|
||||||
|
|
||||||
func sessionIdToKey(sessionId int64) string {
|
func sessionIdToKey(sessionId int) string {
|
||||||
return fmt.Sprintf("%s:%d", sessionPrefix, sessionId)
|
return fmt.Sprintf("%s:%d", sessionPrefix, sessionId)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,21 +32,22 @@ type RedisSM struct {
|
|||||||
Rdb *redis.Client
|
Rdb *redis.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (redisSM RedisSM) Get(sessionId int64) SessionData {
|
func (redisSM RedisSM) Get(sessionId int) SessionData {
|
||||||
var foundSession SessionData
|
var foundSession SessionData
|
||||||
err := redisSM.Rdb.HGetAll(ctx, sessionIdToKey(sessionId)).Scan(foundSession)
|
redisKey := sessionIdToKey(sessionId)
|
||||||
|
err := redisSM.Rdb.HGetAll(ctx, redisKey).Scan(&foundSession)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("> error reading %d", sessionId)
|
log.Printf("> error reading %s : %s", redisKey, err)
|
||||||
return SessionData{}
|
return SessionData{}
|
||||||
}
|
}
|
||||||
log.Printf("> successfully found %d %+v", sessionId, foundSession)
|
log.Printf("> successfully found %d %+v", sessionId, foundSession)
|
||||||
return foundSession
|
return foundSession
|
||||||
}
|
}
|
||||||
func (redisSM RedisSM) Save(roomId string, personId int64) (int64, error) {
|
func (redisSM RedisSM) Save(roomName string, personId int) (int, error) {
|
||||||
randId := rand.Int63()
|
randId := rand.Int()
|
||||||
newSession := SessionData{
|
newSession := SessionData{
|
||||||
SessionId: randId,
|
SessionId: randId,
|
||||||
RoomId: roomId,
|
RoomId: roomName,
|
||||||
PersonId: personId,
|
PersonId: personId,
|
||||||
}
|
}
|
||||||
err := redisSM.Rdb.HSet(ctx, sessionIdToKey(randId), newSession).Err()
|
err := redisSM.Rdb.HSet(ctx, sessionIdToKey(randId), newSession).Err()
|
||||||
@ -59,11 +60,11 @@ func (redisSM RedisSM) Save(roomId string, personId int64) (int64, error) {
|
|||||||
|
|
||||||
type DummySM struct{}
|
type DummySM struct{}
|
||||||
|
|
||||||
func (d DummySM) Get(sessionId int64) SessionData {
|
func (d DummySM) Get(sessionId int) SessionData {
|
||||||
log.Printf("get dummy session by %d", sessionId)
|
log.Printf("get dummy session by %d", sessionId)
|
||||||
return SessionData{}
|
return SessionData{}
|
||||||
}
|
}
|
||||||
func (d DummySM) Save(roomId string, personId int64) (int64, error) {
|
func (d DummySM) Save(roomName string, personId int) (int, error) {
|
||||||
log.Printf("save dummy session with %d %d", roomId, personId)
|
log.Printf("save dummy session with %s %d", roomName, personId)
|
||||||
return 1, nil
|
return 1, nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user