refactor(global): move config to global package and consolidate handlers

- Move Config struct and related functions to global package
- Consolidate handler utilities into utils package
- Remove deprecated handlers and instance packages
- Add new handlers package with settings and proxy functionality
- Update config.json to include watchdog enabled flag
This commit is contained in:
2026-04-22 19:52:33 +08:00
parent ddf91299e7
commit 489c37e095
10 changed files with 384 additions and 353 deletions

View File

@@ -2,26 +2,15 @@ package config
import (
"encoding/json"
"errors"
"fmt"
"os"
"strconv"
"strings"
"super-frpc/global"
"github.com/BurntSushi/toml"
)
type Config struct {
ListenAddr string `json:"listenAddr"`
ListenPort string `json:"listenPort"`
FrpcPath string `json:"frpcPath"`
InstancePath string `json:"instancePath"`
Debug bool `json:"debug"`
Watchdog struct {
Port int `json:"port"`
} `json:"watchdog"`
}
type InstanceInfo struct {
Name string `json:"name"`
ServerAddr string `json:"serverAddr"`
@@ -56,60 +45,64 @@ type FrpcConfig struct {
Proxies []map[string]interface{} `toml:"proxies"`
}
var globalConfig *Config
func LoadConfig(configPath string, getInitSystem func() string) (*Config, error) {
func LoadConfig(configPath string, getInitSystem func() string) error {
data, err := os.ReadFile(configPath)
if err != nil {
return nil, fmt.Errorf("failed to read config file: %w", err)
return fmt.Errorf("failed to read config file: %w", err)
}
var config Config
if err := json.Unmarshal(data, &config); err != nil {
return nil, fmt.Errorf("failed to parse config file: %w", err)
var fileConfig global.Config
if err := json.Unmarshal(data, &fileConfig); err != nil {
return fmt.Errorf("failed to parse config file: %w", err)
}
if config.ListenAddr == "" {
config.ListenAddr = "0.0.0.0"
if fileConfig.ListenAddr != "" {
global.CurrentConfig.ListenAddr = fileConfig.ListenAddr
}
if config.ListenPort == "" {
config.ListenPort = "8080"
if fileConfig.ListenPort != "" {
global.CurrentConfig.ListenPort = fileConfig.ListenPort
}
if config.FrpcPath == "" {
if getInitSystem() == "windows" {
config.FrpcPath = "frp_client/frpc.exe"
if fileConfig.FrpcPath != "" {
global.CurrentConfig.FrpcPath = fileConfig.FrpcPath
} else {
config.FrpcPath = "/usr/bin/frpc"
if getInitSystem() == "windows" {
global.CurrentConfig.FrpcPath = "frp_client/frpc.exe"
} else {
global.CurrentConfig.FrpcPath = "/usr/bin/frpc"
}
}
if config.InstancePath == "" {
config.InstancePath = "./configs"
if fileConfig.InstancePath != "" {
global.CurrentConfig.InstancePath = fileConfig.InstancePath
} else {
global.CurrentConfig.InstancePath = "./configs"
}
if config.Watchdog.Port == 0 {
config.Watchdog.Port = 12380
global.CurrentConfig.Debug = fileConfig.Debug
if fileConfig.Watchdog.Port != 0 {
global.CurrentConfig.Watchdog.Port = fileConfig.Watchdog.Port
} else {
global.CurrentConfig.Watchdog.Port = 12380
}
if err := os.MkdirAll(config.InstancePath, 0755); err != nil {
return nil, fmt.Errorf("failed to create config directory: %w", err)
global.CurrentConfig.Watchdog.Enabled = fileConfig.Watchdog.Enabled
if err := os.MkdirAll(global.CurrentConfig.InstancePath, 0755); err != nil {
return fmt.Errorf("failed to create config directory: %w", err)
}
globalConfig = &config
return &config, nil
return nil
}
func GetConfig() (*Config, error) {
if globalConfig == nil {
return nil, errors.New("config not loaded")
}
return globalConfig, nil
func GetConfig() *global.Config {
return &global.CurrentConfig
}
func SaveConfig(configPath string, config *Config) error {
data, err := json.MarshalIndent(config, "", " ")
func SaveConfig(configPath string) error {
data, err := json.MarshalIndent(global.CurrentConfig, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal config: %w", err)
}
@@ -118,7 +111,6 @@ func SaveConfig(configPath string, config *Config) error {
return fmt.Errorf("failed to write config file: %w", err)
}
globalConfig = config
return nil
}

View File

@@ -13,6 +13,14 @@ type SoftwareInfo struct {
BuildType string
}
var Software = SoftwareInfo{
Name: "Super-frpc",
Version: "0.0.1",
Developer: "Madobi Nanami",
BuildVer: 1,
BuildType: "debug",
}
type StatusFlags struct {
Debug bool
Online bool
@@ -25,16 +33,35 @@ var (
LogsDB *sql.DB
)
var Software = SoftwareInfo{
Name: "Super-frpc",
Version: "0.0.1",
Developer: "Madobi Nanami",
BuildVer: 1,
BuildType: "debug",
}
var Is = StatusFlags{
Debug: false,
Online: false,
WatchdogConnected: false,
}
type Config struct {
ListenAddr string `json:"listenAddr"`
ListenPort string `json:"listenPort"`
FrpcPath string `json:"frpcPath"`
InstancePath string `json:"instancePath"`
Debug bool `json:"debug"`
Watchdog struct {
Enabled bool `json:"enabled"`
Port int `json:"port"`
} `json:"watchdog"`
}
var CurrentConfig = Config{
ListenAddr: "0.0.0.0",
ListenPort: "7000",
FrpcPath: "/usr/bin/frpc",
InstancePath: "/var/lib/frpc",
Debug: false,
Watchdog: struct {
Enabled bool `json:"enabled"`
Port int `json:"port"`
}{
Enabled: false,
Port: 0,
},
}

View File

@@ -1,4 +1,4 @@
package instance
package handlers
import (
"database/sql"
@@ -13,15 +13,15 @@ import (
"super-frpc/config"
"super-frpc/database"
"super-frpc/handlers"
"super-frpc/utils"
"super-frpc/postLog"
"super-frpc/service"
)
func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
userID, err := handlers.Auth(w, r, http.MethodPost, "superuser", "admin")
userID, err := utils.Auth(w, r, http.MethodPost, "superuser", "admin")
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[CreateInstanceHandler] Auth failed: %v", err))
return
}
@@ -29,7 +29,7 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to read request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
return
}
defer r.Body.Close()
@@ -37,7 +37,7 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
var reqMap map[string]interface{}
if err := json.Unmarshal(body, &reqMap); err != nil {
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to unmarshal request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
return
}
@@ -55,7 +55,7 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
instanceInfoMap, ok := reqMap["instanceInfo"].(map[string]interface{})
if !ok {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceInfo format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceInfo format")
return
}
@@ -80,7 +80,7 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
if req.InstanceInfo.Name == "" || req.InstanceInfo.ServerAddr == "" ||
req.InstanceInfo.ServerPort == "" || req.InstanceInfo.AuthMethod == "" {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Missing required fields in instanceInfo")
utils.SendErrorResponse(w, http.StatusBadRequest, "Missing required fields in instanceInfo")
return
}
@@ -92,14 +92,14 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
user, err := database.GetUserByID(userID)
if err != nil {
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to get user info: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info")
return
}
configDir, err := service.GetConfigDir()
if err != nil {
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to get config directory: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get config directory")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get config directory")
return
}
@@ -112,7 +112,7 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
if err := config.HandleConfigFileCreate(configPath, req.InstanceInfo, setKeyTextWrapper); err != nil {
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to create config file %s: %v", configPath, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to create config file")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to create config file")
return
}
@@ -128,7 +128,7 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
if err := database.DBAddFrpcInstance(instance); err != nil {
os.Remove(configPath)
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to save instance %s to database: %v", req.InstanceInfo.Name, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to save instance to database")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to save instance to database")
return
}
@@ -136,7 +136,7 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
if err != nil {
os.Remove(configPath)
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to query created instance: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query created instance")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query created instance")
return
}
@@ -144,19 +144,19 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
database.DBRemoveFrpcInstanceByID(createdInstance.ID)
os.Remove(configPath)
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to create boot service for instance %s: %v", req.InstanceInfo.Name, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to create boot service")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to create boot service")
return
}
if req.BootAtStart {
if err := service.SetBootAtStart(createdInstance.ID); err != nil {
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to set boot at start for instance %s: %v", req.InstanceInfo.Name, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to set boot at start")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to set boot at start")
return
}
}
handlers.SendSuccessResponse(w, "Instance created successfully", map[string]interface{}{
utils.SendSuccessResponse(w, "Instance created successfully", map[string]interface{}{
"name": req.InstanceInfo.Name,
"configPath": configPath,
"bootAtStart": req.BootAtStart,
@@ -165,9 +165,9 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
}
func DeleteInstanceHandler(w http.ResponseWriter, r *http.Request) {
userID, err := handlers.Auth(w, r, http.MethodPost, "superuser", "admin")
userID, err := utils.Auth(w, r, http.MethodPost, "superuser", "admin")
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[DeleteInstanceHandler] Auth failed: %v", err))
return
}
@@ -175,7 +175,7 @@ func DeleteInstanceHandler(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to read request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
return
}
defer r.Body.Close()
@@ -183,64 +183,64 @@ func DeleteInstanceHandler(w http.ResponseWriter, r *http.Request) {
var reqMap map[string]interface{}
if err := json.Unmarshal(body, &reqMap); err != nil {
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to unmarshal request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
return
}
instanceIDStr := getStringFromMap(reqMap, "instanceID")
if instanceIDStr == "" {
handlers.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
return
}
instanceID, err := strconv.Atoi(instanceIDStr)
if err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
return
}
instance, err := database.DBQueryFrpcInstanceByID(instanceID)
if err == sql.ErrNoRows {
handlers.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
utils.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] User %d tried to delete a not existed instance: %d", userID, instanceID))
return
}
if err != nil {
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to query instance: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
return
}
if err := service.RemoveBootService(instanceID); err != nil {
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to remove boot service for instance %s: %v", instance.Name, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to remove boot service")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to remove boot service")
return
}
if _, err := os.Stat(instance.ConfigPath); err == nil {
if err := os.Remove(instance.ConfigPath); err != nil {
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to remove config file %s: %v", instance.ConfigPath, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to remove config file")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to remove config file")
return
}
}
if err := database.DBRemoveFrpcInstanceByID(instanceID); err != nil {
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to delete instance %d from database: %v", instanceID, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to delete instance from database")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to delete instance from database")
return
}
handlers.SendSuccessResponse(w, "Instance deleted successfully", map[string]interface{}{
utils.SendSuccessResponse(w, "Instance deleted successfully", map[string]interface{}{
"id": instanceID,
})
postLog.Info(fmt.Sprintf("[DeleteInstanceHandler] Instance %d deleted successfully", instanceID))
}
func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request) {
userID, err := handlers.Auth(w, r, http.MethodPost, "superuser", "admin")
userID, err := utils.Auth(w, r, http.MethodPost, "superuser", "admin")
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[ModifyInstanceHandler] Auth failed: %v", err))
return
}
@@ -248,7 +248,7 @@ func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to read request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
return
}
defer r.Body.Close()
@@ -256,61 +256,61 @@ func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request) {
var reqMap map[string]interface{}
if err := json.Unmarshal(body, &reqMap); err != nil {
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to unmarshal request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
return
}
instanceIDStr := getStringFromMap(reqMap, "instanceID")
if instanceIDStr == "" {
handlers.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
return
}
instanceID, err := strconv.Atoi(instanceIDStr)
if err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
return
}
modifyType := getStringFromMap(reqMap, "type")
if modifyType == "" {
handlers.SendErrorResponse(w, http.StatusBadRequest, "type is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "type is required")
return
}
if modifyType != "configFile" && modifyType != "systemConfig" {
handlers.SendErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("Unknown modify type %s", modifyType))
utils.SendErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("Unknown modify type %s", modifyType))
return
}
modifiedData, ok := reqMap["modifiedData"].(map[string]interface{})
if !ok || modifiedData == nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "modifiedData is required and must be an object")
utils.SendErrorResponse(w, http.StatusBadRequest, "modifiedData is required and must be an object")
return
}
instance, err := database.DBQueryFrpcInstanceByID(instanceID)
if err == sql.ErrNoRows {
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] User %d tried to modify a not existed instance: %d", userID, instanceID))
handlers.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
utils.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
return
}
if err != nil {
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to query instance: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
return
}
if instance.UserID != userID {
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] User %d does not have permission to modify instance %d", userID, instanceID))
handlers.SendErrorResponse(w, http.StatusForbidden, "Permission denied")
utils.SendErrorResponse(w, http.StatusForbidden, "Permission denied")
return
}
user, err := database.GetUserByID(instance.UserID)
if err != nil {
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to get user info: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info")
return
}
@@ -355,12 +355,12 @@ func handleConfigFileModify(w http.ResponseWriter, instance database.FrpcInstanc
}
if err := config.SetKeyText(configPath, configKey, "", configValue, os.ReadFile, os.WriteFile); err != nil {
postLog.Error(fmt.Sprintf("[handleConfigFileModify] Failed to set key %s: %v", key, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to set key %s", key))
utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to set key %s", key))
return
}
}
handlers.SendSuccessResponse(w, "Config file modified successfully", map[string]interface{}{
utils.SendSuccessResponse(w, "Config file modified successfully", map[string]interface{}{
"instanceName": instance.Name,
"instanceID": instance.ID,
"configPath": configPath,
@@ -391,7 +391,7 @@ func handleSystemConfigModify(w http.ResponseWriter, r *http.Request, instance d
configDir, err := service.GetConfigDir()
if err != nil {
postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to get config directory: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get config directory")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get config directory")
return
}
@@ -402,7 +402,7 @@ func handleSystemConfigModify(w http.ResponseWriter, r *http.Request, instance d
if _, err := os.Stat(oldConfigPath); err == nil {
if err := os.Rename(oldConfigPath, newConfigPath); err != nil {
postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to rename config file %s to %s: %v", oldConfigPath, newConfigPath, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to rename config file")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to rename config file")
return
}
}
@@ -417,7 +417,7 @@ func handleSystemConfigModify(w http.ResponseWriter, r *http.Request, instance d
if err := database.DBUpdateFrpcInstance(instance); err != nil {
postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to update instance in database: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to update instance in database")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to update instance in database")
return
}
@@ -453,7 +453,7 @@ func handleSystemConfigModify(w http.ResponseWriter, r *http.Request, instance d
if bootServiceError != "" {
data["bootServiceError"] = bootServiceError
}
handlers.SendSuccessResponse(w, "System config modified successfully", data)
utils.SendSuccessResponse(w, "System config modified successfully", data)
}
func GetUserInstances(userID int) ([]database.FrpcInstance, error) {
@@ -497,9 +497,9 @@ func getNumFromMap(m map[string]interface{}, key string) int {
}
func ListInstancesHandler(w http.ResponseWriter, r *http.Request) {
userID, err := handlers.Auth(w, r, http.MethodGet)
userID, err := utils.Auth(w, r, http.MethodGet)
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[ListInstancesHandler] Auth failed: %v", err))
return
}
@@ -507,7 +507,7 @@ func ListInstancesHandler(w http.ResponseWriter, r *http.Request) {
instances, err := GetUserInstances(userID)
if err != nil {
postLog.Error(fmt.Sprintf("[ListInstancesHandler] Failed to get user instances: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get instances")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get instances")
return
}
@@ -531,14 +531,14 @@ func ListInstancesHandler(w http.ResponseWriter, r *http.Request) {
instanceList[i] = instanceData
}
handlers.SendSuccessResponse(w, "Instances retrieved successfully", instanceList)
utils.SendSuccessResponse(w, "Instances retrieved successfully", instanceList)
postLog.Info(fmt.Sprintf("[ListInstancesHandler] Retrieved %d instances for user %d", len(instances), userID))
}
func StartInstanceHandler(w http.ResponseWriter, r *http.Request) {
userID, err := handlers.Auth(w, r, http.MethodPost, "superuser", "admin")
userID, err := utils.Auth(w, r, http.MethodPost, "superuser", "admin")
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[StartInstanceHandler] Auth failed: %v", err))
return
}
@@ -546,7 +546,7 @@ func StartInstanceHandler(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Failed to read request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
return
}
defer r.Body.Close()
@@ -554,36 +554,36 @@ func StartInstanceHandler(w http.ResponseWriter, r *http.Request) {
var reqMap map[string]interface{}
if err := json.Unmarshal(body, &reqMap); err != nil {
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Failed to unmarshal request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
return
}
instanceIDStr := getStringFromMap(reqMap, "instanceID")
if instanceIDStr == "" {
handlers.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
return
}
instanceID, err := strconv.Atoi(instanceIDStr)
if err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
return
}
instance, err := database.DBQueryFrpcInstanceByID(instanceID)
if err == sql.ErrNoRows {
handlers.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
utils.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
postLog.Error(fmt.Sprintf("[StartInstanceHandler] User %d tried to start a not existed instance: %d", userID, instanceID))
return
}
if err != nil {
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Failed to query instance: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
return
}
if instance.UserID != userID {
handlers.SendErrorResponse(w, http.StatusForbidden, "Instance not found")
utils.SendErrorResponse(w, http.StatusForbidden, "Instance not found")
postLog.Error(fmt.Sprintf("[StartInstanceHandler] User %d tried to start instance %d that does not belong to them", userID, instanceID))
return
}
@@ -592,7 +592,7 @@ func StartInstanceHandler(w http.ResponseWriter, r *http.Request) {
serviceName, err := database.GetServiceNameByInstanceID(instanceID)
if err != nil {
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Failed to get service name: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get service name")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get service name")
return
}
@@ -600,7 +600,7 @@ func StartInstanceHandler(w http.ResponseWriter, r *http.Request) {
case "windows":
if err := service.StartWindowsService(serviceName); err != nil {
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Failed to start Windows service %s: %v", serviceName, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to start Windows service: %v", err))
utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to start Windows service: %v", err))
return
}
postLog.Debug(fmt.Sprintf("[StartInstanceHandler] Windows service %s started successfully", serviceName))
@@ -608,7 +608,7 @@ func StartInstanceHandler(w http.ResponseWriter, r *http.Request) {
case "systemd":
if err := service.StartSystemdService(serviceName); err != nil {
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Failed to start systemd service %s: %v", serviceName, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to start systemd service: %v", err))
utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to start systemd service: %v", err))
return
}
postLog.Debug(fmt.Sprintf("[StartInstanceHandler] Systemd service %s started successfully", serviceName))
@@ -616,17 +616,17 @@ func StartInstanceHandler(w http.ResponseWriter, r *http.Request) {
case "init.d":
if err := service.StartInitDService(serviceName); err != nil {
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Failed to start init.d service %s: %v", serviceName, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to start init.d service: %v", err))
utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to start init.d service: %v", err))
return
}
postLog.Debug(fmt.Sprintf("[StartInstanceHandler] Init.d service %s started successfully", serviceName))
default:
handlers.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Unsupported init system: %s", initType))
utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Unsupported init system: %s", initType))
return
}
handlers.SendSuccessResponse(w, "Instance started successfully", map[string]interface{}{
utils.SendSuccessResponse(w, "Instance started successfully", map[string]interface{}{
"instanceID": instanceID,
"serviceName": serviceName,
})
@@ -634,9 +634,9 @@ func StartInstanceHandler(w http.ResponseWriter, r *http.Request) {
}
func StopInstanceHandler(w http.ResponseWriter, r *http.Request) {
userID, err := handlers.Auth(w, r, http.MethodPost, "superuser", "admin")
userID, err := utils.Auth(w, r, http.MethodPost, "superuser", "admin")
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[StopInstanceHandler] Auth failed: %v", err))
return
}
@@ -644,7 +644,7 @@ func StopInstanceHandler(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to read request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
return
}
defer r.Body.Close()
@@ -652,36 +652,36 @@ func StopInstanceHandler(w http.ResponseWriter, r *http.Request) {
var reqMap map[string]interface{}
if err := json.Unmarshal(body, &reqMap); err != nil {
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to unmarshal request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
return
}
instanceIDStr := getStringFromMap(reqMap, "instanceID")
if instanceIDStr == "" {
handlers.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
return
}
instanceID, err := strconv.Atoi(instanceIDStr)
if err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
return
}
instance, err := database.DBQueryFrpcInstanceByID(instanceID)
if err == sql.ErrNoRows {
handlers.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
utils.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
postLog.Error(fmt.Sprintf("[StopInstanceHandler] User %d tried to stop a not existed instance: %d", userID, instanceID))
return
}
if err != nil {
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to query instance: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
return
}
if instance.UserID != userID {
handlers.SendErrorResponse(w, http.StatusForbidden, "Instance not found")
utils.SendErrorResponse(w, http.StatusForbidden, "Instance not found")
postLog.Error(fmt.Sprintf("[StopInstanceHandler] User %d tried to stop instance %d that does not belong to them", userID, instanceID))
return
}
@@ -690,7 +690,7 @@ func StopInstanceHandler(w http.ResponseWriter, r *http.Request) {
serviceName, err := database.GetServiceNameByInstanceID(instanceID)
if err != nil {
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to get service name: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get service name")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get service name")
return
}
@@ -698,7 +698,7 @@ func StopInstanceHandler(w http.ResponseWriter, r *http.Request) {
case "windows":
if err := service.StopWindowsService(serviceName); err != nil {
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to stop Windows service %s: %v", serviceName, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to stop Windows service: %v", err))
utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to stop Windows service: %v", err))
return
}
postLog.Debug(fmt.Sprintf("[StopInstanceHandler] Windows service %s stopped successfully", serviceName))
@@ -706,7 +706,7 @@ func StopInstanceHandler(w http.ResponseWriter, r *http.Request) {
case "systemd":
if err := service.StopSystemdService(serviceName); err != nil {
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to stop systemd service %s: %v", serviceName, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to stop systemd service: %v", err))
utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to stop systemd service: %v", err))
return
}
postLog.Debug(fmt.Sprintf("[StopInstanceHandler] Systemd service %s stopped successfully", serviceName))
@@ -714,17 +714,17 @@ func StopInstanceHandler(w http.ResponseWriter, r *http.Request) {
case "init.d":
if err := service.StopInitDService(serviceName); err != nil {
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to stop init.d service %s: %v", serviceName, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to stop init.d service: %v", err))
utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to stop init.d service: %v", err))
return
}
postLog.Debug(fmt.Sprintf("[StopInstanceHandler] Init.d service %s stopped successfully", serviceName))
default:
handlers.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Unsupported init system: %s", initType))
utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Unsupported init system: %s", initType))
return
}
handlers.SendSuccessResponse(w, "Instance stopped successfully", map[string]interface{}{
utils.SendSuccessResponse(w, "Instance stopped successfully", map[string]interface{}{
"instanceID": instanceID,
"serviceName": serviceName,
})
@@ -732,9 +732,9 @@ func StopInstanceHandler(w http.ResponseWriter, r *http.Request) {
}
func RestartInstanceHandler(w http.ResponseWriter, r *http.Request) {
userID, err := handlers.Auth(w, r, http.MethodPost, "superuser", "admin")
userID, err := utils.Auth(w, r, http.MethodPost, "superuser", "admin")
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[RestartInstanceHandler] Auth failed: %v", err))
return
}
@@ -742,7 +742,7 @@ func RestartInstanceHandler(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Failed to read request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
return
}
defer r.Body.Close()
@@ -750,36 +750,36 @@ func RestartInstanceHandler(w http.ResponseWriter, r *http.Request) {
var reqMap map[string]interface{}
if err := json.Unmarshal(body, &reqMap); err != nil {
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Failed to unmarshal request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
return
}
instanceIDStr := getStringFromMap(reqMap, "instanceID")
if instanceIDStr == "" {
handlers.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
return
}
instanceID, err := strconv.Atoi(instanceIDStr)
if err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
return
}
instance, err := database.DBQueryFrpcInstanceByID(instanceID)
if err == sql.ErrNoRows {
handlers.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
utils.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] User %d tried to restart a not existed instance: %d", userID, instanceID))
return
}
if err != nil {
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Failed to query instance: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
return
}
if instance.UserID != userID {
handlers.SendErrorResponse(w, http.StatusForbidden, "Instance not found")
utils.SendErrorResponse(w, http.StatusForbidden, "Instance not found")
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] User %d tried to restart instance %d that does not belong to them", userID, instanceID))
return
}
@@ -788,7 +788,7 @@ func RestartInstanceHandler(w http.ResponseWriter, r *http.Request) {
serviceName, err := database.GetServiceNameByInstanceID(instanceID)
if err != nil {
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Failed to get service name: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get service name")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get service name")
return
}
@@ -796,7 +796,7 @@ func RestartInstanceHandler(w http.ResponseWriter, r *http.Request) {
case "windows":
if err := service.RestartWindowsService(serviceName); err != nil {
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Failed to restart Windows service %s: %v", serviceName, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to restart Windows service: %v", err))
utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to restart Windows service: %v", err))
return
}
postLog.Debug(fmt.Sprintf("[RestartInstanceHandler] Windows service %s restarted successfully", serviceName))
@@ -804,7 +804,7 @@ func RestartInstanceHandler(w http.ResponseWriter, r *http.Request) {
case "systemd":
if err := service.RestartSystemdService(serviceName); err != nil {
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Failed to restart systemd service %s: %v", serviceName, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to restart systemd service: %v", err))
utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to restart systemd service: %v", err))
return
}
postLog.Debug(fmt.Sprintf("[RestartInstanceHandler] Systemd service %s restarted successfully", serviceName))
@@ -812,17 +812,17 @@ func RestartInstanceHandler(w http.ResponseWriter, r *http.Request) {
case "init.d":
if err := service.RestartInitDService(serviceName); err != nil {
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Failed to restart init.d service %s: %v", serviceName, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to restart init.d service: %v", err))
utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to restart init.d service: %v", err))
return
}
postLog.Debug(fmt.Sprintf("[RestartInstanceHandler] Init.d service %s restarted successfully", serviceName))
default:
handlers.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Unsupported init system: %s", initType))
utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Unsupported init system: %s", initType))
return
}
handlers.SendSuccessResponse(w, "Instance restarted successfully", map[string]interface{}{
utils.SendSuccessResponse(w, "Instance restarted successfully", map[string]interface{}{
"instanceID": instanceID,
"serviceName": serviceName,
})
@@ -830,9 +830,9 @@ func RestartInstanceHandler(w http.ResponseWriter, r *http.Request) {
}
func GetInstanceStatusHandler(w http.ResponseWriter, r *http.Request) {
userID, err := handlers.Auth(w, r, http.MethodGet)
userID, err := utils.Auth(w, r, http.MethodGet)
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[GetInstanceStatusHandler] Auth failed: %v", err))
return
}
@@ -840,45 +840,45 @@ func GetInstanceStatusHandler(w http.ResponseWriter, r *http.Request) {
queryParams := r.URL.Query()
instanceIDStr := queryParams.Get("instanceID")
if instanceIDStr == "" {
handlers.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
return
}
instanceID, err := strconv.Atoi(instanceIDStr)
if err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
return
}
instance, err := database.DBQueryFrpcInstanceByID(instanceID)
if err == sql.ErrNoRows {
handlers.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
utils.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
return
}
if err != nil {
postLog.Error(fmt.Sprintf("[GetInstanceStatusHandler] Failed to query instance: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
return
}
if instance.UserID != userID {
handlers.SendErrorResponse(w, http.StatusForbidden, "Instance not found")
utils.SendErrorResponse(w, http.StatusForbidden, "Instance not found")
return
}
err = service.IsInstanceRunning(instanceID)
isRunning := err == nil
handlers.SendSuccessResponse(w, "Instance status retrieved successfully", map[string]interface{}{
utils.SendSuccessResponse(w, "Instance status retrieved successfully", map[string]interface{}{
"instanceID": instanceID,
"isRunning": isRunning,
})
}
func GetInstanceInfoHandler(w http.ResponseWriter, r *http.Request) {
userID, err := handlers.Auth(w, r, http.MethodGet)
userID, err := utils.Auth(w, r, http.MethodGet)
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[GetInstanceInfoHandler] Auth failed: %v", err))
return
}
@@ -886,57 +886,57 @@ func GetInstanceInfoHandler(w http.ResponseWriter, r *http.Request) {
queryParams := r.URL.Query()
instanceIDStr := queryParams.Get("instanceID")
if instanceIDStr == "" {
handlers.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
return
}
instanceID, err := strconv.Atoi(instanceIDStr)
if err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
return
}
instance, err := database.DBQueryFrpcInstanceByID(instanceID)
if err == sql.ErrNoRows {
handlers.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
utils.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
return
}
if err != nil {
postLog.Error(fmt.Sprintf("[GetInstanceInfoHandler] Failed to query instance: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
return
}
if instance.UserID != userID {
handlers.SendErrorResponse(w, http.StatusForbidden, "Instance not found")
utils.SendErrorResponse(w, http.StatusForbidden, "Instance not found")
return
}
user, err := database.GetUserByID(userID)
if err != nil {
postLog.Error(fmt.Sprintf("[GetInstanceInfoHandler] Failed to get user info: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info")
return
}
serviceName, err := database.GetServiceNameByInstanceID(instanceID)
if err != nil {
postLog.Error(fmt.Sprintf("[GetInstanceInfoHandler] Failed to get service name: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get service name")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get service name")
return
}
configContent, err := os.ReadFile(instance.ConfigPath)
if err != nil {
postLog.Error(fmt.Sprintf("[GetInstanceInfoHandler] Failed to read config file: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to read config file")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to read config file")
return
}
frpcConfig, err := config.DecodeFrpcConfig(string(configContent))
if err != nil {
postLog.Error(fmt.Sprintf("[GetInstanceInfoHandler] Failed to decode frpc config: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to decode frpc config")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to decode frpc config")
return
}
@@ -960,5 +960,5 @@ func GetInstanceInfoHandler(w http.ResponseWriter, r *http.Request) {
response["serverPort"] = frpcConfig.Global["serverPort"]
}
handlers.SendSuccessResponse(w, "Instance info retrieved successfully", response)
utils.SendSuccessResponse(w, "Instance info retrieved successfully", response)
}

View File

@@ -1,4 +1,4 @@
package instance
package handlers
import (
"encoding/json"
@@ -10,16 +10,16 @@ import (
"super-frpc/config"
"super-frpc/database"
"super-frpc/handlers"
"super-frpc/utils"
"super-frpc/postLog"
"github.com/BurntSushi/toml"
)
func CreateProxyHandler(w http.ResponseWriter, r *http.Request) {
userID, err := handlers.Auth(w, r, http.MethodPost, "superuser", "admin")
userID, err := utils.Auth(w, r, http.MethodPost, "superuser", "admin")
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[CreateProxyHandler] Auth failed: %v", err))
return
}
@@ -27,7 +27,7 @@ func CreateProxyHandler(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
postLog.Error(fmt.Sprintf("[CreateProxyHandler] Failed to read request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
return
}
defer r.Body.Close()
@@ -35,21 +35,21 @@ func CreateProxyHandler(w http.ResponseWriter, r *http.Request) {
var reqMap map[string]interface{}
if err := json.Unmarshal(body, &reqMap); err != nil {
postLog.Error(fmt.Sprintf("[CreateProxyHandler] Failed to unmarshal request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
return
}
instanceID := getStringFromMap(reqMap, "instanceID")
if instanceID == "" {
postLog.Error("[CreateProxyHandler] instanceID is required")
handlers.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
return
}
proxyInfoMap, ok := reqMap["proxyInfo"].(map[string]interface{})
if !ok {
postLog.Error("[CreateProxyHandler] Invalid proxyInfo format")
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid proxyInfo format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid proxyInfo format")
return
}
@@ -64,7 +64,7 @@ func CreateProxyHandler(w http.ResponseWriter, r *http.Request) {
if proxyInfo.Name == "" || proxyInfo.Type == "" || proxyInfo.LocalIP == "" ||
proxyInfo.LocalPort == 0 || proxyInfo.RemotePort == 0 {
postLog.Error("[CreateProxyHandler] Missing required fields in proxyInfo")
handlers.SendErrorResponse(w, http.StatusBadRequest, "Missing required fields in proxyInfo")
utils.SendErrorResponse(w, http.StatusBadRequest, "Missing required fields in proxyInfo")
return
}
@@ -73,37 +73,37 @@ func CreateProxyHandler(w http.ResponseWriter, r *http.Request) {
instance, err = database.DBQueryFrpcInstanceByID(instanceIDInt)
if err != nil {
postLog.Error(fmt.Sprintf("[CreateProxyHandler] Failed to query instance: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
return
}
if instance.UserID != userID {
postLog.Error(fmt.Sprintf("[CreateProxyHandler] Instance not found for user %d", userID))
handlers.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
utils.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
return
}
configContent, err := os.ReadFile(instance.ConfigPath)
if err != nil {
postLog.Error(fmt.Sprintf("[CreateProxyHandler] Failed to read config file %s: %v", instance.ConfigPath, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to read config file")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to read config file")
return
}
updatedContent, err := config.AddFrpcProxy(string(configContent), proxyInfo)
if err != nil {
postLog.Error(fmt.Sprintf("[CreateProxyHandler] Failed to add proxy: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to add proxy")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to add proxy")
return
}
if err := os.WriteFile(instance.ConfigPath, []byte(updatedContent), 0644); err != nil {
postLog.Error(fmt.Sprintf("[CreateProxyHandler] Failed to write config file %s: %v", instance.ConfigPath, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to write config file")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to write config file")
return
}
handlers.SendSuccessResponse(w, "Proxy created successfully", map[string]interface{}{
utils.SendSuccessResponse(w, "Proxy created successfully", map[string]interface{}{
"instanceID": instance.ID,
"configPath": instance.ConfigPath,
"proxyName": proxyInfo.Name,
@@ -112,9 +112,9 @@ func CreateProxyHandler(w http.ResponseWriter, r *http.Request) {
}
func ModifyProxyHandler(w http.ResponseWriter, r *http.Request) {
userID, err := handlers.Auth(w, r, http.MethodPost, "superuser", "admin")
userID, err := utils.Auth(w, r, http.MethodPost, "superuser", "admin")
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[ModifyProxyHandler] Auth failed: %v", err))
return
}
@@ -122,7 +122,7 @@ func ModifyProxyHandler(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
postLog.Error(fmt.Sprintf("[ModifyProxyHandler] Failed to read request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
return
}
defer r.Body.Close()
@@ -130,21 +130,21 @@ func ModifyProxyHandler(w http.ResponseWriter, r *http.Request) {
var reqMap map[string]interface{}
if err := json.Unmarshal(body, &reqMap); err != nil {
postLog.Error(fmt.Sprintf("[ModifyProxyHandler] Failed to unmarshal request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
return
}
instanceID := getStringFromMap(reqMap, "instanceID")
if instanceID == "" {
postLog.Error("[ModifyProxyHandler] instanceID is required")
handlers.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
return
}
proxyInfoMap, ok := reqMap["proxyInfo"].(map[string]interface{})
if !ok {
postLog.Error("[ModifyProxyHandler] Invalid proxyInfo format")
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid proxyInfo format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid proxyInfo format")
return
}
@@ -159,7 +159,7 @@ func ModifyProxyHandler(w http.ResponseWriter, r *http.Request) {
if proxyInfo.Name == "" || proxyInfo.Type == "" || proxyInfo.LocalIP == "" ||
proxyInfo.LocalPort == 0 || proxyInfo.RemotePort == 0 {
postLog.Error("[ModifyProxyHandler] Missing required fields in proxyInfo")
handlers.SendErrorResponse(w, http.StatusBadRequest, "Missing required fields in proxyInfo")
utils.SendErrorResponse(w, http.StatusBadRequest, "Missing required fields in proxyInfo")
return
}
@@ -168,37 +168,37 @@ func ModifyProxyHandler(w http.ResponseWriter, r *http.Request) {
instance, err = database.DBQueryFrpcInstanceByID(instanceIDInt)
if err != nil {
postLog.Error(fmt.Sprintf("[ModifyProxyHandler] Failed to query instance: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
return
}
if instance.UserID != userID {
postLog.Error(fmt.Sprintf("[ModifyProxyHandler] Instance not found for user %d", userID))
handlers.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
utils.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
return
}
configContent, err := os.ReadFile(instance.ConfigPath)
if err != nil {
postLog.Error(fmt.Sprintf("[ModifyProxyHandler] Failed to read config file %s: %v", instance.ConfigPath, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to read config file")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to read config file")
return
}
updatedContent, err := config.ModifyFrpcProxy(string(configContent), proxyInfo)
if err != nil {
postLog.Error(fmt.Sprintf("[ModifyProxyHandler] Failed to modify proxy: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to modify proxy")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to modify proxy")
return
}
if err := os.WriteFile(instance.ConfigPath, []byte(updatedContent), 0644); err != nil {
postLog.Error(fmt.Sprintf("[ModifyProxyHandler] Failed to write config file %s: %v", instance.ConfigPath, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to write config file")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to write config file")
return
}
handlers.SendSuccessResponse(w, "Proxy modified successfully", map[string]interface{}{
utils.SendSuccessResponse(w, "Proxy modified successfully", map[string]interface{}{
"instanceID": instance.ID,
"configPath": instance.ConfigPath,
"proxyName": proxyInfo.Name,
@@ -207,9 +207,9 @@ func ModifyProxyHandler(w http.ResponseWriter, r *http.Request) {
}
func DeleteProxyHandler(w http.ResponseWriter, r *http.Request) {
userID, err := handlers.Auth(w, r, http.MethodPost, "superuser", "admin")
userID, err := utils.Auth(w, r, http.MethodPost, "superuser", "admin")
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[DeleteProxyHandler] Auth failed: %v", err))
return
}
@@ -217,7 +217,7 @@ func DeleteProxyHandler(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
postLog.Error(fmt.Sprintf("[DeleteProxyHandler] Failed to read request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
return
}
defer r.Body.Close()
@@ -225,21 +225,21 @@ func DeleteProxyHandler(w http.ResponseWriter, r *http.Request) {
var reqMap map[string]interface{}
if err := json.Unmarshal(body, &reqMap); err != nil {
postLog.Error(fmt.Sprintf("[DeleteProxyHandler] Failed to unmarshal request body: %v", err))
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
return
}
instanceID := getStringFromMap(reqMap, "instanceID")
if instanceID == "" {
postLog.Error("[DeleteProxyHandler] instanceID is required")
handlers.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
return
}
proxyName := getStringFromMap(reqMap, "proxyName")
if proxyName == "" {
postLog.Error("[DeleteProxyHandler] proxyName is required")
handlers.SendErrorResponse(w, http.StatusBadRequest, "proxyName is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "proxyName is required")
return
}
@@ -248,37 +248,37 @@ func DeleteProxyHandler(w http.ResponseWriter, r *http.Request) {
instance, err = database.DBQueryFrpcInstanceByID(instanceIDInt)
if err != nil {
postLog.Error(fmt.Sprintf("[DeleteProxyHandler] Failed to query instance: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
return
}
if instance.UserID != userID {
postLog.Error(fmt.Sprintf("[DeleteProxyHandler] Instance not found for user %d", userID))
handlers.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
utils.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
return
}
configContent, err := os.ReadFile(instance.ConfigPath)
if err != nil {
postLog.Error(fmt.Sprintf("[DeleteProxyHandler] Failed to read config file %s: %v", instance.ConfigPath, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to read config file")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to read config file")
return
}
updatedContent, err := config.RemoveFrpcProxy(string(configContent), proxyName)
if err != nil {
postLog.Error(fmt.Sprintf("[DeleteProxyHandler] Failed to remove proxy: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to remove proxy")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to remove proxy")
return
}
if err := os.WriteFile(instance.ConfigPath, []byte(updatedContent), 0644); err != nil {
postLog.Error(fmt.Sprintf("[DeleteProxyHandler] Failed to write config file %s: %v", instance.ConfigPath, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to write config file")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to write config file")
return
}
handlers.SendSuccessResponse(w, "Proxy deleted successfully", map[string]interface{}{
utils.SendSuccessResponse(w, "Proxy deleted successfully", map[string]interface{}{
"instanceID": instance.ID,
"configPath": instance.ConfigPath,
"proxyName": proxyName,
@@ -287,9 +287,9 @@ func DeleteProxyHandler(w http.ResponseWriter, r *http.Request) {
}
func ListProxiesHandler(w http.ResponseWriter, r *http.Request) {
userID, err := handlers.Auth(w, r, http.MethodGet)
userID, err := utils.Auth(w, r, http.MethodGet)
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[ListProxiesHandler] Auth failed: %v", err))
return
}
@@ -298,7 +298,7 @@ func ListProxiesHandler(w http.ResponseWriter, r *http.Request) {
instanceID := queryParams.Get("instanceID")
if instanceID == "" {
postLog.Error("[ListProxiesHandler] instanceID is required")
handlers.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
return
}
@@ -307,27 +307,27 @@ func ListProxiesHandler(w http.ResponseWriter, r *http.Request) {
instance, err = database.DBQueryFrpcInstanceByID(instanceIDInt)
if err != nil {
postLog.Error(fmt.Sprintf("[ListProxiesHandler] Failed to query instance: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
return
}
if instance.UserID != userID {
postLog.Error(fmt.Sprintf("[ListProxiesHandler] Instance not found for user %d", userID))
handlers.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
utils.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
return
}
configContent, err := os.ReadFile(instance.ConfigPath)
if err != nil {
postLog.Error(fmt.Sprintf("[ListProxiesHandler] Failed to read config file %s: %v", instance.ConfigPath, err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to read config file")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to read config file")
return
}
var cfg config.FrpcConfig
if _, err := toml.Decode(string(configContent), &cfg); err != nil {
postLog.Error(fmt.Sprintf("[ListProxiesHandler] Failed to parse config: %v", err))
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to parse config file")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to parse config file")
return
}
@@ -343,7 +343,7 @@ func ListProxiesHandler(w http.ResponseWriter, r *http.Request) {
proxyList[i] = proxyData
}
handlers.SendSuccessResponse(w, "Proxies listed successfully", map[string]interface{}{
utils.SendSuccessResponse(w, "Proxies listed successfully", map[string]interface{}{
"instanceID": instance.ID,
"proxyCount": len(proxyList),
"proxies": proxyList,

18
handlers/settings.go Normal file
View File

@@ -0,0 +1,18 @@
package handlers
import (
"fmt"
"net/http"
"super-frpc/postLog"
"super-frpc/utils"
)
func GetSettingsHandler(w http.ResponseWriter, r *http.Request) {
_, err := utils.Auth(w, r, http.MethodGet, "superuser", "admin")
if err != nil {
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[GetSettingsHandler] Auth failed: %v", err))
return
}
}

View File

@@ -1,4 +1,4 @@
package user
package handlers
import (
"encoding/json"
@@ -8,7 +8,7 @@ import (
"super-frpc/database"
"super-frpc/global"
"super-frpc/handlers"
"super-frpc/utils"
"super-frpc/postLog"
"super-frpc/session"
)
@@ -50,20 +50,20 @@ type RemoveSessionRequest struct {
func RegisterHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
handlers.SendErrorResponse(w, http.StatusMethodNotAllowed, "Invalid request method")
utils.SendErrorResponse(w, http.StatusMethodNotAllowed, "Invalid request method")
postLog.Warning(fmt.Sprintf("[RegisterHandler] Invalid request method: %s", r.Method))
return
}
if !session.ValidateTimeStamp(r.Header, global.Is.Debug) {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid or missing X-Timestamp in header")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid or missing X-Timestamp in header")
postLog.Warning(fmt.Sprintf("[RegisterHandler] Invalid or missing X-Timestamp in header: %s", r.Header.Get("X-Timestamp")))
return
}
body, err := io.ReadAll(r.Body)
if err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
postLog.Warning(fmt.Sprintf("[RegisterHandler] Failed to read request body: %v", err))
return
}
@@ -71,32 +71,32 @@ func RegisterHandler(w http.ResponseWriter, r *http.Request) {
var req RegisterRequest
if err := json.Unmarshal(body, &req); err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
postLog.Warning(fmt.Sprintf("[RegisterHandler] Invalid request format: %v", err))
return
}
if req.Username == "" || req.Passwd == "" {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Username and password are required")
utils.SendErrorResponse(w, http.StatusBadRequest, "Username and password are required")
postLog.Warning("[RegisterHandler] New user registration failed: username or password is empty")
return
}
if !isValidInput(req.Username) || !isValidInput(req.Passwd) {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid input: contains illegal characters")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid input: contains illegal characters")
postLog.Debug(fmt.Sprintf("[RegisterHandler] New user registration failed: username or password contains illegal characters \"%s\":\"%s\"", req.Username, req.Passwd))
return
}
if !session.IsValidPassword(req.Passwd) {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Password does not meet complexity requirements (must contain uppercase, lowercase, digit, and special character)")
utils.SendErrorResponse(w, http.StatusBadRequest, "Password does not meet complexity requirements (must contain uppercase, lowercase, digit, and special character)")
postLog.Debug(fmt.Sprintf("[RegisterHandler] New user registration failed: password \"%s\" does not meet complexity requirements", req.Passwd))
return
}
userList, err := database.DBListUsers()
if err != nil {
handlers.SendErrorResponse(w, http.StatusInternalServerError, err.Error())
utils.SendErrorResponse(w, http.StatusInternalServerError, err.Error())
postLog.Error(fmt.Sprintf("[RegisterHandler] Failed to list users: %v", err))
return
}
@@ -109,19 +109,19 @@ func RegisterHandler(w http.ResponseWriter, r *http.Request) {
userID, err := database.AddUser(req.Username, req.Passwd, newUserType, session.HashPassword, session.IsValidPassword)
if err != nil {
handlers.SendErrorResponse(w, http.StatusInternalServerError, err.Error())
utils.SendErrorResponse(w, http.StatusInternalServerError, err.Error())
postLog.Error(fmt.Sprintf("[RegisterHandler] Failed to register user \"%s\": %v", req.Username, err))
return
}
user, err := database.GetUserByID(userID)
if err != nil {
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to retrieve user after registration")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to retrieve user after registration")
postLog.Error(fmt.Sprintf("[RegisterHandler] Failed to retrieve user \"%s\" after registration: %v", req.Username, err))
return
}
handlers.SendSuccessResponse(w, "user registered successfully", map[string]interface{}{
utils.SendSuccessResponse(w, "user registered successfully", map[string]interface{}{
"userID": user.UserID,
"username": user.Username,
"type": user.Type,
@@ -130,19 +130,19 @@ func RegisterHandler(w http.ResponseWriter, r *http.Request) {
func LoginHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
handlers.SendErrorResponse(w, http.StatusMethodNotAllowed, "Invalid request method")
utils.SendErrorResponse(w, http.StatusMethodNotAllowed, "Invalid request method")
postLog.Warning(fmt.Sprintf("[LoginHandler] Invalid request method: %s", r.Method))
return
}
if !session.ValidateTimeStamp(r.Header, global.Is.Debug) {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid or missing X-Timestamp in header")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid or missing X-Timestamp in header")
return
}
body, err := io.ReadAll(r.Body)
if err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
postLog.Warning(fmt.Sprintf("[LoginHandler] Failed to read request body: %v", err))
return
}
@@ -150,57 +150,57 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
var req LoginRequest
if err := json.Unmarshal(body, &req); err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
postLog.Warning(fmt.Sprintf("[LoginHandler] Invalid request format: %v", err))
return
}
if req.Username == "" || req.Passwd == "" {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Username and password are required")
utils.SendErrorResponse(w, http.StatusBadRequest, "Username and password are required")
postLog.Warning("[LoginHandler] Login failed: username or password is empty")
return
}
if !isValidInput(req.Username) || !isValidInput(req.Passwd) {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid input: contains illegal characters")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid input: contains illegal characters")
postLog.Debug(fmt.Sprintf("[LoginHandler] Login failed: username or password contains illegal characters \"%s\":\"%s\"", req.Username, req.Passwd))
return
}
user, err := database.GetUserByUsername(req.Username)
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, "User not exist")
utils.SendErrorResponse(w, http.StatusUnauthorized, "User not exist")
postLog.Warning(fmt.Sprintf("[LoginHandler] Login failed: User not exist \"%s\"", req.Username))
return
}
if !session.VerifyPassword(req.Passwd, user.Passwd) {
handlers.SendErrorResponse(w, http.StatusUnauthorized, "Invalid password")
utils.SendErrorResponse(w, http.StatusUnauthorized, "Invalid password")
postLog.Warning(fmt.Sprintf("[LoginHandler] Login failed: invalid password for user \"%s\"", req.Username))
return
}
existingTokenInfo, err := session.GetTokenInfo(user.UserID)
if err == nil && existingTokenInfo != nil {
handlers.SendErrorResponse(w, http.StatusConflict, "User is already logged in")
utils.SendErrorResponse(w, http.StatusConflict, "User is already logged in")
postLog.Warning(fmt.Sprintf("[LoginHandler] Login failed: user \"%s\" is already logged in", req.Username))
return
}
token, err := session.GenerateToken(user.UserID)
if err != nil {
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to generate token")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to generate token")
postLog.Error(fmt.Sprintf("[LoginHandler] Failed to generate token for user \"%s\": %v", req.Username, err))
return
}
if err := session.JoinSession(user.UserID, user.Username, token); err != nil {
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to create session")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to create session")
postLog.Error(fmt.Sprintf("[LoginHandler] Failed to create session for user \"%s\": %v", req.Username, err))
return
}
handlers.SendSuccessResponse(w, "Login successful", map[string]interface{}{
utils.SendSuccessResponse(w, "Login successful", map[string]interface{}{
"token": token,
"userID": user.UserID,
"username": user.Username,
@@ -210,9 +210,9 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
}
func LogoutHandler(w http.ResponseWriter, r *http.Request) {
userID, err := handlers.Auth(w, r, http.MethodGet)
userID, err := utils.Auth(w, r, http.MethodGet)
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[LogoutHandler] Auth failed: %v", err))
return
}
@@ -229,32 +229,32 @@ func LogoutHandler(w http.ResponseWriter, r *http.Request) {
sessionTokenMux.RUnlock()
if sessionID == "" {
handlers.SendErrorResponse(w, http.StatusNotFound, "Session not found for token")
utils.SendErrorResponse(w, http.StatusNotFound, "Session not found for token")
postLog.Warning(fmt.Sprintf("[LogoutHandler] Session not found for token from user [%d]%s", userID, session.GetUsernameByID(userID)))
return
}
if err := session.RemoveSession(sessionID); err != nil {
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to logout")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to logout")
postLog.Error(fmt.Sprintf("[LogoutHandler] Failed to logout user [%d]%s: %v", userID, session.GetUsernameByID(userID), err))
return
}
handlers.SendSuccessResponse(w, "Logout successful", nil)
utils.SendSuccessResponse(w, "Logout successful", nil)
postLog.Info(fmt.Sprintf("[LogoutHandler] User [%d]%s Logout successful", userID, session.GetUsernameByID(userID)))
}
func RemoveSessionHandler(w http.ResponseWriter, r *http.Request) {
userID, err := handlers.Auth(w, r, http.MethodPost, "superuser")
userID, err := utils.Auth(w, r, http.MethodPost, "superuser")
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[RemoveSessionHandler] Auth failed: %v", err))
return
}
body, err := io.ReadAll(r.Body)
if err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
postLog.Warning(fmt.Sprintf("[RemoveSessionHandler] Failed to read request body: %v", err))
return
}
@@ -262,38 +262,38 @@ func RemoveSessionHandler(w http.ResponseWriter, r *http.Request) {
var req RemoveSessionRequest
if err := json.Unmarshal(body, &req); err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
postLog.Warning(fmt.Sprintf("[RemoveSessionHandler] Invalid request format: %v", err))
return
}
if req.SessionID == "" {
handlers.SendErrorResponse(w, http.StatusBadRequest, "SessionID is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "SessionID is required")
postLog.Warning("[RemoveSessionHandler] SessionID is empty")
return
}
if err := session.RemoveSession(req.SessionID); err != nil {
handlers.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to remove session: %v", err))
utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to remove session: %v", err))
postLog.Error(fmt.Sprintf("[RemoveSessionHandler] Failed to remove session %s: %v", req.SessionID, err))
return
}
postLog.Info(fmt.Sprintf("[RemoveSessionHandler] User [%d]%s removed session %s", userID, session.GetUsernameByID(userID), req.SessionID))
handlers.SendSuccessResponse(w, "Session removed successfully", nil)
utils.SendSuccessResponse(w, "Session removed successfully", nil)
}
func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
_, err := handlers.Auth(w, r, http.MethodPost, "superuser")
_, err := utils.Auth(w, r, http.MethodPost, "superuser")
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[CreateUserHandler] Auth failed: %v", err))
return
}
body, err := io.ReadAll(r.Body)
if err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
postLog.Warning(fmt.Sprintf("[CreateUserHandler] Failed to read request body: %v", err))
return
}
@@ -301,38 +301,38 @@ func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
var req CreateUserRequest
if err := json.Unmarshal(body, &req); err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
postLog.Warning(fmt.Sprintf("[CreateUserHandler] Invalid request format: %v", err))
return
}
if req.Username == "" || req.Passwd == "" || req.Type == "" {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Username, password, and type are required")
utils.SendErrorResponse(w, http.StatusBadRequest, "Username, password, and type are required")
postLog.Warning("[CreateUserHandler] CreateUser failed: username, password, or type is empty")
return
}
if req.Type != "admin" && req.Type != "user" && req.Type != "superuser" {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid type: must be 'admin' or 'user' or 'superuser'")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid type: must be 'admin' or 'user' or 'superuser'")
postLog.Warning(fmt.Sprintf("[CreateUserHandler] CreateUser failed: invalid type: %s", req.Type))
return
}
userID, err := database.AddUser(req.Username, req.Passwd, req.Type, session.HashPassword, session.IsValidPassword)
if err != nil {
handlers.SendErrorResponse(w, http.StatusInternalServerError, err.Error())
utils.SendErrorResponse(w, http.StatusInternalServerError, err.Error())
postLog.Error(fmt.Sprintf("[RegisterHandler] Failed to register user \"%s\": %v", req.Username, err))
return
}
user, err := database.GetUserByID(userID)
if err != nil {
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to retrieve user after creation")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to retrieve user after creation")
postLog.Error(fmt.Sprintf("[CreateUserHandler] Failed to retrieve user \"%s\" after creation: %v", req.Username, err))
return
}
handlers.SendSuccessResponse(w, "User created successfully", map[string]interface{}{
utils.SendSuccessResponse(w, "User created successfully", map[string]interface{}{
"userID": user.UserID,
"username": user.Username,
"type": user.Type,
@@ -341,15 +341,15 @@ func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
}
func ModifyUserHandler(w http.ResponseWriter, r *http.Request) {
_, err := handlers.Auth(w, r, http.MethodPost, "user", "admin", "superuser")
_, err := utils.Auth(w, r, http.MethodPost, "user", "admin", "superuser")
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, fmt.Sprintf("Auth failed: %v", err))
utils.SendErrorResponse(w, http.StatusUnauthorized, fmt.Sprintf("Auth failed: %v", err))
return
}
body, err := io.ReadAll(r.Body)
if err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
postLog.Warning(fmt.Sprintf("[ModifyUserHandler] Failed to read request body: %v", err))
return
}
@@ -358,43 +358,43 @@ func ModifyUserHandler(w http.ResponseWriter, r *http.Request) {
var req ModifyUserRequest
if err := json.Unmarshal(body, &req); err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
postLog.Warning(fmt.Sprintf("[ModifyUserHandler] Invalid request format: %v", err))
return
}
if req.UserID == 0 {
handlers.SendErrorResponse(w, http.StatusBadRequest, "UserID is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "UserID is required")
postLog.Warning("[ModifyUserHandler] ModifyUser failed: UserID is empty")
return
}
if req.Username == "" {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Username is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "Username is required")
postLog.Warning("[ModifyUserHandler] ModifyUser failed: username is empty")
return
}
if err := database.DBUpdateUser(req.UserID, req.Username, req.Passwd); err != nil {
handlers.SendErrorResponse(w, http.StatusInternalServerError, err.Error())
utils.SendErrorResponse(w, http.StatusInternalServerError, err.Error())
postLog.Error(fmt.Sprintf("[ModifyUserHandler] Failed to update user [%d]: %v", req.UserID, err))
return
}
handlers.SendSuccessResponse(w, "User updated successfully", nil)
utils.SendSuccessResponse(w, "User updated successfully", nil)
postLog.Info(fmt.Sprintf("[ModifyUserHandler] User [%d]%s updated successfully to: %s", req.UserID, session.GetUsernameByID(req.UserID), req.Username))
}
func ModifyUserTypeHandler(w http.ResponseWriter, r *http.Request) {
_, err := handlers.Auth(w, r, http.MethodPost, "superuser")
_, err := utils.Auth(w, r, http.MethodPost, "superuser")
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[ModifyUserTypeHandler] Auth failed: %v", err))
return
}
body, err := io.ReadAll(r.Body)
if err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
postLog.Warning(fmt.Sprintf("[ModifyUserTypeHandler] Failed to read request body: %v", err))
return
}
@@ -403,40 +403,40 @@ func ModifyUserTypeHandler(w http.ResponseWriter, r *http.Request) {
var req ModifyUserTypeRequest
if err := json.Unmarshal(body, &req); err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
postLog.Warning(fmt.Sprintf("[ModifyUserTypeHandler] Invalid request format: %v", err))
return
}
if req.UserID == 0 {
handlers.SendErrorResponse(w, http.StatusBadRequest, "UserID is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "UserID is required")
postLog.Warning("[ModifyUserTypeHandler] ModifyUserType failed: UserID is empty")
return
}
if req.Type != "admin" && req.Type != "visitor" && req.Type != "superuser" {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid type: must be 'admin' or 'visitor' or 'superuser'")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid type: must be 'admin' or 'visitor' or 'superuser'")
postLog.Warning(fmt.Sprintf("[ModifyUserTypeHandler] ModifyUserType failed: invalid type: %s", req.Type))
return
}
if err := database.DBUpdateUserType(req.UserID, req.Type); err != nil {
handlers.SendErrorResponse(w, http.StatusInternalServerError, err.Error())
utils.SendErrorResponse(w, http.StatusInternalServerError, err.Error())
postLog.Error(fmt.Sprintf("[ModifyUserTypeHandler] Failed to update user type [%d]: %v", req.UserID, err))
return
}
handlers.SendSuccessResponse(w, "User type updated successfully", nil)
utils.SendSuccessResponse(w, "User type updated successfully", nil)
postLog.Info(fmt.Sprintf("[ModifyUserTypeHandler] User [%d]%s type updated successfully to: %s", req.UserID, session.GetUsernameByID(req.UserID), req.Type))
}
func RemoveUserHandler(w http.ResponseWriter, r *http.Request) {
_, err := handlers.Auth(w, r, http.MethodPost, "superuser")
_, err := utils.Auth(w, r, http.MethodPost, "superuser")
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[RemoveUserHandler] Auth failed: %v", err))
return
}
body, err := io.ReadAll(r.Body)
if err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
postLog.Warning(fmt.Sprintf("[RemoveUserHandler] Failed to read request body: %v", err))
return
}
@@ -444,51 +444,51 @@ func RemoveUserHandler(w http.ResponseWriter, r *http.Request) {
var req RemoveUserRequest
if err := json.Unmarshal(body, &req); err != nil {
handlers.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
postLog.Warning(fmt.Sprintf("[RemoveUserHandler] Invalid request format: %v", err))
return
}
if req.TargetUserID == 0 {
handlers.SendErrorResponse(w, http.StatusBadRequest, "TargetUserID is required")
utils.SendErrorResponse(w, http.StatusBadRequest, "TargetUserID is required")
postLog.Warning("[RemoveUserHandler] RemoveUser failed: TargetUserID is empty")
return
}
if err := database.RemoveUser(req.TargetUserID); err != nil {
handlers.SendErrorResponse(w, http.StatusInternalServerError, err.Error())
utils.SendErrorResponse(w, http.StatusInternalServerError, err.Error())
postLog.Error(fmt.Sprintf("[RemoveUserHandler] Failed to remove user [%d]: %v", req.TargetUserID, err))
return
}
handlers.SendSuccessResponse(w, "User removed successfully", nil)
utils.SendSuccessResponse(w, "User removed successfully", nil)
}
func ListUserHandler(w http.ResponseWriter, r *http.Request) {
_, err := handlers.Auth(w, r, http.MethodGet, "superuser")
_, err := utils.Auth(w, r, http.MethodGet, "superuser")
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[ListUserHandler] Auth failed: %v", err))
return
}
userList, err := database.DBListUsers()
if err != nil {
handlers.SendErrorResponse(w, http.StatusInternalServerError, "Failed to list users")
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to list users")
postLog.Error(fmt.Sprintf("[ListUserHandler] Failed to list users: %v", err))
return
}
handlers.SendSuccessResponse(w, "User list retrieved successfully", userList)
utils.SendSuccessResponse(w, "User list retrieved successfully", userList)
}
func ListActiveSessionsHandler(w http.ResponseWriter, r *http.Request) {
userID, err := handlers.Auth(w, r, http.MethodGet, "superuser", "admin")
userID, err := utils.Auth(w, r, http.MethodGet, "superuser", "admin")
if err != nil {
handlers.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
postLog.Warning(fmt.Sprintf("[ListActiveSessionsHandler] Auth failed: %v", err))
return
}
sessions := session.ListActiveSessions()
postLog.Debug(fmt.Sprintf("[ListActiveSessionsHandler] User [%d]%s listed %d active sessions", userID, session.GetUsernameByID(userID), len(sessions)))
handlers.SendSuccessResponse(w, "Active sessions listed", sessions)
utils.SendSuccessResponse(w, "Active sessions listed", sessions)
}
func isValidInput(input string) bool {

41
main.go
View File

@@ -1,6 +1,7 @@
package main
import (
"encoding/json"
"flag"
"fmt"
"net/http"
@@ -10,10 +11,10 @@ import (
"super-frpc/database"
"super-frpc/frpLogger"
"super-frpc/global"
"super-frpc/handlers"
"super-frpc/postLog"
"super-frpc/session"
"super-frpc/service"
"super-frpc/session"
"super-frpc/utils"
"super-frpc/watchdog"
"syscall"
"time"
@@ -27,24 +28,23 @@ func main() {
flag.Parse()
if _, err := os.Stat(*configPath); os.IsNotExist(err) {
defaultConfig := `{
"listenAddr": "0.0.0.0",
"listenPort": "8080",
"configDir": "./configs"
}`
if err := os.WriteFile(*configPath, []byte(defaultConfig), 0644); err != nil {
// Load the default config
configData, err := json.MarshalIndent(global.CurrentConfig, "", " ")
if err != nil {
postLog.Warning(fmt.Sprintf("Failed to marshal default config: %v", err))
} else if err := os.WriteFile(*configPath, configData, 0644); err != nil {
postLog.Warning(fmt.Sprintf("Failed to create default config file: %v", err))
}
postLog.Info(fmt.Sprintf("Created default config file at %s", *configPath))
}
cfg, err := config.LoadConfig(*configPath, service.GetInitSystem)
err := config.LoadConfig(*configPath, service.GetInitSystem)
if err != nil {
postLog.Fatal(fmt.Sprintf("Failed to load config: %v", err))
}
postLog.SetDebugMode(cfg.Debug)
global.Is.Debug = cfg.Debug
postLog.SetDebugMode(global.CurrentConfig.Debug)
global.Is.Debug = global.CurrentConfig.Debug
if err := postLog.InitLogsDatabase(*dbPath_log); err != nil {
postLog.Fatal(fmt.Sprintf("Failed to initialize logs database: %v", err))
@@ -61,12 +61,9 @@ func main() {
}
frpLogger.SetDatabase(global.ConfigDB, global.FrpcDB)
frpLogger.SetDebugMode(cfg.Debug)
frpLogger.SetDebugMode(global.CurrentConfig.Debug)
_, err = config.GetConfig()
if err != nil {
postLog.Fatal(fmt.Sprintf("Failed to get config: %v", err))
}
config.GetConfig()
postLog.InitLogBroadcaster()
@@ -76,15 +73,15 @@ func main() {
if err != nil {
postLog.Error(fmt.Sprintf("Unable to initialize Watchdog: %s", err))
} else {
if !watchdog.Connect("127.0.0.1", cfg.Watchdog.Port) {
postLog.Error(fmt.Sprintf("Failed to connect to Watchdog at %s:%d", "127.0.0.1", cfg.Watchdog.Port))
if !watchdog.Connect("127.0.0.1", global.CurrentConfig.Watchdog.Port) {
postLog.Error(fmt.Sprintf("Failed to connect to Watchdog at %s:%d", "127.0.0.1", global.CurrentConfig.Watchdog.Port))
} else {
postLog.Info(fmt.Sprintf("Connected to Watchdog at %s:%d", "127.0.0.1", cfg.Watchdog.Port))
postLog.Info(fmt.Sprintf("Connected to Watchdog at %s:%d", "127.0.0.1", global.CurrentConfig.Watchdog.Port))
global.Is.WatchdogConnected = true
}
}
addr := fmt.Sprintf("%s:%s", cfg.ListenAddr, cfg.ListenPort)
addr := fmt.Sprintf("%s:%s", global.CurrentConfig.ListenAddr, global.CurrentConfig.ListenPort)
server := &http.Server{
Addr: addr,
ReadTimeout: 15 * time.Second,
@@ -139,9 +136,9 @@ func GetStatusHandler(w http.ResponseWriter, r *http.Request) {
if global.Is.WatchdogConnected {
statusInfo["WatchdogStatus"] = "Online"
}
handlers.SendSuccessResponse(w, "getStatus", statusInfo)
utils.SendSuccessResponse(w, "getStatus", statusInfo)
}
func GetSoftwareInfoHandler(w http.ResponseWriter, r *http.Request) {
handlers.SendSuccessResponse(w, "getSoftwareInfo", global.Software)
utils.SendSuccessResponse(w, "getSoftwareInfo", global.Software)
}

View File

@@ -4,11 +4,10 @@ import (
"fmt"
"net/http"
"super-frpc/frpLogger"
"super-frpc/handlers"
"super-frpc/instance"
"super-frpc/utils"
"super-frpc/postLog"
"super-frpc/session"
"super-frpc/user"
"super-frpc/handlers"
)
func setupRoutes() {
@@ -17,33 +16,33 @@ func setupRoutes() {
systemLogHandler := postLog.NewLogSocketHandler(postLog.GetLogBroadcaster())
http.HandleFunc("/system/getLogs", systemLogHandler.Handle)
http.HandleFunc("/register", user.RegisterHandler)
http.HandleFunc("/login", user.LoginHandler)
http.HandleFunc("/logout", user.LogoutHandler)
http.HandleFunc("/register", handlers.RegisterHandler)
http.HandleFunc("/login", handlers.LoginHandler)
http.HandleFunc("/logout", handlers.LogoutHandler)
http.HandleFunc("/userMgr/create", user.CreateUserHandler)
http.HandleFunc("/userMgr/remove", user.RemoveUserHandler)
http.HandleFunc("/userMgr/list", user.ListUserHandler)
http.HandleFunc("/userMgr/modify", user.ModifyUserHandler)
http.HandleFunc("/userMgr/modifyType", user.ModifyUserTypeHandler)
http.HandleFunc("/userMgr/create", handlers.CreateUserHandler)
http.HandleFunc("/userMgr/remove", handlers.RemoveUserHandler)
http.HandleFunc("/userMgr/list", handlers.ListUserHandler)
http.HandleFunc("/userMgr/modify", handlers.ModifyUserHandler)
http.HandleFunc("/userMgr/modifyType", handlers.ModifyUserTypeHandler)
http.HandleFunc("/sessionMgr/list", user.ListActiveSessionsHandler)
http.HandleFunc("/sessionMgr/remove", user.RemoveSessionHandler)
http.HandleFunc("/sessionMgr/list", handlers.ListActiveSessionsHandler)
http.HandleFunc("/sessionMgr/remove", handlers.RemoveSessionHandler)
http.HandleFunc("/frpcAct/instanceMgr/create", instance.CreateInstanceHandler)
http.HandleFunc("/frpcAct/instanceMgr/delete", instance.DeleteInstanceHandler)
http.HandleFunc("/frpcAct/instanceMgr/modify", instance.ModifyInstanceHandler)
http.HandleFunc("/frpcAct/instanceMgr/list", instance.ListInstancesHandler)
http.HandleFunc("/frpcAct/instanceMgr/start", instance.StartInstanceHandler)
http.HandleFunc("/frpcAct/instanceMgr/stop", instance.StopInstanceHandler)
http.HandleFunc("/frpcAct/instanceMgr/restart", instance.RestartInstanceHandler)
http.HandleFunc("/frpcAct/instanceMgr/status", instance.GetInstanceStatusHandler)
http.HandleFunc("/frpcAct/instanceMgr/getInfo", instance.GetInstanceInfoHandler)
http.HandleFunc("/frpcAct/instanceMgr/create", handlers.CreateInstanceHandler)
http.HandleFunc("/frpcAct/instanceMgr/delete", handlers.DeleteInstanceHandler)
http.HandleFunc("/frpcAct/instanceMgr/modify", handlers.ModifyInstanceHandler)
http.HandleFunc("/frpcAct/instanceMgr/list", handlers.ListInstancesHandler)
http.HandleFunc("/frpcAct/instanceMgr/start", handlers.StartInstanceHandler)
http.HandleFunc("/frpcAct/instanceMgr/stop", handlers.StopInstanceHandler)
http.HandleFunc("/frpcAct/instanceMgr/restart", handlers.RestartInstanceHandler)
http.HandleFunc("/frpcAct/instanceMgr/status", handlers.GetInstanceStatusHandler)
http.HandleFunc("/frpcAct/instanceMgr/getInfo", handlers.GetInstanceInfoHandler)
http.HandleFunc("/frpcAct/instanceMgr/logs", frpLogger.NewInstanceLogHandler(session.ValidateTokenFromMap).ServeHTTP)
http.HandleFunc("/frpcAct/proxyMgr/create", instance.CreateProxyHandler)
http.HandleFunc("/frpcAct/proxyMgr/modify", instance.ModifyProxyHandler)
http.HandleFunc("/frpcAct/proxyMgr/delete", instance.DeleteProxyHandler)
http.HandleFunc("/frpcAct/proxyMgr/list", instance.ListProxiesHandler)
http.HandleFunc("/frpcAct/proxyMgr/create", handlers.CreateProxyHandler)
http.HandleFunc("/frpcAct/proxyMgr/modify", handlers.ModifyProxyHandler)
http.HandleFunc("/frpcAct/proxyMgr/delete", handlers.DeleteProxyHandler)
http.HandleFunc("/frpcAct/proxyMgr/list", handlers.ListProxiesHandler)
http.HandleFunc("/", NotFoundHandler)
@@ -53,5 +52,5 @@ func setupRoutes() {
func NotFoundHandler(w http.ResponseWriter, r *http.Request) {
postLog.Error(fmt.Sprintf("Route not found: %s %s", r.Method, r.URL.Path))
handlers.SendErrorResponse(w, http.StatusNotFound, "Invalid request path")
utils.SendErrorResponse(w, http.StatusNotFound, "Invalid request path")
}

View File

@@ -9,27 +9,17 @@ import (
"strconv"
"strings"
"super-frpc/config"
"super-frpc/database"
"super-frpc/global"
"super-frpc/postLog"
)
func GetConfigDir() (string, error) {
cfg, err := config.GetConfig()
if err != nil {
postLog.Error(fmt.Sprintf("[GetConfigDir] Failed to get config: %v", err))
return "", err
}
return cfg.InstancePath, nil
return global.CurrentConfig.InstancePath, nil
}
func GetFrpcPath() (string, error) {
cfg, err := config.GetConfig()
if err != nil {
postLog.Error(fmt.Sprintf("[GetFrpcPath] Failed to get config: %v", err))
return "", err
}
return cfg.FrpcPath, nil
return global.CurrentConfig.FrpcPath, nil
}
func GetInitSystem() string {

View File

@@ -1,4 +1,4 @@
package handlers
package utils
import (
"encoding/json"
@@ -19,6 +19,8 @@ type Response struct {
Data interface{} `json:"data,omitempty"`
}
// SendErrorResponse sends an error response with the specified status code and message.
// If data is provided, it is included in the response.
func SendErrorResponse(w http.ResponseWriter, statusCode int, message string, data ...interface{}) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(statusCode)
@@ -37,6 +39,8 @@ func SendErrorResponse(w http.ResponseWriter, statusCode int, message string, da
w.Write(jsonResp)
}
// SendSuccessResponse sends a success response with the specified message and data.
// If data is provided, it is included in the response.
func SendSuccessResponse(w http.ResponseWriter, message string, data interface{}) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
@@ -53,6 +57,10 @@ func SendSuccessResponse(w http.ResponseWriter, message string, data interface{}
w.Write(jsonResp)
}
// Auth authenticates the request.
// It checks the request method, timestamp, and token.
// If any of these checks fail, it returns an error.
// If no error occurs, it returns the user ID.
func Auth(w http.ResponseWriter, r *http.Request, targetMethod string, allowedUserLevels ...string) (int, error) {
if r.Method != targetMethod {
return 0, fmt.Errorf("Method not allowed: %s", targetMethod)