enforce max-keys

This commit is contained in:
leah 2025-06-13 19:15:25 +01:00
parent 2275bed000
commit db4b23bb48
5 changed files with 33 additions and 2 deletions

View file

@ -1094,7 +1094,7 @@ metadata:
# how many keys can a client subscribe to? # how many keys can a client subscribe to?
# set to 0 to disable subscriptions or -1 to allow unlimited subscriptions. # set to 0 to disable subscriptions or -1 to allow unlimited subscriptions.
max-subs: 100 max-subs: 100
# how many keys can a given target store? set to -1 to allow unlimited keys. # how many keys can a user store about themselves? set to -1 to allow unlimited keys.
max-keys: 1000 max-keys: 1000
# experimental support for mobile push notifications # experimental support for mobile push notifications

View file

@ -728,7 +728,7 @@ type Config struct {
Enabled bool Enabled bool
MaxSubs int `yaml:"max-subs"` MaxSubs int `yaml:"max-subs"`
MaxKeys int `yaml:"max-keys"` MaxKeys int `yaml:"max-keys"`
MaxValueBytes int `yaml:"max-value-length"` MaxValueBytes int `yaml:"max-value-length"` // todo: currently unenforced!!
} }
WebPush struct { WebPush struct {

View file

@ -935,6 +935,17 @@ func (channel *Channel) ClearMetadata() MetadataStore {
return oldMap return oldMap
} }
func (channel *Channel) CountMetadata() int {
channel.stateMutex.RLock()
defer channel.stateMutex.RUnlock()
if channel.metadata == nil {
return 0
}
return len(channel.metadata)
}
func (client *Client) GetMetadata(key string) (string, error) { func (client *Client) GetMetadata(key string) (string, error) {
client.stateMutex.RLock() client.stateMutex.RLock()
defer client.stateMutex.RUnlock() defer client.stateMutex.RUnlock()
@ -982,3 +993,14 @@ func (client *Client) ClearMetadata() MetadataStore {
return oldMap return oldMap
} }
func (client *Client) CountMetadata() int {
client.stateMutex.RLock()
defer client.stateMutex.RUnlock()
if client.metadata == nil {
return 0
}
return len(client.metadata)
}

View file

@ -3167,6 +3167,14 @@ func metadataHandler(server *Server, client *Client, msg ircmsg.Message, rb *Res
return return
} }
maxKeys := server.Config().Metadata.MaxKeys
isSelf := targetClient != nil && client == targetClient
if isSelf && maxKeys > 0 && t.CountMetadata() >= maxKeys {
rb.Add(nil, server.name, "FAIL", "METADATA", "LIMIT_REACHED", client.nick, client.t("You have too many keys set on yourself"))
return
}
server.logger.Debug("metadata", "setting", key, value, "on", target) server.logger.Debug("metadata", "setting", key, value, "on", target)
t.SetMetadata(key, value) t.SetMetadata(key, value)

View file

@ -23,6 +23,7 @@ type MetadataHaver = interface {
DeleteMetadata(key string) DeleteMetadata(key string)
ListMetadata() MetadataStore ListMetadata() MetadataStore
ClearMetadata() MetadataStore ClearMetadata() MetadataStore
CountMetadata() int
} }
func notifySubscribers(server *Server, session *Session, target string, key string, value string) { func notifySubscribers(server *Server, session *Session, target string, key string, value string) {