aboutsummaryrefslogtreecommitdiff
path: root/hotline/server.go
diff options
context:
space:
mode:
authorJeff Halter <868228+jhalter@users.noreply.github.com>2026-03-14 14:43:24 -0700
committerJeff Halter <868228+jhalter@users.noreply.github.com>2026-03-14 14:43:24 -0700
commit2cf9f33ef42188dd35eaf4905cd2f05557aecca1 (patch)
treee2cb7db1ccd7a4defae39395b76b144d66aacf2c /hotline/server.go
parent0003a0912b04308fbbdfcb2801d0373e6d4de2f0 (diff)
Refactor ban management behind BanMgr interface
Extract ban logic into a BanMgr interface with two implementations: - BanFile: file-based YAML storage with support for IP, username, and nickname bans (backwards-compatible with legacy format) - RedisBanMgr: Redis-backed implementation with permanent and temporary ban support, using fail-safe deny-on-error behavior This replaces scattered Redis calls in API handlers, transaction handlers, and server connection logic with unified interface calls, removing the Redis dependency from the API server constructor and enabling ban functionality for both file-only and Redis deployments.
Diffstat (limited to 'hotline/server.go')
-rw-r--r--hotline/server.go40
1 files changed, 18 insertions, 22 deletions
diff --git a/hotline/server.go b/hotline/server.go
index d797c1e..545e84c 100644
--- a/hotline/server.go
+++ b/hotline/server.go
@@ -496,23 +496,17 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser
// Check if remoteAddr is present in the ban list, we do this after we have the login name
ipAddr, _, _ := net.SplitHostPort(remoteAddr)
- if s.Redis != nil {
- // Redis-based ban check
- bannedUser, _ := s.Redis.SIsMember(ctx, "mobius:banned:users", login).Result()
- bannedIP, _ := s.Redis.SIsMember(ctx, "mobius:banned:ips", ipAddr).Result()
- if bannedUser {
- s.Redis.SAdd(ctx, "mobius:banned:ips", ipAddr)
- sendBanMessage(rwc, "You are banned on this server")
- s.Logger.Debug("Disconnecting banned user", "login", login, "ip", ipAddr)
- return nil
- }
- if bannedIP {
- sendBanMessage(rwc, "You are banned on this server")
- s.Logger.Debug("Disconnecting banned IP", "ip", ipAddr)
- return nil
- }
- } else {
- // Fallback to in-memory ban list
+
+ // Check if user is banned
+ if s.BanList != nil && s.BanList.IsUsernameBanned(login) {
+ _ = s.BanList.Add(ipAddr, nil)
+ sendBanMessage(rwc, "You are banned on this server")
+ s.Logger.Debug("Disconnecting banned user", "login", login, "ip", ipAddr)
+ return nil
+ }
+
+ // Check if IP is banned
+ if s.BanList != nil {
if isBanned, banUntil := s.BanList.IsBanned(ipAddr); isBanned {
// permaban
if banUntil == nil {
@@ -531,16 +525,18 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser
c := s.NewClientConn(rwc, remoteAddr)
// Add the client to the list of connected clients
+
+ // TODO: refactor this into a connection manager interface, maybe?
if s.Redis != nil {
- s.Redis.SAdd(context.Background(), "mobius:online", login+"::"+ipAddr)
+ s.Redis.SAdd(context.Background(), RedisKeyOnline, login+"::"+ipAddr)
}
// Remove the client from the list of connected clients when they disconnect
defer func() {
if s.Redis != nil {
- s.Redis.SRem(context.Background(), "mobius:online", login+"::"+ipAddr)
+ s.Redis.SRem(context.Background(), RedisKeyOnline, login+"::"+ipAddr)
if len(c.UserName) != 0 {
- s.Redis.SRem(context.Background(), "mobius:online", login+":"+string(c.UserName)+":"+ipAddr)
+ s.Redis.SRem(context.Background(), RedisKeyOnline, login+":"+string(c.UserName)+":"+ipAddr)
}
}
c.Disconnect()
@@ -621,9 +617,9 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser
// Update the Redis set with the new information
if s.Redis != nil && len(c.UserName) != 0 {
// Remove old entry (login::ip)
- s.Redis.SRem(context.Background(), "mobius:online", login+"::"+ipAddr)
+ s.Redis.SRem(context.Background(), RedisKeyOnline, login+"::"+ipAddr)
// Add new entry with login, nickname, ip
- s.Redis.SAdd(context.Background(), "mobius:online", login+":"+string(c.UserName)+":"+ipAddr)
+ s.Redis.SAdd(context.Background(), RedisKeyOnline, login+":"+string(c.UserName)+":"+ipAddr)
}
// Notify other clients on the server that the new user has logged in. For 1.5+ clients we don't have this