Create invitations for closed registrations (#233)

This commit is contained in:
Thomas Miceli
2024-04-02 21:27:15 +02:00
parent 3f5f4e01f1
commit ef004675a5
14 changed files with 301 additions and 21 deletions

View File

@ -42,7 +42,7 @@ func Setup(dbPath string, sharedCache bool) error {
return err
}
if err = db.AutoMigrate(&User{}, &Gist{}, &SSHKey{}, &AdminSetting{}); err != nil {
if err = db.AutoMigrate(&User{}, &Gist{}, &SSHKey{}, &AdminSetting{}, &Invitation{}); err != nil {
return err
}

87
internal/db/invitation.go Normal file
View File

@ -0,0 +1,87 @@
package db
import (
"math/rand"
"time"
)
type Invitation struct {
ID uint `gorm:"primaryKey"`
Code string
ExpiresAt int64
NbUsed uint
NbMax uint
}
func GetAllInvitations() ([]*Invitation, error) {
var invitations []*Invitation
err := db.
Order("(((expires_at >= strftime('%s', 'now')) AND ((nb_max <= 0) OR (nb_used < nb_max)))) desc").
Order("id asc").
Find(&invitations).Error
return invitations, err
}
func GetInvitationByID(id uint) (*Invitation, error) {
invitation := new(Invitation)
err := db.
Where("id = ?", id).
First(&invitation).Error
return invitation, err
}
func GetInvitationByCode(code string) (*Invitation, error) {
invitation := new(Invitation)
err := db.
Where("code = ?", code).
First(&invitation).Error
return invitation, err
}
func InvitationCodeExists(code string) (bool, error) {
var count int64
err := db.Model(&Invitation{}).Where("code = ?", code).Count(&count).Error
return count > 0, err
}
func (i *Invitation) Create() error {
i.Code = generateRandomCode()
return db.Create(&i).Error
}
func (i *Invitation) Update() error {
return db.Save(&i).Error
}
func (i *Invitation) Delete() error {
return db.Delete(&i).Error
}
func (i *Invitation) IsExpired() bool {
return i.ExpiresAt < time.Now().Unix()
}
func (i *Invitation) IsMaxedOut() bool {
return i.NbMax > 0 && i.NbUsed >= i.NbMax
}
func (i *Invitation) IsUsable() bool {
return !i.IsExpired() && !i.IsMaxedOut()
}
func (i *Invitation) Use() error {
i.NbUsed++
return i.Update()
}
func generateRandomCode() string {
const charset = "0123456789ABCDEF"
var seededRand = rand.New(rand.NewSource(time.Now().UnixNano()))
result := make([]byte, 16)
for i := range result {
result[i] = charset[seededRand.Intn(len(charset))]
}
return string(result)
}