Merge pull request #1463 from slingamn/issue1294_purge.1

Enhancements to CS PURGE
This commit is contained in:
Shivaram Lingamneni 2020-12-16 02:24:45 -05:00 committed by GitHub
commit 91cc2156f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 76 additions and 19 deletions

View File

@ -4,6 +4,7 @@
package irc
import (
"sort"
"sync"
"github.com/oragono/oragono/irc/utils"
@ -405,3 +406,14 @@ func (cm *ChannelManager) Unpurge(chname string) (err error) {
}
return nil
}
func (cm *ChannelManager) ListPurged() (result []string) {
cm.RLock()
result = make([]string, 0, len(cm.purgedChannels))
for c := range cm.purgedChannels {
result = append(result, c)
}
cm.RUnlock()
sort.Strings(result)
return
}

View File

@ -114,28 +114,19 @@ To cancel a pending transfer, transfer the channel to yourself.`,
},
"purge": {
handler: csPurgeHandler,
help: `Syntax: $bPURGE #channel [reason]$b
help: `Syntax: $bPURGE <ADD | DEL | LIST> #channel [code] [reason]$b
PURGE blacklists a channel from the server, making it impossible to join
PURGE ADD blacklists a channel from the server, making it impossible to join
or otherwise interact with the channel. If the channel currently has members,
they will be kicked from it. PURGE may also be applied preemptively to
channels that do not currently have members.`,
channels that do not currently have members. A purge can be undone with
PURGE DEL. To list purged channels, use PURGE LIST.`,
helpShort: `$bPURGE$b blacklists a channel from the server.`,
capabs: []string{"chanreg"},
minParams: 1,
maxParams: 2,
maxParams: 3,
unsplitFinalParam: true,
},
"unpurge": {
handler: csUnpurgeHandler,
help: `Syntax: $bUNPURGE #channel$b
UNPURGE removes any blacklisting of a channel that was previously
set using PURGE.`,
helpShort: `$bUNPURGE$b undoes a previous PURGE command.`,
capabs: []string{"chanreg"},
minParams: 1,
},
"list": {
handler: csListHandler,
help: `Syntax: $bLIST [regex]$b
@ -587,19 +578,53 @@ func csPurgeHandler(service *ircService, server *Server, client *Client, command
return // should be impossible because you need oper capabs for this
}
switch strings.ToLower(params[0]) {
case "add":
csPurgeAddHandler(service, client, params[1:], oper.Name, rb)
case "del", "remove":
csPurgeDelHandler(service, client, params[1:], oper.Name, rb)
case "list":
csPurgeListHandler(service, client, rb)
default:
service.Notice(rb, client.t("Invalid parameters"))
}
}
func csPurgeAddHandler(service *ircService, client *Client, params []string, operName string, rb *ResponseBuffer) {
if len(params) == 0 {
service.Notice(rb, client.t("Invalid parameters"))
return
}
chname := params[0]
params = params[1:]
channel := client.server.channels.Get(chname) // possibly nil
var ctime time.Time
if channel != nil {
chname = channel.Name()
ctime = channel.Ctime()
}
code := utils.ConfirmationCode(chname, ctime)
if len(params) == 0 || params[0] != code {
service.Notice(rb, ircfmt.Unescape(client.t("$bWarning: you are about to empty this channel and remove it from the server.$b")))
service.Notice(rb, fmt.Sprintf(client.t("To confirm, run this command: %s"), fmt.Sprintf("/CS PURGE ADD %s %s", chname, code)))
return
}
params = params[1:]
var reason string
if 1 < len(params) {
reason = params[1]
}
purgeRecord := ChannelPurgeRecord{
Oper: oper.Name,
Oper: operName,
PurgedAt: time.Now().UTC(),
Reason: reason,
}
switch server.channels.Purge(chname, purgeRecord) {
switch client.server.channels.Purge(chname, purgeRecord) {
case nil:
channel := server.channels.Get(chname)
if channel != nil { // channel need not exist to be purged
for _, target := range channel.Members() {
channel.Kick(client, target, "Cleared by ChanServ", rb, true)
@ -613,9 +638,14 @@ func csPurgeHandler(service *ircService, server *Server, client *Client, command
}
}
func csUnpurgeHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
func csPurgeDelHandler(service *ircService, client *Client, params []string, operName string, rb *ResponseBuffer) {
if len(params) == 0 {
service.Notice(rb, client.t("Invalid parameters"))
return
}
chname := params[0]
switch server.channels.Unpurge(chname) {
switch client.server.channels.Unpurge(chname) {
case nil:
service.Notice(rb, fmt.Sprintf(client.t("Successfully unpurged channel %s from the server"), chname))
case errNoSuchChannel:
@ -625,6 +655,14 @@ func csUnpurgeHandler(service *ircService, server *Server, client *Client, comma
}
}
func csPurgeListHandler(service *ircService, client *Client, rb *ResponseBuffer) {
l := client.server.channels.ListPurged()
service.Notice(rb, fmt.Sprintf(client.t("There are %d purged channel(s)."), len(l)))
for i, c := range l {
service.Notice(rb, fmt.Sprintf("%d: %s", i+1, c))
}
}
func csListHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
if !client.HasRoleCapabs("chanreg") {
service.Notice(rb, client.t("Insufficient privileges"))

View File

@ -523,3 +523,10 @@ func (channel *Channel) setForward(forward string) {
channel.forward = forward
channel.stateMutex.Unlock()
}
func (channel *Channel) Ctime() (ctime time.Time) {
channel.stateMutex.RLock()
ctime = channel.createdTime
channel.stateMutex.RUnlock()
return
}