package server import ( "fmt" d "playback-device-server/data" m "playback-device-server/management" "strings" "github.com/labstack/echo/v4" "github.com/rs/zerolog/log" ) type AuthContext struct { echo.Context User *d.User Session *d.UserSession } type Authenticator struct { userManager *m.UserManager } func (r *Authenticator) SetUserManager(userManager *m.UserManager) { r.userManager = userManager } func (r *Authenticator) Authenticate(path string, exceptions []string) func(next echo.HandlerFunc) echo.HandlerFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(context echo.Context) error { requestURI := context.Request().RequestURI if !strings.HasPrefix(requestURI, path) { return next(context) } for _, exception := range exceptions { if strings.HasPrefix(requestURI, exception) { return next(context) } } cookie, err := context.Cookie("token") if err != nil { SendError(401, context, "no session token found") return err } session, error := r.userManager.GetSession(cookie.Value) if error != nil || session == nil { SendError(401, context, fmt.Sprintf("session not found: %s", cookie.Value)) return fmt.Errorf("session not found: %s", cookie.Value) } user, error := r.userManager.GetUserById(session.UserID) if error != nil { log.Error().Err(error).Msg("error getting user by id") SendError(401, context, "no user found for given session") return error } if user == nil { SendError(401, context, "no user found for given session") return fmt.Errorf("no user found for session '%s'", cookie.Value) } authContext := AuthContext{Context: context, User: user, Session: session} return next(authContext) } } }