Add option for scale-up allow/deny lists for servers (#397)
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/google/uuid"
|
||||
"os"
|
||||
)
|
||||
|
||||
type AllowDenyLists struct {
|
||||
Allowlist []PlayerInfo
|
||||
Denylist []PlayerInfo
|
||||
}
|
||||
|
||||
type AllowDenyConfig struct {
|
||||
Global AllowDenyLists
|
||||
Servers map[string]AllowDenyLists
|
||||
}
|
||||
|
||||
func ParseAllowDenyConfig(allowDenyListPath string) (*AllowDenyConfig, error) {
|
||||
allowDenyConfig := AllowDenyConfig{}
|
||||
data, err := os.ReadFile(allowDenyListPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = json.Unmarshal(data, &allowDenyConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &allowDenyConfig, nil
|
||||
}
|
||||
|
||||
func entryMatchesPlayer(entry *PlayerInfo, userInfo *PlayerInfo) bool {
|
||||
// User has added an "empty" entry
|
||||
// This should never match player info
|
||||
if entry.Name == "" && entry.Uuid == uuid.Nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if entry.Name != "" && entry.Uuid != uuid.Nil {
|
||||
return *entry == *userInfo
|
||||
}
|
||||
|
||||
if entry.Uuid != uuid.Nil {
|
||||
return entry.Uuid == userInfo.Uuid
|
||||
}
|
||||
|
||||
return entry.Name == userInfo.Name
|
||||
}
|
||||
|
||||
func (allowDenyConfig *AllowDenyConfig) ServerAllowsPlayer(serverAddress string, userInfo *PlayerInfo) bool {
|
||||
if allowDenyConfig == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
allowlist := allowDenyConfig.Global.Allowlist
|
||||
denylist := allowDenyConfig.Global.Denylist
|
||||
serverAllowDenyConfig, ok := allowDenyConfig.Servers[serverAddress]
|
||||
// Merges global allow/deny lists with server-specific allow/deny lists if provided
|
||||
if ok {
|
||||
allowlist = append(allowlist, serverAllowDenyConfig.Allowlist...)
|
||||
denylist = append(denylist, serverAllowDenyConfig.Denylist...)
|
||||
}
|
||||
|
||||
// If the allowlist is not empty, the player must have an entry or they will be denied
|
||||
// If the allowlist is empty, then the denylist is checked
|
||||
// If the allowlist is empty and the player was not in the denylist, then they are allowed
|
||||
for _, allowedPlayer := range allowlist {
|
||||
if entryMatchesPlayer(&allowedPlayer, userInfo) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if len(allowlist) > 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, deniedPlayer := range denylist {
|
||||
if entryMatchesPlayer(&deniedPlayer, userInfo) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user