legacy only - implement ban.

This commit is contained in:
Miroslav Šedivý 2024-09-07 23:18:21 +02:00
parent daf8f79eb5
commit bba8fce895
3 changed files with 87 additions and 14 deletions

View file

@ -5,6 +5,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"net"
"net/http" "net/http"
"net/url" "net/url"
@ -41,6 +42,8 @@ var (
type LegacyHandler struct { type LegacyHandler struct {
logger zerolog.Logger logger zerolog.Logger
serverAddr string serverAddr string
bannedIPs map[string]struct{}
sessionIPs map[string]string
} }
func New() *LegacyHandler { func New() *LegacyHandler {
@ -49,12 +52,14 @@ func New() *LegacyHandler {
return &LegacyHandler{ return &LegacyHandler{
logger: log.With().Str("module", "legacy").Logger(), logger: log.With().Str("module", "legacy").Logger(),
serverAddr: "127.0.0.1:8080", serverAddr: "127.0.0.1:8080",
bannedIPs: make(map[string]struct{}),
sessionIPs: make(map[string]string),
} }
} }
func (h *LegacyHandler) Route(r types.Router) { func (h *LegacyHandler) Route(r types.Router) {
r.Get("/ws", func(w http.ResponseWriter, r *http.Request) error { r.Get("/ws", func(w http.ResponseWriter, r *http.Request) error {
s := newSession(h.logger, h.serverAddr) s := h.newSession(r)
// create a new websocket connection // create a new websocket connection
connClient, err := DefaultUpgrader.Upgrade(w, r, nil) connClient, err := DefaultUpgrader.Upgrade(w, r, nil)
@ -66,6 +71,14 @@ func (h *LegacyHandler) Route(r types.Router) {
defer connClient.Close() defer connClient.Close()
s.connClient = connClient s.connClient = connClient
if h.isBanned(r) {
s.toClient(&oldMessage.SystemMessage{
Event: oldEvent.SYSTEM_DISCONNECT,
Title: "banned ip",
Message: "you are banned",
})
}
// create a new session // create a new session
username := r.URL.Query().Get("username") username := r.URL.Query().Get("username")
password := r.URL.Query().Get("password") password := r.URL.Query().Get("password")
@ -180,7 +193,11 @@ func (h *LegacyHandler) Route(r types.Router) {
}) })
r.Get("/stats", func(w http.ResponseWriter, r *http.Request) error { r.Get("/stats", func(w http.ResponseWriter, r *http.Request) error {
s := newSession(h.logger, h.serverAddr) if h.isBanned(r) {
return utils.HttpForbidden("banned ip")
}
s := h.newSession(r)
// create a new session // create a new session
username := r.URL.Query().Get("usr") username := r.URL.Query().Get("usr")
@ -253,7 +270,11 @@ func (h *LegacyHandler) Route(r types.Router) {
}) })
r.Get("/screenshot.jpg", func(w http.ResponseWriter, r *http.Request) error { r.Get("/screenshot.jpg", func(w http.ResponseWriter, r *http.Request) error {
s := newSession(h.logger, h.serverAddr) if h.isBanned(r) {
return utils.HttpForbidden("banned ip")
}
s := h.newSession(r)
// create a new session // create a new session
username := r.URL.Query().Get("usr") username := r.URL.Query().Get("usr")
@ -287,7 +308,11 @@ func (h *LegacyHandler) Route(r types.Router) {
// allow downloading and uploading files // allow downloading and uploading files
r.Get("/file", func(w http.ResponseWriter, r *http.Request) error { r.Get("/file", func(w http.ResponseWriter, r *http.Request) error {
s := newSession(h.logger, h.serverAddr) if h.isBanned(r) {
return utils.HttpForbidden("banned ip")
}
s := h.newSession(r)
// create a new session // create a new session
username := r.URL.Query().Get("usr") username := r.URL.Query().Get("usr")
@ -315,7 +340,11 @@ func (h *LegacyHandler) Route(r types.Router) {
}) })
r.Post("/file", func(w http.ResponseWriter, r *http.Request) error { r.Post("/file", func(w http.ResponseWriter, r *http.Request) error {
s := newSession(h.logger, h.serverAddr) if h.isBanned(r) {
return utils.HttpForbidden("banned ip")
}
s := h.newSession(r)
// create a new session // create a new session
username := r.URL.Query().Get("usr") username := r.URL.Query().Get("usr")
@ -341,3 +370,36 @@ func (h *LegacyHandler) Route(r types.Router) {
return err return err
}) })
} }
func (h *LegacyHandler) ban(sessionId string) error {
// find session by id
ip, ok := h.sessionIPs[sessionId]
if !ok {
return fmt.Errorf("session not found")
}
h.bannedIPs[ip] = struct{}{}
return nil
}
func (h *LegacyHandler) isBanned(r *http.Request) bool {
ipPort := r.RemoteAddr
ip, _, err := net.SplitHostPort(ipPort)
if err != nil {
h.logger.Error().Err(err).Msg("couldn't split host and port")
return false
}
_, ok := h.bannedIPs[ip]
return ok
}
func getIp(r *http.Request) string {
ipPort := r.RemoteAddr
ip, _, err := net.SplitHostPort(ipPort)
if err != nil {
return ""
}
return ip
}

View file

@ -29,10 +29,13 @@ type memberStruct struct {
} }
type session struct { type session struct {
r *http.Request
h *LegacyHandler
logger zerolog.Logger logger zerolog.Logger
serverAddr string serverAddr string
id string id, ip string
token string token string
name string name string
isAdmin bool isAdmin bool
@ -48,10 +51,12 @@ type session struct {
connBackend *websocket.Conn connBackend *websocket.Conn
} }
func newSession(logger zerolog.Logger, serverAddr string) *session { func (h *LegacyHandler) newSession(r *http.Request) *session {
return &session{ return &session{
logger: logger, r: r,
serverAddr: serverAddr, h: h,
logger: h.logger,
serverAddr: h.serverAddr,
client: http.DefaultClient, client: http.DefaultClient,
sessions: make(map[string]*memberStruct), sessions: make(map[string]*memberStruct),
} }
@ -171,7 +176,8 @@ func (s *session) create(username, password string) error {
return err return err
} }
s.id = data.ID s.id, s.ip = data.ID, getIp(s.r)
s.h.sessionIPs[s.id] = s.ip // save session ip by id
s.token = data.Token s.token = data.Token
s.name = data.Profile.Name s.name = data.Profile.Name
s.isAdmin = data.Profile.IsAdmin s.isAdmin = data.Profile.IsAdmin
@ -192,4 +198,7 @@ func (s *session) destroy() {
if err != nil { if err != nil {
s.logger.Error().Err(err).Msg("failed to logout") s.logger.Error().Err(err).Msg("failed to logout")
} }
// remove session id from ip map
delete(s.h.sessionIPs, s.id)
} }

View file

@ -329,8 +329,12 @@ func (s *session) wsToBackend(msg []byte) error {
return err return err
} }
// TODO: No WS equivalent, call HTTP API. err = s.h.ban(request.ID)
return fmt.Errorf("event not implemented: %s", header.Event) if err != nil {
return err
}
fallthrough // continue to kick
case oldEvent.ADMIN_KICK: case oldEvent.ADMIN_KICK:
request := &oldMessage.Admin{} request := &oldMessage.Admin{}
@ -339,8 +343,6 @@ func (s *session) wsToBackend(msg []byte) error {
return err return err
} }
// TODO: we need to send a message to the user before kicking them
// that they are being kicked so they will not automatically rejoin
return s.apiReq(http.MethodPost, "/api/members/"+request.ID, map[string]any{ return s.apiReq(http.MethodPost, "/api/members/"+request.ID, map[string]any{
"can_login": false, "can_login": false,
}, nil) }, nil)