feat(irc): support optional SASL and NickServ auth (#511)

* feat(irc): support SASL and NickServ auth

* feat(irc): add missing fields

* feat(irc): support SASL and NickServ auth

* feat(irc): add missing fields

* feat(irc): add validation

* feat(indexers): unify and set required values

* feat(irc): add postgres migrations

* feat(irc): use nick as handlerkey

* feat(irc): use account for nickserv

* fix(irc): pg db migration
This commit is contained in:
ze0s 2022-10-27 22:25:58 +02:00 committed by GitHub
parent 4ef0408f33
commit 4bf023d030
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
65 changed files with 1404 additions and 631 deletions

View file

@ -26,7 +26,7 @@ func NewIrcRepo(log logger.Logger, db *DB) domain.IrcRepo {
func (r *IrcRepo) GetNetworkByID(ctx context.Context, id int64) (*domain.IrcNetwork, error) {
queryBuilder := r.db.squirrel.
Select("id", "enabled", "name", "server", "port", "tls", "pass", "invite_command", "nickserv_account", "nickserv_password").
Select("id", "enabled", "name", "server", "port", "tls", "pass", "nick", "auth_mechanism", "auth_account", "auth_password", "invite_command").
From("irc_network").
Where("id = ?", id)
@ -38,20 +38,21 @@ func (r *IrcRepo) GetNetworkByID(ctx context.Context, id int64) (*domain.IrcNetw
var n domain.IrcNetwork
var pass, inviteCmd sql.NullString
var nsAccount, nsPassword sql.NullString
var pass, nick, inviteCmd sql.NullString
var account, password sql.NullString
var tls sql.NullBool
row := r.db.handler.QueryRowContext(ctx, query, args...)
if err := row.Scan(&n.ID, &n.Enabled, &n.Name, &n.Server, &n.Port, &tls, &pass, &inviteCmd, &nsAccount, &nsPassword); err != nil {
if err := row.Scan(&n.ID, &n.Enabled, &n.Name, &n.Server, &n.Port, &tls, &pass, &nick, &n.Auth.Mechanism, &account, &password, &inviteCmd); err != nil {
return nil, errors.Wrap(err, "error scanning row")
}
n.TLS = tls.Bool
n.Pass = pass.String
n.Nick = nick.String
n.InviteCommand = inviteCmd.String
n.NickServ.Account = nsAccount.String
n.NickServ.Password = nsPassword.String
n.Auth.Account = account.String
n.Auth.Password = password.String
return &n, nil
}
@ -103,7 +104,7 @@ func (r *IrcRepo) DeleteNetwork(ctx context.Context, id int64) error {
func (r *IrcRepo) FindActiveNetworks(ctx context.Context) ([]domain.IrcNetwork, error) {
queryBuilder := r.db.squirrel.
Select("id", "enabled", "name", "server", "port", "tls", "pass", "invite_command", "nickserv_account", "nickserv_password").
Select("id", "enabled", "name", "server", "port", "tls", "pass", "nick", "auth_mechanism", "auth_account", "auth_password", "invite_command").
From("irc_network").
Where("enabled = ?", true)
@ -123,20 +124,21 @@ func (r *IrcRepo) FindActiveNetworks(ctx context.Context) ([]domain.IrcNetwork,
for rows.Next() {
var net domain.IrcNetwork
var pass, inviteCmd sql.NullString
var nsAccount, nsPassword sql.NullString
var pass, nick, inviteCmd sql.NullString
var account, password sql.NullString
var tls sql.NullBool
if err := rows.Scan(&net.ID, &net.Enabled, &net.Name, &net.Server, &net.Port, &tls, &pass, &inviteCmd, &nsAccount, &nsPassword); err != nil {
if err := rows.Scan(&net.ID, &net.Enabled, &net.Name, &net.Server, &net.Port, &tls, &pass, &nick, &net.Auth.Mechanism, &account, &password, &inviteCmd); err != nil {
return nil, errors.Wrap(err, "error scanning row")
}
net.TLS = tls.Bool
net.Pass = pass.String
net.Nick = nick.String
net.InviteCommand = inviteCmd.String
net.NickServ.Account = nsAccount.String
net.NickServ.Password = nsPassword.String
net.Auth.Account = account.String
net.Auth.Password = password.String
networks = append(networks, net)
}
@ -149,7 +151,7 @@ func (r *IrcRepo) FindActiveNetworks(ctx context.Context) ([]domain.IrcNetwork,
func (r *IrcRepo) ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error) {
queryBuilder := r.db.squirrel.
Select("id", "enabled", "name", "server", "port", "tls", "pass", "invite_command", "nickserv_account", "nickserv_password").
Select("id", "enabled", "name", "server", "port", "tls", "pass", "nick", "auth_mechanism", "auth_account", "auth_password", "invite_command").
From("irc_network").
OrderBy("name ASC")
@ -169,20 +171,21 @@ func (r *IrcRepo) ListNetworks(ctx context.Context) ([]domain.IrcNetwork, error)
for rows.Next() {
var net domain.IrcNetwork
var pass, inviteCmd sql.NullString
var nsAccount, nsPassword sql.NullString
var pass, nick, inviteCmd sql.NullString
var account, password sql.NullString
var tls sql.NullBool
if err := rows.Scan(&net.ID, &net.Enabled, &net.Name, &net.Server, &net.Port, &tls, &pass, &inviteCmd, &nsAccount, &nsPassword); err != nil {
if err := rows.Scan(&net.ID, &net.Enabled, &net.Name, &net.Server, &net.Port, &tls, &pass, &nick, &net.Auth.Mechanism, &account, &password, &inviteCmd); err != nil {
return nil, errors.Wrap(err, "error scanning row")
}
net.TLS = tls.Bool
net.Pass = pass.String
net.Nick = nick.String
net.InviteCommand = inviteCmd.String
net.NickServ.Account = nsAccount.String
net.NickServ.Password = nsPassword.String
net.Auth.Account = account.String
net.Auth.Password = password.String
networks = append(networks, net)
}
@ -232,10 +235,10 @@ func (r *IrcRepo) ListChannels(networkID int64) ([]domain.IrcChannel, error) {
func (r *IrcRepo) CheckExistingNetwork(ctx context.Context, network *domain.IrcNetwork) (*domain.IrcNetwork, error) {
queryBuilder := r.db.squirrel.
Select("id", "enabled", "name", "server", "port", "tls", "pass", "invite_command", "nickserv_account", "nickserv_password").
Select("id", "enabled", "name", "server", "port", "tls", "pass", "nick", "auth_mechanism", "auth_account", "auth_password", "invite_command").
From("irc_network").
Where("server = ?", network.Server).
Where("nickserv_account = ?", network.NickServ.Account)
Where("auth_account = ?", network.Auth.Account)
query, args, err := queryBuilder.ToSql()
if err != nil {
@ -247,10 +250,11 @@ func (r *IrcRepo) CheckExistingNetwork(ctx context.Context, network *domain.IrcN
var net domain.IrcNetwork
var pass, inviteCmd, nickPass sql.NullString
var pass, nick, inviteCmd sql.NullString
var account, password sql.NullString
var tls sql.NullBool
err = row.Scan(&net.ID, &net.Enabled, &net.Name, &net.Server, &net.Port, &tls, &pass, &inviteCmd, &net.NickServ.Account, &nickPass)
err = row.Scan(&net.ID, &net.Enabled, &net.Name, &net.Server, &net.Port, &tls, &pass, &nick, &net.Auth.Mechanism, &account, &password, &inviteCmd)
if err == sql.ErrNoRows {
// no result is not an error in our case
return nil, nil
@ -260,8 +264,10 @@ func (r *IrcRepo) CheckExistingNetwork(ctx context.Context, network *domain.IrcN
net.TLS = tls.Bool
net.Pass = pass.String
net.Nick = nick.String
net.InviteCommand = inviteCmd.String
net.NickServ.Password = nickPass.String
net.Auth.Account = account.String
net.Auth.Password = password.String
return &net, nil
}
@ -269,10 +275,11 @@ func (r *IrcRepo) CheckExistingNetwork(ctx context.Context, network *domain.IrcN
func (r *IrcRepo) StoreNetwork(network *domain.IrcNetwork) error {
netName := toNullString(network.Name)
pass := toNullString(network.Pass)
nick := toNullString(network.Nick)
inviteCmd := toNullString(network.InviteCommand)
nsAccount := toNullString(network.NickServ.Account)
nsPassword := toNullString(network.NickServ.Password)
account := toNullString(network.Auth.Account)
password := toNullString(network.Auth.Password)
var err error
var retID int64
@ -286,9 +293,11 @@ func (r *IrcRepo) StoreNetwork(network *domain.IrcNetwork) error {
"port",
"tls",
"pass",
"nick",
"auth_mechanism",
"auth_account",
"auth_password",
"invite_command",
"nickserv_account",
"nickserv_password",
).
Values(
network.Enabled,
@ -297,9 +306,11 @@ func (r *IrcRepo) StoreNetwork(network *domain.IrcNetwork) error {
network.Port,
network.TLS,
pass,
nick,
network.Auth.Mechanism,
account,
password,
inviteCmd,
nsAccount,
nsPassword,
).
Suffix("RETURNING id").
RunWith(r.db.handler)
@ -317,10 +328,11 @@ func (r *IrcRepo) StoreNetwork(network *domain.IrcNetwork) error {
func (r *IrcRepo) UpdateNetwork(ctx context.Context, network *domain.IrcNetwork) error {
netName := toNullString(network.Name)
pass := toNullString(network.Pass)
nick := toNullString(network.Nick)
inviteCmd := toNullString(network.InviteCommand)
nsAccount := toNullString(network.NickServ.Account)
nsPassword := toNullString(network.NickServ.Password)
account := toNullString(network.Auth.Account)
password := toNullString(network.Auth.Password)
var err error
@ -332,9 +344,11 @@ func (r *IrcRepo) UpdateNetwork(ctx context.Context, network *domain.IrcNetwork)
Set("port", network.Port).
Set("tls", network.TLS).
Set("pass", pass).
Set("nick", nick).
Set("auth_mechanism", network.Auth.Mechanism).
Set("auth_account", account).
Set("auth_password", password).
Set("invite_command", inviteCmd).
Set("nickserv_account", nsAccount).
Set("nickserv_password", nsPassword).
Set("updated_at", time.Now().Format(time.RFC3339)).
Where("id = ?", network.ID)

View file

@ -36,14 +36,16 @@ CREATE TABLE irc_network
port INTEGER NOT NULL,
tls BOOLEAN,
pass TEXT,
nick TEXT,
auth_mechanism TEXT,
auth_account TEXT,
auth_password TEXT,
invite_command TEXT,
nickserv_account TEXT,
nickserv_password TEXT,
connected BOOLEAN,
connected_since TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE (server, port, nickserv_account)
UNIQUE (server, port, nick)
);
CREATE TABLE irc_channel
@ -589,4 +591,28 @@ CREATE INDEX indexer_identifier_index
ALTER TABLE filter
ADD COLUMN use_regex_release_tags BOOLEAN DEFAULT FALSE;
`,
`ALTER TABLE irc_network
RENAME COLUMN nickserv_account TO auth_account;
ALTER TABLE irc_network
RENAME COLUMN nickserv_password TO auth_password;
ALTER TABLE irc_network
ADD nick TEXT;
ALTER TABLE irc_network
ADD auth_mechanism TEXT DEFAULT 'SASL_PLAIN';
ALTER TABLE irc_network
DROP CONSTRAINT irc_network_server_port_nickserv_account_key;
ALTER TABLE irc_network
ADD CONSTRAINT irc_network_server_port_nick_key
UNIQUE (server, port, nick);
UPDATE irc_network
SET nick = irc_network.auth_account;
UPDATE irc_network
SET auth_mechanism = 'SASL_PLAIN';`,
}

View file

@ -36,14 +36,16 @@ CREATE TABLE irc_network
port INTEGER NOT NULL,
tls BOOLEAN,
pass TEXT,
nick TEXT,
auth_mechanism TEXT,
auth_account TEXT,
auth_password TEXT,
invite_command TEXT,
nickserv_account TEXT,
nickserv_password TEXT,
connected BOOLEAN,
connected_since TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE (server, port, nickserv_account)
UNIQUE (server, port, nick)
);
CREATE TABLE irc_channel
@ -909,4 +911,52 @@ CREATE INDEX indexer_identifier_index
ALTER TABLE filter
ADD COLUMN use_regex_release_tags BOOLEAN DEFAULT FALSE;
`,
`
CREATE TABLE irc_network_dg_tmp
(
id INTEGER
primary key,
enabled BOOLEAN,
name TEXT not null,
server TEXT not null,
port INTEGER not null,
tls BOOLEAN,
pass TEXT,
nick TEXT,
auth_mechanism TEXT,
auth_account TEXT,
auth_password TEXT,
invite_command TEXT,
connected BOOLEAN,
connected_since TIMESTAMP,
created_at TIMESTAMP default CURRENT_TIMESTAMP,
updated_at TIMESTAMP default CURRENT_TIMESTAMP,
unique (server, port, nick)
);
INSERT INTO irc_network_dg_tmp(id, enabled, name, server, port, tls, pass, nick, auth_mechanism, auth_account, auth_password, invite_command,
connected, connected_since, created_at, updated_at)
SELECT id,
enabled,
name,
server,
port,
tls,
pass,
nickserv_account,
'SASL_PLAIN',
nickserv_account,
nickserv_password,
invite_command,
connected,
connected_since,
created_at,
updated_at
FROM irc_network;
DROP TABLE irc_network;
ALTER TABLE irc_network_dg_tmp
RENAME TO irc_network;
`,
}