Allow networks to be disabled

This commit is contained in:
Simon Ser 2021-05-26 10:49:52 +02:00
parent d9a40addf7
commit 7d648f702e
7 changed files with 56 additions and 13 deletions

View File

@ -181,6 +181,7 @@ func main() {
n.Username = netIdent n.Username = netIdent
n.Realname = netRealname n.Realname = netRealname
n.Pass = pass n.Pass = pass
n.Enabled = section.Values.Get("IRCConnectEnabled") != "false"
if err := db.StoreNetwork(userID, n); err != nil { if err := db.StoreNetwork(userID, n); err != nil {
logger.Fatalf("failed to store network: %v", err) logger.Fatalf("failed to store network: %v", err)

1
db.go
View File

@ -60,6 +60,7 @@ type Network struct {
Pass string Pass string
ConnectCommands []string ConnectCommands []string
SASL SASL SASL SASL
Enabled bool
} }
func (net *Network) GetName() string { func (net *Network) GetName() string {

View File

@ -34,6 +34,7 @@ CREATE TABLE Network (
sasl_plain_password VARCHAR(255), sasl_plain_password VARCHAR(255),
sasl_external_cert BLOB DEFAULT NULL, sasl_external_cert BLOB DEFAULT NULL,
sasl_external_key BLOB DEFAULT NULL, sasl_external_key BLOB DEFAULT NULL,
enabled INTEGER NOT NULL DEFAULT 1,
FOREIGN KEY(user) REFERENCES User(id), FOREIGN KEY(user) REFERENCES User(id),
UNIQUE(user, addr, nick), UNIQUE(user, addr, nick),
UNIQUE(user, name) UNIQUE(user, name)
@ -131,6 +132,7 @@ var sqliteMigrations = []string{
); );
`, `,
"ALTER TABLE Channel ADD COLUMN detached_internal_msgid VARCHAR(255)", "ALTER TABLE Channel ADD COLUMN detached_internal_msgid VARCHAR(255)",
"ALTER TABLE Network ADD COLUMN enabled INTEGER NOT NULL DEFAULT 1",
} }
type SqliteDB struct { type SqliteDB struct {
@ -312,7 +314,7 @@ func (db *SqliteDB) ListNetworks(userID int64) ([]Network, error) {
rows, err := db.db.Query(`SELECT id, name, addr, nick, username, realname, pass, rows, err := db.db.Query(`SELECT id, name, addr, nick, username, realname, pass,
connect_commands, sasl_mechanism, sasl_plain_username, sasl_plain_password, connect_commands, sasl_mechanism, sasl_plain_username, sasl_plain_password,
sasl_external_cert, sasl_external_key sasl_external_cert, sasl_external_key, enabled
FROM Network FROM Network
WHERE user = ?`, WHERE user = ?`,
userID) userID)
@ -328,7 +330,7 @@ func (db *SqliteDB) ListNetworks(userID int64) ([]Network, error) {
var saslMechanism, saslPlainUsername, saslPlainPassword sql.NullString var saslMechanism, saslPlainUsername, saslPlainPassword sql.NullString
err := rows.Scan(&net.ID, &name, &net.Addr, &net.Nick, &username, &realname, err := rows.Scan(&net.ID, &name, &net.Addr, &net.Nick, &username, &realname,
&pass, &connectCommands, &saslMechanism, &saslPlainUsername, &saslPlainPassword, &pass, &connectCommands, &saslMechanism, &saslPlainUsername, &saslPlainPassword,
&net.SASL.External.CertBlob, &net.SASL.External.PrivKeyBlob) &net.SASL.External.CertBlob, &net.SASL.External.PrivKeyBlob, &net.Enabled)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -382,21 +384,21 @@ func (db *SqliteDB) StoreNetwork(userID int64, network *Network) error {
_, err = db.db.Exec(`UPDATE Network _, err = db.db.Exec(`UPDATE Network
SET name = ?, addr = ?, nick = ?, username = ?, realname = ?, pass = ?, connect_commands = ?, SET name = ?, addr = ?, nick = ?, username = ?, realname = ?, pass = ?, connect_commands = ?,
sasl_mechanism = ?, sasl_plain_username = ?, sasl_plain_password = ?, sasl_mechanism = ?, sasl_plain_username = ?, sasl_plain_password = ?,
sasl_external_cert = ?, sasl_external_key = ? sasl_external_cert = ?, sasl_external_key = ?, enabled = ?
WHERE id = ?`, WHERE id = ?`,
netName, network.Addr, network.Nick, netUsername, realname, pass, connectCommands, netName, network.Addr, network.Nick, netUsername, realname, pass, connectCommands,
saslMechanism, saslPlainUsername, saslPlainPassword, saslMechanism, saslPlainUsername, saslPlainPassword,
network.SASL.External.CertBlob, network.SASL.External.PrivKeyBlob, network.SASL.External.CertBlob, network.SASL.External.PrivKeyBlob, network.Enabled,
network.ID) network.ID)
} else { } else {
var res sql.Result var res sql.Result
res, err = db.db.Exec(`INSERT INTO Network(user, name, addr, nick, username, res, err = db.db.Exec(`INSERT INTO Network(user, name, addr, nick, username,
realname, pass, connect_commands, sasl_mechanism, sasl_plain_username, realname, pass, connect_commands, sasl_mechanism, sasl_plain_username,
sasl_plain_password, sasl_external_cert, sasl_external_key) sasl_plain_password, sasl_external_cert, sasl_external_key, enabled)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
userID, netName, network.Addr, network.Nick, netUsername, realname, pass, connectCommands, userID, netName, network.Addr, network.Nick, netUsername, realname, pass, connectCommands,
saslMechanism, saslPlainUsername, saslPlainPassword, network.SASL.External.CertBlob, saslMechanism, saslPlainUsername, saslPlainPassword, network.SASL.External.CertBlob,
network.SASL.External.PrivKeyBlob) network.SASL.External.PrivKeyBlob, network.Enabled)
if err != nil { if err != nil {
return err return err
} }

View File

@ -158,6 +158,10 @@ abbreviated form, for instance *network* can be abbreviated as *net* or just
Connect with the specified nickname. By default, the account's username Connect with the specified nickname. By default, the account's username
is used. is used.
*-enabled* true|false
Enable or disable the network. If the network is disabled, the bouncer
won't connect to it. By default, the network is enabled.
*-connect-command* <command> *-connect-command* <command>
Send the specified command as a raw IRC message right after connecting Send the specified command as a raw IRC message right after connecting
to the server. This can be used to identify to an account when the to the server. This can be used to identify to an account when the

View File

@ -1001,8 +1001,9 @@ func (dc *downstreamConn) loadNetwork() error {
dc.logger.Printf("auto-saving network %q", dc.networkName) dc.logger.Printf("auto-saving network %q", dc.networkName)
var err error var err error
network, err = dc.user.createNetwork(&Network{ network, err = dc.user.createNetwork(&Network{
Addr: dc.networkName, Addr: dc.networkName,
Nick: nick, Nick: nick,
Enabled: true,
}) })
if err != nil { if err != nil {
return err return err
@ -2174,6 +2175,7 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
Username: username, Username: username,
Realname: realname, Realname: realname,
Pass: pass, Pass: pass,
Enabled: true,
} }
network, err := dc.user.createNetwork(record) network, err := dc.user.createNetwork(record)
if err != nil { if err != nil {

View File

@ -18,6 +18,7 @@ import (
"io/ioutil" "io/ioutil"
"math/big" "math/big"
"sort" "sort"
"strconv"
"strings" "strings"
"time" "time"
@ -149,7 +150,7 @@ func init() {
"network": { "network": {
children: serviceCommandSet{ children: serviceCommandSet{
"create": { "create": {
usage: "-addr <addr> [-name name] [-username username] [-pass pass] [-realname realname] [-nick nick] [-connect-command command]...", usage: "-addr <addr> [-name name] [-username username] [-pass pass] [-realname realname] [-nick nick] [-enabled enabled] [-connect-command command]...",
desc: "add a new network", desc: "add a new network",
handle: handleServiceNetworkCreate, handle: handleServiceNetworkCreate,
}, },
@ -158,7 +159,7 @@ func init() {
handle: handleServiceNetworkStatus, handle: handleServiceNetworkStatus,
}, },
"update": { "update": {
usage: "<name> [-addr addr] [-name name] [-username username] [-pass pass] [-realname realname] [-nick nick] [-connect-command command]...", usage: "<name> [-addr addr] [-name name] [-username username] [-pass pass] [-realname realname] [-nick nick] [-enabled enabled] [-connect-command command]...",
desc: "update a network", desc: "update a network",
handle: handleServiceNetworkUpdate, handle: handleServiceNetworkUpdate,
}, },
@ -317,9 +318,30 @@ func (f stringPtrFlag) Set(s string) error {
return nil return nil
} }
type boolPtrFlag struct {
ptr **bool
}
func (f boolPtrFlag) String() string {
if f.ptr == nil || *f.ptr == nil {
return "<nil>"
}
return strconv.FormatBool(**f.ptr)
}
func (f boolPtrFlag) Set(s string) error {
v, err := strconv.ParseBool(s)
if err != nil {
return err
}
*f.ptr = &v
return nil
}
type networkFlagSet struct { type networkFlagSet struct {
*flag.FlagSet *flag.FlagSet
Addr, Name, Nick, Username, Pass, Realname *string Addr, Name, Nick, Username, Pass, Realname *string
Enabled *bool
ConnectCommands []string ConnectCommands []string
} }
@ -331,6 +353,7 @@ func newNetworkFlagSet() *networkFlagSet {
fs.Var(stringPtrFlag{&fs.Username}, "username", "") fs.Var(stringPtrFlag{&fs.Username}, "username", "")
fs.Var(stringPtrFlag{&fs.Pass}, "pass", "") fs.Var(stringPtrFlag{&fs.Pass}, "pass", "")
fs.Var(stringPtrFlag{&fs.Realname}, "realname", "") fs.Var(stringPtrFlag{&fs.Realname}, "realname", "")
fs.Var(boolPtrFlag{&fs.Enabled}, "enabled", "")
fs.Var((*stringSliceFlag)(&fs.ConnectCommands), "connect-command", "") fs.Var((*stringSliceFlag)(&fs.ConnectCommands), "connect-command", "")
return fs return fs
} }
@ -362,6 +385,9 @@ func (fs *networkFlagSet) update(network *Network) error {
if fs.Realname != nil { if fs.Realname != nil {
network.Realname = *fs.Realname network.Realname = *fs.Realname
} }
if fs.Enabled != nil {
network.Enabled = *fs.Enabled
}
if fs.ConnectCommands != nil { if fs.ConnectCommands != nil {
if len(fs.ConnectCommands) == 1 && fs.ConnectCommands[0] == "" { if len(fs.ConnectCommands) == 1 && fs.ConnectCommands[0] == "" {
network.ConnectCommands = nil network.ConnectCommands = nil
@ -388,8 +414,9 @@ func handleServiceNetworkCreate(dc *downstreamConn, params []string) error {
} }
record := &Network{ record := &Network{
Addr: *fs.Addr, Addr: *fs.Addr,
Nick: dc.nick, Nick: dc.nick,
Enabled: true,
} }
if err := fs.update(record); err != nil { if err := fs.update(record); err != nil {
return err return err
@ -415,6 +442,8 @@ func handleServiceNetworkStatus(dc *downstreamConn, params []string) error {
statuses = append(statuses, "connected") statuses = append(statuses, "connected")
} }
details = fmt.Sprintf("%v channels", uc.channels.Len()) details = fmt.Sprintf("%v channels", uc.channels.Len())
} else if !net.Enabled {
statuses = append(statuses, "disabled")
} else { } else {
statuses = append(statuses, "disconnected") statuses = append(statuses, "disconnected")
if net.lastError != nil { if net.lastError != nil {

View File

@ -172,6 +172,10 @@ func userIdent(u *User) string {
} }
func (net *network) run() { func (net *network) run() {
if !net.Enabled {
return
}
var lastTry time.Time var lastTry time.Time
for { for {
if net.isStopped() { if net.isStopped() {