package api import ( "errors" "net/http" "strings" "time" "github.com/gin-gonic/gin" "gitlab.celogeek.com/photos/api/internal/photos/models" "gitlab.celogeek.com/photos/api/internal/photoserrors" "gorm.io/gorm" ) func (s *Service) RequireAuthToken(c *gin.Context) { tokenAuth := c.GetHeader("Authorization") tokenCookie, _ := c.Cookie("photoapitoken") if tokenAuth != "" { if !strings.HasPrefix(tokenAuth, "Private ") { s.Error(c, http.StatusForbidden, photoserrors.ErrTokenMissing) } else { c.Set("token", tokenAuth[8:]) } } else if tokenCookie != "" { c.Set("token", tokenCookie) } else { s.Error(c, http.StatusForbidden, photoserrors.ErrTokenMissing) } } func (s *Service) RequireSession(c *gin.Context) { s.RequireAuthToken(c) if c.IsAborted() { return } sess := &models.Session{} if err := s.DB.Preload("Account").Where("token = ?", c.GetString("token")).First(sess).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { s.Error(c, http.StatusForbidden, photoserrors.ErrSessionNotFound) } else { s.Error(c, http.StatusForbidden, err) } return } if sess.Account == nil { s.Error(c, http.StatusInternalServerError, photoserrors.ErrSessionInvalid) return } s.DB.Select("updated_at").Save(sess) s.LogOk.Printf("Session", "User: %s", sess.Account.Login) c.Set("session", sess) } func (s *Service) CurrentSession(c *gin.Context) *models.Session { return c.MustGet("session").(*models.Session) } func (s *Service) SessionCleaner() { for range time.Tick(time.Minute) { t := time.Now().UTC().Add(-3 * time.Hour).Truncate(time.Minute) s.LogOk.Printf("Session", "Cleaning old session < %s", t) if err := s.DB.Where("updated_at < ?", t).Delete(&models.Session{}).Error; err != nil { s.LogErr.Printf("Session", "Cleaning failed: %s", err) } } }