125 lines
2.8 KiB
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)
|
|
}
|