refactor permission checks

This commit is contained in:
Shivaram Lingamneni 2025-06-15 12:19:12 -04:00
parent 5da2ddbc07
commit e6aaaf1b88
4 changed files with 27 additions and 39 deletions

View file

@ -724,6 +724,7 @@ oper-classes:
- "history" # modify or delete history messages - "history" # modify or delete history messages
- "defcon" # use the DEFCON command (restrict server capabilities) - "defcon" # use the DEFCON command (restrict server capabilities)
- "massmessage" # message all users on the server - "massmessage" # message all users on the server
- "metadata" # modify arbitrary metadata on channels and users
# ircd operators # ircd operators
opers: opers:

View file

@ -3155,7 +3155,7 @@ func metadataHandler(server *Server, client *Client, msg ircmsg.Message, rb *Res
return return
} }
if !metadataCanIEditThisKey(client, target, key) { if !metadataCanIEditThisKey(client, targetObj, key) {
noKeyPerms(key) noKeyPerms(key)
return return
} }
@ -3192,6 +3192,11 @@ func metadataHandler(server *Server, client *Client, msg ircmsg.Message, rb *Res
} }
case "get": case "get":
if !metadataCanISeeThisTarget(client, targetObj) {
noKeyPerms("*")
return
}
batchId := rb.StartNestedBatch("metadata") batchId := rb.StartNestedBatch("metadata")
defer rb.EndNestedBatch(batchId) defer rb.EndNestedBatch(batchId)
@ -3224,7 +3229,7 @@ func metadataHandler(server *Server, client *Client, msg ircmsg.Message, rb *Res
} }
case "clear": case "clear":
if !metadataCanIEditThisTarget(client, target) { if !metadataCanIEditThisTarget(client, targetObj) {
invalidTarget() invalidTarget()
return return
} }

View file

@ -117,48 +117,29 @@ func metadataKeyIsEvil(key string) bool {
metadataEvilCharsRegexp.MatchString(key) // key can't contain the stuff it can't contain metadataEvilCharsRegexp.MatchString(key) // key can't contain the stuff it can't contain
} }
func metadataCanIEditThisKey(client *Client, target string, _ string) bool { func metadataCanIEditThisKey(client *Client, targetObj MetadataHaver, key string) bool {
if !metadataCanIEditThisTarget(client, target) { // you can't edit keys on targets you can't edit. // no key-specific logic as yet
return false return metadataCanIEditThisTarget(client, targetObj)
}
// todo: we don't actually do anything regarding visibility yet so there's not much to do here
return true
} }
func metadataCanIEditThisTarget(client *Client, target string) bool { func metadataCanIEditThisTarget(client *Client, targetObj MetadataHaver) bool {
if !metadataCanISeeThisTarget(client, target) { // you can't edit what you can't see. a wise man told me this once switch target := targetObj.(type) {
return false case *Client:
return client == target || client.HasRoleCapabs("metadata")
case *Channel:
return target.ClientIsAtLeast(client, modes.Operator) || client.HasRoleCapabs("metadata")
default:
return false // impossible
} }
if client.HasRoleCapabs("sajoin") { // sajoin opers can do whatever they want
return true
}
if target == client.Nick() { // your right to swing your fist ends where my nose begins
return true
}
// if you're a channel operator, knock yourself out
channel := client.server.channels.Get(target)
if channel != nil && channel.ClientIsAtLeast(client, modes.Operator) {
return true
}
return false
} }
func metadataCanISeeThisTarget(client *Client, target string) bool { func metadataCanISeeThisTarget(client *Client, targetObj MetadataHaver) bool {
if client.HasRoleCapabs("sajoin") { // sajoin opers can do whatever they want switch target := targetObj.(type) {
case *Client:
return true return true
case *Channel:
return target.hasClient(client) || client.HasRoleCapabs("metadata")
default:
return false // impossible
} }
// check if the user is in the channel
channel := client.server.channels.Get(target)
if channel != nil && !channel.hasClient(client) {
return false
}
return true
} }

View file

@ -695,6 +695,7 @@ oper-classes:
- "history" # modify or delete history messages - "history" # modify or delete history messages
- "defcon" # use the DEFCON command (restrict server capabilities) - "defcon" # use the DEFCON command (restrict server capabilities)
- "massmessage" # message all users on the server - "massmessage" # message all users on the server
- "metadata" # modify arbitrary metadata on channels and users
# ircd operators # ircd operators
opers: opers: