Pass config struct into irc.Client

This commit is contained in:
Ken-Håvard Lieng 2020-05-23 09:42:20 +02:00
parent 9aac4f4e29
commit e97c7f2ada
11 changed files with 206 additions and 181 deletions

View file

@ -4,7 +4,6 @@ import (
"crypto/tls"
"encoding/hex"
"fmt"
"net"
"github.com/khlieng/dispatch/pkg/irc"
"github.com/khlieng/dispatch/storage"
@ -17,12 +16,12 @@ func createNickInUseHandler(i *irc.Client, state *State) func(string) string {
if newNick == i.GetNick() {
state.sendJSON("nick_fail", NickFail{
Server: i.Host,
Server: i.Host(),
})
}
state.sendJSON("error", IRCError{
Server: i.Host,
Server: i.Host(),
Message: fmt.Sprintf("Nickname %s is unavailable, trying %s instead", nick, newNick),
})
@ -31,57 +30,53 @@ func createNickInUseHandler(i *irc.Client, state *State) func(string) string {
}
func connectIRC(server *storage.Server, state *State, srcIP []byte) *irc.Client {
i := irc.NewClient(server.Nick, server.Username)
i.TLS = server.TLS
i.Realname = server.Realname
i.Version = fmt.Sprintf("Dispatch %s (git: %s)", version.Tag, version.Commit)
i.Source = "https://github.com/khlieng/dispatch"
i.HandleNickInUse = createNickInUseHandler(i, state)
address := server.Host
if server.Port != "" {
address = net.JoinHostPort(server.Host, server.Port)
}
cfg := state.srv.Config()
ircCfg := irc.Config{
Host: server.Host,
Port: server.Port,
TLS: server.TLS,
Nick: server.Nick,
Username: server.Username,
Realname: server.Realname,
Version: fmt.Sprintf("Dispatch %s (git: %s)", version.Tag, version.Commit),
Source: "https://github.com/khlieng/dispatch",
}
if server.TLS {
ircCfg.TLSConfig = &tls.Config{
InsecureSkipVerify: !cfg.VerifyCertificates,
}
if cert := state.user.GetCertificate(); cert != nil {
ircCfg.TLSConfig.Certificates = []tls.Certificate{*cert}
}
}
if cfg.HexIP {
i.Username = hex.EncodeToString(srcIP)
} else if i.Username == "" {
i.Username = server.Nick
}
if i.Realname == "" {
i.Realname = server.Nick
}
if server.ServerPassword == "" &&
cfg.Defaults.ServerPassword != "" &&
address == cfg.Defaults.Host {
i.Password = cfg.Defaults.ServerPassword
} else {
i.Password = server.ServerPassword
ircCfg.Username = hex.EncodeToString(srcIP)
}
if server.Account != "" && server.Password != "" {
i.SASL = &irc.SASLPlain{
ircCfg.SASL = &irc.SASLPlain{
Username: server.Account,
Password: server.Password,
}
}
if i.TLS {
i.TLSConfig = &tls.Config{
InsecureSkipVerify: !cfg.VerifyCertificates,
}
if cert := state.user.GetCertificate(); cert != nil {
i.TLSConfig.Certificates = []tls.Certificate{*cert}
}
if server.ServerPassword == "" &&
cfg.Defaults.ServerPassword != "" &&
server.Host == cfg.Defaults.Host {
ircCfg.Password = cfg.Defaults.ServerPassword
} else {
ircCfg.Password = server.ServerPassword
}
i := irc.NewClient(ircCfg)
i.Config.HandleNickInUse = createNickInUseHandler(i, state)
state.setIRC(server.Host, i)
i.Connect(address)
i.Connect()
go newIRCHandler(i, state).run()
return i

View file

@ -52,15 +52,15 @@ func (i *ircHandler) run() {
select {
case msg, ok := <-i.client.Messages:
if !ok {
i.state.deleteIRC(i.client.Host)
i.state.deleteIRC(i.client.Host())
return
}
i.dispatchMessage(msg)
case state := <-i.client.ConnectionChanged:
i.state.sendJSON("connection_update", newConnectionUpdate(i.client.Host, state))
i.state.setConnectionState(i.client.Host, state)
i.state.sendJSON("connection_update", newConnectionUpdate(i.client.Host(), state))
i.state.setConnectionState(i.client.Host(), state)
if state.Error != nil && (lastConnErr == nil ||
state.Error.Error() != lastConnErr.Error()) {
@ -89,7 +89,7 @@ func (i *ircHandler) run() {
func (i *ircHandler) dispatchMessage(msg *irc.Message) {
if msg.Command[0] == '4' && !isExcludedError(msg.Command) {
err := IRCError{
Server: i.client.Host,
Server: i.client.Host(),
Message: msg.LastParam(),
}
@ -112,36 +112,36 @@ func (i *ircHandler) dispatchMessage(msg *irc.Message) {
func (i *ircHandler) nick(msg *irc.Message) {
i.state.sendJSON("nick", Nick{
Server: i.client.Host,
Server: i.client.Host(),
Old: msg.Nick,
New: msg.LastParam(),
})
channelStore.RenameUser(msg.Nick, msg.LastParam(), i.client.Host)
channelStore.RenameUser(msg.Nick, msg.LastParam(), i.client.Host())
if i.client.Is(msg.LastParam()) {
go i.state.user.SetNick(msg.LastParam(), i.client.Host)
go i.state.user.SetNick(msg.LastParam(), i.client.Host())
}
}
func (i *ircHandler) join(msg *irc.Message) {
i.state.sendJSON("join", Join{
Server: i.client.Host,
Server: i.client.Host(),
User: msg.Nick,
Channels: msg.Params,
})
channel := msg.Params[0]
channelStore.AddUser(msg.Nick, i.client.Host, channel)
channelStore.AddUser(msg.Nick, i.client.Host(), channel)
if i.client.Is(msg.Nick) {
// In case no topic is set and there's a cached one that needs to be cleared
i.client.Topic(channel)
i.state.sendLastMessages(i.client.Host, channel, 50)
i.state.sendLastMessages(i.client.Host(), channel, 50)
go i.state.user.AddChannel(&storage.Channel{
Server: i.client.Host,
Server: i.client.Host(),
Name: channel,
})
}
@ -149,7 +149,7 @@ func (i *ircHandler) join(msg *irc.Message) {
func (i *ircHandler) part(msg *irc.Message) {
part := Part{
Server: i.client.Host,
Server: i.client.Host(),
User: msg.Nick,
Channel: msg.Params[0],
}
@ -160,10 +160,10 @@ func (i *ircHandler) part(msg *irc.Message) {
i.state.sendJSON("part", part)
channelStore.RemoveUser(msg.Nick, i.client.Host, part.Channel)
channelStore.RemoveUser(msg.Nick, i.client.Host(), part.Channel)
if i.client.Is(msg.Nick) {
go i.state.user.RemoveChannel(i.client.Host, part.Channel)
go i.state.user.RemoveChannel(i.client.Host(), part.Channel)
}
}
@ -171,13 +171,13 @@ func (i *ircHandler) mode(msg *irc.Message) {
target := msg.Params[0]
if len(msg.Params) > 2 && isChannel(target) {
mode := parseMode(msg.Params[1])
mode.Server = i.client.Host
mode.Server = i.client.Host()
mode.Channel = target
mode.User = msg.Params[2]
i.state.sendJSON("mode", mode)
channelStore.SetMode(i.client.Host, target, msg.Params[2], mode.Add, mode.Remove)
channelStore.SetMode(i.client.Host(), target, msg.Params[2], mode.Add, mode.Remove)
}
}
@ -195,7 +195,7 @@ func (i *ircHandler) message(msg *irc.Message) {
message := Message{
ID: betterguid.New(),
Server: i.client.Host,
Server: i.client.Host(),
From: msg.Nick,
Content: msg.LastParam(),
}
@ -205,7 +205,7 @@ func (i *ircHandler) message(msg *irc.Message) {
i.state.sendJSON("pm", message)
if !msg.IsFromServer() {
i.state.user.AddOpenDM(i.client.Host, message.From)
i.state.user.AddOpenDM(i.client.Host(), message.From)
}
target = message.From
@ -216,38 +216,38 @@ func (i *ircHandler) message(msg *irc.Message) {
if target != "*" && !msg.IsFromServer() {
go i.state.user.LogMessage(message.ID,
i.client.Host, msg.Nick, target, msg.LastParam())
i.client.Host(), msg.Nick, target, msg.LastParam())
}
}
func (i *ircHandler) quit(msg *irc.Message) {
i.state.sendJSON("quit", Quit{
Server: i.client.Host,
Server: i.client.Host(),
User: msg.Nick,
Reason: msg.LastParam(),
})
channelStore.RemoveUserAll(msg.Nick, i.client.Host)
channelStore.RemoveUserAll(msg.Nick, i.client.Host())
}
func (i *ircHandler) info(msg *irc.Message) {
if msg.Command == irc.RPL_WELCOME {
i.state.sendJSON("nick", Nick{
Server: i.client.Host,
Server: i.client.Host(),
New: msg.Params[0],
})
_, needsUpdate := channelIndexes.Get(i.client.Host)
_, needsUpdate := channelIndexes.Get(i.client.Host())
if needsUpdate {
i.listBuffer = storage.NewMapChannelListIndex()
i.client.List()
}
go i.state.user.SetNick(msg.Params[0], i.client.Host)
go i.state.user.SetNick(msg.Params[0], i.client.Host())
}
i.state.sendJSON("pm", Message{
Server: i.client.Host,
Server: i.client.Host(),
From: msg.Nick,
Content: strings.Join(msg.Params[1:], " "),
})
@ -255,13 +255,13 @@ func (i *ircHandler) info(msg *irc.Message) {
func (i *ircHandler) features(msg *irc.Message) {
i.state.sendJSON("features", Features{
Server: i.client.Host,
Server: i.client.Host(),
Features: i.client.Features.Map(),
})
if name := i.client.Features.String("NETWORK"); name != "" {
go func() {
server, err := i.state.user.GetServer(i.client.Host)
server, err := i.state.user.GetServer(i.client.Host())
if err == nil && server.Name == "" {
i.state.user.SetServerName(name, server.Host)
}
@ -303,24 +303,24 @@ func (i *ircHandler) topic(msg *irc.Message) {
}
i.state.sendJSON("topic", Topic{
Server: i.client.Host,
Server: i.client.Host(),
Channel: channel,
Topic: msg.LastParam(),
Nick: nick,
})
channelStore.SetTopic(msg.LastParam(), i.client.Host, channel)
channelStore.SetTopic(msg.LastParam(), i.client.Host(), channel)
}
func (i *ircHandler) noTopic(msg *irc.Message) {
channel := msg.Params[1]
i.state.sendJSON("topic", Topic{
Server: i.client.Host,
Server: i.client.Host(),
Channel: channel,
})
channelStore.SetTopic("", i.client.Host, channel)
channelStore.SetTopic("", i.client.Host(), channel)
}
func (i *ircHandler) names(msg *irc.Message) {
@ -334,17 +334,17 @@ func (i *ircHandler) namesEnd(msg *irc.Message) {
users := i.userBuffers[channel]
i.state.sendJSON("users", Userlist{
Server: i.client.Host,
Server: i.client.Host(),
Channel: channel,
Users: users,
})
channelStore.SetUsers(users, i.client.Host, channel)
channelStore.SetUsers(users, i.client.Host(), channel)
delete(i.userBuffers, channel)
}
func (i *ircHandler) motdStart(msg *irc.Message) {
i.motdBuffer.Server = i.client.Host
i.motdBuffer.Server = i.client.Host()
i.motdBuffer.Title = msg.LastParam()
}
@ -358,7 +358,7 @@ func (i *ircHandler) motdEnd(msg *irc.Message) {
}
func (i *ircHandler) list(msg *irc.Message) {
if i.listBuffer == nil && i.state.Bool("update_chanlist_"+i.client.Host) {
if i.listBuffer == nil && i.state.Bool("update_chanlist_"+i.client.Host()) {
i.listBuffer = storage.NewMapChannelListIndex()
}
@ -374,11 +374,11 @@ func (i *ircHandler) list(msg *irc.Message) {
func (i *ircHandler) listEnd(msg *irc.Message) {
if i.listBuffer != nil {
i.state.Set("update_chanlist_"+i.client.Host, false)
i.state.Set("update_chanlist_"+i.client.Host(), false)
go func(idx storage.ChannelListIndex) {
idx.Finish()
channelIndexes.Set(i.client.Host, idx)
channelIndexes.Set(i.client.Host(), idx)
}(i.listBuffer)
i.listBuffer = nil
@ -387,14 +387,14 @@ func (i *ircHandler) listEnd(msg *irc.Message) {
func (i *ircHandler) badNick(msg *irc.Message) {
i.state.sendJSON("nick_fail", NickFail{
Server: i.client.Host,
Server: i.client.Host(),
})
}
func (i *ircHandler) forward(msg *irc.Message) {
if len(msg.Params) > 2 {
i.state.sendJSON("channel_forward", ChannelForward{
Server: i.client.Host,
Server: i.client.Host(),
Old: msg.Params[1],
New: msg.Params[2],
})
@ -403,7 +403,7 @@ func (i *ircHandler) forward(msg *irc.Message) {
func (i *ircHandler) error(msg *irc.Message) {
i.state.sendJSON("error", IRCError{
Server: i.client.Host,
Server: i.client.Host(),
Message: msg.LastParam(),
})
}
@ -424,7 +424,7 @@ func (i *ircHandler) receiveDCCSend(pack *irc.DCCSend, msg *irc.Message) {
i.state.setPendingDCC(pack.File, pack)
i.state.sendJSON("dcc_send", DCCSend{
Server: i.client.Host,
Server: i.client.Host(),
From: msg.Nick,
Filename: pack.File,
URL: fmt.Sprintf("%s://%s/downloads/%s/%s",
@ -476,12 +476,12 @@ func (i *ircHandler) initHandlers() {
}
func (i *ircHandler) log(v ...interface{}) {
log.Println("[IRC]", i.state.user.ID, i.client.Host, fmt.Sprint(v...))
log.Println("[IRC]", i.state.user.ID, i.client.Host(), fmt.Sprint(v...))
}
func (i *ircHandler) sendDCCInfo(message string, log bool, a ...interface{}) {
msg := Message{
Server: i.client.Host,
Server: i.client.Host(),
From: "@dcc",
Content: fmt.Sprintf(message, a...),
}

View file

@ -54,8 +54,11 @@ func dispatchMessage(msg *irc.Message) WSResponse {
}
func dispatchMessageMulti(msg *irc.Message) chan WSResponse {
c := irc.NewClient("nick", "user")
c.Host = "host.com"
c := irc.NewClient(irc.Config{
Nick: "nick",
Username: "user",
Host: "host.com",
})
s := NewState(user, nil)
newIRCHandler(c, s).dispatchMessage(msg)
@ -200,8 +203,11 @@ func TestHandleIRCWelcome(t *testing.T) {
}
func TestHandleIRCWhois(t *testing.T) {
c := irc.NewClient("nick", "user")
c.Host = "host.com"
c := irc.NewClient(irc.Config{
Nick: "nick",
Username: "user",
Host: "host.com",
})
s := NewState(nil, nil)
i := newIRCHandler(c, s)
@ -268,8 +274,11 @@ func TestHandleIRCNoTopic(t *testing.T) {
}
func TestHandleIRCNames(t *testing.T) {
c := irc.NewClient("nick", "user")
c.Host = "host.com"
c := irc.NewClient(irc.Config{
Nick: "nick",
Username: "user",
Host: "host.com",
})
s := NewState(nil, nil)
i := newIRCHandler(c, s)
@ -294,8 +303,11 @@ func TestHandleIRCNames(t *testing.T) {
}
func TestHandleIRCMotd(t *testing.T) {
c := irc.NewClient("nick", "user")
c.Host = "host.com"
c := irc.NewClient(irc.Config{
Nick: "nick",
Username: "user",
Host: "host.com",
})
s := NewState(nil, nil)
i := newIRCHandler(c, s)
@ -321,8 +333,11 @@ func TestHandleIRCMotd(t *testing.T) {
}
func TestHandleIRCBadNick(t *testing.T) {
c := irc.NewClient("nick", "user")
c.Host = "host.com"
c := irc.NewClient(irc.Config{
Nick: "nick",
Username: "user",
Host: "host.com",
})
s := NewState(nil, nil)
i := newIRCHandler(c, s)

View file

@ -132,8 +132,8 @@ func (h *wsHandler) reconnect(b []byte) {
data.UnmarshalJSON(b)
if i, ok := h.state.getIRC(data.Server); ok && !i.Connected() {
if i.TLS {
i.TLSConfig.InsecureSkipVerify = data.SkipVerify
if i.Config.TLS {
i.Config.TLSConfig.InsecureSkipVerify = data.SkipVerify
}
i.Reconnect()
}