Files
ersteller/authentication/auth.go
T
2025-09-17 17:32:50 +02:00

111 lines
2.9 KiB
Go

package authentication
import (
. "ersteller-lib"
"net/http"
"strings"
"github.com/gorilla/sessions"
"golang.org/x/net/context"
)
const sessionName = "session"
const EmailKey = "email"
const UserIdKey = "userId"
const AuthContextKey = "authContext"
type AuthContext struct {
Email string
UserId int
}
func SaveEmailAndUserIdToSessionStore(request *http.Request, writer http.ResponseWriter, store *sessions.CookieStore, email string, userId int) error {
session, err := store.New(request, sessionName)
if err != nil {
LogError("Failed to create session: %v", err)
return err
}
session.Values = map[interface{}]interface{}{
EmailKey: email,
UserIdKey: userId,
}
err = session.Save(request, writer)
if err != nil {
LogError("Failed to save session: %v", err)
return err
}
return nil
}
func SetUserIdAndEmailFromSessionStore(request *http.Request, store *sessions.CookieStore) (bool, *http.Request, error) {
session, err := store.Get(request, sessionName)
if err != nil {
LogError("Failed to get session: %v", err)
return false, nil, err
}
email, ok := session.Values[EmailKey].(string)
if !ok {
return false, nil, nil
}
userId, ok := session.Values[UserIdKey].(int)
if !ok {
return false, nil, nil
}
ctx := context.WithValue(request.Context(), AuthContextKey, AuthContext{
Email: email,
UserId: userId,
})
return true, request.WithContext(ctx), nil
}
func LogoutSession(writer http.ResponseWriter, request *http.Request, sessionStore *sessions.CookieStore, redirectUrl string) {
// Clear the session
session, err := sessionStore.Get(request, sessionName) // Using default session name
if err != nil {
LogError("Failed to get session: %v", err)
http.Redirect(writer, request, redirectUrl, http.StatusTemporaryRedirect)
return
}
session.Options.MaxAge = -1
err = session.Save(request, writer)
if err != nil {
LogError("Failed to save session: %v", err)
http.Error(writer, "Failed to clear session", http.StatusInternalServerError)
return
}
http.Redirect(writer, request, redirectUrl, http.StatusTemporaryRedirect)
}
func Middleware(store *sessions.CookieStore, excludedPrefixes []string, redirectUrl string) MiddlewareFunc {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Debug("Authenticating")
if r.Method == http.MethodOptions {
next.ServeHTTP(w, r)
return
}
for _, prefix := range excludedPrefixes {
if strings.HasPrefix(r.URL.Path, prefix) {
next.ServeHTTP(w, r)
return
}
}
ok, r, err := SetUserIdAndEmailFromSessionStore(r, store)
if err != nil {
LogError("Failed to set user id and email from session: %v", err)
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
if ok {
next.ServeHTTP(w, r)
} else {
Debug("Redirecting to login because there is no session")
http.Redirect(w, r, redirectUrl, http.StatusTemporaryRedirect)
}
})
}
}