refactor(frpc, database): move all database actions to database.go
This commit is contained in:
+61
-1
@@ -5,6 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
_ "modernc.org/sqlite"
|
_ "modernc.org/sqlite"
|
||||||
)
|
)
|
||||||
@@ -283,4 +284,63 @@ func InitUserDatabase(dbPath string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DBAddFrpcInstance(instance FrpcInstance) error {
|
||||||
|
_, err := frpcDB.Exec("INSERT INTO frpcInstances (userID, name, serverAddr, serverPort, auth_method, bootAtStart, runUser, configPath, createdAt) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
|
instance.UserID, instance.Name, instance.ServerAddr, instance.ServerPort, instance.AuthMethod, instance.BootAtStart, instance.RunUser, instance.ConfigPath, time.Now().Format(time.RFC3339))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to insert frpc instance: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DBQueryFrpcInstance(userID int, instanceName string) (FrpcInstance, error) {
|
||||||
|
var instance FrpcInstance
|
||||||
|
err := frpcDB.QueryRow("SELECT id, userID, name, serverAddr, serverPort, auth_method, bootAtStart, runUser, configPath, createdAt FROM frpcInstances WHERE userID = ? AND name = ?", userID, instanceName).Scan(
|
||||||
|
&instance.ID, &instance.UserID, &instance.Name, &instance.ServerAddr, &instance.ServerPort, &instance.AuthMethod, &instance.BootAtStart, &instance.RunUser, &instance.ConfigPath, &instance.CreatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return instance, fmt.Errorf("failed to query frpc instance: %w", err)
|
||||||
|
}
|
||||||
|
return instance, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DBRemoveFrpcInstance(userID int, instanceName string) error {
|
||||||
|
_, err := frpcDB.Exec("DELETE FROM frpcInstances WHERE userID = ? AND name = ?", userID, instanceName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to delete frpc instance: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DBUpdateFrpcInstance(instance FrpcInstance) error {
|
||||||
|
_, err := frpcDB.Exec("UPDATE frpcInstances SET serverAddr = ?, serverPort = ?, auth_method = ?, bootAtStart = ?, runUser = ?, configPath = ? WHERE id = ?",
|
||||||
|
instance.ServerAddr, instance.ServerPort, instance.AuthMethod, instance.BootAtStart, instance.RunUser, instance.ConfigPath, instance.ID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to update frpc instance: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DBListFrpcInstances(userID int) ([]FrpcInstance, error) {
|
||||||
|
rows, err := frpcDB.Query("SELECT id, userID, name, serverAddr, serverPort, auth_method, bootAtStart, runUser, configPath, createdAt FROM frpcInstances WHERE userID = ?", userID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to query frpc instances: %w", err)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var instances []FrpcInstance
|
||||||
|
for rows.Next() {
|
||||||
|
var instance FrpcInstance
|
||||||
|
if err := rows.Scan(&instance.ID, &instance.UserID, &instance.Name, &instance.ServerAddr, &instance.ServerPort, &instance.AuthMethod, &instance.BootAtStart, &instance.RunUser, &instance.ConfigPath, &instance.CreatedAt); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to scan frpc instance: %w", err)
|
||||||
|
}
|
||||||
|
instances = append(instances, instance)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = rows.Err(); err != nil {
|
||||||
|
return nil, fmt.Errorf("rows error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return instances, nil
|
||||||
|
}
|
||||||
@@ -165,6 +165,7 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add frpc instance
|
||||||
configFileName := fmt.Sprintf("superfrpc_%s_%s.toml", user.Username, req.InstanceInfo.Name)
|
configFileName := fmt.Sprintf("superfrpc_%s_%s.toml", user.Username, req.InstanceInfo.Name)
|
||||||
configPath := filepath.Join(configDir, configFileName)
|
configPath := filepath.Join(configDir, configFileName)
|
||||||
|
|
||||||
@@ -175,13 +176,18 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = frpcDB.Exec(`
|
instance := FrpcInstance{
|
||||||
INSERT INTO frpcInstances (userID, name, serverAddr, serverPort, auth_method, bootAtStart, runUser, configPath, createdAt)
|
UserID: userID,
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
Name: req.InstanceInfo.Name,
|
||||||
`, userID, req.InstanceInfo.Name, req.InstanceInfo.ServerAddr, req.InstanceInfo.ServerPort,
|
ServerAddr: req.InstanceInfo.ServerAddr,
|
||||||
req.InstanceInfo.AuthMethod, req.BootAtStart, runUser, configPath, time.Now().Format(time.RFC3339))
|
ServerPort: req.InstanceInfo.ServerPort,
|
||||||
|
AuthMethod: req.InstanceInfo.AuthMethod,
|
||||||
|
BootAtStart: req.BootAtStart,
|
||||||
|
RunUser: runUser,
|
||||||
|
ConfigPath: configPath,
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err := DBAddFrpcInstance(instance); err != nil {
|
||||||
os.Remove(configPath)
|
os.Remove(configPath)
|
||||||
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to save instance %s to database: %v", req.InstanceInfo.Name, err))
|
postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to save instance %s to database: %v", req.InstanceInfo.Name, err))
|
||||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to save instance to database")
|
SendErrorResponse(w, http.StatusInternalServerError, "Failed to save instance to database")
|
||||||
@@ -197,6 +203,7 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Finish add frpc instance
|
||||||
|
|
||||||
SendSuccessResponse(w, "Instance created successfully", map[string]interface{}{
|
SendSuccessResponse(w, "Instance created successfully", map[string]interface{}{
|
||||||
"name": req.InstanceInfo.Name,
|
"name": req.InstanceInfo.Name,
|
||||||
@@ -233,7 +240,6 @@ func DeleteInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从Header中验证token和timeStamp
|
|
||||||
userID, _, err := ValidateRequestWithHeader(w, r)
|
userID, _, err := ValidateRequestWithHeader(w, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to validate request header: %v", err))
|
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to validate request header: %v", err))
|
||||||
@@ -255,15 +261,16 @@ func DeleteInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var instance FrpcInstance
|
var instance FrpcInstance
|
||||||
err = frpcDB.QueryRow(`
|
// err = frpcDB.QueryRow(`
|
||||||
SELECT id, userID, name, serverAddr, serverPort, auth_method, bootAtStart, runUser, configPath, createdAt
|
// SELECT id, userID, name, serverAddr, serverPort, auth_method, bootAtStart, runUser, configPath, createdAt
|
||||||
FROM frpcInstances WHERE userID = ? AND name = ?
|
// FROM frpcInstances WHERE userID = ? AND name = ?
|
||||||
`, userID, instanceName).Scan(
|
// `, userID, instanceName).Scan(
|
||||||
&instance.ID, &instance.UserID, &instance.Name, &instance.ServerAddr, &instance.ServerPort,
|
// &instance.ID, &instance.UserID, &instance.Name, &instance.ServerAddr, &instance.ServerPort,
|
||||||
&instance.AuthMethod, &instance.BootAtStart, &instance.RunUser, &instance.ConfigPath, &instance.CreatedAt)
|
// &instance.AuthMethod, &instance.BootAtStart, &instance.RunUser, &instance.ConfigPath, &instance.CreatedAt)
|
||||||
|
instance, err = DBQueryFrpcInstance(userID, instanceName)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
SendErrorResponse(w, http.StatusNotFound, "instance not found")
|
SendErrorResponse(w, http.StatusNotFound, "Instance not found")
|
||||||
|
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] User %d tried to delete a not existed instance: %s", userID, instanceName))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -288,8 +295,7 @@ func DeleteInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = frpcDB.Exec("DELETE FROM frpcInstances WHERE id = ?", instance.ID)
|
if err := DBRemoveFrpcInstance(userID, instanceName); err != nil {
|
||||||
if err != nil {
|
|
||||||
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to delete instance %s from database: %v", instanceName, err))
|
postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to delete instance %s from database: %v", instanceName, err))
|
||||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to delete instance from database")
|
SendErrorResponse(w, http.StatusInternalServerError, "Failed to delete instance from database")
|
||||||
return
|
return
|
||||||
@@ -351,15 +357,16 @@ func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request, field string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
var instance FrpcInstance
|
var instance FrpcInstance
|
||||||
err = frpcDB.QueryRow(`
|
// err = frpcDB.QueryRow(`
|
||||||
SELECT id, userID, name, serverAddr, serverPort, auth_method, bootAtStart, runUser, configPath, createdAt
|
// SELECT id, userID, name, serverAddr, serverPort, auth_method, bootAtStart, runUser, configPath, createdAt
|
||||||
FROM frpcInstances WHERE userID = ? AND name = ?
|
// FROM frpcInstances WHERE userID = ? AND name = ?
|
||||||
`, userID, instanceName).Scan(
|
// `, userID, instanceName).Scan(
|
||||||
&instance.ID, &instance.UserID, &instance.Name, &instance.ServerAddr, &instance.ServerPort,
|
// &instance.ID, &instance.UserID, &instance.Name, &instance.ServerAddr, &instance.ServerPort,
|
||||||
&instance.AuthMethod, &instance.BootAtStart, &instance.RunUser, &instance.ConfigPath, &instance.CreatedAt)
|
// &instance.AuthMethod, &instance.BootAtStart, &instance.RunUser, &instance.ConfigPath, &instance.CreatedAt)
|
||||||
|
instance, err = DBQueryFrpcInstance(userID, instanceName)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
SendErrorResponse(w, http.StatusNotFound, "instance not found")
|
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] User %d tried to modify a not existed instance: %s", userID, instanceName))
|
||||||
|
SendErrorResponse(w, http.StatusNotFound, "Instance not found")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -435,12 +442,20 @@ func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request, field string)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = frpcDB.Exec(`
|
// _, err = frpcDB.Exec(`
|
||||||
UPDATE frpcInstances
|
// UPDATE frpcInstances
|
||||||
SET name = ?, serverAddr = ?, serverPort = ?, auth_method = ?, bootAtStart = ?, runUser = ?, configPath = ?
|
// SET name = ?, serverAddr = ?, serverPort = ?, auth_method = ?, bootAtStart = ?, runUser = ?, configPath = ?
|
||||||
WHERE id = ?
|
// WHERE id = ?
|
||||||
`, newName, newServerAddr, newServerPort, newAuthMethod, newBootAtStart, newRunUser, newConfigPath, instance.ID)
|
// `, newName, newServerAddr, newServerPort, newAuthMethod, newBootAtStart, newRunUser, newConfigPath, instance.ID)
|
||||||
|
|
||||||
|
instance.Name = newName
|
||||||
|
instance.ServerAddr = newServerAddr
|
||||||
|
instance.ServerPort = newServerPort
|
||||||
|
instance.AuthMethod = newAuthMethod
|
||||||
|
instance.BootAtStart = newBootAtStart
|
||||||
|
instance.RunUser = newRunUser
|
||||||
|
instance.ConfigPath = newConfigPath
|
||||||
|
err = DBUpdateFrpcInstance(instance)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to update instance in database: %v", err))
|
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to update instance in database: %v", err))
|
||||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to update instance in database")
|
SendErrorResponse(w, http.StatusInternalServerError, "Failed to update instance in database")
|
||||||
@@ -483,30 +498,19 @@ func ListInstancesHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rows, err := frpcDB.Query(`
|
// rows, err := frpcDB.Query(`
|
||||||
SELECT id, userID, name, serverAddr, serverPort, auth_method, bootAtStart, runUser, configPath, createdAt
|
// SELECT id, userID, name, serverAddr, serverPort, auth_method, bootAtStart, runUser, configPath, createdAt
|
||||||
FROM frpcInstances WHERE userID = ?
|
// FROM frpcInstances WHERE userID = ?
|
||||||
`, userID)
|
// `, userID)
|
||||||
|
instanceList, err := DBListFrpcInstances(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
postLog.Error(fmt.Sprintf("[ListInstancesHandler] Failed to query instances: %v", err))
|
postLog.Error(fmt.Sprintf("[ListInstancesHandler] Failed to query instances: %v", err))
|
||||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instances")
|
SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instances")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
|
||||||
|
|
||||||
var instances []map[string]interface{}
|
|
||||||
for rows.Next() {
|
|
||||||
var instance FrpcInstance
|
|
||||||
var createdAtStr string
|
|
||||||
if err := rows.Scan(
|
|
||||||
&instance.ID, &instance.UserID, &instance.Name, &instance.ServerAddr, &instance.ServerPort,
|
|
||||||
&instance.AuthMethod, &instance.BootAtStart, &instance.RunUser, &instance.ConfigPath, &createdAtStr,
|
|
||||||
); err != nil {
|
|
||||||
postLog.Error(fmt.Sprintf("[ListInstancesHandler] Failed to scan instance: %v", err))
|
|
||||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to scan instance")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
var responseInstances []map[string]interface{}
|
||||||
|
for _, instance := range instanceList {
|
||||||
instanceData := map[string]interface{}{
|
instanceData := map[string]interface{}{
|
||||||
"name": instance.Name,
|
"name": instance.Name,
|
||||||
"serverAddr": instance.ServerAddr,
|
"serverAddr": instance.ServerAddr,
|
||||||
@@ -515,7 +519,7 @@ func ListInstancesHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
"bootAtStart": instance.BootAtStart,
|
"bootAtStart": instance.BootAtStart,
|
||||||
"runUser": instance.RunUser,
|
"runUser": instance.RunUser,
|
||||||
"configPath": instance.ConfigPath,
|
"configPath": instance.ConfigPath,
|
||||||
"createdAt": createdAtStr,
|
"createdAt": instance.CreatedAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
if userType == "visitor" {
|
if userType == "visitor" {
|
||||||
@@ -524,14 +528,14 @@ func ListInstancesHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
delete(instanceData, "auth_method")
|
delete(instanceData, "auth_method")
|
||||||
}
|
}
|
||||||
|
|
||||||
instances = append(instances, instanceData)
|
responseInstances = append(responseInstances, instanceData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if instances == nil {
|
if responseInstances == nil {
|
||||||
instances = []map[string]interface{}{}
|
responseInstances = []map[string]interface{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
SendSuccessResponse(w, "Instances retrieved successfully", instances)
|
SendSuccessResponse(w, "Instances retrieved successfully", responseInstances)
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateFrpcConfig(info InstanceInfo) string {
|
func generateFrpcConfig(info InstanceInfo) string {
|
||||||
@@ -550,7 +554,7 @@ func generateFrpcConfig(info InstanceInfo) string {
|
|||||||
|
|
||||||
func addFrpcProxy(info FrpcProxyInfo) string {
|
func addFrpcProxy(info FrpcProxyInfo) string {
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
sb.WriteString("[[proxies]]")
|
sb.WriteString("[[proxies]]\n")
|
||||||
sb.WriteString(fmt.Sprintf("name = %s\n", info.Name))
|
sb.WriteString(fmt.Sprintf("name = %s\n", info.Name))
|
||||||
sb.WriteString(fmt.Sprintf("type = %s\n", info.Type))
|
sb.WriteString(fmt.Sprintf("type = %s\n", info.Type))
|
||||||
sb.WriteString(fmt.Sprintf("local_ip = %s\n", info.LocalIP))
|
sb.WriteString(fmt.Sprintf("local_ip = %s\n", info.LocalIP))
|
||||||
|
|||||||
Reference in New Issue
Block a user