ソースを参照

Merge pull request #274 from slingamn/chanunreg.1

add CHANSERV UNREGISTER
tags/v0.12.0
Daniel Oaks 6年前
コミット
f4a284675d
コミッターのメールアドレスに関連付けられたアカウントが存在しません
5個のファイルの変更132行の追加54行の削除
  1. 11
    0
      irc/channel.go
  2. 14
    0
      irc/channelreg.go
  3. 62
    5
      irc/chanserv.go
  4. 1
    1
      irc/getters.go
  5. 44
    48
      irc/server.go

+ 11
- 0
irc/channel.go ファイルの表示

@@ -157,6 +157,17 @@ func (channel *Channel) SetRegistered(founder string) error {
157 157
 	return nil
158 158
 }
159 159
 
160
+// SetUnregistered deletes the channel's registration information.
161
+func (channel *Channel) SetUnregistered() {
162
+	channel.stateMutex.Lock()
163
+	defer channel.stateMutex.Unlock()
164
+
165
+	channel.registeredFounder = ""
166
+	var zeroTime time.Time
167
+	channel.registeredTime = zeroTime
168
+	channel.accountToUMode = make(map[string]modes.Mode)
169
+}
170
+
160 171
 // IsRegistered returns whether the channel is registered.
161 172
 func (channel *Channel) IsRegistered() bool {
162 173
 	channel.stateMutex.RLock()

+ 14
- 0
irc/channelreg.go ファイルの表示

@@ -201,6 +201,20 @@ func (reg *ChannelRegistry) LoadChannel(nameCasefolded string) (info *Registered
201 201
 	return info
202 202
 }
203 203
 
204
+func (reg *ChannelRegistry) Delete(casefoldedName string, info RegisteredChannel) {
205
+	if !reg.server.ChannelRegistrationEnabled() {
206
+		return
207
+	}
208
+
209
+	reg.Lock()
210
+	defer reg.Unlock()
211
+
212
+	reg.server.store.Update(func(tx *buntdb.Tx) error {
213
+		reg.deleteChannel(tx, casefoldedName, info)
214
+		return nil
215
+	})
216
+}
217
+
204 218
 // Rename handles the persistence part of a channel rename: the channel is
205 219
 // persisted under its new name, and the old name is cleaned up if necessary.
206 220
 func (reg *ChannelRegistry) Rename(channel *Channel, casefoldedOldName string) {

+ 62
- 5
irc/chanserv.go ファイルの表示

@@ -4,8 +4,11 @@
4 4
 package irc
5 5
 
6 6
 import (
7
+	"bytes"
7 8
 	"fmt"
9
+	"hash/crc32"
8 10
 	"sort"
11
+	"strconv"
9 12
 	"strings"
10 13
 
11 14
 	"github.com/goshuirc/irc-go/ircfmt"
@@ -22,6 +25,10 @@ To see in-depth help for a specific ChanServ command, try:
22 25
 Here are the commands you can use:
23 26
 %s`
24 27
 
28
+func chanregEnabled(server *Server) bool {
29
+	return server.ChannelRegistrationEnabled()
30
+}
31
+
25 32
 var (
26 33
 	chanservCommands = map[string]*serviceCommand{
27 34
 		"op": {
@@ -32,6 +39,7 @@ OP makes the given nickname, or yourself, a channel admin. You can only use
32 39
 this command if you're the founder of the channel.`,
33 40
 			helpShort:    `$bOP$b makes the given user (or yourself) a channel admin.`,
34 41
 			authRequired: true,
42
+			enabled:      chanregEnabled,
35 43
 		},
36 44
 		"register": {
37 45
 			handler: csRegisterHandler,
@@ -42,6 +50,17 @@ given admin privs on it. Modes set on the channel and the topic will also be
42 50
 remembered.`,
43 51
 			helpShort:    `$bREGISTER$b lets you own a given channel.`,
44 52
 			authRequired: true,
53
+			enabled:      chanregEnabled,
54
+		},
55
+		"unregister": {
56
+			handler: csUnregisterHandler,
57
+			help: `Syntax: $bUNREGISTER #channel [code]$b
58
+
59
+UNREGISTER deletes a channel registration, allowing someone else to claim it.
60
+To prevent accidental unregistrations, a verification code is required;
61
+invoking the command without a code will display the necessary code.`,
62
+			helpShort: `$bUNREGISTER$b deletes a channel registration.`,
63
+			enabled:   chanregEnabled,
45 64
 		},
46 65
 		"amode": {
47 66
 			handler: csAmodeHandler,
@@ -53,6 +72,7 @@ account the +o operator mode every time they join #channel. To list current
53 72
 accounts and modes, use $bAMODE #channel$b. Note that users are always
54 73
 referenced by their registered account names, not their nicknames.`,
55 74
 			helpShort: `$bAMODE$b modifies persistent mode settings for channel members.`,
75
+			enabled:   chanregEnabled,
56 76
 		},
57 77
 	}
58 78
 )
@@ -197,11 +217,6 @@ func csOpHandler(server *Server, client *Client, command, params string, rb *Res
197 217
 }
198 218
 
199 219
 func csRegisterHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
200
-	if !server.channelRegistrationEnabled {
201
-		csNotice(rb, client.t("Channel registration is not enabled"))
202
-		return
203
-	}
204
-
205 220
 	channelName := strings.TrimSpace(params)
206 221
 	if channelName == "" {
207 222
 		csNotice(rb, ircfmt.Unescape(client.t("Syntax: $bREGISTER #channel$b")))
@@ -246,3 +261,45 @@ func csRegisterHandler(server *Server, client *Client, command, params string, r
246 261
 		}
247 262
 	}
248 263
 }
264
+
265
+func csUnregisterHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
266
+	channelName, verificationCode := utils.ExtractParam(params)
267
+	channelKey, err := CasefoldChannel(channelName)
268
+	if channelKey == "" || err != nil {
269
+		csNotice(rb, client.t("Channel name is not valid"))
270
+		return
271
+	}
272
+
273
+	channel := server.channels.Get(channelKey)
274
+	if channel == nil {
275
+		csNotice(rb, client.t("No such channel"))
276
+		return
277
+	}
278
+
279
+	hasPrivs := client.HasRoleCapabs("chanreg")
280
+	if !hasPrivs {
281
+		founder := channel.Founder()
282
+		hasPrivs = founder != "" && founder == client.Account()
283
+	}
284
+	if !hasPrivs {
285
+		csNotice(rb, client.t("Insufficient privileges"))
286
+		return
287
+	}
288
+
289
+	info := channel.ExportRegistration(0)
290
+	// verification code is the crc32 of the name, plus the registration time
291
+	var codeInput bytes.Buffer
292
+	codeInput.WriteString(info.Name)
293
+	codeInput.WriteString(strconv.FormatInt(info.RegisteredAt.Unix(), 16))
294
+	expectedCode := int(crc32.ChecksumIEEE(codeInput.Bytes()))
295
+	receivedCode, err := strconv.Atoi(verificationCode)
296
+	if err != nil || expectedCode != receivedCode {
297
+		csNotice(rb, client.t("$bWarning:$b Unregistering this channel will remove all stored channel attributes."))
298
+		csNotice(rb, fmt.Sprintf(client.t("To confirm channel unregistration, type: /CS UNREGISTER %s %d"), channelKey, expectedCode))
299
+		return
300
+	}
301
+
302
+	channel.SetUnregistered()
303
+	go server.channelRegistry.Delete(channelKey, info)
304
+	csNotice(rb, fmt.Sprintf(client.t("Channel %s is now unregistered"), channelKey))
305
+}

+ 1
- 1
irc/getters.go ファイルの表示

@@ -62,7 +62,7 @@ func (server *Server) DefaultChannelModes() modes.Modes {
62 62
 func (server *Server) ChannelRegistrationEnabled() bool {
63 63
 	server.configurableStateMutex.RLock()
64 64
 	defer server.configurableStateMutex.RUnlock()
65
-	return server.channelRegistrationEnabled
65
+	return server.config.Channels.Registration.Enabled
66 66
 }
67 67
 
68 68
 func (server *Server) AccountConfig() *AccountConfig {

+ 44
- 48
irc/server.go ファイルの表示

@@ -87,51 +87,50 @@ type ListenerWrapper struct {
87 87
 
88 88
 // Server is the main Oragono server.
89 89
 type Server struct {
90
-	accounts                   *AccountManager
91
-	batches                    *BatchManager
92
-	channelRegistrationEnabled bool
93
-	channels                   *ChannelManager
94
-	channelRegistry            *ChannelRegistry
95
-	checkIdent                 bool
96
-	clients                    *ClientManager
97
-	config                     *Config
98
-	configFilename             string
99
-	configurableStateMutex     sync.RWMutex // tier 1; generic protection for server state modified by rehash()
100
-	connectionLimiter          *connection_limits.Limiter
101
-	connectionThrottler        *connection_limits.Throttler
102
-	ctime                      time.Time
103
-	defaultChannelModes        modes.Modes
104
-	dlines                     *DLineManager
105
-	loggingRawIO               bool
106
-	isupport                   *isupport.List
107
-	klines                     *KLineManager
108
-	languages                  *languages.Manager
109
-	limits                     Limits
110
-	listeners                  map[string]*ListenerWrapper
111
-	logger                     *logger.Manager
112
-	maxSendQBytes              uint32
113
-	monitorManager             *MonitorManager
114
-	motdLines                  []string
115
-	name                       string
116
-	nameCasefolded             string
117
-	networkName                string
118
-	operators                  map[string]*Oper
119
-	operclasses                map[string]*OperClass
120
-	password                   []byte
121
-	passwords                  *passwd.SaltedManager
122
-	recoverFromErrors          bool
123
-	rehashMutex                sync.Mutex // tier 4
124
-	rehashSignal               chan os.Signal
125
-	pprofServer                *http.Server
126
-	proxyAllowedFrom           []string
127
-	signals                    chan os.Signal
128
-	snomasks                   *SnoManager
129
-	store                      *buntdb.DB
130
-	stsEnabled                 bool
131
-	webirc                     []webircConfig
132
-	whoWas                     *WhoWasList
133
-	stats                      *Stats
134
-	semaphores                 *ServerSemaphores
90
+	accounts               *AccountManager
91
+	batches                *BatchManager
92
+	channels               *ChannelManager
93
+	channelRegistry        *ChannelRegistry
94
+	checkIdent             bool
95
+	clients                *ClientManager
96
+	config                 *Config
97
+	configFilename         string
98
+	configurableStateMutex sync.RWMutex // tier 1; generic protection for server state modified by rehash()
99
+	connectionLimiter      *connection_limits.Limiter
100
+	connectionThrottler    *connection_limits.Throttler
101
+	ctime                  time.Time
102
+	defaultChannelModes    modes.Modes
103
+	dlines                 *DLineManager
104
+	loggingRawIO           bool
105
+	isupport               *isupport.List
106
+	klines                 *KLineManager
107
+	languages              *languages.Manager
108
+	limits                 Limits
109
+	listeners              map[string]*ListenerWrapper
110
+	logger                 *logger.Manager
111
+	maxSendQBytes          uint32
112
+	monitorManager         *MonitorManager
113
+	motdLines              []string
114
+	name                   string
115
+	nameCasefolded         string
116
+	networkName            string
117
+	operators              map[string]*Oper
118
+	operclasses            map[string]*OperClass
119
+	password               []byte
120
+	passwords              *passwd.SaltedManager
121
+	recoverFromErrors      bool
122
+	rehashMutex            sync.Mutex // tier 4
123
+	rehashSignal           chan os.Signal
124
+	pprofServer            *http.Server
125
+	proxyAllowedFrom       []string
126
+	signals                chan os.Signal
127
+	snomasks               *SnoManager
128
+	store                  *buntdb.DB
129
+	stsEnabled             bool
130
+	webirc                 []webircConfig
131
+	whoWas                 *WhoWasList
132
+	stats                  *Stats
133
+	semaphores             *ServerSemaphores
135 134
 }
136 135
 
137 136
 var (
@@ -955,9 +954,6 @@ func (server *Server) applyConfig(config *Config, initial bool) error {
955 954
 	server.operators = opers
956 955
 	server.checkIdent = config.Server.CheckIdent
957 956
 
958
-	// registration
959
-	server.channelRegistrationEnabled = config.Channels.Registration.Enabled
960
-
961 957
 	server.defaultChannelModes = ParseDefaultChannelModes(config)
962 958
 	server.configurableStateMutex.Unlock()
963 959
 

読み込み中…
キャンセル
保存