Make the auto-away functionality configurable

This commit is contained in:
zsrv 2022-09-26 13:49:26 -04:00 committed by Simon Ser
parent d605d64d1d
commit 926dcb37ac
6 changed files with 35 additions and 16 deletions

View file

@ -131,6 +131,7 @@ type Network struct {
Pass string
ConnectCommands []string
SASL SASL
AutoAway bool
Enabled bool
}

View file

@ -51,6 +51,7 @@ CREATE TABLE "Network" (
sasl_plain_password VARCHAR(255),
sasl_external_cert BYTEA,
sasl_external_key BYTEA,
auto_away BOOLEAN NOT NULL DEFAULT TRUE,
enabled BOOLEAN NOT NULL DEFAULT TRUE,
UNIQUE("user", addr, nick),
UNIQUE("user", name)
@ -163,6 +164,7 @@ var postgresMigrations = []string{
ALTER COLUMN "user"
SET NOT NULL;
`,
`ALTER TABLE "Network" ADD COLUMN auto_away BOOLEAN NOT NULL DEFAULT TRUE`,
}
type PostgresDB struct {
@ -379,7 +381,7 @@ func (db *PostgresDB) ListNetworks(ctx context.Context, userID int64) ([]Network
rows, err := db.db.QueryContext(ctx, `
SELECT id, name, addr, nick, username, realname, pass, connect_commands, sasl_mechanism,
sasl_plain_username, sasl_plain_password, sasl_external_cert, sasl_external_key, enabled
sasl_plain_username, sasl_plain_password, sasl_external_cert, sasl_external_key, auto_away, enabled
FROM "Network"
WHERE "user" = $1`, userID)
if err != nil {
@ -394,7 +396,7 @@ func (db *PostgresDB) ListNetworks(ctx context.Context, userID int64) ([]Network
var saslMechanism, saslPlainUsername, saslPlainPassword sql.NullString
err := rows.Scan(&net.ID, &name, &net.Addr, &nick, &username, &realname,
&pass, &connectCommands, &saslMechanism, &saslPlainUsername, &saslPlainPassword,
&net.SASL.External.CertBlob, &net.SASL.External.PrivKeyBlob, &net.Enabled)
&net.SASL.External.CertBlob, &net.SASL.External.PrivKeyBlob, &net.AutoAway, &net.Enabled)
if err != nil {
return nil, err
}
@ -450,23 +452,23 @@ func (db *PostgresDB) StoreNetwork(ctx context.Context, userID int64, network *N
err = db.db.QueryRowContext(ctx, `
INSERT INTO "Network" ("user", name, addr, nick, username, realname, pass, connect_commands,
sasl_mechanism, sasl_plain_username, sasl_plain_password, sasl_external_cert,
sasl_external_key, enabled)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
sasl_external_key, auto_away, enabled)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
RETURNING id`,
userID, netName, network.Addr, nick, netUsername, realname, pass, connectCommands,
saslMechanism, saslPlainUsername, saslPlainPassword, network.SASL.External.CertBlob,
network.SASL.External.PrivKeyBlob, network.Enabled).Scan(&network.ID)
network.SASL.External.PrivKeyBlob, network.AutoAway, network.Enabled).Scan(&network.ID)
} else {
_, err = db.db.ExecContext(ctx, `
UPDATE "Network"
SET name = $2, addr = $3, nick = $4, username = $5, realname = $6, pass = $7,
connect_commands = $8, sasl_mechanism = $9, sasl_plain_username = $10,
sasl_plain_password = $11, sasl_external_cert = $12, sasl_external_key = $13,
enabled = $14
auto_away = $14, enabled = $15
WHERE id = $1`,
network.ID, netName, network.Addr, nick, netUsername, realname, pass, connectCommands,
saslMechanism, saslPlainUsername, saslPlainPassword, network.SASL.External.CertBlob,
network.SASL.External.PrivKeyBlob, network.Enabled)
network.SASL.External.PrivKeyBlob, network.AutoAway, network.Enabled)
}
return err
}

View file

@ -49,6 +49,7 @@ CREATE TABLE Network (
sasl_plain_password TEXT,
sasl_external_cert BLOB,
sasl_external_key BLOB,
auto_away INTEGER NOT NULL DEFAULT 1,
enabled INTEGER NOT NULL DEFAULT 1,
FOREIGN KEY(user) REFERENCES User(id),
UNIQUE(user, addr, nick),
@ -248,6 +249,7 @@ var sqliteMigrations = []string{
UPDATE WebPushSubscription AS wps SET user = (SELECT n.user FROM Network AS n WHERE n.id = wps.network);
`,
"ALTER TABLE User ADD COLUMN nick TEXT;",
"ALTER TABLE Network ADD COLUMN auto_away INTEGER NOT NULL DEFAULT 1;",
}
type SqliteDB struct {
@ -488,7 +490,7 @@ func (db *SqliteDB) ListNetworks(ctx context.Context, userID int64) ([]Network,
rows, err := db.db.QueryContext(ctx, `
SELECT id, name, addr, nick, username, realname, pass,
connect_commands, sasl_mechanism, sasl_plain_username, sasl_plain_password,
sasl_external_cert, sasl_external_key, enabled
sasl_external_cert, sasl_external_key, auto_away, enabled
FROM Network
WHERE user = ?`,
userID)
@ -504,7 +506,7 @@ func (db *SqliteDB) ListNetworks(ctx context.Context, userID int64) ([]Network,
var saslMechanism, saslPlainUsername, saslPlainPassword sql.NullString
err := rows.Scan(&net.ID, &name, &net.Addr, &nick, &username, &realname,
&pass, &connectCommands, &saslMechanism, &saslPlainUsername, &saslPlainPassword,
&net.SASL.External.CertBlob, &net.SASL.External.PrivKeyBlob, &net.Enabled)
&net.SASL.External.CertBlob, &net.SASL.External.PrivKeyBlob, &net.AutoAway, &net.Enabled)
if err != nil {
return nil, err
}
@ -561,6 +563,7 @@ func (db *SqliteDB) StoreNetwork(ctx context.Context, userID int64, network *Net
sql.Named("sasl_plain_password", saslPlainPassword),
sql.Named("sasl_external_cert", network.SASL.External.CertBlob),
sql.Named("sasl_external_key", network.SASL.External.PrivKeyBlob),
sql.Named("auto_away", network.AutoAway),
sql.Named("enabled", network.Enabled),
sql.Named("id", network.ID), // only for UPDATE
@ -575,17 +578,17 @@ func (db *SqliteDB) StoreNetwork(ctx context.Context, userID int64, network *Net
realname = :realname, pass = :pass, connect_commands = :connect_commands,
sasl_mechanism = :sasl_mechanism, sasl_plain_username = :sasl_plain_username, sasl_plain_password = :sasl_plain_password,
sasl_external_cert = :sasl_external_cert, sasl_external_key = :sasl_external_key,
enabled = :enabled
auto_away = :auto_away, enabled = :enabled
WHERE id = :id`, args...)
} else {
var res sql.Result
res, err = db.db.ExecContext(ctx, `
INSERT INTO Network(user, name, addr, nick, username, realname, pass,
connect_commands, sasl_mechanism, sasl_plain_username,
sasl_plain_password, sasl_external_cert, sasl_external_key, enabled)
sasl_plain_password, sasl_external_cert, sasl_external_key, auto_away, enabled)
VALUES (:user, :name, :addr, :nick, :username, :realname, :pass,
:connect_commands, :sasl_mechanism, :sasl_plain_username,
:sasl_plain_password, :sasl_external_cert, :sasl_external_key, :enabled)`,
:sasl_plain_password, :sasl_external_cert, :sasl_external_key, :auto_away, :enabled)`,
args...)
if err != nil {
return err

View file

@ -36,7 +36,7 @@ If a network specified in the username doesn't exist, and the network name is a
valid hostname, the network will be automatically added.
When all clients are disconnected from the bouncer, the user is automatically
marked as away.
marked as away by default.
soju will reload the configuration file, the TLS certificate/key and the MOTD
file when it receives the HUP signal. The configuration options _listen_, _db_
@ -217,6 +217,11 @@ abbreviated form, for instance *network* can be abbreviated as *net* or just
Connect with the specified nickname. By default, the account's username
is used.
*-auto-away* true|false
Enable or disable the auto-away feature. If the feature is enabled, the
user will be marked as away when all clients are disconnected from the
bouncer. By default, auto-away is enabled.
*-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.

View file

@ -201,7 +201,7 @@ func init() {
"network": {
children: serviceCommandSet{
"create": {
usage: "-addr <addr> [-name name] [-username username] [-pass pass] [-realname realname] [-nick nick] [-enabled enabled] [-connect-command command]...",
usage: "-addr <addr> [-name name] [-username username] [-pass pass] [-realname realname] [-nick nick] [-auto-away auto-away] [-enabled enabled] [-connect-command command]...",
desc: "add a new network",
handle: handleServiceNetworkCreate,
},
@ -210,7 +210,7 @@ func init() {
handle: handleServiceNetworkStatus,
},
"update": {
usage: "[name] [-addr addr] [-name name] [-username username] [-pass pass] [-realname realname] [-nick nick] [-enabled enabled] [-connect-command command]...",
usage: "[name] [-addr addr] [-name name] [-username username] [-pass pass] [-realname realname] [-nick nick] [-auto-away auto-away] [-enabled enabled] [-connect-command command]...",
desc: "update a network",
handle: handleServiceNetworkUpdate,
},
@ -431,7 +431,7 @@ func getNetworkFromArg(dc *downstreamConn, params []string) (*network, []string,
type networkFlagSet struct {
*flag.FlagSet
Addr, Name, Nick, Username, Pass, Realname *string
Enabled *bool
AutoAway, Enabled *bool
ConnectCommands []string
}
@ -443,6 +443,7 @@ func newNetworkFlagSet() *networkFlagSet {
fs.Var(stringPtrFlag{&fs.Username}, "username", "")
fs.Var(stringPtrFlag{&fs.Pass}, "pass", "")
fs.Var(stringPtrFlag{&fs.Realname}, "realname", "")
fs.Var(boolPtrFlag{&fs.AutoAway}, "auto-away", "")
fs.Var(boolPtrFlag{&fs.Enabled}, "enabled", "")
fs.Var((*stringSliceFlag)(&fs.ConnectCommands), "connect-command", "")
return fs
@ -478,6 +479,9 @@ func (fs *networkFlagSet) update(network *database.Network) error {
if fs.Realname != nil {
network.Realname = *fs.Realname
}
if fs.AutoAway != nil {
network.AutoAway = *fs.AutoAway
}
if fs.Enabled != nil {
network.Enabled = *fs.Enabled
}

View file

@ -1958,6 +1958,10 @@ func (uc *upstreamConn) produce(target string, msg *irc.Message, originID uint64
func (uc *upstreamConn) updateAway() {
ctx := context.TODO()
if !uc.network.AutoAway {
return
}
away := true
uc.forEachDownstream(func(dc *downstreamConn) {
if dc.away == nil {