mirror of
https://github.com/m1k1o/neko.git
synced 2025-04-29 10:26:22 +02:00
legacy: add stats.
This commit is contained in:
parent
6a8f8052cd
commit
a1f2e379cd
4 changed files with 158 additions and 55 deletions
|
@ -1,12 +1,17 @@
|
|||
package legacy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"m1k1o/neko/internal/api"
|
||||
"m1k1o/neko/internal/api/room"
|
||||
oldEvent "m1k1o/neko/internal/http/legacy/event"
|
||||
oldMessage "m1k1o/neko/internal/http/legacy/message"
|
||||
oldTypes "m1k1o/neko/internal/http/legacy/types"
|
||||
|
||||
"m1k1o/neko/pkg/types"
|
||||
"m1k1o/neko/pkg/types/event"
|
||||
|
@ -36,6 +41,7 @@ var (
|
|||
type LegacyHandler struct {
|
||||
logger zerolog.Logger
|
||||
serverAddr string
|
||||
startedAt time.Time
|
||||
}
|
||||
|
||||
func New() *LegacyHandler {
|
||||
|
@ -44,6 +50,7 @@ func New() *LegacyHandler {
|
|||
return &LegacyHandler{
|
||||
logger: log.With().Str("module", "legacy").Logger(),
|
||||
serverAddr: "127.0.0.1:8080",
|
||||
startedAt: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +71,7 @@ func (h *LegacyHandler) Route(r types.Router) {
|
|||
// create a new session
|
||||
username := r.URL.Query().Get("username")
|
||||
password := r.URL.Query().Get("password")
|
||||
token, err := s.create(username, password)
|
||||
err = s.create(username, password)
|
||||
if err != nil {
|
||||
h.logger.Error().Err(err).Msg("couldn't create a new session")
|
||||
|
||||
|
@ -80,7 +87,7 @@ func (h *LegacyHandler) Route(r types.Router) {
|
|||
defer s.destroy()
|
||||
|
||||
// dial to the remote backend
|
||||
connBackend, _, err := DefaultDialer.Dial("ws://"+h.serverAddr+"/api/ws?token="+token, nil)
|
||||
connBackend, _, err := DefaultDialer.Dial("ws://"+h.serverAddr+"/api/ws?token="+s.token, nil)
|
||||
if err != nil {
|
||||
h.logger.Error().Err(err).Msg("couldn't dial to the remote backend")
|
||||
|
||||
|
@ -174,24 +181,90 @@ func (h *LegacyHandler) Route(r types.Router) {
|
|||
return nil
|
||||
})
|
||||
|
||||
/*
|
||||
r.Get("/stats", func(w http.ResponseWriter, r *http.Request) error {
|
||||
password := r.URL.Query().Get("pwd")
|
||||
isAdmin, err := webSocketHandler.IsAdmin(password)
|
||||
if err != nil {
|
||||
return utils.HttpForbidden(err)
|
||||
}
|
||||
s := newSession(h.logger, h.serverAddr)
|
||||
|
||||
if !isAdmin {
|
||||
// create a new session
|
||||
username := r.URL.Query().Get("usr")
|
||||
password := r.URL.Query().Get("pwd")
|
||||
err := s.create(username, password)
|
||||
if err != nil {
|
||||
return utils.HttpForbidden(err.Error())
|
||||
}
|
||||
defer s.destroy()
|
||||
|
||||
if !s.isAdmin {
|
||||
return utils.HttpUnauthorized().Msg("bad authorization")
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
stats := webSocketHandler.Stats()
|
||||
// get all sessions
|
||||
sessions := []api.SessionDataPayload{}
|
||||
err = s.apiReq(http.MethodGet, "/api/sessions", nil, &sessions)
|
||||
if err != nil {
|
||||
return utils.HttpInternalServerError().WithInternalErr(err)
|
||||
}
|
||||
|
||||
// get current control status
|
||||
control := room.ControlStatusPayload{}
|
||||
err = s.apiReq(http.MethodGet, "/api/room/control", nil, &control)
|
||||
if err != nil {
|
||||
return utils.HttpInternalServerError().WithInternalErr(err)
|
||||
}
|
||||
|
||||
// get settings
|
||||
settings := types.Settings{}
|
||||
err = s.apiReq(http.MethodGet, "/api/room/settings", nil, &settings)
|
||||
if err != nil {
|
||||
return utils.HttpInternalServerError().WithInternalErr(err)
|
||||
}
|
||||
|
||||
var stats oldTypes.Stats
|
||||
|
||||
// create empty array so that it's not null in json
|
||||
stats.Members = []*oldTypes.Member{}
|
||||
|
||||
for _, session := range sessions {
|
||||
if session.State.IsConnected {
|
||||
stats.Connections++
|
||||
member, err := profileToMember(session.ID, session.Profile)
|
||||
if err != nil {
|
||||
return utils.HttpInternalServerError().WithInternalErr(err)
|
||||
}
|
||||
// append members
|
||||
stats.Members = append(stats.Members, member)
|
||||
} else if session.State.NotConnectedSince != nil {
|
||||
//
|
||||
// TODO: This wont work if the user is removed after the session is closed
|
||||
//
|
||||
// populate last admin left time
|
||||
if session.Profile.IsAdmin && (stats.LastAdminLeftAt == nil || (*session.State.NotConnectedSince).After(*stats.LastAdminLeftAt)) {
|
||||
stats.LastAdminLeftAt = session.State.NotConnectedSince
|
||||
}
|
||||
// populate last user left time
|
||||
if !session.Profile.IsAdmin && (stats.LastUserLeftAt == nil || (*session.State.NotConnectedSince).After(*stats.LastUserLeftAt)) {
|
||||
stats.LastUserLeftAt = session.State.NotConnectedSince
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
locks, err := s.settingsToLocks(settings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stats.Host = control.HostId
|
||||
// TODO: stats.Banned, not implemented yet
|
||||
stats.Locked = locks
|
||||
stats.ServerStartedAt = h.startedAt
|
||||
stats.ControlProtection = settings.ControlProtection
|
||||
stats.ImplicitControl = settings.ImplicitHosting
|
||||
|
||||
return json.NewEncoder(w).Encode(stats)
|
||||
})
|
||||
|
||||
/*
|
||||
r.Get("/screenshot.jpg", func(w http.ResponseWriter, r *http.Request) error {
|
||||
password := r.URL.Query().Get("pwd")
|
||||
isAdmin, err := webSocketHandler.IsAdmin(password)
|
||||
|
|
|
@ -35,6 +35,7 @@ type session struct {
|
|||
id string
|
||||
token string
|
||||
name string
|
||||
isAdmin bool
|
||||
client *http.Client
|
||||
|
||||
lastHostID string
|
||||
|
@ -142,7 +143,7 @@ func (s *session) toBackend(event string, payload any) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *session) create(username, password string) (string, error) {
|
||||
func (s *session) create(username, password string) error {
|
||||
data := api.SessionDataPayload{}
|
||||
|
||||
err := s.apiReq(http.MethodPost, "/api/login", api.SessionLoginPayload{
|
||||
|
@ -150,19 +151,20 @@ func (s *session) create(username, password string) (string, error) {
|
|||
Password: password,
|
||||
}, &data)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return err
|
||||
}
|
||||
|
||||
s.id = data.ID
|
||||
s.token = data.Token
|
||||
s.name = data.Profile.Name
|
||||
s.isAdmin = data.Profile.IsAdmin
|
||||
|
||||
// if Cookie auth, the token will be empty
|
||||
if s.token == "" {
|
||||
return "", fmt.Errorf("token not found - make sure you are not using Cookie auth on the server")
|
||||
return fmt.Errorf("token not found - make sure you are not using Cookie auth on the server")
|
||||
}
|
||||
|
||||
return data.Token, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *session) destroy() {
|
||||
|
|
|
@ -1,5 +1,23 @@
|
|||
package types
|
||||
|
||||
import "time"
|
||||
|
||||
type Stats struct {
|
||||
Connections uint32 `json:"connections"`
|
||||
Host string `json:"host"`
|
||||
Members []*Member `json:"members"`
|
||||
|
||||
Banned map[string]string `json:"banned"` // IP -> session ID (that banned it)
|
||||
Locked map[string]string `json:"locked"` // resource name -> session ID (that locked it)
|
||||
|
||||
ServerStartedAt time.Time `json:"server_started_at"`
|
||||
LastAdminLeftAt *time.Time `json:"last_admin_left_at"`
|
||||
LastUserLeftAt *time.Time `json:"last_user_left_at"`
|
||||
|
||||
ControlProtection bool `json:"control_protection"`
|
||||
ImplicitControl bool `json:"implicit_control"`
|
||||
}
|
||||
|
||||
type Member struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"displayname"`
|
||||
|
|
|
@ -67,6 +67,41 @@ func screenConfigurations(screenSizes []types.ScreenSize) map[int]oldTypes.Scree
|
|||
return screenSizesList
|
||||
}
|
||||
|
||||
func (s *session) settingsToLocks(settings types.Settings) (map[string]string, error) {
|
||||
//
|
||||
// FileTransfer
|
||||
//
|
||||
|
||||
filetransferSettings := filetransfer.Settings{
|
||||
Enabled: true, // defaults to true
|
||||
}
|
||||
|
||||
err := settings.Plugins.Unmarshal(filetransfer.PluginName, &filetransferSettings)
|
||||
if err != nil && !errors.Is(err, types.ErrPluginSettingsNotFound) {
|
||||
return nil, fmt.Errorf("unable to unmarshal %s plugin settings from global settings: %w", filetransfer.PluginName, err)
|
||||
}
|
||||
|
||||
//
|
||||
// Locks
|
||||
//
|
||||
|
||||
locks := map[string]string{}
|
||||
if settings.LockedLogins {
|
||||
locks["login"] = "" // TODO: We don't know who locked the login.
|
||||
s.lockedLogins = true
|
||||
}
|
||||
if settings.LockedControls {
|
||||
locks["control"] = "" // TODO: We don't know who locked the control.
|
||||
s.lockedControls = true
|
||||
}
|
||||
if !filetransferSettings.Enabled {
|
||||
locks["file_transfer"] = "" // TODO: We don't know who locked the file transfer.
|
||||
s.lockedFileTransfer = true
|
||||
}
|
||||
|
||||
return locks, nil
|
||||
}
|
||||
|
||||
func (s *session) sendControlHost(request message.ControlHost) error {
|
||||
lastHostID := s.lastHostID
|
||||
|
||||
|
@ -198,34 +233,9 @@ func (s *session) wsToClient(msg []byte) error {
|
|||
return err
|
||||
}
|
||||
|
||||
//
|
||||
// FileTransfer
|
||||
//
|
||||
|
||||
filetransferSettings := filetransfer.Settings{
|
||||
Enabled: true, // defaults to true
|
||||
}
|
||||
|
||||
err = request.Settings.Plugins.Unmarshal(filetransfer.PluginName, &filetransferSettings)
|
||||
if err != nil && !errors.Is(err, types.ErrPluginSettingsNotFound) {
|
||||
return fmt.Errorf("unable to unmarshal %s plugin settings from global settings: %w", filetransfer.PluginName, err)
|
||||
}
|
||||
|
||||
//
|
||||
// Locks
|
||||
//
|
||||
locks := map[string]string{}
|
||||
if request.Settings.LockedLogins {
|
||||
locks["login"] = "" // TODO: We don't know who locked the login.
|
||||
s.lockedLogins = true
|
||||
}
|
||||
if request.Settings.LockedControls {
|
||||
locks["control"] = "" // TODO: We don't know who locked the control.
|
||||
s.lockedControls = true
|
||||
}
|
||||
if !filetransferSettings.Enabled {
|
||||
locks["file_transfer"] = "" // TODO: We don't know who locked the file transfer.
|
||||
s.lockedFileTransfer = true
|
||||
locks, err := s.settingsToLocks(request.Settings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.toClient(&oldMessage.SystemInit{
|
||||
|
|
Loading…
Add table
Reference in a new issue