appidea-restapi/routers/api/v1/user/session.go

125 lines
2.8 KiB
Go

package user
import (
"time"
"git.umbach.dev/app-idea/rest-api/modules/database"
"git.umbach.dev/app-idea/rest-api/modules/structs"
"github.com/gofiber/fiber/v2"
ua "github.com/mileusna/useragent"
log "github.com/sirupsen/logrus"
"gorm.io/gorm"
)
func isSessionIdValid(sessionId string) bool {
deleteExpiredSessions(database.DB)
var res string
db := database.DB
db.Raw("SELECT "+cfg.Settings.Cookies.SessionId+" FROM sessions WHERE "+cfg.Settings.Cookies.SessionId+" = ?", sessionId).Scan(&res)
if res == "" {
return false
} else {
return true
}
}
func DeleteSession(c *fiber.Ctx) error {
// swagger:operation POST /sessions/{id} Sessions sessions
// ---
// summary: Delete a user sessions
// responses:
// '200':
// description: User informations
// '400':
// description: Session id invalid
db := database.DB
userId, err := getUserIdBySessionId(c.Cookies(cfg.Settings.Cookies.SessionId))
if err != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
res := db.Where("user_id = ? AND session_id = ?", userId, c.Cookies(cfg.Settings.Cookies.SessionId)).Delete(&structs.Session{})
// session isn't in list
if res.RowsAffected == 0 {
return c.SendStatus(fiber.StatusBadRequest)
}
return c.SendStatus(fiber.StatusOK)
}
func deleteExpiredSessions(db *gorm.DB) {
var res string
db.Raw("DELETE FROM sessions WHERE expires < ?", time.Now()).Scan(&res)
}
func createUserSession(db *gorm.DB, userId string, ip string, userAgent string) (string, error) {
sessionId, err := generateRandomString(32, 1)
if err != nil {
log.Warnln("Failed to generate user session:", err)
return "", err
}
ua := ua.Parse(userAgent)
session := structs.Session{UserId: userId, SessionId: sessionId, IP: ip, UserAgent: ua.OS + " " + ua.Name, LastLogin: time.Now(), Expires: getUserSessionExpiresTime()}
res := db.Create(&session)
if res.Error != nil {
log.Warnln("failed to create session:", res.Error)
return "", err
}
return sessionId, nil
}
func getUserSessionExpiresTime() time.Time {
return time.Now().Add(time.Hour * time.Duration(cfg.Settings.Expires.UserSession))
}
func SessionIdCheck(c *fiber.Ctx) error {
var sessionId string
if c.Method() == "GET" {
sessionId = c.Query(cfg.Settings.Cookies.SessionId)
} else {
sessionId = c.Cookies(cfg.Settings.Cookies.SessionId)
}
if sessionId == "" {
return fiber.ErrUnauthorized
}
valid := isSessionIdValid(sessionId)
if valid {
return c.Next()
}
return fiber.ErrUnauthorized
}
func AuthSession(c *fiber.Ctx) error {
sessionId := c.Cookies(cfg.Settings.Cookies.SessionId)
if sessionId == "" {
return fiber.ErrUnauthorized
}
valid := isSessionIdValid(sessionId)
if valid {
return c.SendStatus(fiber.StatusOK)
}
return c.SendStatus(fiber.StatusUnauthorized)
}