Add max-user-networks config option

This commit is contained in:
Simon Ser 2021-10-07 20:43:10 +02:00
parent 9f021ba9a9
commit 94dbfff11d
5 changed files with 47 additions and 22 deletions

View File

@ -88,6 +88,7 @@ func main() {
srv.LogPath = cfg.LogPath srv.LogPath = cfg.LogPath
srv.HTTPOrigins = cfg.HTTPOrigins srv.HTTPOrigins = cfg.HTTPOrigins
srv.AcceptProxyIPs = cfg.AcceptProxyIPs srv.AcceptProxyIPs = cfg.AcceptProxyIPs
srv.MaxUserNetworks = cfg.MaxUserNetworks
srv.Debug = debug srv.Debug = debug
for _, listen := range cfg.Listen { for _, listen := range cfg.Listen {

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"net" "net"
"os" "os"
"strconv"
"git.sr.ht/~emersion/go-scfg" "git.sr.ht/~emersion/go-scfg"
) )
@ -39,11 +40,15 @@ type Server struct {
Listen []string Listen []string
Hostname string Hostname string
TLS *TLS TLS *TLS
SQLDriver string SQLDriver string
SQLSource string SQLSource string
LogPath string LogPath string
HTTPOrigins []string HTTPOrigins []string
AcceptProxyIPs IPSet AcceptProxyIPs IPSet
MaxUserNetworks int
} }
func Defaults() *Server { func Defaults() *Server {
@ -55,6 +60,7 @@ func Defaults() *Server {
Hostname: hostname, Hostname: hostname,
SQLDriver: "sqlite3", SQLDriver: "sqlite3",
SQLSource: "soju.db", SQLSource: "soju.db",
MaxUserNetworks: -1,
} }
} }
@ -113,6 +119,15 @@ func parse(cfg scfg.Block) (*Server, error) {
} }
srv.AcceptProxyIPs = append(srv.AcceptProxyIPs, n) srv.AcceptProxyIPs = append(srv.AcceptProxyIPs, n)
} }
case "max-user-networks":
var max string
if err := d.ParseParams(&max); err != nil {
return nil, err
}
var err error
if srv.MaxUserNetworks, err = strconv.Atoi(max); err != nil {
return nil, fmt.Errorf("directive %q: %v", d.Name, err)
}
default: default:
return nil, fmt.Errorf("unknown directive %q", d.Name) return nil, fmt.Errorf("unknown directive %q", d.Name)
} }

View File

@ -129,6 +129,9 @@ The following directives are supported:
By default, all IPs are rejected. By default, all IPs are rejected.
*max-user-networks* <limit>
Maximum number of networks per user. By default, there is no limit.
# IRC SERVICE # IRC SERVICE
soju exposes an IRC service called *BouncerServ* to manage the bouncer. soju exposes an IRC service called *BouncerServ* to manage the bouncer.

View File

@ -53,6 +53,7 @@ type Server struct {
Debug bool Debug bool
HTTPOrigins []string HTTPOrigins []string
AcceptProxyIPs config.IPSet AcceptProxyIPs config.IPSet
MaxUserNetworks int
Identd *Identd // can be nil Identd *Identd // can be nil
db Database db Database
@ -68,6 +69,7 @@ func NewServer(db Database) *Server {
return &Server{ return &Server{
Logger: log.New(log.Writer(), "", log.LstdFlags), Logger: log.New(log.Writer(), "", log.LstdFlags),
HistoryLimit: 1000, HistoryLimit: 1000,
MaxUserNetworks: -1,
db: db, db: db,
listeners: make(map[net.Listener]struct{}), listeners: make(map[net.Listener]struct{}),
users: make(map[string]*user), users: make(map[string]*user),

View File

@ -748,6 +748,10 @@ func (u *user) createNetwork(record *Network) (*network, error) {
return nil, err return nil, err
} }
if u.srv.MaxUserNetworks >= 0 && len(u.networks) >= u.srv.MaxUserNetworks {
return nil, fmt.Errorf("maximum number of networks reached")
}
network := newNetwork(u, record, nil) network := newNetwork(u, record, nil)
err := u.srv.db.StoreNetwork(u.ID, &network.Network) err := u.srv.db.StoreNetwork(u.ID, &network.Network)
if err != nil { if err != nil {