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"
"fmt"
"io"
"net"
"net/http"
"net/url"
@ -41,6 +42,8 @@ var (
type LegacyHandler struct {
logger zerolog.Logger
serverAddr string
bannedIPs map[string]struct{}
sessionIPs map[string]string
}
func New() *LegacyHandler {
@ -49,12 +52,14 @@ func New() *LegacyHandler {
return &LegacyHandler{
logger: log.With().Str("module", "legacy").Logger(),
serverAddr: "127.0.0.1:8080",
bannedIPs: make(map[string]struct{}),
sessionIPs: make(map[string]string),
}
}
func (h *LegacyHandler) Route(r types.Router) {
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
connClient, err := DefaultUpgrader.Upgrade(w, r, nil)
@ -66,6 +71,14 @@ func (h *LegacyHandler) Route(r types.Router) {
defer connClient.Close()
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
username := r.URL.Query().Get("username")
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 {
s := newSession(h.logger, h.serverAddr)
if h.isBanned(r) {
return utils.HttpForbidden("banned ip")
}
s := h.newSession(r)
// create a new session
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 {
s := newSession(h.logger, h.serverAddr)
if h.isBanned(r) {
return utils.HttpForbidden("banned ip")
}
s := h.newSession(r)
// create a new session
username := r.URL.Query().Get("usr")
@ -287,7 +308,11 @@ func (h *LegacyHandler) Route(r types.Router) {
// allow downloading and uploading files
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
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 {
s := newSession(h.logger, h.serverAddr)
if h.isBanned(r) {
return utils.HttpForbidden("banned ip")
}
s := h.newSession(r)
// create a new session
username := r.URL.Query().Get("usr")
@ -341,3 +370,36 @@ func (h *LegacyHandler) Route(r types.Router) {
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 {
r *http.Request
h *LegacyHandler
logger zerolog.Logger
serverAddr string
id string
id, ip string
token string
name string
isAdmin bool
@ -48,10 +51,12 @@ type session struct {
connBackend *websocket.Conn
}
func newSession(logger zerolog.Logger, serverAddr string) *session {
func (h *LegacyHandler) newSession(r *http.Request) *session {
return &session{
logger: logger,
serverAddr: serverAddr,
r: r,
h: h,
logger: h.logger,
serverAddr: h.serverAddr,
client: http.DefaultClient,
sessions: make(map[string]*memberStruct),
}
@ -171,7 +176,8 @@ func (s *session) create(username, password string) error {
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.name = data.Profile.Name
s.isAdmin = data.Profile.IsAdmin
@ -192,4 +198,7 @@ func (s *session) destroy() {
if err != nil {
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
}
// TODO: No WS equivalent, call HTTP API.
return fmt.Errorf("event not implemented: %s", header.Event)
err = s.h.ban(request.ID)
if err != nil {
return err
}
fallthrough // continue to kick
case oldEvent.ADMIN_KICK:
request := &oldMessage.Admin{}
@ -339,8 +343,6 @@ func (s *session) wsToBackend(msg []byte) error {
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{
"can_login": false,
}, nil)