mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-13 07:29:30 +01:00
review fixes, bug fixes
This commit is contained in:
parent
5e62cc4ebc
commit
cc9941cb07
@ -109,7 +109,7 @@ func (am *AccountManager) buildNickToAccountIndex() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (am *AccountManager) initVHostRequestQueue() {
|
func (am *AccountManager) initVHostRequestQueue() {
|
||||||
if !am.server.AccountConfig().HostServ.Enabled {
|
if !am.server.AccountConfig().VHosts.Enabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -642,10 +642,7 @@ func (am *AccountManager) Unregister(account string) error {
|
|||||||
tx.Delete(credentialsKey)
|
tx.Delete(credentialsKey)
|
||||||
tx.Delete(vhostKey)
|
tx.Delete(vhostKey)
|
||||||
_, err := tx.Delete(vhostQueueKey)
|
_, err := tx.Delete(vhostQueueKey)
|
||||||
if err != nil {
|
am.decrementVHostQueueCount(casefoldedAccount, err)
|
||||||
// 2's complement decrement
|
|
||||||
atomic.AddUint64(&am.vhostRequestPendingCount, ^uint64(0))
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -737,7 +734,7 @@ type PendingVHostRequest struct {
|
|||||||
// callback type implementing the actual business logic of vhost operations
|
// callback type implementing the actual business logic of vhost operations
|
||||||
type vhostMunger func(input VHostInfo) (output VHostInfo, err error)
|
type vhostMunger func(input VHostInfo) (output VHostInfo, err error)
|
||||||
|
|
||||||
func (am *AccountManager) VHostSet(account string, vhost string) (err error) {
|
func (am *AccountManager) VHostSet(account string, vhost string) (result VHostInfo, err error) {
|
||||||
munger := func(input VHostInfo) (output VHostInfo, err error) {
|
munger := func(input VHostInfo) (output VHostInfo, err error) {
|
||||||
output = input
|
output = input
|
||||||
output.Enabled = true
|
output.Enabled = true
|
||||||
@ -748,7 +745,7 @@ func (am *AccountManager) VHostSet(account string, vhost string) (err error) {
|
|||||||
return am.performVHostChange(account, munger)
|
return am.performVHostChange(account, munger)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *AccountManager) VHostRequest(account string, vhost string) (err error) {
|
func (am *AccountManager) VHostRequest(account string, vhost string) (result VHostInfo, err error) {
|
||||||
munger := func(input VHostInfo) (output VHostInfo, err error) {
|
munger := func(input VHostInfo) (output VHostInfo, err error) {
|
||||||
output = input
|
output = input
|
||||||
output.RequestedVHost = vhost
|
output.RequestedVHost = vhost
|
||||||
@ -761,7 +758,7 @@ func (am *AccountManager) VHostRequest(account string, vhost string) (err error)
|
|||||||
return am.performVHostChange(account, munger)
|
return am.performVHostChange(account, munger)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *AccountManager) VHostApprove(account string) (err error) {
|
func (am *AccountManager) VHostApprove(account string) (result VHostInfo, err error) {
|
||||||
munger := func(input VHostInfo) (output VHostInfo, err error) {
|
munger := func(input VHostInfo) (output VHostInfo, err error) {
|
||||||
output = input
|
output = input
|
||||||
output.Enabled = true
|
output.Enabled = true
|
||||||
@ -774,7 +771,7 @@ func (am *AccountManager) VHostApprove(account string) (err error) {
|
|||||||
return am.performVHostChange(account, munger)
|
return am.performVHostChange(account, munger)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *AccountManager) VHostReject(account string, reason string) (err error) {
|
func (am *AccountManager) VHostReject(account string, reason string) (result VHostInfo, err error) {
|
||||||
munger := func(input VHostInfo) (output VHostInfo, err error) {
|
munger := func(input VHostInfo) (output VHostInfo, err error) {
|
||||||
output = input
|
output = input
|
||||||
output.RejectedVHost = output.RequestedVHost
|
output.RejectedVHost = output.RequestedVHost
|
||||||
@ -786,7 +783,7 @@ func (am *AccountManager) VHostReject(account string, reason string) (err error)
|
|||||||
return am.performVHostChange(account, munger)
|
return am.performVHostChange(account, munger)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *AccountManager) VHostSetEnabled(client *Client, enabled bool) (err error) {
|
func (am *AccountManager) VHostSetEnabled(client *Client, enabled bool) (result VHostInfo, err error) {
|
||||||
munger := func(input VHostInfo) (output VHostInfo, err error) {
|
munger := func(input VHostInfo) (output VHostInfo, err error) {
|
||||||
output = input
|
output = input
|
||||||
output.Enabled = enabled
|
output.Enabled = enabled
|
||||||
@ -796,10 +793,11 @@ func (am *AccountManager) VHostSetEnabled(client *Client, enabled bool) (err err
|
|||||||
return am.performVHostChange(client.Account(), munger)
|
return am.performVHostChange(client.Account(), munger)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *AccountManager) performVHostChange(account string, munger vhostMunger) (err error) {
|
func (am *AccountManager) performVHostChange(account string, munger vhostMunger) (result VHostInfo, err error) {
|
||||||
account, err = CasefoldName(account)
|
account, err = CasefoldName(account)
|
||||||
if err != nil || account == "" {
|
if err != nil || account == "" {
|
||||||
return errAccountDoesNotExist
|
err = errAccountDoesNotExist
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
am.vHostUpdateMutex.Lock()
|
am.vHostUpdateMutex.Lock()
|
||||||
@ -807,19 +805,22 @@ func (am *AccountManager) performVHostChange(account string, munger vhostMunger)
|
|||||||
|
|
||||||
clientAccount, err := am.LoadAccount(account)
|
clientAccount, err := am.LoadAccount(account)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errAccountDoesNotExist
|
err = errAccountDoesNotExist
|
||||||
|
return
|
||||||
} else if !clientAccount.Verified {
|
} else if !clientAccount.Verified {
|
||||||
return errAccountUnverified
|
err = errAccountUnverified
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := munger(clientAccount.VHost)
|
result, err = munger(clientAccount.VHost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
vhtext, err := json.Marshal(result)
|
vhtext, err := json.Marshal(result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errAccountUpdateFailed
|
err = errAccountUpdateFailed
|
||||||
|
return
|
||||||
}
|
}
|
||||||
vhstr := string(vhtext)
|
vhstr := string(vhtext)
|
||||||
|
|
||||||
@ -839,21 +840,30 @@ func (am *AccountManager) performVHostChange(account string, munger vhostMunger)
|
|||||||
atomic.AddUint64(&am.vhostRequestPendingCount, 1)
|
atomic.AddUint64(&am.vhostRequestPendingCount, 1)
|
||||||
} else if clientAccount.VHost.RequestedVHost != "" && result.RequestedVHost == "" {
|
} else if clientAccount.VHost.RequestedVHost != "" && result.RequestedVHost == "" {
|
||||||
_, err = tx.Delete(queueKey)
|
_, err = tx.Delete(queueKey)
|
||||||
if err != nil {
|
am.decrementVHostQueueCount(account, err)
|
||||||
// XXX this is the decrement operation for two's complement
|
|
||||||
atomic.AddUint64(&am.vhostRequestPendingCount, ^uint64(0))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errAccountUpdateFailed
|
err = errAccountUpdateFailed
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
am.applyVhostToClients(account, result)
|
am.applyVhostToClients(account, result)
|
||||||
return nil
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX annoying helper method for keeping the queue count in sync with the DB
|
||||||
|
// `err` is the buntdb error returned from deleting the queue key
|
||||||
|
func (am *AccountManager) decrementVHostQueueCount(account string, err error) {
|
||||||
|
if err == nil {
|
||||||
|
// successfully deleted a queue entry, do a 2's complement decrement:
|
||||||
|
atomic.AddUint64(&am.vhostRequestPendingCount, ^uint64(0))
|
||||||
|
} else if err != buntdb.ErrNotFound {
|
||||||
|
am.server.logger.Error("internal", "buntdb dequeue error", account, err.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *AccountManager) VHostListRequests(limit int) (requests []PendingVHostRequest, total int) {
|
func (am *AccountManager) VHostListRequests(limit int) (requests []PendingVHostRequest, total int) {
|
||||||
@ -893,7 +903,7 @@ func (am *AccountManager) VHostListRequests(limit int) (requests []PendingVHostR
|
|||||||
func (am *AccountManager) applyVHostInfo(client *Client, info VHostInfo) {
|
func (am *AccountManager) applyVHostInfo(client *Client, info VHostInfo) {
|
||||||
// if hostserv is disabled in config, then don't grant vhosts
|
// if hostserv is disabled in config, then don't grant vhosts
|
||||||
// that were previously approved while it was enabled
|
// that were previously approved while it was enabled
|
||||||
if !am.server.AccountConfig().HostServ.Enabled {
|
if !am.server.AccountConfig().VHosts.Enabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,10 +311,6 @@ func (client *Client) Ping() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// server goroutine
|
|
||||||
//
|
|
||||||
|
|
||||||
// Register sets the client details as appropriate when entering the network.
|
// Register sets the client details as appropriate when entering the network.
|
||||||
func (client *Client) Register() {
|
func (client *Client) Register() {
|
||||||
client.stateMutex.Lock()
|
client.stateMutex.Lock()
|
||||||
@ -584,8 +580,8 @@ func (client *Client) SetVHost(vhost string) (updated bool) {
|
|||||||
func (client *Client) updateNick(nick string) {
|
func (client *Client) updateNick(nick string) {
|
||||||
casefoldedName, err := CasefoldName(nick)
|
casefoldedName, err := CasefoldName(nick)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(fmt.Sprintf("ERROR: Nick [%s] couldn't be casefolded... this should never happen. Printing stacktrace.", client.nick))
|
client.server.logger.Error("internal", "nick couldn't be casefolded", nick, err.Error())
|
||||||
debug.PrintStack()
|
return
|
||||||
}
|
}
|
||||||
client.stateMutex.Lock()
|
client.stateMutex.Lock()
|
||||||
client.nick = nick
|
client.nick = nick
|
||||||
@ -616,8 +612,8 @@ func (client *Client) updateNickMaskNoMutex() {
|
|||||||
nickMaskString := fmt.Sprintf("%s!%s@%s", client.nick, client.username, client.hostname)
|
nickMaskString := fmt.Sprintf("%s!%s@%s", client.nick, client.username, client.hostname)
|
||||||
nickMaskCasefolded, err := Casefold(nickMaskString)
|
nickMaskCasefolded, err := Casefold(nickMaskString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(fmt.Sprintf("ERROR: Nickmask [%s] couldn't be casefolded... this should never happen. Printing stacktrace.", client.nickMaskString))
|
client.server.logger.Error("internal", "nickmask couldn't be casefolded", nickMaskString, err.Error())
|
||||||
debug.PrintStack()
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
client.nickMaskString = nickMaskString
|
client.nickMaskString = nickMaskString
|
||||||
|
@ -64,7 +64,7 @@ type AccountConfig struct {
|
|||||||
AuthenticationEnabled bool `yaml:"authentication-enabled"`
|
AuthenticationEnabled bool `yaml:"authentication-enabled"`
|
||||||
SkipServerPassword bool `yaml:"skip-server-password"`
|
SkipServerPassword bool `yaml:"skip-server-password"`
|
||||||
NickReservation NickReservationConfig `yaml:"nick-reservation"`
|
NickReservation NickReservationConfig `yaml:"nick-reservation"`
|
||||||
HostServ HostServConfig
|
VHosts VHostConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountRegistrationConfig controls account registration.
|
// AccountRegistrationConfig controls account registration.
|
||||||
@ -92,13 +92,16 @@ type AccountRegistrationConfig struct {
|
|||||||
AllowMultiplePerConnection bool `yaml:"allow-multiple-per-connection"`
|
AllowMultiplePerConnection bool `yaml:"allow-multiple-per-connection"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type HostServConfig struct {
|
type VHostConfig struct {
|
||||||
Enabled bool
|
Enabled bool
|
||||||
UserRequestsEnabled bool `yaml:"user-requests-enabled"`
|
MaxLength int `yaml:"max-length"`
|
||||||
Cooldown time.Duration
|
ValidRegexpRaw string `yaml:"valid-regexp"`
|
||||||
MaxVHostLen int `yaml:"max-vhost-len"`
|
ValidRegexp *regexp.Regexp
|
||||||
ValidRegexpRaw string `yaml:"valid-regexp"`
|
UserRequests struct {
|
||||||
ValidRegexp *regexp.Regexp
|
Enabled bool
|
||||||
|
Channel string
|
||||||
|
Cooldown time.Duration
|
||||||
|
} `yaml:"user-requests"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NickReservationMethod int
|
type NickReservationMethod int
|
||||||
@ -543,17 +546,17 @@ func LoadConfig(filename string) (config *Config, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rawRegexp := config.Accounts.HostServ.ValidRegexpRaw
|
rawRegexp := config.Accounts.VHosts.ValidRegexpRaw
|
||||||
if rawRegexp != "" {
|
if rawRegexp != "" {
|
||||||
regexp, err := regexp.Compile(rawRegexp)
|
regexp, err := regexp.Compile(rawRegexp)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
config.Accounts.HostServ.ValidRegexp = regexp
|
config.Accounts.VHosts.ValidRegexp = regexp
|
||||||
} else {
|
} else {
|
||||||
log.Printf("invalid vhost regexp: %s\n", err.Error())
|
log.Printf("invalid vhost regexp: %s\n", err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if config.Accounts.HostServ.ValidRegexp == nil {
|
if config.Accounts.VHosts.ValidRegexp == nil {
|
||||||
config.Accounts.HostServ.ValidRegexp = validVhostRegex
|
config.Accounts.VHosts.ValidRegexp = defaultValidVhostRegex
|
||||||
}
|
}
|
||||||
|
|
||||||
maxSendQBytes, err := bytefmt.ToBytes(config.Server.MaxSendQString)
|
maxSendQBytes, err := bytefmt.ToBytes(config.Server.MaxSendQString)
|
||||||
|
@ -75,9 +75,12 @@ func (client *Client) ApplyProxiedIP(proxiedIP string, tls bool) (exiting bool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// given IP is sane! override the client's current IP
|
// given IP is sane! override the client's current IP
|
||||||
|
rawHostname := utils.LookupHostname(proxiedIP)
|
||||||
|
client.stateMutex.Lock()
|
||||||
client.proxiedIP = parsedProxiedIP
|
client.proxiedIP = parsedProxiedIP
|
||||||
client.rawHostname = utils.LookupHostname(proxiedIP)
|
client.rawHostname = rawHostname
|
||||||
client.hostname = client.rawHostname
|
client.stateMutex.Unlock()
|
||||||
|
// nickmask will be updated when the client completes registration
|
||||||
|
|
||||||
// set tls info
|
// set tls info
|
||||||
client.certfp = ""
|
client.certfp = ""
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2017 Daniel Oaks <daniel@danieloaks.net>
|
// Copyright (c) 2018 Shivaram Lingamneni <slingamn@cs.stanford.edu>
|
||||||
// released under the MIT license
|
// released under the MIT license
|
||||||
|
|
||||||
package irc
|
package irc
|
||||||
@ -26,16 +26,16 @@ var (
|
|||||||
errVHostBadCharacters = errors.New("Vhost contains prohibited characters")
|
errVHostBadCharacters = errors.New("Vhost contains prohibited characters")
|
||||||
errVHostTooLong = errors.New("Vhost is too long")
|
errVHostTooLong = errors.New("Vhost is too long")
|
||||||
// ascii only for now
|
// ascii only for now
|
||||||
validVhostRegex = regexp.MustCompile(`^[0-9A-Za-z.\-_/]+$`)
|
defaultValidVhostRegex = regexp.MustCompile(`^[0-9A-Za-z.\-_/]+$`)
|
||||||
)
|
)
|
||||||
|
|
||||||
func hostservEnabled(server *Server) bool {
|
func hostservEnabled(server *Server) bool {
|
||||||
return server.AccountConfig().HostServ.Enabled
|
return server.AccountConfig().VHosts.Enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
func hostservRequestsEnabled(server *Server) bool {
|
func hostservRequestsEnabled(server *Server) bool {
|
||||||
ac := server.AccountConfig()
|
ac := server.AccountConfig()
|
||||||
return ac.HostServ.Enabled && ac.HostServ.UserRequestsEnabled
|
return ac.VHosts.Enabled && ac.VHosts.UserRequests.Enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -84,7 +84,7 @@ request for a new one.`,
|
|||||||
|
|
||||||
SET sets a user's vhost, bypassing the request system.`,
|
SET sets a user's vhost, bypassing the request system.`,
|
||||||
helpShort: `$bSET$b sets a user's vhost.`,
|
helpShort: `$bSET$b sets a user's vhost.`,
|
||||||
capabs: []string{"hostserv"},
|
capabs: []string{"vhosts"},
|
||||||
enabled: hostservEnabled,
|
enabled: hostservEnabled,
|
||||||
},
|
},
|
||||||
"del": {
|
"del": {
|
||||||
@ -93,7 +93,7 @@ SET sets a user's vhost, bypassing the request system.`,
|
|||||||
|
|
||||||
DEL sets a user's vhost, bypassing the request system.`,
|
DEL sets a user's vhost, bypassing the request system.`,
|
||||||
helpShort: `$bDEL$b deletes a user's vhost.`,
|
helpShort: `$bDEL$b deletes a user's vhost.`,
|
||||||
capabs: []string{"hostserv"},
|
capabs: []string{"vhosts"},
|
||||||
enabled: hostservEnabled,
|
enabled: hostservEnabled,
|
||||||
},
|
},
|
||||||
"waiting": {
|
"waiting": {
|
||||||
@ -103,7 +103,7 @@ DEL sets a user's vhost, bypassing the request system.`,
|
|||||||
WAITING shows a list of pending vhost requests, which can then be approved
|
WAITING shows a list of pending vhost requests, which can then be approved
|
||||||
or rejected.`,
|
or rejected.`,
|
||||||
helpShort: `$bWAITING$b shows a list of pending vhost requests.`,
|
helpShort: `$bWAITING$b shows a list of pending vhost requests.`,
|
||||||
capabs: []string{"hostserv"},
|
capabs: []string{"vhosts"},
|
||||||
enabled: hostservEnabled,
|
enabled: hostservEnabled,
|
||||||
},
|
},
|
||||||
"approve": {
|
"approve": {
|
||||||
@ -112,7 +112,7 @@ or rejected.`,
|
|||||||
|
|
||||||
APPROVE approves a user's vhost request.`,
|
APPROVE approves a user's vhost request.`,
|
||||||
helpShort: `$bAPPROVE$b approves a user's vhost request.`,
|
helpShort: `$bAPPROVE$b approves a user's vhost request.`,
|
||||||
capabs: []string{"hostserv"},
|
capabs: []string{"vhosts"},
|
||||||
enabled: hostservEnabled,
|
enabled: hostservEnabled,
|
||||||
},
|
},
|
||||||
"reject": {
|
"reject": {
|
||||||
@ -122,7 +122,7 @@ APPROVE approves a user's vhost request.`,
|
|||||||
REJECT rejects a user's vhost request, optionally giving them a reason
|
REJECT rejects a user's vhost request, optionally giving them a reason
|
||||||
for the rejection.`,
|
for the rejection.`,
|
||||||
helpShort: `$bREJECT$b rejects a user's vhost request.`,
|
helpShort: `$bREJECT$b rejects a user's vhost request.`,
|
||||||
capabs: []string{"hostserv"},
|
capabs: []string{"vhosts"},
|
||||||
enabled: hostservEnabled,
|
enabled: hostservEnabled,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -133,13 +133,26 @@ func hsNotice(rb *ResponseBuffer, text string) {
|
|||||||
rb.Add(nil, "HostServ", "NOTICE", rb.target.Nick(), text)
|
rb.Add(nil, "HostServ", "NOTICE", rb.target.Nick(), text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hsNotifyChannel notifies the designated channel of new vhost activity
|
||||||
|
func hsNotifyChannel(server *Server, message string) {
|
||||||
|
chname := server.AccountConfig().VHosts.UserRequests.Channel
|
||||||
|
channel := server.channels.Get(chname)
|
||||||
|
if channel == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
chname = channel.Name()
|
||||||
|
for _, client := range channel.Members() {
|
||||||
|
client.Send(nil, "HostServ", "PRIVMSG", chname, message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func hsOnOffHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
|
func hsOnOffHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
|
||||||
enable := false
|
enable := false
|
||||||
if command == "on" {
|
if command == "on" {
|
||||||
enable = true
|
enable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
err := server.accounts.VHostSetEnabled(client, enable)
|
_, err := server.accounts.VHostSetEnabled(client, enable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hsNotice(rb, client.t("An error occurred"))
|
hsNotice(rb, client.t("An error occurred"))
|
||||||
} else if enable {
|
} else if enable {
|
||||||
@ -163,7 +176,7 @@ func hsRequestHandler(server *Server, client *Client, command, params string, rb
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
elapsed := time.Now().Sub(account.VHost.LastRequestTime)
|
elapsed := time.Now().Sub(account.VHost.LastRequestTime)
|
||||||
remainingTime := server.AccountConfig().HostServ.Cooldown - elapsed
|
remainingTime := server.AccountConfig().VHosts.UserRequests.Cooldown - elapsed
|
||||||
// you can update your existing request, but if you were rejected,
|
// you can update your existing request, but if you were rejected,
|
||||||
// you can't spam a replacement request
|
// you can't spam a replacement request
|
||||||
if account.VHost.RequestedVHost == "" && remainingTime > 0 {
|
if account.VHost.RequestedVHost == "" && remainingTime > 0 {
|
||||||
@ -171,11 +184,13 @@ func hsRequestHandler(server *Server, client *Client, command, params string, rb
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = server.accounts.VHostRequest(accountName, vhost)
|
_, err = server.accounts.VHostRequest(accountName, vhost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hsNotice(rb, client.t("An error occurred"))
|
hsNotice(rb, client.t("An error occurred"))
|
||||||
} else {
|
} else {
|
||||||
hsNotice(rb, fmt.Sprintf(client.t("Your vhost request will be reviewed by an administrator")))
|
hsNotice(rb, fmt.Sprintf(client.t("Your vhost request will be reviewed by an administrator")))
|
||||||
|
chanMsg := fmt.Sprintf("Account %s requests vhost %s", accountName, vhost)
|
||||||
|
hsNotifyChannel(server, chanMsg)
|
||||||
// TODO send admins a snomask of some kind
|
// TODO send admins a snomask of some kind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,10 +223,10 @@ func hsStatusHandler(server *Server, client *Client, command, params string, rb
|
|||||||
|
|
||||||
func validateVhost(server *Server, vhost string, oper bool) error {
|
func validateVhost(server *Server, vhost string, oper bool) error {
|
||||||
ac := server.AccountConfig()
|
ac := server.AccountConfig()
|
||||||
if len(vhost) > ac.HostServ.MaxVHostLen {
|
if len(vhost) > ac.VHosts.MaxLength {
|
||||||
return errVHostTooLong
|
return errVHostTooLong
|
||||||
}
|
}
|
||||||
if !ac.HostServ.ValidRegexp.MatchString(vhost) {
|
if !ac.VHosts.ValidRegexp.MatchString(vhost) {
|
||||||
return errVHostBadCharacters
|
return errVHostBadCharacters
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -235,7 +250,7 @@ func hsSetHandler(server *Server, client *Client, command, params string, rb *Re
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := server.accounts.VHostSet(user, vhost)
|
_, err := server.accounts.VHostSet(user, vhost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hsNotice(rb, client.t("An error occurred"))
|
hsNotice(rb, client.t("An error occurred"))
|
||||||
} else if vhost != "" {
|
} else if vhost != "" {
|
||||||
@ -260,11 +275,13 @@ func hsApproveHandler(server *Server, client *Client, command, params string, rb
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := server.accounts.VHostApprove(user)
|
vhostInfo, err := server.accounts.VHostApprove(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hsNotice(rb, client.t("An error occurred"))
|
hsNotice(rb, client.t("An error occurred"))
|
||||||
} else {
|
} else {
|
||||||
hsNotice(rb, fmt.Sprintf(client.t("Successfully approved vhost request for %s"), user))
|
hsNotice(rb, fmt.Sprintf(client.t("Successfully approved vhost request for %s"), user))
|
||||||
|
chanMsg := fmt.Sprintf("Oper %s approved vhost %s for account %s", client.Nick(), vhostInfo.ApprovedVHost, user)
|
||||||
|
hsNotifyChannel(server, chanMsg)
|
||||||
for _, client := range server.accounts.AccountToClients(user) {
|
for _, client := range server.accounts.AccountToClients(user) {
|
||||||
client.Notice(client.t("Your vhost request was approved by an administrator"))
|
client.Notice(client.t("Your vhost request was approved by an administrator"))
|
||||||
}
|
}
|
||||||
@ -279,11 +296,13 @@ func hsRejectHandler(server *Server, client *Client, command, params string, rb
|
|||||||
}
|
}
|
||||||
reason := strings.TrimSpace(params)
|
reason := strings.TrimSpace(params)
|
||||||
|
|
||||||
err := server.accounts.VHostReject(user, reason)
|
vhostInfo, err := server.accounts.VHostReject(user, reason)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hsNotice(rb, client.t("An error occurred"))
|
hsNotice(rb, client.t("An error occurred"))
|
||||||
} else {
|
} else {
|
||||||
hsNotice(rb, fmt.Sprintf(client.t("Successfully rejected vhost request for %s"), user))
|
hsNotice(rb, fmt.Sprintf(client.t("Successfully rejected vhost request for %s"), user))
|
||||||
|
chanMsg := fmt.Sprintf("Oper %s rejected vhost %s for account %s, with the reason: %v", client.Nick(), vhostInfo.RejectedVHost, user, reason)
|
||||||
|
hsNotifyChannel(server, chanMsg)
|
||||||
for _, client := range server.accounts.AccountToClients(user) {
|
for _, client := range server.accounts.AccountToClients(user) {
|
||||||
if reason == "" {
|
if reason == "" {
|
||||||
client.Notice("Your vhost request was rejected by an administrator")
|
client.Notice("Your vhost request was rejected by an administrator")
|
||||||
|
@ -858,8 +858,8 @@ func (server *Server) applyConfig(config *Config, initial bool) error {
|
|||||||
server.accounts.buildNickToAccountIndex()
|
server.accounts.buildNickToAccountIndex()
|
||||||
}
|
}
|
||||||
|
|
||||||
hsPreviouslyDisabled := oldAccountConfig != nil && !oldAccountConfig.HostServ.Enabled
|
hsPreviouslyDisabled := oldAccountConfig != nil && !oldAccountConfig.VHosts.Enabled
|
||||||
hsNowEnabled := config.Accounts.HostServ.Enabled
|
hsNowEnabled := config.Accounts.VHosts.Enabled
|
||||||
if hsPreviouslyDisabled && hsNowEnabled {
|
if hsPreviouslyDisabled && hsNowEnabled {
|
||||||
server.accounts.initVHostRequestQueue()
|
server.accounts.initVHostRequestQueue()
|
||||||
}
|
}
|
||||||
|
35
oragono.yaml
35
oragono.yaml
@ -198,21 +198,36 @@ accounts:
|
|||||||
# rename-prefix - this is the prefix to use when renaming clients (e.g. Guest-AB54U31)
|
# rename-prefix - this is the prefix to use when renaming clients (e.g. Guest-AB54U31)
|
||||||
rename-prefix: Guest-
|
rename-prefix: Guest-
|
||||||
|
|
||||||
hostserv:
|
# vhosts controls the assignment of vhosts (strings displayed in place of the user's
|
||||||
# is hostserv enabled at all?
|
# hostname/IP) by the HostServ service
|
||||||
|
vhosts:
|
||||||
|
# are vhosts enabled at all?
|
||||||
enabled: true
|
enabled: true
|
||||||
# can users request vhosts from operators? if this is false, operators with the
|
|
||||||
# "hostserv" capability can still assign vhosts manually:
|
|
||||||
user-requests-enabled: false
|
|
||||||
# to prevent users from spamming requests, they must wait at least this long between
|
|
||||||
# distinct requests:
|
|
||||||
cooldown: 1h
|
|
||||||
# maximum length of a vhost
|
# maximum length of a vhost
|
||||||
max-vhost-len: 64
|
max-length: 64
|
||||||
|
|
||||||
# regexp for testing the validity of a vhost
|
# regexp for testing the validity of a vhost
|
||||||
# (make sure any changes you make here are RFC-compliant)
|
# (make sure any changes you make here are RFC-compliant)
|
||||||
valid-regexp: '^[0-9A-Za-z.\-_/]+$'
|
valid-regexp: '^[0-9A-Za-z.\-_/]+$'
|
||||||
|
|
||||||
|
# options controlling users requesting vhosts:
|
||||||
|
user-requests:
|
||||||
|
# can users request vhosts at all? if this is false, operators with the
|
||||||
|
# 'vhosts' capability can still assign vhosts manually
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
# if uncommented, all new vhost requests will be dumped into the given
|
||||||
|
# channel, so opers can review them as they are sent in. ensure that you
|
||||||
|
# have registered and restricted the channel appropriately before you
|
||||||
|
# uncomment this.
|
||||||
|
#channel: "#vhosts"
|
||||||
|
|
||||||
|
# after a user's vhost has been approved or rejected, they need to wait
|
||||||
|
# this long (starting from the time of their original request)
|
||||||
|
# before they can request a new one.
|
||||||
|
cooldown: 168h
|
||||||
|
|
||||||
# channel options
|
# channel options
|
||||||
channels:
|
channels:
|
||||||
# modes that are set when new channels are created
|
# modes that are set when new channels are created
|
||||||
@ -267,7 +282,7 @@ oper-classes:
|
|||||||
- "oper:die"
|
- "oper:die"
|
||||||
- "unregister"
|
- "unregister"
|
||||||
- "samode"
|
- "samode"
|
||||||
- "hostserv"
|
- "vhosts"
|
||||||
|
|
||||||
# ircd operators
|
# ircd operators
|
||||||
opers:
|
opers:
|
||||||
|
Loading…
Reference in New Issue
Block a user