172 lines
3.9 KiB
Go
172 lines
3.9 KiB
Go
package auth
|
|
|
|
import (
|
|
"dk/internal/cookies"
|
|
"dk/internal/helpers"
|
|
"dk/internal/models/users"
|
|
"dk/internal/router"
|
|
"dk/internal/session"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/valyala/fasthttp"
|
|
)
|
|
|
|
const SessionCookieName = "dk_session"
|
|
|
|
func Middleware() router.Middleware {
|
|
return func(next router.Handler) router.Handler {
|
|
return func(ctx router.Ctx, params []string) {
|
|
sessionID := cookies.GetCookie(ctx, SessionCookieName)
|
|
var sess *session.Session
|
|
|
|
if sessionID != "" {
|
|
if existingSess, exists := session.Get(sessionID); exists {
|
|
sess = existingSess
|
|
sess.Touch()
|
|
|
|
if sess.UserID > 0 { // User session
|
|
user, err := users.Find(sess.UserID)
|
|
if err == nil && user != nil {
|
|
ctx.SetUserValue("user", user)
|
|
} else {
|
|
// User not found, reset to guest session
|
|
sess.SetUserID(0)
|
|
}
|
|
}
|
|
session.Store(sess)
|
|
setSessionCookie(ctx, sessionID)
|
|
}
|
|
}
|
|
|
|
// Create guest session if none exists
|
|
if sess == nil {
|
|
sess = session.Create(0) // Guest session
|
|
setSessionCookie(ctx, sess.ID)
|
|
}
|
|
|
|
ctx.SetUserValue("session", sess)
|
|
next(ctx, params)
|
|
}
|
|
}
|
|
}
|
|
|
|
func RequireAuth(paths ...string) router.Middleware {
|
|
redirect := "/login"
|
|
if len(paths) > 0 && paths[0] != "" {
|
|
redirect = paths[0]
|
|
}
|
|
|
|
return func(next router.Handler) router.Handler {
|
|
return func(ctx router.Ctx, params []string) {
|
|
if !IsAuthenticated(ctx) {
|
|
ctx.Redirect(redirect, fasthttp.StatusFound)
|
|
return
|
|
}
|
|
|
|
user := ctx.UserValue("user").(*users.User)
|
|
user.UpdateLastOnline()
|
|
user.Save()
|
|
|
|
next(ctx, params)
|
|
}
|
|
}
|
|
}
|
|
|
|
func RequireGuest(paths ...string) router.Middleware {
|
|
redirect := "/"
|
|
if len(paths) > 0 && paths[0] != "" {
|
|
redirect = paths[0]
|
|
}
|
|
|
|
return func(next router.Handler) router.Handler {
|
|
return func(ctx router.Ctx, params []string) {
|
|
if IsAuthenticated(ctx) {
|
|
fmt.Println("RequireGuest: user is authenticated")
|
|
ctx.Redirect(redirect, fasthttp.StatusFound)
|
|
return
|
|
}
|
|
next(ctx, params)
|
|
}
|
|
}
|
|
}
|
|
|
|
func IsAuthenticated(ctx router.Ctx) bool {
|
|
if user, ok := ctx.UserValue("user").(*users.User); ok && user != nil {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func GetCurrentUser(ctx router.Ctx) *users.User {
|
|
if user, ok := ctx.UserValue("user").(*users.User); ok {
|
|
return user
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func GetCurrentSession(ctx router.Ctx) *session.Session {
|
|
if sess, ok := ctx.UserValue("session").(*session.Session); ok {
|
|
return sess
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func Login(ctx router.Ctx, user *users.User) {
|
|
sess := ctx.UserValue("session").(*session.Session)
|
|
|
|
// Update the session to be authenticated
|
|
sess.SetUserID(user.ID) // This updates the struct field
|
|
sess.RegenerateID() // Generate new ID for security
|
|
sess.SetFlash("success", fmt.Sprintf("Welcome back, %s!", user.Username))
|
|
|
|
// Remove any old user_id from session data if it exists
|
|
sess.Delete("user_id")
|
|
|
|
session.Store(sess)
|
|
|
|
// Update context values
|
|
ctx.SetUserValue("session", sess)
|
|
ctx.SetUserValue("user", user)
|
|
|
|
// Update cookie with new session ID
|
|
setSessionCookie(ctx, sess.ID)
|
|
}
|
|
|
|
func Logout(ctx router.Ctx) {
|
|
sess := ctx.UserValue("session").(*session.Session)
|
|
if sess != nil {
|
|
// Convert back to guest session
|
|
sess.SetUserID(0) // Reset to guest
|
|
sess.RegenerateID() // Generate new ID for security
|
|
|
|
// Clean up any user-related session data
|
|
sess.Delete("user_id")
|
|
|
|
session.Store(sess)
|
|
ctx.SetUserValue("session", sess)
|
|
|
|
// Update cookie with new session ID
|
|
setSessionCookie(ctx, sess.ID)
|
|
}
|
|
|
|
ctx.SetUserValue("user", nil)
|
|
}
|
|
|
|
// Helper functions for session cookies
|
|
func setSessionCookie(ctx router.Ctx, sessionID string) {
|
|
cookies.SetSecureCookie(ctx, cookies.CookieOptions{
|
|
Name: SessionCookieName,
|
|
Value: sessionID,
|
|
Path: "/",
|
|
Expires: time.Now().Add(24 * time.Hour),
|
|
HTTPOnly: true,
|
|
Secure: helpers.IsHTTPS(ctx),
|
|
SameSite: "lax",
|
|
})
|
|
}
|
|
|
|
func deleteSessionCookie(ctx router.Ctx) {
|
|
cookies.DeleteCookie(ctx, SessionCookieName)
|
|
}
|