package model import ( "crypto/rand" "encoding/base64" "strings" "time" "github.com/labstack/echo-contrib/session" "github.com/labstack/echo/v4" "gitnet.fr/deblan/budget/database/manager" "golang.org/x/crypto/bcrypt" ) type User struct { ID uint `gorm:"primaryKey" json:"id"` Username string `gorm:"unique;not null" json:"username"` Password string `gorm:"not null" json:"-"` DisplayName string `gorm:"not null" json:"display_name"` ApiKey string `json:"api_key"` LoggedAt time.Time `json:"logged_at"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } func NewUser(username, password, displayName string) *User { user := User{ Username: username, DisplayName: displayName, } user.UpdatePassword(password) return &user } func (u *User) GenerateApiKey() { buffer := make([]byte, 64) rand.Read(buffer) u.ApiKey = base64.URLEncoding.EncodeToString(buffer)[:64] } func (u *User) UpdatePassword(password string) { hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) u.Password = string(hashedPassword) } func (u *User) HasPassword(password string) bool { return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password)) == nil } func LoadUser(c echo.Context) *User { user := LoadApiUser(c) if user == nil { user = LoadSessionUser(c) } return user } func LoadApiUser(c echo.Context) *User { headers := c.Request().Header apiKey := "" for key, values := range headers { if strings.ToLower(key) == "x-api-key" { apiKey = values[0] } } if apiKey == "" { return nil } var count int64 db := manager.Get() db.Db.Model(User{}).Where("api_key = ?", apiKey).Count(&count) if count == 0 { return nil } var user User manager.Get().Db.Model(User{}).Where("api_key = ?", apiKey).Find(&user) return &user } func LoadSessionUser(c echo.Context) *User { sess, err := session.Get("session", c) if err != nil { return nil } value := sess.Values["user"] if value == nil { return nil } id := value.(uint) var count int64 db := manager.Get() db.Db.Model(User{}).Where("id = ?", id).Count(&count) if count == 0 { return nil } var user User manager.Get().Db.Model(User{}).Where("id = ?", id).Find(&user) if user.ApiKey == "" { user.GenerateApiKey() db.Db.Save(user) } return &user }