Quellcode durchsuchen

Refactor nickserv.go to better support NS HELP and translations

tags/v0.11.0-beta
Daniel Oaks vor 6 Jahren
Ursprung
Commit
7b8c4e7e91
3 geänderte Dateien mit 347 neuen und 214 gelöschten Zeilen
  1. 326
    214
      irc/nickserv.go
  2. 8
    0
      irc/server.go
  3. 13
    0
      irc/utils/args.go

+ 326
- 214
irc/nickserv.go Datei anzeigen

@@ -5,161 +5,342 @@ package irc
5 5
 
6 6
 import (
7 7
 	"fmt"
8
+	"sort"
8 9
 	"strings"
10
+
11
+	"github.com/goshuirc/irc-go/ircfmt"
12
+
13
+	"github.com/oragono/oragono/irc/modes"
14
+	"github.com/oragono/oragono/irc/utils"
9 15
 )
10 16
 
11 17
 // TODO: "email" is an oversimplification here; it's actually any callback, e.g.,
12 18
 // person@example.com, mailto:person@example.com, tel:16505551234.
13
-const nickservHelp = `NickServ lets you register and log into a user account.
14
-
15
-To register an account:
16
-	/NS REGISTER username email [password]
17
-Leave out [password] if you're registering using your client certificate fingerprint.
18
-The server may or may not allow you to register anonymously (by sending * as your
19
-email address).
20
-
21
-To verify an account (if you were sent a verification code):
22
-	/NS VERIFY username code
23
-
24
-To unregister an account:
25
-	/NS UNREGISTER [username]
26
-Leave out [username] if you're unregistering the user you're currently logged in as.
27
-
28
-To login to an account:
29
-	/NS IDENTIFY [username password]
30
-Leave out [username password] to use your client certificate fingerprint. Otherwise,
31
-the given username and password will be used.
32
-
33
-To see account information:
34
-	/NS INFO [username]
35
-Leave out [username] to see your own account information.
36
-
37
-To associate your current nick with the account you're logged into:
38
-	/NS GROUP
39
-
40
-To disassociate a nick with the account you're logged into:
41
-	/NS DROP [nickname]
42
-Leave out [nickname] to drop your association with your current nickname.`
43
-
44
-// extractParam extracts a parameter from the given string, returning the param and the rest of the string.
45
-func extractParam(line string) (string, string) {
46
-	rawParams := strings.SplitN(strings.TrimSpace(line), " ", 2)
47
-	param0 := rawParams[0]
48
-	var param1 string
49
-	if 1 < len(rawParams) {
50
-		param1 = strings.TrimSpace(rawParams[1])
51
-	}
52
-	return param0, param1
53
-}
19
+const nickservHelp = `NickServ lets you register and login to an account.
54 20
 
55
-// nickservNoticeHandler handles NOTICEs that NickServ receives.
56
-func (server *Server) nickservNoticeHandler(client *Client, message string, rb *ResponseBuffer) {
57
-	// do nothing
21
+To see in-depth help for a specific NickServ command, try:
22
+    $b/NS HELP <command>$b
23
+
24
+Here are the commands you can use:
25
+%s`
26
+
27
+type nsCommand struct {
28
+	capabs          []string // oper capabs the given user has to have to access this command
29
+	handler         func(server *Server, client *Client, command, params string, rb *ResponseBuffer)
30
+	help            string
31
+	helpShort       string
32
+	nickReservation bool // nick reservation must be enabled to use this command
33
+	oper            bool // true if the user has to be an oper to use this command
58 34
 }
59 35
 
36
+var (
37
+	nickservCommands = map[string]*nsCommand{
38
+		"drop": {
39
+			handler: nsDropHandler,
40
+			help: `Syntax: $bDROP [nickname]$b
41
+
42
+DROP de-links the given (or your current) nickname from your user account.`,
43
+			helpShort:       `$bDROP$b de-links your current (or the given) nickname from your user account.`,
44
+			nickReservation: true,
45
+		},
46
+		"ghost": {
47
+			handler: nsGhostHandler,
48
+			help: `Syntax: $bGHOST <nickname>$b
49
+
50
+GHOST disconnects the given user from the network if they're logged in with the
51
+same user account, letting you reclaim your nickname.`,
52
+			helpShort: `$bGHOST$b reclaims your nickname.`,
53
+		},
54
+		"group": {
55
+			handler: nsGroupHandler,
56
+			help: `Syntax: $bGROUP$b
57
+
58
+GROUP links your current nickname with your logged-in account, preventing other
59
+users from changing to it (or forcing them to rename).`,
60
+			helpShort:       `$bGROUP$b links your current nickname to your user account.`,
61
+			nickReservation: true,
62
+		},
63
+		"help": {
64
+			help: `Syntax: $bHELP [command]$b
65
+
66
+HELP returns information on the given command.`,
67
+			helpShort: `$bHELP$b shows in-depth information about commands.`,
68
+		},
69
+		"identify": {
70
+			handler: nsIdentifyHandler,
71
+			help: `Syntax: $bIDENTIFY <username> [password]$b
72
+
73
+IDENTIFY lets you login to the given username using either password auth, or
74
+certfp (your client certificate) if a password is not given.`,
75
+			helpShort: `$bIDENTIFY$b lets you login to your account.`,
76
+		},
77
+		"info": {
78
+			handler: nsInfoHandler,
79
+			help: `Syntax: $bINFO [username]$b
80
+
81
+INFO gives you information about the given (or your own) user account.`,
82
+			helpShort: `$bINFO$b gives you information on a user account.`,
83
+		},
84
+		"register": {
85
+			handler: nsRegisterHandler,
86
+			help: `Syntax: $bREGISTER <username> <email> [password]$b
87
+
88
+REGISTER lets you register a user account. If the server allows anonymous
89
+registration, you can send an asterisk (*) as the email address.
90
+
91
+If the password is left out, your account will be registered to your TLS client
92
+certificate (and you will need to use that certificate to login in future).`,
93
+			helpShort: `$bREGISTER$b lets you register a user account.`,
94
+		},
95
+		"sadrop": {
96
+			handler: nsDropHandler,
97
+			help: `Syntax: $bSADROP <nickname>$b
98
+
99
+SADROP foribly de-links the given nickname from the attached user account.`,
100
+			helpShort:       `$bSADROP$b forcibly de-links the given nickname from its user account.`,
101
+			nickReservation: true,
102
+			capabs:          []string{"unregister"},
103
+		},
104
+		"unregister": {
105
+			handler: nsUnregisterHandler,
106
+			help: `Syntax: $bUNREGISTER [username]$b
107
+
108
+UNREGISTER lets you delete your user account (or the given one, if you're an
109
+IRC operator with the correct permissions).`,
110
+			helpShort: `$bUNREGISTER$b lets you delete your user account.`,
111
+		},
112
+		"verify": {
113
+			handler: nsVerifyHandler,
114
+			help: `Syntax: $bVERIFY <username> <code>$b
115
+
116
+VERIFY lets you complete an account registration, if the server requires email
117
+or other verification.`,
118
+			helpShort: `$bVERIFY$b lets you complete account registration.`,
119
+		},
120
+	}
121
+)
122
+
60 123
 // send a notice from the NickServ "nick"
61 124
 func nsNotice(rb *ResponseBuffer, text string) {
62 125
 	rb.Add(nil, "NickServ", "NOTICE", rb.target.Nick(), text)
63 126
 }
64 127
 
128
+// nickservNoticeHandler handles NOTICEs that NickServ receives.
129
+func (server *Server) nickservNoticeHandler(client *Client, message string, rb *ResponseBuffer) {
130
+	// do nothing
131
+}
132
+
65 133
 // nickservPrivmsgHandler handles PRIVMSGs that NickServ receives.
66 134
 func (server *Server) nickservPrivmsgHandler(client *Client, message string, rb *ResponseBuffer) {
67
-	command, params := extractParam(message)
68
-	command = strings.ToLower(command)
135
+	commandName, params := utils.ExtractParam(message)
136
+	commandName = strings.ToLower(commandName)
69 137
 
70
-	if command == "help" {
71
-		for _, line := range strings.Split(nickservHelp, "\n") {
72
-			nsNotice(rb, line)
73
-		}
74
-	} else if command == "register" {
75
-		// get params
76
-		username, afterUsername := extractParam(params)
77
-		email, passphrase := extractParam(afterUsername)
78
-		server.nickservRegisterHandler(client, username, email, passphrase, rb)
79
-	} else if command == "verify" {
80
-		username, code := extractParam(params)
81
-		server.nickservVerifyHandler(client, username, code, rb)
82
-	} else if command == "identify" {
83
-		username, passphrase := extractParam(params)
84
-		server.nickservIdentifyHandler(client, username, passphrase, rb)
85
-	} else if command == "unregister" {
86
-		username, _ := extractParam(params)
87
-		server.nickservUnregisterHandler(client, username, rb)
88
-	} else if command == "ghost" {
89
-		nick, _ := extractParam(params)
90
-		server.nickservGhostHandler(client, nick, rb)
91
-	} else if command == "info" {
92
-		nick, _ := extractParam(params)
93
-		server.nickservInfoHandler(client, nick, rb)
94
-	} else if command == "group" {
95
-		server.nickservGroupHandler(client, rb)
96
-	} else if command == "drop" {
97
-		nick, _ := extractParam(params)
98
-		server.nickservDropHandler(client, nick, false, rb)
99
-	} else if command == "sadrop" {
100
-		nick, _ := extractParam(params)
101
-		server.nickservDropHandler(client, nick, true, rb)
102
-	} else {
103
-		nsNotice(rb, client.t("Command not recognised. To see the available commands, run /NS HELP"))
138
+	commandInfo := nickservCommands[commandName]
139
+	if commandInfo == nil {
140
+		nsNotice(rb, client.t("Unknown command. To see available commands, run /NS HELP"))
141
+		return
104 142
 	}
105
-}
106 143
 
107
-func (server *Server) nickservUnregisterHandler(client *Client, username string, rb *ResponseBuffer) {
108
-	if !server.AccountConfig().Registration.Enabled {
144
+	if commandInfo.oper && !client.HasMode(modes.Operator) {
145
+		nsNotice(rb, client.t("Command restricted"))
146
+		return
147
+	}
148
+
149
+	if 0 < len(commandInfo.capabs) && !client.HasRoleCapabs(commandInfo.capabs...) {
150
+		nsNotice(rb, client.t("Command restricted"))
151
+		return
152
+	}
153
+
154
+	if commandInfo.nickReservation && !server.AccountConfig().Registration.Enabled {
109 155
 		nsNotice(rb, client.t("Account registration has been disabled"))
110 156
 		return
111 157
 	}
112 158
 
113
-	if username == "" {
114
-		username = client.Account()
159
+	// custom help handling here to prevent recursive init loop
160
+	if commandName == "help" {
161
+		nsHelpHandler(server, client, commandName, params, rb)
162
+		return
115 163
 	}
116
-	if username == "" {
117
-		nsNotice(rb, client.t("You're not logged into an account"))
164
+
165
+	if commandInfo.handler == nil {
166
+		nsNotice(rb, client.t("Command error. Please report this to the developers"))
118 167
 		return
119 168
 	}
120
-	cfname, err := CasefoldName(username)
121
-	if err != nil {
122
-		nsNotice(rb, client.t("Invalid username"))
169
+
170
+	commandInfo.handler(server, client, commandName, params, rb)
171
+}
172
+
173
+func nsDropHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
174
+	sadrop := command == "sadrop"
175
+	nick, _ := utils.ExtractParam(params)
176
+
177
+	err := server.accounts.SetNickReserved(client, nick, sadrop, false)
178
+	if err == nil {
179
+		nsNotice(rb, fmt.Sprintf(client.t("Successfully ungrouped nick %s with your account"), nick))
180
+	} else if err == errAccountNotLoggedIn {
181
+		nsNotice(rb, client.t("You're not logged into an account"))
182
+	} else if err == errAccountCantDropPrimaryNick {
183
+		nsNotice(rb, client.t("You can't ungroup your primary nickname (try unregistering your account instead)"))
184
+	} else if err == errNicknameReserved {
185
+		nsNotice(rb, client.t("That nickname is already reserved by someone else"))
186
+	} else {
187
+		nsNotice(rb, client.t("Could not ungroup nick"))
188
+	}
189
+}
190
+
191
+func nsGhostHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
192
+	nick, _ := utils.ExtractParam(params)
193
+
194
+	account := client.Account()
195
+	if account == "" || server.accounts.NickToAccount(nick) != account {
196
+		nsNotice(rb, client.t("You don't own that nick"))
123 197
 		return
124 198
 	}
125
-	if !(cfname == client.Account() || client.HasRoleCapabs("unregister")) {
126
-		nsNotice(rb, client.t("Insufficient oper privs"))
199
+
200
+	ghost := server.clients.Get(nick)
201
+	if ghost == nil {
202
+		nsNotice(rb, client.t("No such nick"))
203
+		return
204
+	} else if ghost == client {
205
+		nsNotice(rb, client.t("You can't GHOST yourself (try /QUIT instead)"))
127 206
 		return
128 207
 	}
129 208
 
130
-	if cfname == client.Account() {
131
-		client.server.accounts.Logout(client)
209
+	ghost.Quit(fmt.Sprintf(ghost.t("GHOSTed by %s"), client.Nick()))
210
+	ghost.destroy(false)
211
+}
212
+
213
+func nsGroupHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
214
+	account := client.Account()
215
+	if account == "" {
216
+		nsNotice(rb, client.t("You're not logged into an account"))
217
+		return
132 218
 	}
133 219
 
134
-	err = server.accounts.Unregister(cfname)
135
-	if err == errAccountDoesNotExist {
136
-		nsNotice(rb, client.t(err.Error()))
137
-	} else if err != nil {
138
-		nsNotice(rb, client.t("Error while unregistering account"))
220
+	nick := client.NickCasefolded()
221
+	err := server.accounts.SetNickReserved(client, nick, false, true)
222
+	if err == nil {
223
+		nsNotice(rb, fmt.Sprintf(client.t("Successfully grouped nick %s with your account"), nick))
224
+	} else if err == errAccountTooManyNicks {
225
+		nsNotice(rb, client.t("You have too many nicks reserved already (you can remove some with /NS DROP)"))
226
+	} else if err == errNicknameReserved {
227
+		nsNotice(rb, client.t("That nickname is already reserved by someone else"))
139 228
 	} else {
140
-		nsNotice(rb, fmt.Sprintf(client.t("Successfully unregistered account %s"), cfname))
229
+		nsNotice(rb, client.t("Error reserving nickname"))
141 230
 	}
142 231
 }
143 232
 
144
-func (server *Server) nickservVerifyHandler(client *Client, username string, code string, rb *ResponseBuffer) {
145
-	err := server.accounts.Verify(client, username, code)
233
+func nsHelpHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
234
+	nsNotice(rb, ircfmt.Unescape(client.t("*** $bNickServ HELP$b ***")))
146 235
 
147
-	var errorMessage string
148
-	if err == errAccountVerificationInvalidCode || err == errAccountAlreadyVerified {
149
-		errorMessage = err.Error()
150
-	} else if err != nil {
151
-		errorMessage = errAccountVerificationFailed.Error()
236
+	if params == "" {
237
+		// show general help
238
+		var shownHelpLines sort.StringSlice
239
+		for _, commandInfo := range nickservCommands {
240
+			// skip commands user can't access
241
+			if commandInfo.oper && !client.HasMode(modes.Operator) {
242
+				continue
243
+			}
244
+			if 0 < len(commandInfo.capabs) && !client.HasRoleCapabs(commandInfo.capabs...) {
245
+				continue
246
+			}
247
+			if commandInfo.nickReservation && !server.AccountConfig().Registration.Enabled {
248
+				continue
249
+			}
250
+
251
+			shownHelpLines = append(shownHelpLines, "    "+client.t(commandInfo.helpShort))
252
+		}
253
+
254
+		// sort help lines
255
+		sort.Sort(shownHelpLines)
256
+
257
+		// assemble help text
258
+		assembledHelpLines := strings.Join(shownHelpLines, "\n")
259
+		fullHelp := ircfmt.Unescape(fmt.Sprintf(client.t(nickservHelp), assembledHelpLines))
260
+
261
+		// push out help text
262
+		for _, line := range strings.Split(fullHelp, "\n") {
263
+			nsNotice(rb, line)
264
+		}
265
+	} else {
266
+		commandInfo := nickservCommands[strings.ToLower(strings.TrimSpace(params))]
267
+		if commandInfo == nil {
268
+			nsNotice(rb, client.t("Unknown command. To see available commands, run /NS HELP"))
269
+		} else {
270
+			for _, line := range strings.Split(ircfmt.Unescape(client.t(commandInfo.help)), "\n") {
271
+				nsNotice(rb, line)
272
+			}
273
+		}
152 274
 	}
153 275
 
154
-	if errorMessage != "" {
155
-		nsNotice(rb, client.t(errorMessage))
276
+	nsNotice(rb, ircfmt.Unescape(client.t("*** $bEnd of NickServ HELP$b ***")))
277
+}
278
+
279
+func nsIdentifyHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
280
+	// fail out if we need to
281
+	if !server.AccountConfig().AuthenticationEnabled {
282
+		nsNotice(rb, client.t("Login has been disabled"))
156 283
 		return
157 284
 	}
158 285
 
159
-	sendSuccessfulRegResponse(client, rb, true)
286
+	loginSuccessful := false
287
+
288
+	username, passphrase := utils.ExtractParam(params)
289
+
290
+	// try passphrase
291
+	if username != "" && passphrase != "" {
292
+		err := server.accounts.AuthenticateByPassphrase(client, username, passphrase)
293
+		loginSuccessful = (err == nil)
294
+	}
295
+
296
+	// try certfp
297
+	if !loginSuccessful && client.certfp != "" {
298
+		err := server.accounts.AuthenticateByCertFP(client)
299
+		loginSuccessful = (err == nil)
300
+	}
301
+
302
+	if loginSuccessful {
303
+		sendSuccessfulSaslAuth(client, rb, true)
304
+	} else {
305
+		nsNotice(rb, client.t("Could not login with your TLS certificate or supplied username/password"))
306
+	}
160 307
 }
161 308
 
162
-func (server *Server) nickservRegisterHandler(client *Client, username, email, passphrase string, rb *ResponseBuffer) {
309
+func nsInfoHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
310
+	nick, _ := utils.ExtractParam(params)
311
+
312
+	if nick == "" {
313
+		nick = client.Nick()
314
+	}
315
+
316
+	accountName := nick
317
+	if server.AccountConfig().NickReservation.Enabled {
318
+		accountName = server.accounts.NickToAccount(nick)
319
+		if accountName == "" {
320
+			nsNotice(rb, client.t("That nickname is not registered"))
321
+			return
322
+		}
323
+	}
324
+
325
+	account, err := server.accounts.LoadAccount(accountName)
326
+	if err != nil || !account.Verified {
327
+		nsNotice(rb, client.t("Account does not exist"))
328
+	}
329
+
330
+	nsNotice(rb, fmt.Sprintf(client.t("Account: %s"), account.Name))
331
+	registeredAt := account.RegisteredAt.Format("Jan 02, 2006 15:04:05Z")
332
+	nsNotice(rb, fmt.Sprintf(client.t("Registered at: %s"), registeredAt))
333
+	// TODO nicer formatting for this
334
+	for _, nick := range account.AdditionalNicks {
335
+		nsNotice(rb, fmt.Sprintf(client.t("Additional grouped nick: %s"), nick))
336
+	}
337
+}
338
+
339
+func nsRegisterHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
340
+	// get params
341
+	username, afterUsername := utils.ExtractParam(params)
342
+	email, passphrase := utils.ExtractParam(afterUsername)
343
+
163 344
 	if !server.AccountConfig().Registration.Enabled {
164 345
 		nsNotice(rb, client.t("Account registration has been disabled"))
165 346
 		return
@@ -236,130 +417,61 @@ func (server *Server) nickservRegisterHandler(client *Client, username, email, p
236 417
 	}
237 418
 }
238 419
 
239
-func (server *Server) nickservIdentifyHandler(client *Client, username, passphrase string, rb *ResponseBuffer) {
240
-	// fail out if we need to
241
-	if !server.AccountConfig().AuthenticationEnabled {
242
-		nsNotice(rb, client.t("Login has been disabled"))
243
-		return
244
-	}
245
-
246
-	loginSuccessful := false
420
+func nsUnregisterHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
421
+	username, _ := utils.ExtractParam(params)
247 422
 
248
-	// try passphrase
249
-	if username != "" && passphrase != "" {
250
-		err := server.accounts.AuthenticateByPassphrase(client, username, passphrase)
251
-		loginSuccessful = (err == nil)
252
-	}
253
-
254
-	// try certfp
255
-	if !loginSuccessful && client.certfp != "" {
256
-		err := server.accounts.AuthenticateByCertFP(client)
257
-		loginSuccessful = (err == nil)
258
-	}
259
-
260
-	if loginSuccessful {
261
-		sendSuccessfulSaslAuth(client, rb, true)
262
-	} else {
263
-		nsNotice(rb, client.t("Could not login with your TLS certificate or supplied username/password"))
264
-	}
265
-}
266
-
267
-func (server *Server) nickservGhostHandler(client *Client, nick string, rb *ResponseBuffer) {
268
-	if !server.AccountConfig().NickReservation.Enabled {
269
-		nsNotice(rb, client.t("Nickname reservation is disabled"))
423
+	if !server.AccountConfig().Registration.Enabled {
424
+		nsNotice(rb, client.t("Account registration has been disabled"))
270 425
 		return
271 426
 	}
272 427
 
273
-	account := client.Account()
274
-	if account == "" || server.accounts.NickToAccount(nick) != account {
275
-		nsNotice(rb, client.t("You don't own that nick"))
276
-		return
428
+	if username == "" {
429
+		username = client.Account()
277 430
 	}
278
-
279
-	ghost := server.clients.Get(nick)
280
-	if ghost == nil {
281
-		nsNotice(rb, client.t("No such nick"))
431
+	if username == "" {
432
+		nsNotice(rb, client.t("You're not logged into an account"))
282 433
 		return
283
-	} else if ghost == client {
284
-		nsNotice(rb, client.t("You can't GHOST yourself (try /QUIT instead)"))
434
+	}
435
+	cfname, err := CasefoldName(username)
436
+	if err != nil {
437
+		nsNotice(rb, client.t("Invalid username"))
285 438
 		return
286 439
 	}
287
-
288
-	ghost.Quit(fmt.Sprintf(ghost.t("GHOSTed by %s"), client.Nick()))
289
-	ghost.destroy(false)
290
-}
291
-
292
-func (server *Server) nickservGroupHandler(client *Client, rb *ResponseBuffer) {
293
-	if !server.AccountConfig().NickReservation.Enabled {
294
-		nsNotice(rb, client.t("Nickname reservation is disabled"))
440
+	if !(cfname == client.Account() || client.HasRoleCapabs("unregister")) {
441
+		nsNotice(rb, client.t("Insufficient oper privs"))
295 442
 		return
296 443
 	}
297 444
 
298
-	account := client.Account()
299
-	if account == "" {
300
-		nsNotice(rb, client.t("You're not logged into an account"))
301
-		return
445
+	if cfname == client.Account() {
446
+		client.server.accounts.Logout(client)
302 447
 	}
303 448
 
304
-	nick := client.NickCasefolded()
305
-	err := server.accounts.SetNickReserved(client, nick, false, true)
306
-	if err == nil {
307
-		nsNotice(rb, fmt.Sprintf(client.t("Successfully grouped nick %s with your account"), nick))
308
-	} else if err == errAccountTooManyNicks {
309
-		nsNotice(rb, client.t("You have too many nicks reserved already (you can remove some with /NS DROP)"))
310
-	} else if err == errNicknameReserved {
311
-		nsNotice(rb, client.t("That nickname is already reserved by someone else"))
449
+	err = server.accounts.Unregister(cfname)
450
+	if err == errAccountDoesNotExist {
451
+		nsNotice(rb, client.t(err.Error()))
452
+	} else if err != nil {
453
+		nsNotice(rb, client.t("Error while unregistering account"))
312 454
 	} else {
313
-		nsNotice(rb, client.t("Error reserving nickname"))
455
+		nsNotice(rb, fmt.Sprintf(client.t("Successfully unregistered account %s"), cfname))
314 456
 	}
315 457
 }
316 458
 
317
-func (server *Server) nickservInfoHandler(client *Client, nick string, rb *ResponseBuffer) {
318
-	if nick == "" {
319
-		nick = client.Nick()
320
-	}
459
+func nsVerifyHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
460
+	username, code := utils.ExtractParam(params)
321 461
 
322
-	accountName := nick
323
-	if server.AccountConfig().NickReservation.Enabled {
324
-		accountName = server.accounts.NickToAccount(nick)
325
-		if accountName == "" {
326
-			nsNotice(rb, client.t("That nickname is not registered"))
327
-			return
328
-		}
329
-	}
330
-
331
-	account, err := server.accounts.LoadAccount(accountName)
332
-	if err != nil || !account.Verified {
333
-		nsNotice(rb, client.t("Account does not exist"))
334
-	}
462
+	err := server.accounts.Verify(client, username, code)
335 463
 
336
-	nsNotice(rb, fmt.Sprintf(client.t("Account: %s"), account.Name))
337
-	registeredAt := account.RegisteredAt.Format("Jan 02, 2006 15:04:05Z")
338
-	nsNotice(rb, fmt.Sprintf(client.t("Registered at: %s"), registeredAt))
339
-	// TODO nicer formatting for this
340
-	for _, nick := range account.AdditionalNicks {
341
-		nsNotice(rb, fmt.Sprintf(client.t("Additional grouped nick: %s"), nick))
464
+	var errorMessage string
465
+	if err == errAccountVerificationInvalidCode || err == errAccountAlreadyVerified {
466
+		errorMessage = err.Error()
467
+	} else if err != nil {
468
+		errorMessage = errAccountVerificationFailed.Error()
342 469
 	}
343
-}
344 470
 
345
-func (server *Server) nickservDropHandler(client *Client, nick string, sadrop bool, rb *ResponseBuffer) {
346
-	if sadrop {
347
-		if !client.HasRoleCapabs("unregister") {
348
-			nsNotice(rb, client.t("Insufficient oper privs"))
349
-			return
350
-		}
471
+	if errorMessage != "" {
472
+		nsNotice(rb, client.t(errorMessage))
473
+		return
351 474
 	}
352 475
 
353
-	err := server.accounts.SetNickReserved(client, nick, sadrop, false)
354
-	if err == nil {
355
-		nsNotice(rb, fmt.Sprintf(client.t("Successfully ungrouped nick %s with your account"), nick))
356
-	} else if err == errAccountNotLoggedIn {
357
-		nsNotice(rb, fmt.Sprintf(client.t("You're not logged into an account")))
358
-	} else if err == errAccountCantDropPrimaryNick {
359
-		nsNotice(rb, fmt.Sprintf(client.t("You can't ungroup your primary nickname (try unregistering your account instead)")))
360
-	} else if err == errNicknameReserved {
361
-		nsNotice(rb, fmt.Sprintf(client.t("That nickname is already reserved by someone else")))
362
-	} else {
363
-		nsNotice(rb, client.t("Error ungrouping nick"))
364
-	}
476
+	sendSuccessfulRegResponse(client, rb, true)
365 477
 }

+ 8
- 0
irc/server.go Datei anzeigen

@@ -175,6 +175,14 @@ func NewServer(config *Config, logger *logger.Manager) (*Server, error) {
175 175
 		return nil, err
176 176
 	}
177 177
 
178
+	// confirm help entries for NickServ exist.
179
+	// this forces people to write help entries for every single NS command.
180
+	for commandName, commandInfo := range nickservCommands {
181
+		if commandInfo.help == "" || commandInfo.helpShort == "" {
182
+			return nil, fmt.Errorf("Help entry does not exist for NickServ command %s", commandName)
183
+		}
184
+	}
185
+
178 186
 	// Attempt to clean up when receiving these signals.
179 187
 	signal.Notify(server.signals, ServerExitSignals...)
180 188
 	signal.Notify(server.rehashSignal, syscall.SIGHUP)

+ 13
- 0
irc/utils/args.go Datei anzeigen

@@ -3,6 +3,19 @@
3 3
 
4 4
 package utils
5 5
 
6
+import "strings"
7
+
8
+// ExtractParam extracts a parameter from the given string, returning the param and the rest of the string.
9
+func ExtractParam(line string) (string, string) {
10
+	rawParams := strings.SplitN(strings.TrimSpace(line), " ", 2)
11
+	param0 := rawParams[0]
12
+	var param1 string
13
+	if 1 < len(rawParams) {
14
+		param1 = strings.TrimSpace(rawParams[1])
15
+	}
16
+	return param0, param1
17
+}
18
+
6 19
 // ArgsToStrings takes the arguments and splits them into a series of strings,
7 20
 // each argument separated by delim and each string bounded by maxLength.
8 21
 func ArgsToStrings(maxLength int, arguments []string, delim string) []string {

Laden…
Abbrechen
Speichern