* refactor: update api and client to reference humanIds * fix: prevent deletion of network member This may cause various side effects if there is data in other services which reference this member
83 lines
2.1 KiB
Go
83 lines
2.1 KiB
Go
package middleware
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/flowy-live/llink/internal/auth"
|
|
)
|
|
|
|
type contextKey string
|
|
|
|
const (
|
|
emailContextKey contextKey = "email"
|
|
humanIdContextKey contextKey = "humanId"
|
|
)
|
|
|
|
// WithEmail adds the email to the context
|
|
func WithEmail(ctx context.Context, email string) context.Context {
|
|
return context.WithValue(ctx, emailContextKey, email)
|
|
}
|
|
|
|
// EmailFromContext extracts the email from the context
|
|
func EmailFromContext(ctx context.Context) (string, bool) {
|
|
email, ok := ctx.Value(emailContextKey).(string)
|
|
return email, ok
|
|
}
|
|
|
|
// WithHumanId adds the humanId to the context
|
|
func WithHumanId(ctx context.Context, humanId string) context.Context {
|
|
return context.WithValue(ctx, humanIdContextKey, humanId)
|
|
}
|
|
|
|
// HumanIdFromContext extracts the id from the context
|
|
func HumanIdFromContext(ctx context.Context) (string, bool) {
|
|
humanId, ok := ctx.Value(humanIdContextKey).(string)
|
|
return humanId, ok
|
|
}
|
|
|
|
// Auth returns a middleware that validates the session token and adds the email to the context
|
|
func Auth(authSvc auth.AuthService) func(http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
token := extractBearerToken(r)
|
|
if token == "" {
|
|
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
session, err := authSvc.GetSession(r.Context(), token)
|
|
if err != nil {
|
|
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
// Auto-extend session
|
|
if err := authSvc.ExtendSession(r.Context(), token); err != nil {
|
|
slog.Warn("failed to extend session", "error", err)
|
|
}
|
|
|
|
ctx := WithEmail(r.Context(), session.Email)
|
|
ctx = WithHumanId(ctx, session.HumanId)
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
})
|
|
}
|
|
}
|
|
|
|
// extractBearerToken extracts the token from the Authorization header
|
|
func extractBearerToken(r *http.Request) string {
|
|
authHeader := r.Header.Get("Authorization")
|
|
if authHeader == "" {
|
|
return ""
|
|
}
|
|
|
|
parts := strings.SplitN(authHeader, " ", 2)
|
|
if len(parts) != 2 || !strings.EqualFold(parts[0], "Bearer") {
|
|
return ""
|
|
}
|
|
|
|
return parts[1]
|
|
}
|