From c7d4a22c64a51126a8a2e535cfecd7acfe3edff2 Mon Sep 17 00:00:00 2001 From: Eslam-Nawara Date: Mon, 4 Dec 2023 17:25:15 +0200 Subject: [PATCH] add voucher duration to the voucher model and set it on voucher creation --- server/app/user_handler.go | 23 ++++++++++++++--------- server/app/voucher_handler.go | 21 ++++++++++++++------- server/internal/config_parser.go | 1 + server/models/voucher.go | 23 ++++++++++++----------- 4 files changed, 41 insertions(+), 27 deletions(-) diff --git a/server/app/user_handler.go b/server/app/user_handler.go index 18efa7d8..7081ba0e 100644 --- a/server/app/user_handler.go +++ b/server/app/user_handler.go @@ -66,9 +66,10 @@ type EmailInput struct { // ApplyForVoucherInput struct for user to apply for voucher type ApplyForVoucherInput struct { - VMs int `json:"vms" binding:"required" validate:"min=0"` - PublicIPs int `json:"public_ips" binding:"required" validate:"min=0"` - Reason string `json:"reason" binding:"required" validate:"nonzero"` + VMs int `json:"vms" binding:"required" validate:"min=0"` + PublicIPs int `json:"public_ips" binding:"required" validate:"min=0"` + Reason string `json:"reason" binding:"required" validate:"nonzero"` + VoucherDuration int `json:"voucher_duration" binding:"required"` } // AddVoucherInput struct for voucher applied by user @@ -80,7 +81,6 @@ type AddVoucherInput struct { func (a *App) SignUpHandler(req *http.Request) (interface{}, Response) { var signUp SignUpInput err := json.NewDecoder(req.Body).Decode(&signUp) - if err != nil { log.Error().Err(err).Send() return nil, BadRequest(errors.New("failed to read sign up data")) @@ -573,14 +573,19 @@ func (a *App) ApplyForVoucherHandler(req *http.Request) (interface{}, Response) return nil, BadRequest(errors.New("invalid voucher data")) } + if input.VoucherDuration > a.config.VouchersMaxDuration { + return nil, BadRequest(fmt.Errorf("invalid voucher duration, max duration is %d", a.config.VouchersMaxDuration)) + } + // generate voucher for user but can't use it until admin approves it v := internal.GenerateRandomVoucher(5) voucher := models.Voucher{ - Voucher: v, - UserID: userID, - VMs: input.VMs, - Reason: input.Reason, - PublicIPs: input.PublicIPs, + Voucher: v, + UserID: userID, + VMs: input.VMs, + Reason: input.Reason, + PublicIPs: input.PublicIPs, + VoucherDuration: input.VoucherDuration, } err = a.db.CreateVoucher(&voucher) diff --git a/server/app/voucher_handler.go b/server/app/voucher_handler.go index 90a24aca..a46a62e8 100644 --- a/server/app/voucher_handler.go +++ b/server/app/voucher_handler.go @@ -4,6 +4,7 @@ package app import ( "encoding/json" "errors" + "fmt" "net/http" "strconv" @@ -17,9 +18,10 @@ import ( // GenerateVoucherInput struct for data needed when user generate vouchers type GenerateVoucherInput struct { - Length int `json:"length" binding:"required" validate:"min=3,max=20"` - VMs int `json:"vms" binding:"required"` - PublicIPs int `json:"public_ips" binding:"required"` + Length int `json:"length" binding:"required" validate:"min=3,max=20"` + VMs int `json:"vms" binding:"required"` + PublicIPs int `json:"public_ips" binding:"required"` + VoucherDuration int `json:"voucher_duration" binding:"required"` } // UpdateVoucherInput struct for data needed when user update voucher @@ -43,11 +45,16 @@ func (a *App) GenerateVoucherHandler(req *http.Request) (interface{}, Response) } voucher := internal.GenerateRandomVoucher(input.Length) + if input.VoucherDuration > a.config.VouchersMaxDuration { + return nil, BadRequest(fmt.Errorf("invalid voucher duration, max duration is %d", a.config.VouchersMaxDuration)) + } + v := models.Voucher{ - Voucher: voucher, - VMs: input.VMs, - PublicIPs: input.PublicIPs, - Approved: true, + Voucher: voucher, + VMs: input.VMs, + PublicIPs: input.PublicIPs, + VoucherDuration: input.VoucherDuration, + Approved: true, } err = a.db.CreateVoucher(&v) diff --git a/server/internal/config_parser.go b/server/internal/config_parser.go index 678de081..f84c1cad 100644 --- a/server/internal/config_parser.go +++ b/server/internal/config_parser.go @@ -21,6 +21,7 @@ type Configuration struct { NotifyAdminsIntervalHours int `json:"notifyAdminsIntervalHours"` AdminSSHKey string `json:"adminSSHKey"` BalanceThreshold int `json:"balanceThreshold"` + VouchersMaxDuration int `json:"vouchersDuration"` } // Server struct to hold server's information diff --git a/server/models/voucher.go b/server/models/voucher.go index 8c3c8f56..e3b3208c 100644 --- a/server/models/voucher.go +++ b/server/models/voucher.go @@ -5,15 +5,16 @@ import "time" // Voucher struct holds data of vouchers type Voucher struct { - ID int `json:"id" gorm:"primaryKey"` - UserID string `json:"user_id" binding:"required"` - Voucher string `json:"voucher" gorm:"unique"` - VMs int `json:"vms" binding:"required"` - PublicIPs int `json:"public_ips" binding:"required"` - Reason string `json:"reason" binding:"required"` - Used bool `json:"used" binding:"required"` - Approved bool `json:"approved" binding:"required"` - Rejected bool `json:"rejected" binding:"required"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ID int `json:"id" gorm:"primaryKey"` + UserID string `json:"user_id" binding:"required"` + Voucher string `json:"voucher" gorm:"unique"` + VMs int `json:"vms" binding:"required"` + PublicIPs int `json:"public_ips" binding:"required"` + Reason string `json:"reason" binding:"required"` + Used bool `json:"used" binding:"required"` + Approved bool `json:"approved" binding:"required"` + Rejected bool `json:"rejected" binding:"required"` + VoucherDuration int `json:"voucher_duration" binding:"required"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` }