package web import ( "net/http" "net/url" "uPortal/internal/auth" ) // HandleSessions lists the current user's active sessions. func (s *WebService) HandleSessions(w http.ResponseWriter, r *http.Request) { data, ok := s.basicViewData(w, r, "Sessions") if !ok { http.Redirect(w, r, "/signin", http.StatusSeeOther) return } // A generous limit; the page renders whatever comes back. sessions, err := s.auths.GetSessionByUserId(r.Context(), data.User.Id, 100, 0) if err != nil { s.log.Error("failed to get sessions: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } data.Sessions = sessions s.render(w, r, "session/view.html", data) } // HandleSessionEnd deletes a single session identified by the form field "token". // It enforces ownership: a user can only delete their own session unless they are a superuser. func (s *WebService) HandleSessionEnd(w http.ResponseWriter, r *http.Request) { if err := auth.ValidateCsrf(r, CsrfCookieName, CsrfFieldName); err != nil { http.Redirect(w, r, "/sessions", http.StatusSeeOther) return } currentUser, err := s.currentUser(r) if err != nil { http.Redirect(w, r, "/signin", http.StatusSeeOther) return } token := r.FormValue("token") if token == "" { http.Redirect(w, r, "/sessions", http.StatusSeeOther) return } session, err := s.auths.GetSessionByToken(r.Context(), token) if err != nil { http.Redirect(w, r, "/sessions", http.StatusSeeOther) return } if session.UserId == currentUser.Id { // User deleting their own session — use defense-in-depth method _ = s.auths.DeleteSessionByTokenAndUserId(r.Context(), token, currentUser.Id) } else if currentUser.SuperUser { // Superuser overriding — can delete any session _ = s.auths.DeleteSession(r.Context(), token) } else { http.Error(w, "Forbidden", http.StatusForbidden) return } http.Redirect(w, r, "/sessions", http.StatusSeeOther) } // HandleSessionEndAll ends every session belonging to the current user. func (s *WebService) HandleSessionEndAll(w http.ResponseWriter, r *http.Request) { if err := auth.ValidateCsrf(r, CsrfCookieName, CsrfFieldName); err != nil { http.Redirect(w, r, "/sessions", http.StatusSeeOther) return } u, err := s.currentUser(r) if err != nil { http.Redirect(w, r, "/signin?redirect="+url.PathEscape(r.URL.RequestURI()), http.StatusSeeOther) return } _ = s.auths.DeleteSessionsByUserId(r.Context(), u.Id) http.Redirect(w, r, "/sessions", http.StatusSeeOther) }