mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-25 13:29:27 +01:00
impose throttle checks on HS TAKE
This commit is contained in:
parent
dedf78d0e9
commit
955cdbdfef
@ -1142,12 +1142,40 @@ type PendingVHostRequest struct {
|
||||
Account string
|
||||
}
|
||||
|
||||
type vhostThrottleExceeded struct {
|
||||
timeRemaining time.Duration
|
||||
}
|
||||
|
||||
func (vhe *vhostThrottleExceeded) Error() string {
|
||||
return fmt.Sprintf("Wait at least %v and try again", vhe.timeRemaining)
|
||||
}
|
||||
|
||||
func (vh *VHostInfo) checkThrottle(cooldown time.Duration) (err error) {
|
||||
if cooldown == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
now := time.Now().UTC()
|
||||
elapsed := now.Sub(vh.LastRequestTime)
|
||||
if elapsed > cooldown {
|
||||
// success
|
||||
vh.LastRequestTime = now
|
||||
return nil
|
||||
} else {
|
||||
return &vhostThrottleExceeded{timeRemaining: cooldown - elapsed}
|
||||
}
|
||||
}
|
||||
|
||||
// callback type implementing the actual business logic of vhost operations
|
||||
type vhostMunger func(input VHostInfo) (output VHostInfo, err error)
|
||||
|
||||
func (am *AccountManager) VHostSet(account string, vhost string) (result VHostInfo, err error) {
|
||||
func (am *AccountManager) VHostSet(account string, vhost string, cooldown time.Duration) (result VHostInfo, err error) {
|
||||
munger := func(input VHostInfo) (output VHostInfo, err error) {
|
||||
output = input
|
||||
err = output.checkThrottle(cooldown)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
output.Enabled = true
|
||||
output.ApprovedVHost = vhost
|
||||
return
|
||||
@ -1156,9 +1184,17 @@ func (am *AccountManager) VHostSet(account string, vhost string) (result VHostIn
|
||||
return am.performVHostChange(account, munger)
|
||||
}
|
||||
|
||||
func (am *AccountManager) VHostRequest(account string, vhost string) (result VHostInfo, err error) {
|
||||
func (am *AccountManager) VHostRequest(account string, vhost string, cooldown time.Duration) (result VHostInfo, err error) {
|
||||
munger := func(input VHostInfo) (output VHostInfo, err error) {
|
||||
output = input
|
||||
// you can update your existing request, but if you were approved or rejected,
|
||||
// you can't spam a new request
|
||||
if output.RequestedVHost == "" {
|
||||
err = output.checkThrottle(cooldown)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
output.RequestedVHost = vhost
|
||||
output.RejectedVHost = ""
|
||||
output.RejectionReason = ""
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"time"
|
||||
)
|
||||
|
||||
const hostservHelp = `HostServ lets you manage your vhost (i.e., the string displayed
|
||||
@ -213,23 +212,13 @@ func hsRequestHandler(server *Server, client *Client, command string, params []s
|
||||
}
|
||||
|
||||
accountName := client.Account()
|
||||
account, err := server.accounts.LoadAccount(client.Account())
|
||||
_, err := server.accounts.VHostRequest(accountName, vhost, server.Config().Accounts.VHosts.UserRequests.Cooldown)
|
||||
if err != nil {
|
||||
hsNotice(rb, client.t("An error occurred"))
|
||||
return
|
||||
}
|
||||
elapsed := time.Since(account.VHost.LastRequestTime)
|
||||
remainingTime := server.AccountConfig().VHosts.UserRequests.Cooldown - elapsed
|
||||
// you can update your existing request, but if you were rejected,
|
||||
// you can't spam a replacement request
|
||||
if account.VHost.RequestedVHost == "" && remainingTime > 0 {
|
||||
hsNotice(rb, fmt.Sprintf(client.t("You must wait an additional %v before making another request"), remainingTime))
|
||||
return
|
||||
}
|
||||
|
||||
_, err = server.accounts.VHostRequest(accountName, vhost)
|
||||
if err != nil {
|
||||
hsNotice(rb, client.t("An error occurred"))
|
||||
if throttled, ok := err.(*vhostThrottleExceeded); ok {
|
||||
hsNotice(rb, fmt.Sprintf(client.t("You must wait an additional %v before making another request"), throttled.timeRemaining))
|
||||
} else {
|
||||
hsNotice(rb, client.t("An error occurred"))
|
||||
}
|
||||
} else {
|
||||
hsNotice(rb, client.t("Your vhost request will be reviewed by an administrator"))
|
||||
chanMsg := fmt.Sprintf("Account %s requests vhost %s", accountName, vhost)
|
||||
@ -309,7 +298,7 @@ func hsSetHandler(server *Server, client *Client, command string, params []strin
|
||||
}
|
||||
// else: command == "del", vhost == ""
|
||||
|
||||
_, err := server.accounts.VHostSet(user, vhost)
|
||||
_, err := server.accounts.VHostSet(user, vhost, 0)
|
||||
if err != nil {
|
||||
hsNotice(rb, client.t("An error occurred"))
|
||||
} else if vhost != "" {
|
||||
@ -402,9 +391,10 @@ func hsOfferListHandler(server *Server, client *Client, command string, params [
|
||||
}
|
||||
|
||||
func hsTakeHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||
config := server.Config()
|
||||
vhost := params[0]
|
||||
found := false
|
||||
for _, offered := range server.Config().Accounts.VHosts.OfferList {
|
||||
for _, offered := range config.Accounts.VHosts.OfferList {
|
||||
if offered == vhost {
|
||||
found = true
|
||||
}
|
||||
@ -414,9 +404,13 @@ func hsTakeHandler(server *Server, client *Client, command string, params []stri
|
||||
return
|
||||
}
|
||||
|
||||
_, err := server.accounts.VHostSet(client.Account(), vhost)
|
||||
_, err := server.accounts.VHostSet(client.Account(), vhost, config.Accounts.VHosts.UserRequests.Cooldown)
|
||||
if err != nil {
|
||||
hsNotice(rb, client.t("An error occurred"))
|
||||
if throttled, ok := err.(*vhostThrottleExceeded); ok {
|
||||
hsNotice(rb, fmt.Sprintf(client.t("You must wait an additional %v before taking a vhost"), throttled.timeRemaining))
|
||||
} else {
|
||||
hsNotice(rb, client.t("An error occurred"))
|
||||
}
|
||||
} else if vhost != "" {
|
||||
hsNotice(rb, client.t("Successfully set vhost"))
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user