mirror of
https://github.com/jeremyd/ergo.git
synced 2026-08-01 11:43:06 -07:00
fix #2424
Add a ChanServ setting to suppress storage of non-message events (JOIN/PART/QUIT can be especially spammy)
This commit is contained in:
+2
-1
@@ -7,7 +7,7 @@ We're pleased to be publishing the release candidate for v2.19.0 (the official r
|
||||
|
||||
This release includes changes to the config file format, one of which is not backwards-compatible (see below to determine whether you are affected). It includes no changes to the database file format.
|
||||
|
||||
Many thanks to [@andymandias](https://github.com/andymandias), [@emersion](https://github.com/emersion), [@englut](https://github.com/englut), [@Jokler](https://github.com/Jokler), [@jwheare](https://github.com/jwheare), [@KlaasT](https://github.com/KlaasT), [@SAY-5](https://github.com/SAY-5), [@skizzerz](https://github.com/skizzerz), [@ValwareIRC](https://github.com/ValwareIRC), and [@whitequark](https://github.com/whitequark) for helpful discussions, contributing patches, reporting issues, and helping test.
|
||||
Many thanks to [@andymandias](https://github.com/andymandias), [@emersion](https://github.com/emersion), [@englut](https://github.com/englut), [@Jokler](https://github.com/Jokler), [@jwheare](https://github.com/jwheare), [@KlaasT](https://github.com/KlaasT), [@luxaritas](https://github.com/luxaritas), [@SAY-5](https://github.com/SAY-5), [@skizzerz](https://github.com/skizzerz), [@ValwareIRC](https://github.com/ValwareIRC), and [@whitequark](https://github.com/whitequark) for helpful discussions, contributing patches, reporting issues, and helping test.
|
||||
|
||||
### Compatibility breaks
|
||||
* The `extjwt` configuration block now takes `algorithm` (`hmac`, `rsa`, or `eddsa`) and either `key` or `key-file` to configure the signing key (see `default.yaml` for examples). If you are using `extjwt`, the suggested upgrade path is to add the new keys before upgrading (duplicating the legacy keys `secret` and/or `rsa-private-key-file`), upgrade Ergo, then once the new version is confirmed stable, delete the legacy keys. (#2385)
|
||||
@@ -29,6 +29,7 @@ Many thanks to [@andymandias](https://github.com/andymandias), [@emersion](https
|
||||
* Added support for [draft/whoami](https://github.com/ircv3/ircv3-specifications/pull/603), a proposed IRCv3 extension allowing clients to track their message source ("NUH") (#2417)
|
||||
* HTTP cookies are harvested from the initial websocket handshake; if a websocket client sends `SASL EXTERNAL`, they can be passed to an `auth-script` for validation (future versions of Ergo may implement some form of native HTTP cookie authentication) (#2185, thanks [@emersion](https://github.com/emersion)!)
|
||||
* Added new API endpoints: `/v1/whois` (analogue of the `WHOIS` command to get information about an active nickname), `/v1/ns/saget` (retrieves user account settings), and `/v1/ns/saset` (modifies user account settings) (#2387, #2421, thanks [@KlaasT](https://github.com/KlaasT)!)
|
||||
* Added a new ChanServ setting `store-events` to optionally suppress history storage of events like `JOIN` and `QUIT` (#2424, thanks [@luxaritas](https://github.com/luxaritas)!)
|
||||
|
||||
### Fixed
|
||||
* Fixed a race condition where an always-on client's channel join might not be persisted (#2398)
|
||||
|
||||
+22
-5
@@ -28,6 +28,7 @@ import (
|
||||
type ChannelSettings struct {
|
||||
History HistoryStatus
|
||||
QueryCutoff HistoryCutoff
|
||||
StoreEvents StoreEvents
|
||||
}
|
||||
|
||||
// Channel represents a channel that clients can join.
|
||||
@@ -101,7 +102,7 @@ func (channel *Channel) initializeLists() {
|
||||
}
|
||||
|
||||
func (channel *Channel) resizeHistory(config *Config) {
|
||||
status, _, _ := channel.historyStatus(config)
|
||||
status, _, _, _ := channel.historyStatus(config)
|
||||
if status == HistoryEphemeral {
|
||||
channel.history.Resize(config.History.ChannelLength, time.Duration(config.History.AutoresizeWindow))
|
||||
} else {
|
||||
@@ -674,9 +675,9 @@ func (channel *Channel) IsEmpty() bool {
|
||||
|
||||
// figure out where history is being stored: persistent, ephemeral, or neither
|
||||
// target is only needed if we're doing persistent history
|
||||
func (channel *Channel) historyStatus(config *Config) (status HistoryStatus, target string, restrictions HistoryCutoff) {
|
||||
func (channel *Channel) historyStatus(config *Config) (status HistoryStatus, storeEvents StoreEvents, target string, restrictions HistoryCutoff) {
|
||||
if !config.History.Enabled {
|
||||
return HistoryDisabled, "", HistoryCutoffNone
|
||||
return HistoryDisabled, StoreEventsAll, "", HistoryCutoffNone
|
||||
}
|
||||
|
||||
channel.stateMutex.RLock()
|
||||
@@ -690,7 +691,7 @@ func (channel *Channel) historyStatus(config *Config) (status HistoryStatus, tar
|
||||
restrictions = config.History.Restrictions.queryCutoff
|
||||
}
|
||||
|
||||
return channelHistoryStatus(config, registered, settings.History), target, restrictions
|
||||
return channelHistoryStatus(config, registered, settings.History), settings.StoreEvents, target, restrictions
|
||||
}
|
||||
|
||||
func (channel *Channel) joinTimeCutoff(client *Client) (present bool, cutoff time.Time) {
|
||||
@@ -726,12 +727,28 @@ func channelHistoryStatus(config *Config, registered bool, storedStatus HistoryS
|
||||
}
|
||||
}
|
||||
|
||||
func channelEventIsStorable(itemType history.ItemType, storeEvents StoreEvents) bool {
|
||||
switch storeEvents {
|
||||
case StoreEventsAll:
|
||||
return true
|
||||
case StoreEventsNoJoins:
|
||||
return !(itemType == history.Join || itemType == history.Part || itemType == history.Quit)
|
||||
case StoreEventsNone:
|
||||
return itemType == history.Privmsg || itemType == history.Notice || itemType == history.Tagmsg
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func (channel *Channel) AddHistoryItem(item history.Item, account string) (err error) {
|
||||
if !itemIsStorable(&item, channel.server.Config()) {
|
||||
return
|
||||
}
|
||||
|
||||
status, target, _ := channel.historyStatus(channel.server.Config())
|
||||
status, storeEvents, target, _ := channel.historyStatus(channel.server.Config())
|
||||
if !channelEventIsStorable(item.Type, storeEvents) {
|
||||
return
|
||||
}
|
||||
if status == HistoryPersistent {
|
||||
err = channel.server.historyDB.AddChannelItem(target, item, account)
|
||||
if err != nil {
|
||||
|
||||
@@ -183,6 +183,12 @@ by unprivileged users. Your options are:
|
||||
channel; note that history will be effectively
|
||||
unavailable to clients that are not always-on]
|
||||
4. 'default' [use the server default]`,
|
||||
`$bSTORE-EVENTS$b
|
||||
'store-events' lets you control whether non-message events (like JOIN or
|
||||
QUIT) are stored in your channel's history. Your options are:
|
||||
1. 'all' [store all events, the default]
|
||||
2. 'no-joins' [don't store JOIN/PART/QUIT]
|
||||
3. 'none' [don't store any events, including TOPIC/KICK]`,
|
||||
},
|
||||
enabled: chanregEnabled,
|
||||
minParams: 3,
|
||||
@@ -813,6 +819,8 @@ func displayChannelSetting(service *ircService, settingName string, settings Cha
|
||||
}
|
||||
service.Notice(rb, fmt.Sprintf(client.t("The stored channel history query cutoff setting is: %s"), historyCutoffToString(settings.QueryCutoff)))
|
||||
service.Notice(rb, fmt.Sprintf(client.t("Given current server settings, the channel history query cutoff setting is: %s"), historyCutoffToString(effectiveValue)))
|
||||
case "store-events":
|
||||
service.Notice(rb, fmt.Sprintf(client.t("The stored channel setting for store-events is: %s"), storeEventsToString(settings.StoreEvents)))
|
||||
default:
|
||||
service.Notice(rb, client.t("Invalid params"))
|
||||
}
|
||||
@@ -863,6 +871,13 @@ func csSetHandler(service *ircService, server *Server, client *Client, command s
|
||||
break
|
||||
}
|
||||
channel.SetSettings(settings)
|
||||
case "store-events":
|
||||
settings.StoreEvents, err = storeEventsFromString(value)
|
||||
if err != nil {
|
||||
err = errInvalidParams
|
||||
break
|
||||
}
|
||||
channel.SetSettings(settings)
|
||||
}
|
||||
|
||||
switch err {
|
||||
|
||||
@@ -242,6 +242,40 @@ func historyStatusToString(status HistoryStatus) string {
|
||||
}
|
||||
}
|
||||
|
||||
type StoreEvents uint
|
||||
|
||||
const (
|
||||
StoreEventsAll StoreEvents = iota // default, store all events
|
||||
StoreEventsNoJoins // don't store JOIN/QUIT/PART, do store TOPIC and NICK
|
||||
StoreEventsNone // don't store any events, only HISTORY/PRIVMSG/TAGMSG
|
||||
)
|
||||
|
||||
func storeEventsFromString(str string) (status StoreEvents, err error) {
|
||||
switch strings.ToLower(str) {
|
||||
case "all", "default", "on", "true", "yes":
|
||||
return StoreEventsAll, nil
|
||||
case "no-joins":
|
||||
return StoreEventsNoJoins, nil
|
||||
case "none":
|
||||
return StoreEventsNone, nil
|
||||
default:
|
||||
return StoreEventsAll, errInvalidParams
|
||||
}
|
||||
}
|
||||
|
||||
func storeEventsToString(storeEvents StoreEvents) string {
|
||||
switch storeEvents {
|
||||
case StoreEventsAll:
|
||||
return "all"
|
||||
case StoreEventsNoJoins:
|
||||
return "no-joins"
|
||||
case StoreEventsNone:
|
||||
return "none"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// XXX you must have already checked History.Enabled before calling this
|
||||
func historyEnabled(serverSetting PersistentStatus, localSetting HistoryStatus) (result HistoryStatus) {
|
||||
switch serverSetting {
|
||||
|
||||
+1
-1
@@ -3721,7 +3721,7 @@ func renameHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respo
|
||||
}
|
||||
|
||||
config := server.Config()
|
||||
status, _, _ := channel.historyStatus(config)
|
||||
status, _, _, _ := channel.historyStatus(config)
|
||||
if status == HistoryPersistent {
|
||||
rb.Add(nil, server.name, "FAIL", "RENAME", "CANNOT_RENAME", oldName, utils.SafeErrorParam(newName), client.t("Channels with persistent history cannot be renamed"))
|
||||
return false
|
||||
|
||||
+2
-2
@@ -1177,7 +1177,7 @@ func (server *Server) GetHistorySequence(providedChannel *Channel, client *Clien
|
||||
err = errInsufficientPrivs
|
||||
return
|
||||
}
|
||||
status, target, restriction = channel.historyStatus(config)
|
||||
status, _, target, restriction = channel.historyStatus(config)
|
||||
switch status {
|
||||
case HistoryEphemeral:
|
||||
hist = &channel.history
|
||||
@@ -1279,7 +1279,7 @@ func (server *Server) DeleteMessage(target, msgid, accountName string) (err erro
|
||||
if target[0] == '#' {
|
||||
channel := server.channels.Get(target)
|
||||
if channel != nil {
|
||||
if status, _, _ := channel.historyStatus(config); status == HistoryEphemeral {
|
||||
if status, _, _, _ := channel.historyStatus(config); status == HistoryEphemeral {
|
||||
hist = &channel.history
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user