@@ -4,11 +4,12 @@ import (
44 "net/http"
55 "time"
66
7+ "github.com/gin-contrib/sessions"
78 "github.com/gin-gonic/gin"
89 "github.com/sirupsen/logrus"
910 "github.com/thand-io/agent/internal/common"
1011 "github.com/thand-io/agent/internal/models"
11- "github.com/thand-io/agent/internal/sessions"
12+ sessionManager "github.com/thand-io/agent/internal/sessions"
1213)
1314
1415// postSession creates a new session
@@ -121,8 +122,8 @@ func (s *Server) postSession(c *gin.Context) {
121122 }).Debugln ("Creating session" )
122123
123124 // Now lets store the session in the users local session manager.
124- sessionManager := sessions .GetSessionManager ()
125- err = sessionManager .AddSession (
125+ sessionMgr := sessionManager .GetSessionManager ()
126+ err = sessionMgr .AddSession (
126127 loginServer ,
127128 sessionCreateRequest .Provider ,
128129 session ,
@@ -146,12 +147,21 @@ func (s *Server) postSession(c *gin.Context) {
146147// @Tags sessions
147148// @Accept json
148149// @Produce json
149- // @Success 200 {object} sessions.LoginServer "List of sessions"
150+ // @Success 200 {object} models.SessionsResponse "List of sessions with default provider "
150151// @Failure 400 {object} map[string]any "Bad request"
151152// @Failure 500 {object} map[string]any "Internal server error"
152153// @Router /sessions [get]
153154func (s * Server ) getSessions (c * gin.Context ) {
154155
156+ // Get the default provider from cookie
157+ defaultProvider := ""
158+ defaultCookie := sessions .DefaultMany (c , ThandCookieName )
159+ if provider := defaultCookie .Get (ThandCookieAttributeActiveName ); provider != nil {
160+ if providerStr , ok := provider .(string ); ok {
161+ defaultProvider = providerStr
162+ }
163+ }
164+
155165 if s .Config .IsServer () {
156166
157167 remoteSessions , err := s .getUserSessions (c )
@@ -171,13 +181,14 @@ func (s *Server) getSessions(c *gin.Context) {
171181 }
172182 }
173183
174- sessionsList := sessions.LoginServer {
175- Version : "1" ,
176- Timestamp : time .Now (),
177- Sessions : foundSessions ,
184+ sessionsResponse := models.SessionsResponse {
185+ Version : "1" ,
186+ Timestamp : time .Now (),
187+ Sessions : foundSessions ,
188+ DefaultProvider : defaultProvider ,
178189 }
179190
180- c .JSON (http .StatusOK , sessionsList )
191+ c .JSON (http .StatusOK , sessionsResponse )
181192 return
182193
183194 } else if s .Config .IsAgent () {
@@ -188,16 +199,23 @@ func (s *Server) getSessions(c *gin.Context) {
188199 "loginServer" : loginServer ,
189200 }).Debugln ("Fetching sessions" )
190201
191- sessionManager := sessions .GetSessionManager ()
192- sessionManager .Load (loginServer )
193- sessionsList , err := sessionManager .GetLoginServer (loginServer )
202+ sessionMgr := sessionManager .GetSessionManager ()
203+ sessionMgr .Load (loginServer )
204+ sessionsList , err := sessionMgr .GetLoginServer (loginServer )
194205
195206 if err != nil {
196207 s .getErrorPage (c , http .StatusInternalServerError , "Failed to list sessions" , err )
197208 return
198209 }
199210
200- c .JSON (http .StatusOK , sessionsList )
211+ sessionsResponse := models.SessionsResponse {
212+ Version : sessionsList .Version ,
213+ Timestamp : sessionsList .Timestamp ,
214+ Sessions : sessionsList .Sessions ,
215+ DefaultProvider : defaultProvider ,
216+ }
217+
218+ c .JSON (http .StatusOK , sessionsResponse )
201219 return
202220
203221 } else {
@@ -235,9 +253,9 @@ func (s *Server) getSessionByProvider(c *gin.Context) {
235253 "provider" : provider ,
236254 }).Debugln ("Fetching session for provider" )
237255
238- sessionManager := sessions .GetSessionManager ()
239- sessionManager .Load (loginServer )
240- session , err := sessionManager .GetSession (loginServer , provider )
256+ sessionMgr := sessionManager .GetSessionManager ()
257+ sessionMgr .Load (loginServer )
258+ session , err := sessionMgr .GetSession (loginServer , provider )
241259
242260 if err != nil {
243261 s .getErrorPage (c , http .StatusInternalServerError , "Failed to get session" , err )
@@ -254,6 +272,75 @@ func (s *Server) getSessionByProvider(c *gin.Context) {
254272 })
255273}
256274
275+ // putSession sets the default session provider
276+ //
277+ // @Summary Set default session provider
278+ // @Description Update the default session provider for the user
279+ // @Tags sessions
280+ // @Accept json
281+ // @Produce json
282+ // @Param request body models.SessionSetDefaultRequest true "Provider selection request"
283+ // @Success 200 {object} map[string]any "Default provider updated successfully"
284+ // @Failure 400 {object} map[string]any "Bad request"
285+ // @Failure 404 {object} map[string]any "Provider session not found"
286+ // @Failure 500 {object} map[string]any "Internal server error"
287+ // @Router /sessions [put]
288+ func (s * Server ) putSession (c * gin.Context ) {
289+
290+ // This endpoint can only be called in server mode
291+ if ! s .Config .IsServer () {
292+ s .getErrorPage (c , http .StatusBadRequest , "Setting default session can only be called in server mode" )
293+ return
294+ }
295+
296+ // Parse the request body to get the provider name
297+ var requestBody models.SessionSetDefaultRequest
298+ if err := c .ShouldBindJSON (& requestBody ); err != nil {
299+ s .getErrorPage (c , http .StatusBadRequest , "Failed to parse request body" , err )
300+ return
301+ }
302+
303+ provider := requestBody .Provider
304+
305+ logrus .WithFields (logrus.Fields {
306+ "provider" : provider ,
307+ }).Debugln ("Setting default session provider" )
308+
309+ // Verify that the user has an active session for this provider
310+ remoteSessions , err := s .getUserSessions (c )
311+ if err != nil {
312+ s .getErrorPage (c , http .StatusInternalServerError , "Failed to verify session" , err )
313+ return
314+ }
315+
316+ session , exists := remoteSessions [provider ]
317+ if ! exists {
318+ s .getErrorPage (c , http .StatusNotFound , "No active session found for provider" )
319+ return
320+ }
321+
322+ // Validate that the session is not expired
323+ if session .Expiry .Before (time .Now ()) {
324+ s .getErrorPage (c , http .StatusBadRequest , "Session for this provider has expired" )
325+ return
326+ }
327+
328+ // Update the default provider cookie
329+ defaultCookie := sessions .DefaultMany (c , ThandCookieName )
330+ defaultCookie .Set (ThandCookieAttributeActiveName , provider )
331+ err = defaultCookie .Save ()
332+
333+ if err != nil {
334+ s .getErrorPage (c , http .StatusInternalServerError , "Failed to save default provider" , err )
335+ return
336+ }
337+
338+ c .JSON (http .StatusOK , gin.H {
339+ "message" : "Default provider updated successfully" ,
340+ "provider" : provider ,
341+ })
342+ }
343+
257344// deleteSession removes a session
258345//
259346// @Summary Delete session
@@ -274,15 +361,144 @@ func (s *Server) deleteSession(c *gin.Context) {
274361 return
275362 }
276363
277- sessionManager := sessions .GetSessionManager ()
278- err := sessionManager .RemoveSession (s .Config .GetLoginServerHostname (), provider )
364+ logrus .WithFields (logrus.Fields {
365+ "provider" : provider ,
366+ }).Debugln ("Deleting session for provider" )
279367
280- if err != nil {
281- s .getErrorPage (c , http .StatusInternalServerError , "Failed to delete session" , err )
368+ if s .Config .IsServer () {
369+ // Server mode: Clear all cookies for this provider
370+
371+ // Clear the provider-specific cookie
372+ providerCookie := sessions .DefaultMany (c , CreateCookieName (provider ))
373+ providerCookie .Clear ()
374+ err := providerCookie .Save ()
375+
376+ if err != nil {
377+ s .getErrorPage (c , http .StatusInternalServerError , "Failed to clear provider cookie" , err )
378+ return
379+ }
380+
381+ // If this was the default provider, clear the default setting
382+ defaultCookie := sessions .DefaultMany (c , ThandCookieName )
383+ if activeProvider := defaultCookie .Get (ThandCookieAttributeActiveName ); activeProvider != nil {
384+ if activeProviderStr , ok := activeProvider .(string ); ok && activeProviderStr == provider {
385+ defaultCookie .Delete (ThandCookieAttributeActiveName )
386+ err = defaultCookie .Save ()
387+ if err != nil {
388+ s .getErrorPage (c , http .StatusInternalServerError , "Failed to clear default provider" , err )
389+ return
390+ }
391+ }
392+ }
393+
394+ c .JSON (http .StatusOK , gin.H {
395+ "message" : "Session deleted successfully" ,
396+ })
397+ return
398+
399+ } else if s .Config .IsAgent () {
400+ // Agent mode: Delete local session via session manager
401+ sessionMgr := sessionManager .GetSessionManager ()
402+ err := sessionMgr .RemoveSession (s .Config .GetLoginServerHostname (), provider )
403+
404+ if err != nil {
405+ s .getErrorPage (c , http .StatusInternalServerError , "Failed to delete session" , err )
406+ return
407+ }
408+
409+ c .JSON (http .StatusOK , gin.H {
410+ "message" : "Session deleted successfully" ,
411+ })
412+ return
413+
414+ } else {
415+ s .getErrorPage (c , http .StatusBadRequest , "Delete session can only be called in agent or server mode" )
282416 return
283417 }
418+ }
284419
285- c .JSON (http .StatusOK , gin.H {
286- "message" : "Session deleted successfully" ,
287- })
420+ // deleteSessions removes all sessions
421+ //
422+ // @Summary Delete all sessions
423+ // @Description Remove all sessions for the user
424+ // @Tags sessions
425+ // @Accept json
426+ // @Produce json
427+ // @Success 200 {object} map[string]any "All sessions deleted successfully"
428+ // @Failure 400 {object} map[string]any "Bad request"
429+ // @Failure 500 {object} map[string]any "Internal server error"
430+ // @Router /sessions [delete]
431+ func (s * Server ) deleteSessions (c * gin.Context ) {
432+
433+ logrus .Debugln ("Deleting all sessions" )
434+
435+ if s .Config .IsServer () {
436+ // Server mode: Get all user sessions and clear all cookies
437+
438+ remoteSessions , err := s .getUserSessions (c )
439+ if err != nil {
440+ s .getErrorPage (c , http .StatusInternalServerError , "Failed to get user sessions" , err )
441+ return
442+ }
443+
444+ // Clear provider-specific cookies for each session
445+ for providerName := range remoteSessions {
446+ providerCookie := sessions .DefaultMany (c , CreateCookieName (providerName ))
447+ providerCookie .Clear ()
448+ err := providerCookie .Save ()
449+ if err != nil {
450+ logrus .WithFields (logrus.Fields {
451+ "provider" : providerName ,
452+ "error" : err ,
453+ }).Warnln ("Failed to clear provider cookie" )
454+ }
455+ }
456+
457+ // Clear the default provider setting
458+ defaultCookie := sessions .DefaultMany (c , ThandCookieName )
459+ defaultCookie .Clear ()
460+ err = defaultCookie .Save ()
461+ if err != nil {
462+ s .getErrorPage (c , http .StatusInternalServerError , "Failed to clear default cookie" , err )
463+ return
464+ }
465+
466+ c .JSON (http .StatusOK , gin.H {
467+ "message" : "All sessions deleted successfully" ,
468+ })
469+ return
470+
471+ } else if s .Config .IsAgent () {
472+ // Agent mode: Delete all local sessions via session manager
473+ loginServer := s .Config .GetLoginServerHostname ()
474+ sessionMgr := sessionManager .GetSessionManager ()
475+ sessionMgr .Load (loginServer )
476+
477+ // Get all sessions
478+ loginServerData , err := sessionMgr .GetLoginServer (loginServer )
479+ if err != nil {
480+ s .getErrorPage (c , http .StatusInternalServerError , "Failed to get sessions" , err )
481+ return
482+ }
483+
484+ // Delete each session
485+ for providerName := range loginServerData .Sessions {
486+ err := sessionMgr .RemoveSession (loginServer , providerName )
487+ if err != nil {
488+ logrus .WithFields (logrus.Fields {
489+ "provider" : providerName ,
490+ "error" : err ,
491+ }).Warnln ("Failed to delete session" )
492+ }
493+ }
494+
495+ c .JSON (http .StatusOK , gin.H {
496+ "message" : "All sessions deleted successfully" ,
497+ })
498+ return
499+
500+ } else {
501+ s .getErrorPage (c , http .StatusBadRequest , "Delete sessions can only be called in agent or server mode" )
502+ return
503+ }
288504}
0 commit comments