Refactor session handling: Move session checking to session.go

This commit is contained in:
2024-05-01 12:37:00 +07:00
parent b3fdb17113
commit e8e5ce7bd5
8 changed files with 86 additions and 174 deletions

View File

@ -1,13 +1,10 @@
package downloadHandler package downloadHandler
import ( import (
"errors"
"net/http" "net/http"
"github.com/fossyy/filekeeper/db" "github.com/fossyy/filekeeper/db"
"github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/middleware"
"github.com/fossyy/filekeeper/session"
"github.com/fossyy/filekeeper/types" "github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/utils" "github.com/fossyy/filekeeper/utils"
downloadView "github.com/fossyy/filekeeper/view/download" downloadView "github.com/fossyy/filekeeper/view/download"
@ -20,26 +17,7 @@ func init() {
} }
func GET(w http.ResponseWriter, r *http.Request) { func GET(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("Session") userSession := r.Context().Value("user").(types.User)
if err != nil {
if errors.Is(err, http.ErrNoCookie) {
http.Redirect(w, r, "/signin", http.StatusSeeOther)
return
}
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
storeSession, err := session.GlobalSessionStore.Get(cookie.Value)
if err != nil {
if errors.Is(err, &session.SessionNotFoundError{}) {
storeSession.Destroy(w)
}
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
userSession := middleware.GetUser(storeSession)
files, err := db.DB.GetFiles(userSession.UserID.String()) files, err := db.DB.GetFiles(userSession.UserID.String())
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)

View File

@ -1,13 +0,0 @@
package miscHandler
import (
"net/http"
)
func Robot(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/public/robots.txt", http.StatusSeeOther)
}
func Favicon(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/public/favicon.ico", http.StatusSeeOther)
}

View File

@ -10,8 +10,6 @@ import (
"github.com/fossyy/filekeeper/db" "github.com/fossyy/filekeeper/db"
"github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/middleware"
"github.com/fossyy/filekeeper/session"
"github.com/fossyy/filekeeper/types" "github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/types/models" "github.com/fossyy/filekeeper/types/models"
"github.com/google/uuid" "github.com/google/uuid"
@ -25,21 +23,7 @@ func init() {
} }
func POST(w http.ResponseWriter, r *http.Request) { func POST(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("Session") userSession := r.Context().Value("user").(types.User)
if err != nil {
handleError(w, err, http.StatusInternalServerError)
return
}
storeSession, err := session.GlobalSessionStore.Get(cookie.Value)
if err != nil {
if errors.Is(err, &session.SessionNotFoundError{}) {
storeSession.Destroy(w)
}
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
userSession := middleware.GetUser(storeSession)
body, err := io.ReadAll(r.Body) body, err := io.ReadAll(r.Body)
if err != nil { if err != nil {

View File

@ -3,6 +3,7 @@ package uploadHandler
import ( import (
"errors" "errors"
"github.com/fossyy/filekeeper/db" "github.com/fossyy/filekeeper/db"
"github.com/fossyy/filekeeper/types"
"io" "io"
"net/http" "net/http"
"os" "os"
@ -11,8 +12,6 @@ import (
"sync" "sync"
"github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/middleware"
"github.com/fossyy/filekeeper/session"
filesView "github.com/fossyy/filekeeper/view/upload" filesView "github.com/fossyy/filekeeper/view/upload"
) )
@ -38,22 +37,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
return return
} }
cookie, err := r.Cookie("Session") userSession := r.Context().Value("user").(types.User)
if err != nil {
handleCookieError(w, r, err)
return
}
storeSession, err := session.GlobalSessionStore.Get(cookie.Value)
if err != nil {
if errors.Is(err, &session.SessionNotFoundError{}) {
storeSession.Destroy(w)
}
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
userSession := middleware.GetUser(storeSession)
if r.FormValue("done") == "true" { if r.FormValue("done") == "true" {
db.DB.FinalizeFileUpload(fileID) db.DB.FinalizeFileUpload(fileID)

View File

@ -1,11 +1,10 @@
package userHandler package userHandler
import ( import (
"errors" "github.com/fossyy/filekeeper/types"
"net/http" "net/http"
"github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/middleware"
"github.com/fossyy/filekeeper/session" "github.com/fossyy/filekeeper/session"
userView "github.com/fossyy/filekeeper/view/user" userView "github.com/fossyy/filekeeper/view/user"
) )
@ -17,27 +16,9 @@ func init() {
} }
func GET(w http.ResponseWriter, r *http.Request) { func GET(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("Session") userSession := r.Context().Value("user").(types.User)
if err != nil {
return
}
storeSession, err := session.GlobalSessionStore.Get(cookie.Value)
if err != nil {
if errors.Is(err, &session.SessionNotFoundError{}) {
storeSession.Destroy(w)
}
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
userSession := middleware.GetUser(storeSession)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
log.Error(err.Error())
return
}
component := userView.Main("User Page", userSession.Email, userSession.Username, session.UserSessionInfoList[userSession.Email]) component := userView.Main("User Page", userSession.Email, userSession.Username, session.UserSessionInfoList[userSession.Email])
err = component.Render(r.Context(), w) err := component.Render(r.Context(), w)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
log.Error(err.Error()) log.Error(err.Error())

View File

@ -1,7 +1,7 @@
package middleware package middleware
import ( import (
"errors" "context"
"fmt" "fmt"
"net/http" "net/http"
"strings" "strings"
@ -9,7 +9,6 @@ import (
errorHandler "github.com/fossyy/filekeeper/handler/error" errorHandler "github.com/fossyy/filekeeper/handler/error"
"github.com/fossyy/filekeeper/logger" "github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/session" "github.com/fossyy/filekeeper/session"
"github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/utils" "github.com/fossyy/filekeeper/utils"
) )
@ -60,9 +59,16 @@ func Handler(next http.Handler) http.Handler {
} }
func Auth(next http.HandlerFunc, w http.ResponseWriter, r *http.Request) { func Auth(next http.HandlerFunc, w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("Session") status, user := session.GetSession(r)
if err != nil {
if errors.Is(err, http.ErrNoCookie) { switch status {
case session.Authorized:
ctx := context.WithValue(r.Context(), "user", user)
req := r.WithContext(ctx)
r.Context().Value("user")
next.ServeHTTP(w, req)
return
case session.Unauthorized:
http.SetCookie(w, &http.Cookie{ http.SetCookie(w, &http.Cookie{
Name: "redirect", Name: "redirect",
Value: r.RequestURI, Value: r.RequestURI,
@ -70,80 +76,39 @@ func Auth(next http.HandlerFunc, w http.ResponseWriter, r *http.Request) {
}) })
http.Redirect(w, r, "/signin", http.StatusSeeOther) http.Redirect(w, r, "/signin", http.StatusSeeOther)
return return
} case session.InvalidSession:
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
storeSession, err := session.GlobalSessionStore.Get(cookie.Value)
if err != nil {
if errors.Is(err, &session.SessionNotFoundError{}) {
storeSession.Destroy(w)
http.Redirect(w, r, "/signin", http.StatusSeeOther)
return
}
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
userSession := GetUser(storeSession)
if userSession.Authenticated {
session.GetSessionInfo(storeSession.Values["user"].(types.User).Email, cookie.Value).UpdateAccessTime()
next.ServeHTTP(w, r)
return
}
http.SetCookie(w, &http.Cookie{
Name: "redirect",
Value: r.RequestURI,
Path: "/",
})
http.Redirect(w, r, "/signin", http.StatusSeeOther)
return
}
func Guest(next http.HandlerFunc, w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("Session")
if err != nil {
if errors.Is(err, http.ErrNoCookie) {
next.ServeHTTP(w, r)
return
}
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
storeSession, err := session.GlobalSessionStore.Get(cookie.Value)
if err != nil {
if errors.Is(err, &session.SessionNotFoundError{}) {
http.SetCookie(w, &http.Cookie{ http.SetCookie(w, &http.Cookie{
Name: "Session", Name: "Session",
Value: "", Value: "",
Path: "/",
MaxAge: -1,
})
http.Redirect(w, r, "/signin", http.StatusSeeOther)
return
default:
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
}
func Guest(next http.HandlerFunc, w http.ResponseWriter, r *http.Request) {
status, _ := session.GetSession(r)
switch status {
case session.Authorized:
http.Redirect(w, r, "/", http.StatusSeeOther)
return
case session.Unauthorized:
next.ServeHTTP(w, r)
return
case session.InvalidSession:
http.SetCookie(w, &http.Cookie{
Name: "Session",
Value: "",
Path: "/",
MaxAge: -1, MaxAge: -1,
}) })
next.ServeHTTP(w, r) next.ServeHTTP(w, r)
return return
} else {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
} }
} }
userSession := GetUser(storeSession)
if !userSession.Authenticated {
next.ServeHTTP(w, r)
return
}
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
func GetUser(s *session.Session) types.User {
val := s.Values["user"]
var userSession = types.User{}
userSession, ok := val.(types.User)
if !ok {
return types.User{Authenticated: false}
}
return userSession
}

View File

@ -10,7 +10,6 @@ import (
forgotPasswordVerifyHandler "github.com/fossyy/filekeeper/handler/forgotPassword/verify" forgotPasswordVerifyHandler "github.com/fossyy/filekeeper/handler/forgotPassword/verify"
indexHandler "github.com/fossyy/filekeeper/handler/index" indexHandler "github.com/fossyy/filekeeper/handler/index"
logoutHandler "github.com/fossyy/filekeeper/handler/logout" logoutHandler "github.com/fossyy/filekeeper/handler/logout"
miscHandler "github.com/fossyy/filekeeper/handler/misc"
signinHandler "github.com/fossyy/filekeeper/handler/signin" signinHandler "github.com/fossyy/filekeeper/handler/signin"
signupHandler "github.com/fossyy/filekeeper/handler/signup" signupHandler "github.com/fossyy/filekeeper/handler/signup"
signupVerifyHandler "github.com/fossyy/filekeeper/handler/signup/verify" signupVerifyHandler "github.com/fossyy/filekeeper/handler/signup/verify"
@ -187,11 +186,11 @@ func SetupRoutes() *http.ServeMux {
}) })
handler.HandleFunc("/robots.txt", func(w http.ResponseWriter, r *http.Request) { handler.HandleFunc("/robots.txt", func(w http.ResponseWriter, r *http.Request) {
miscHandler.Robot(w, r) http.ServeFile(w, r, "public/robots.txt")
}) })
handler.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) { handler.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/public/favicon.ico", http.StatusSeeOther) http.ServeFile(w, r, "public/favicon.ico")
}) })
fileServer := http.FileServer(http.Dir("./public")) fileServer := http.FileServer(http.Dir("./public"))

View File

@ -1,6 +1,8 @@
package session package session
import ( import (
"errors"
"github.com/fossyy/filekeeper/types"
"net/http" "net/http"
"strconv" "strconv"
"sync" "sync"
@ -30,6 +32,14 @@ type SessionInfo struct {
AccessAt string AccessAt string
} }
type UserStatus string
const (
Authorized UserStatus = "authorized"
Unauthorized UserStatus = "unauthorized"
InvalidSession UserStatus = "invalid_session"
)
type SessionInfoList map[string][]*SessionInfo type SessionInfoList map[string][]*SessionInfo
var GlobalSessionStore = SessionStore{Sessions: make(map[string]*Session)} var GlobalSessionStore = SessionStore{Sessions: make(map[string]*Session)}
@ -125,3 +135,27 @@ func (sessionInfo *SessionInfo) UpdateAccessTime() {
formattedTime := currentTime.Format("01-02-2006") formattedTime := currentTime.Format("01-02-2006")
sessionInfo.AccessAt = formattedTime sessionInfo.AccessAt = formattedTime
} }
func GetSession(r *http.Request) (UserStatus, types.User) {
cookie, err := r.Cookie("Session")
if err != nil {
return Unauthorized, types.User{}
}
storeSession, err := GlobalSessionStore.Get(cookie.Value)
if err != nil {
if errors.Is(err, &SessionNotFoundError{}) {
return InvalidSession, types.User{}
}
return Unauthorized, types.User{}
}
val := storeSession.Values["user"]
var userSession = types.User{}
userSession, ok := val.(types.User)
if !ok {
return Unauthorized, types.User{}
}
return Authorized, userSession
}