~emersion/public-inbox

[RFC soju] Add support for draft/register and draft/account-registration

Details
Message ID
<20210706234600.1200-1-delthas@dille.cc>
DKIM signature
pass
Download raw message
Patch: +59 -11
The capability slightly varies between the old and new name, as a new
parameter was added. This adds support for both.

Fixes: #105
See: https://github.com/ircv3/ircv3-specifications/pull/435
---
 downstream.go | 40 +++++++++++++++++++++++++++++++++++++++-
 upstream.go   | 30 ++++++++++++++++++++----------
 2 files changed, 59 insertions(+), 11 deletions(-)

diff --git a/downstream.go b/downstream.go
index fee5134..540bace 100644
--- a/downstream.go
+++ b/downstream.go
@@ -137,6 +137,15 @@ var needAllDownstreamCaps = map[string]string{
	"multi-prefix":  "",
}

// passthroughCaps is the list of downstream capabilities that are passed
// through from the upstream server to downstream clients.
//
// This is only effective in single-upstream mode.
var passthroughCaps = map[string]string{
	"draft/account-registration": "",
	"draft/register":             "",
}

// passthroughIsupport is the set of ISUPPORT tokens that are directly passed
// through from the upstream server to downstream clients.
//
@@ -894,6 +903,18 @@ func (dc *downstreamConn) updateSupportedCaps() {
			dc.unsetSupportedCap(cap)
		}
	}

	uc := dc.upstream()
	for cap := range passthroughCaps {
		if uc != nil {
			v, ok := uc.supportedCaps[cap]
			if ok && uc.caps[cap] {
				dc.setSupportedCap(cap, v)
				continue
			}
		}
		dc.unsetSupportedCap(cap)
	}
}

func (dc *downstreamConn) updateNick() {
@@ -2343,6 +2364,20 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
				Params:  []string{"BOUNCER", "UNKNOWN_COMMAND", subcommand, "Unknown subcommand"},
			}}
		}
	case "REGISTER", "VERIFY":
		uc := dc.upstream()
		if uc == nil {
			return newUnknownCommandError(msg.Command)
		}
		uc.SendMessageLabeled(dc.id, msg)
		if msg.Command == "REGISTER" && len(msg.Params) >= 2 {
			username := uc.nick
			if len(msg.Params) >= 3 && msg.Params[0] != "*" {
				username = msg.Params[0]
			}
			password := msg.Params[len(msg.Params)-1]
			dc.updateCredentials(uc, username, password)
		}
	default:
		dc.logger.Printf("unhandled message: %v", msg)

@@ -2362,14 +2397,17 @@ func (dc *downstreamConn) handleNickServPRIVMSG(uc *upstreamConn, text string) {
	if !ok {
		return
	}
	dc.updateCredentials(uc, username, password)
}

func (dc *downstreamConn) updateCredentials(uc *upstreamConn, username, password string) {
	// User may have e.g. EXTERNAL mechanism configured. We do not want to
	// automatically erase the key pair or any other credentials.
	if uc.network.SASL.Mechanism != "" && uc.network.SASL.Mechanism != "PLAIN" {
		return
	}

	dc.logger.Printf("auto-saving NickServ credentials with username %q", username)
	dc.logger.Printf("auto-saving credentials with username %q", username)
	n := uc.network
	n.SASL.Mechanism = "PLAIN"
	n.SASL.Plain.Username = username
diff --git a/upstream.go b/upstream.go
index 104f330..46f96d1 100644
--- a/upstream.go
+++ b/upstream.go
@@ -21,16 +21,18 @@ import (
// permanentUpstreamCaps is the static list of upstream capabilities always
// requested when supported.
var permanentUpstreamCaps = map[string]bool{
	"account-tag":      true,
	"away-notify":      true,
	"batch":            true,
	"extended-join":    true,
	"invite-notify":    true,
	"labeled-response": true,
	"message-tags":     true,
	"multi-prefix":     true,
	"server-time":      true,
	"setname":          true,
	"account-tag":                true,
	"away-notify":                true,
	"batch":                      true,
	"extended-join":              true,
	"invite-notify":              true,
	"labeled-response":           true,
	"message-tags":               true,
	"multi-prefix":               true,
	"server-time":                true,
	"setname":                    true,
	"draft/account-registration": true,
	"draft/register":             true,
}

type registrationError string
@@ -1428,6 +1430,14 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
				Params:  []string{dc.nick, upstreamChannel, trailing},
			})
		})
	case "REGISTER", "VERIFY":
		uc.forEachDownstreamByID(downstreamID, func(dc *downstreamConn) {
			dc.SendMessage(&irc.Message{
				Prefix:  uc.srv.prefix(),
				Command: msg.Command,
				Params:  msg.Params,
			})
		})
	case irc.ERR_UNKNOWNCOMMAND, irc.RPL_TRYAGAIN:
		var command, reason string
		if err := parseMessageParams(msg, nil, &command, &reason); err != nil {
-- 
2.30.0
Reply to thread Export thread (mbox)