Browse Source

Initial RELAYMSG implementation

tags/v2.4.0-rc1
Daniel Oaks 4 years ago
parent
commit
4ee49f8450
9 changed files with 91 additions and 1 deletions
  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 View File

583
             - "vhosts"
583
             - "vhosts"
584
             - "chanreg"
584
             - "chanreg"
585
             - "history"
585
             - "history"
586
+            - "relaymsg-anywhere"
586
 
587
 
587
 # ircd operators
588
 # ircd operators
588
 opers:
589
 opers:

+ 6
- 0
gencapdefs.py View File

93
         url="https://ircv3.net/specs/extensions/multi-prefix-3.1.html",
93
         url="https://ircv3.net/specs/extensions/multi-prefix-3.1.html",
94
         standard="IRCv3",
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
     CapDef(
102
     CapDef(
97
         identifier="Rename",
103
         identifier="Rename",
98
         name="draft/rename",
104
         name="draft/rename",

+ 6
- 1
irc/caps/defs.go View File

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

+ 4
- 0
irc/client_lookup_set.go View File

173
 			return "", errNicknameInvalid, false
173
 			return "", errNicknameInvalid, false
174
 		}
174
 		}
175
 
175
 
176
+		if strings.Contains(newCfNick, "/") {
177
+			return "", errNicknameInvalid, false
178
+		}
179
+
176
 		if restrictedCasefoldedNicks[newCfNick] || restrictedSkeletons[newSkeleton] {
180
 		if restrictedCasefoldedNicks[newCfNick] || restrictedSkeletons[newSkeleton] {
177
 			return "", errNicknameInvalid, false
181
 			return "", errNicknameInvalid, false
178
 		}
182
 		}

+ 4
- 0
irc/commands.go View File

250
 			minParams:      2,
250
 			minParams:      2,
251
 			allowedInBatch: true,
251
 			allowedInBatch: true,
252
 		},
252
 		},
253
+		"RELAYMSG": {
254
+			handler:   relaymsgHandler,
255
+			minParams: 3,
256
+		},
253
 		"RENAME": {
257
 		"RENAME": {
254
 			handler:   renameHandler,
258
 			handler:   renameHandler,
255
 			minParams: 2,
259
 			minParams: 2,

+ 3
- 0
irc/config.go View File

1068
 	}
1068
 	}
1069
 	config.Server.capValues[caps.Languages] = config.languageManager.CapValue()
1069
 	config.Server.capValues[caps.Languages] = config.languageManager.CapValue()
1070
 
1070
 
1071
+	// intentionally not configurable
1072
+	config.Server.capValues[caps.Relaymsg] = "/"
1073
+
1071
 	config.Debug.recoverFromErrors = utils.BoolDefaultTrue(config.Debug.RecoverFromErrors)
1074
 	config.Debug.recoverFromErrors = utils.BoolDefaultTrue(config.Debug.RecoverFromErrors)
1072
 
1075
 
1073
 	// process operator definitions, store them to config.operators
1076
 	// process operator definitions, store them to config.operators

+ 56
- 0
irc/handlers.go View File

1887
 		if i == maxTargets {
1887
 		if i == maxTargets {
1888
 			break
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
 		// each target gets distinct msgids
1899
 		// each target gets distinct msgids
1891
 		splitMsg := utils.MakeMessage(message)
1900
 		splitMsg := utils.MakeMessage(message)
1892
 		dispatchMessageToTarget(client, clientOnlyTags, histType, msg.Command, targetString, splitMsg, rb)
1901
 		dispatchMessageToTarget(client, clientOnlyTags, histType, msg.Command, targetString, splitMsg, rb)
2270
 	return false
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
 // RENAME <oldchan> <newchan> [<reason>]
2329
 // RENAME <oldchan> <newchan> [<reason>]
2274
 func renameHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) (result bool) {
2330
 func renameHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) (result bool) {
2275
 	result = false
2331
 	result = false

+ 10
- 0
irc/help.go View File

393
 		text: `PRIVMSG <target>{,<target>} <text to be sent>
393
 		text: `PRIVMSG <target>{,<target>} <text to be sent>
394
 
394
 
395
 Sends the text to the given targets as a PRIVMSG.`,
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
 	"rename": {
407
 	"rename": {
398
 		text: `RENAME <channel> <newname> [<reason>]
408
 		text: `RENAME <channel> <newname> [<reason>]

+ 1
- 0
oragono.yaml View File

609
             - "vhosts"
609
             - "vhosts"
610
             - "chanreg"
610
             - "chanreg"
611
             - "history"
611
             - "history"
612
+            - "relaymsg-anywhere"
612
 
613
 
613
 # ircd operators
614
 # ircd operators
614
 opers:
615
 opers:

Loading…
Cancel
Save