Procházet zdrojové kódy

Initial RELAYMSG implementation

tags/v2.4.0-rc1
Daniel Oaks před 4 roky
rodič
revize
4ee49f8450
9 změnil soubory, kde provedl 91 přidání a 1 odebrání
  1. 1
    0
      conventional.yaml
  2. 6
    0
      gencapdefs.py
  3. 6
    1
      irc/caps/defs.go
  4. 4
    0
      irc/client_lookup_set.go
  5. 4
    0
      irc/commands.go
  6. 3
    0
      irc/config.go
  7. 56
    0
      irc/handlers.go
  8. 10
    0
      irc/help.go
  9. 1
    0
      oragono.yaml

+ 1
- 0
conventional.yaml Zobrazit soubor

@@ -583,6 +583,7 @@ oper-classes:
583 583
             - "vhosts"
584 584
             - "chanreg"
585 585
             - "history"
586
+            - "relaymsg-anywhere"
586 587
 
587 588
 # ircd operators
588 589
 opers:

+ 6
- 0
gencapdefs.py Zobrazit soubor

@@ -93,6 +93,12 @@ CAPDEFS = [
93 93
         url="https://ircv3.net/specs/extensions/multi-prefix-3.1.html",
94 94
         standard="IRCv3",
95 95
     ),
96
+    CapDef(
97
+        identifier="Relaymsg",
98
+        name="draft/relaymsg",
99
+        url="https://github.com/ircv3/ircv3-specifications/pull/417",
100
+        standard="proposed IRCv3",
101
+    ),
96 102
     CapDef(
97 103
         identifier="Rename",
98 104
         name="draft/rename",

+ 6
- 1
irc/caps/defs.go Zobrazit soubor

@@ -7,7 +7,7 @@ package caps
7 7
 
8 8
 const (
9 9
 	// number of recognized capabilities:
10
-	numCapabs = 26
10
+	numCapabs = 27
11 11
 	// length of the uint64 array that represents the bitset:
12 12
 	bitsetLen = 1
13 13
 )
@@ -53,6 +53,10 @@ const (
53 53
 	// https://github.com/ircv3/ircv3-specifications/pull/398
54 54
 	Multiline Capability = iota
55 55
 
56
+	// Relaymsg is the proposed IRCv3 capability named "draft/relaymsg":
57
+	// https://github.com/ircv3/ircv3-specifications/pull/417
58
+	Relaymsg Capability = iota
59
+
56 60
 	// Rename is the proposed IRCv3 capability named "draft/rename":
57 61
 	// https://github.com/SaberUK/ircv3-specifications/blob/rename/extensions/rename.md
58 62
 	Rename Capability = iota
@@ -131,6 +135,7 @@ var (
131 135
 		"draft/event-playback",
132 136
 		"draft/languages",
133 137
 		"draft/multiline",
138
+		"draft/relaymsg",
134 139
 		"draft/rename",
135 140
 		"draft/resume-0.5",
136 141
 		"echo-message",

+ 4
- 0
irc/client_lookup_set.go Zobrazit soubor

@@ -173,6 +173,10 @@ func (clients *ClientManager) SetNick(client *Client, session *Session, newNick
173 173
 			return "", errNicknameInvalid, false
174 174
 		}
175 175
 
176
+		if strings.Contains(newCfNick, "/") {
177
+			return "", errNicknameInvalid, false
178
+		}
179
+
176 180
 		if restrictedCasefoldedNicks[newCfNick] || restrictedSkeletons[newSkeleton] {
177 181
 			return "", errNicknameInvalid, false
178 182
 		}

+ 4
- 0
irc/commands.go Zobrazit soubor

@@ -250,6 +250,10 @@ func init() {
250 250
 			minParams:      2,
251 251
 			allowedInBatch: true,
252 252
 		},
253
+		"RELAYMSG": {
254
+			handler:   relaymsgHandler,
255
+			minParams: 3,
256
+		},
253 257
 		"RENAME": {
254 258
 			handler:   renameHandler,
255 259
 			minParams: 2,

+ 3
- 0
irc/config.go Zobrazit soubor

@@ -1068,6 +1068,9 @@ func LoadConfig(filename string) (config *Config, err error) {
1068 1068
 	}
1069 1069
 	config.Server.capValues[caps.Languages] = config.languageManager.CapValue()
1070 1070
 
1071
+	// intentionally not configurable
1072
+	config.Server.capValues[caps.Relaymsg] = "/"
1073
+
1071 1074
 	config.Debug.recoverFromErrors = utils.BoolDefaultTrue(config.Debug.RecoverFromErrors)
1072 1075
 
1073 1076
 	// process operator definitions, store them to config.operators

+ 56
- 0
irc/handlers.go Zobrazit soubor

@@ -1887,6 +1887,15 @@ func messageHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *R
1887 1887
 		if i == maxTargets {
1888 1888
 			break
1889 1889
 		}
1890
+
1891
+		if strings.Contains(targetString, "/") {
1892
+			if histType == history.Privmsg {
1893
+				rb.Add(nil, server.name, ERR_NOSUCHNICK, client.Nick(), targetString, client.t("Relayed users cannot be sent private messages"))
1894
+			}
1895
+			// TAGMSG/NOTICEs are intentionally silently dropped
1896
+			continue
1897
+		}
1898
+
1890 1899
 		// each target gets distinct msgids
1891 1900
 		splitMsg := utils.MakeMessage(message)
1892 1901
 		dispatchMessageToTarget(client, clientOnlyTags, histType, msg.Command, targetString, splitMsg, rb)
@@ -2270,6 +2279,53 @@ func rehashHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re
2270 2279
 	return false
2271 2280
 }
2272 2281
 
2282
+// RELAYMSG <channel> <spoofed nick> :<message>
2283
+func relaymsgHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) (result bool) {
2284
+	channel := server.channels.Get(msg.Params[0])
2285
+	if channel == nil {
2286
+		rb.Add(nil, server.name, ERR_NOSUCHCHANNEL, client.Nick(), utils.SafeErrorParam(msg.Params[0]), client.t("No such channel"))
2287
+		return false
2288
+	}
2289
+
2290
+	if !(channel.ClientIsAtLeast(client, modes.ChannelOperator) || client.HasRoleCapabs("relaymsg-anywhere")) {
2291
+		rb.Add(nil, server.name, "FAIL", "RELAYMSG", "NOT_PRIVED", client.t("Only channel operators or ircops with the 'relaymsg-anywhere' role can relay messages"))
2292
+		return false
2293
+	}
2294
+
2295
+	rawMessage := msg.Params[2]
2296
+	if strings.TrimSpace(rawMessage) == "" {
2297
+		rb.Add(nil, server.name, "FAIL", "RELAYMSG", "BLANK_MSG", client.t("The message must not be blank"))
2298
+		return false
2299
+	}
2300
+	message := utils.MakeMessage(rawMessage)
2301
+
2302
+	nick := msg.Params[1]
2303
+	_, err := CasefoldName(nick)
2304
+	if err != nil {
2305
+		rb.Add(nil, server.name, "FAIL", "RELAYMSG", "INVALID_NICK", client.t("Invalid nickname"))
2306
+		return false
2307
+	}
2308
+	if !strings.Contains(nick, "/") {
2309
+		rb.Add(nil, server.name, "FAIL", "RELAYMSG", "INVALID_NICK", fmt.Sprintf(client.t("Relayed nicknames MUST contain the relaymsg separator %s"), "/"))
2310
+		return false
2311
+	}
2312
+
2313
+	//TODO: add to history here??
2314
+
2315
+	// send msg
2316
+	for _, member := range channel.Members() {
2317
+		for _, session := range member.Sessions() {
2318
+			tagsToUse := make(map[string]string)
2319
+			if session.capabilities.Has(caps.Relaymsg) {
2320
+				tagsToUse["relaymsg"] = client.Nick()
2321
+			}
2322
+
2323
+			session.sendSplitMsgFromClientInternal(false, nick, "", tagsToUse, "PRIVMSG", channel.Name(), message)
2324
+		}
2325
+	}
2326
+	return false
2327
+}
2328
+
2273 2329
 // RENAME <oldchan> <newchan> [<reason>]
2274 2330
 func renameHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) (result bool) {
2275 2331
 	result = false

+ 10
- 0
irc/help.go Zobrazit soubor

@@ -393,6 +393,16 @@ Replies to a PING. Used to check link connectivity.`,
393 393
 		text: `PRIVMSG <target>{,<target>} <text to be sent>
394 394
 
395 395
 Sends the text to the given targets as a PRIVMSG.`,
396
+	},
397
+	"relaymsg": {
398
+		text: `RELAYMSG <channel> <spoofed nick> :<message>
399
+
400
+This command lets channel operators relay messages to their
401
+channel from other messaging systems using relay bots. The
402
+spoofed nickname MUST contain a forwardslash.
403
+
404
+For example:
405
+	RELAYMSG #ircv3 Mallory/D :Welp, we linked Discord...`,
396 406
 	},
397 407
 	"rename": {
398 408
 		text: `RENAME <channel> <newname> [<reason>]

+ 1
- 0
oragono.yaml Zobrazit soubor

@@ -609,6 +609,7 @@ oper-classes:
609 609
             - "vhosts"
610 610
             - "chanreg"
611 611
             - "history"
612
+            - "relaymsg-anywhere"
612 613
 
613 614
 # ircd operators
614 615
 opers:

Načítá se…
Zrušit
Uložit