1
0
mirror of https://github.com/muety/wakapi.git synced 2023-08-10 21:12:56 +03:00
wakapi/models/user.go

158 lines
4.8 KiB
Go
Raw Normal View History

2019-05-06 01:40:41 +03:00
package models
import (
2021-10-14 13:01:06 +03:00
"crypto/md5"
"fmt"
"regexp"
2021-10-14 13:01:06 +03:00
"strings"
"time"
)
func init() {
mailRegex = regexp.MustCompile(MailPattern)
}
2019-05-06 01:40:41 +03:00
type User struct {
ID string `json:"id" gorm:"primary_key"`
ApiKey string `json:"api_key" gorm:"unique"`
Email string `json:"email" gorm:"index:idx_user_email; size:255"`
Location string `json:"location"`
Password string `json:"-"`
2021-02-07 13:54:07 +03:00
CreatedAt CustomTime `gorm:"type:timestamp; default:CURRENT_TIMESTAMP" swaggertype:"string" format:"date" example:"2006-01-02 15:04:05.000"`
LastLoggedInAt CustomTime `gorm:"type:timestamp; default:CURRENT_TIMESTAMP" swaggertype:"string" format:"date" example:"2006-01-02 15:04:05.000"`
2021-02-07 01:23:26 +03:00
ShareDataMaxDays int `json:"-" gorm:"default:0"`
ShareEditors bool `json:"-" gorm:"default:false; type:bool"`
ShareLanguages bool `json:"-" gorm:"default:false; type:bool"`
ShareProjects bool `json:"-" gorm:"default:false; type:bool"`
ShareOSs bool `json:"-" gorm:"default:false; type:bool; column:share_oss"`
ShareMachines bool `json:"-" gorm:"default:false; type:bool"`
ShareLabels bool `json:"-" gorm:"default:false; type:bool"`
2021-02-12 20:13:49 +03:00
IsAdmin bool `json:"-" gorm:"default:false; type:bool"`
HasData bool `json:"-" gorm:"default:false; type:bool"`
WakatimeApiKey string `json:"-"` // for relay middleware and imports
WakatimeApiUrl string `json:"-"` // for relay middleware and imports
2021-04-05 23:57:57 +03:00
ResetToken string `json:"-"`
2021-04-30 15:07:14 +03:00
ReportsWeekly bool `json:"-" gorm:"default:false; type:bool"`
2019-05-06 01:40:41 +03:00
}
type Login struct {
2020-05-24 17:34:32 +03:00
Username string `schema:"username"`
Password string `schema:"password"`
}
type Signup struct {
Username string `schema:"username"`
Email string `schema:"email"`
2020-05-24 17:34:32 +03:00
Password string `schema:"password"`
PasswordRepeat string `schema:"password_repeat"`
2021-04-25 21:02:45 +03:00
Location string `schema:"location"`
}
2020-05-24 22:42:15 +03:00
2021-04-05 23:57:57 +03:00
type SetPasswordRequest struct {
Password string `schema:"password"`
PasswordRepeat string `schema:"password_repeat"`
Token string `schema:"token"`
}
type ResetPasswordRequest struct {
Email string `schema:"email"`
}
type CredentialsReset struct {
PasswordOld string `schema:"password_old"`
PasswordNew string `schema:"password_new"`
PasswordRepeat string `schema:"password_repeat"`
}
type UserDataUpdate struct {
2021-04-30 17:20:08 +03:00
Email string `schema:"email"`
Location string `schema:"location"`
ReportsWeekly bool `schema:"reports_weekly"`
}
type TimeByUser struct {
User string
Time CustomTime
}
2021-02-13 13:23:58 +03:00
type CountByUser struct {
User string
Count int64
}
func (u *User) TZ() *time.Location {
if u.Location == "" {
u.Location = "Local"
}
tz, err := time.LoadLocation(u.Location)
if err != nil {
return time.Local
}
return tz
}
2022-01-02 22:25:07 +03:00
// TZOffset returns the time difference between the user's current time zone and UTC
// TODO: is this actually working??
func (u *User) TZOffset() time.Duration {
_, offset := time.Now().In(u.TZ()).Zone()
return time.Duration(offset * int(time.Second))
}
2021-10-14 13:01:06 +03:00
func (u *User) AvatarURL(urlTemplate string) string {
urlTemplate = strings.ReplaceAll(urlTemplate, "{username}", u.ID)
urlTemplate = strings.ReplaceAll(urlTemplate, "{email}", u.Email)
if strings.Contains(urlTemplate, "{username_hash}") {
urlTemplate = strings.ReplaceAll(urlTemplate, "{username_hash}", fmt.Sprintf("%x", md5.Sum([]byte(u.ID))))
}
if strings.Contains(urlTemplate, "{email_hash}") {
urlTemplate = strings.ReplaceAll(urlTemplate, "{email_hash}", fmt.Sprintf("%x", md5.Sum([]byte(u.Email))))
}
return urlTemplate
}
// WakaTimeURL returns the user's effective WakaTime URL, i.e. a custom one (which could also point to another Wakapi instance) or fallback if not specified otherwise.
func (u *User) WakaTimeURL(fallback string) string {
if u.WakatimeApiUrl != "" {
return strings.TrimSuffix(u.WakatimeApiUrl, "/")
}
return fallback
}
func (c *CredentialsReset) IsValid() bool {
return ValidatePassword(c.PasswordNew) &&
c.PasswordNew == c.PasswordRepeat
}
2021-04-05 23:57:57 +03:00
func (c *SetPasswordRequest) IsValid() bool {
return ValidatePassword(c.Password) &&
c.Password == c.PasswordRepeat
}
2020-05-24 22:42:15 +03:00
func (s *Signup) IsValid() bool {
return ValidateUsername(s.Username) &&
ValidateEmail(s.Email) &&
ValidatePassword(s.Password) &&
2020-05-24 22:42:15 +03:00
s.Password == s.PasswordRepeat
}
func (r *UserDataUpdate) IsValid() bool {
return ValidateEmail(r.Email) && ValidateTimezone(r.Location)
}
func ValidateUsername(username string) bool {
2021-01-12 13:05:07 +03:00
return len(username) >= 1 && username != "current"
}
func ValidatePassword(password string) bool {
return len(password) >= 6
}
func ValidateEmail(email string) bool {
return email == "" || mailRegex.Match([]byte(email))
}
func ValidateTimezone(tz string) bool {
_, err := time.LoadLocation(tz)
return err == nil
}