Files
labtorary_management_system/backend/system/client.go
2025-02-19 15:01:38 +08:00

520 lines
11 KiB
Go

// system/client.go
package system
import (
"bufio"
"encoding/json"
"fmt"
"net"
"strings"
)
type SystemClient struct {
socketPath string
}
type Command struct {
Action string `json:"action"`
Params map[string]interface{} `json:"params"`
}
type Response struct {
Success bool `json:"success"`
Data interface{} `json:"data"`
Error string `json:"error,omitempty"`
}
type User struct {
Username string `json:"username"`
UID string `json:"uid"`
GID string `json:"gid"`
HomeDir string `json:"home_dir"`
Shell string `json:"shell"`
}
type Group struct {
GroupName string `json:"groupName"`
}
type SambaConnection struct {
PID string `json:"pid"`
Username string `json:"username"`
Group string `json:"group"`
Machine string `json:"machine"`
Protocol string `json:"protocol"`
Folder string `json:"folder"`
}
func NewSystemClient(socketPath string) *SystemClient {
return &SystemClient{
socketPath: socketPath,
}
}
func (c *SystemClient) sendCommand(cmd Command) (*Response, error) {
// 連接到 Unix socket
conn, err := net.Dial("unix", c.socketPath)
if err != nil {
return nil, fmt.Errorf("failed to connect to socket: %v", err)
}
defer conn.Close()
// 發送命令
encoder := json.NewEncoder(conn)
if err := encoder.Encode(cmd); err != nil {
return nil, fmt.Errorf("failed to encode command: %v", err)
}
// 讀取響應
decoder := json.NewDecoder(conn)
var response Response
if err := decoder.Decode(&response); err != nil {
return nil, fmt.Errorf("failed to decode response: %v", err)
}
return &response, nil
}
func (c *SystemClient) GetUsers() ([]User, error) {
resp, err := c.sendCommand(Command{
Action: "get_users",
Params: nil,
})
if err != nil {
return nil, err
}
if !resp.Success {
return nil, fmt.Errorf(resp.Error)
}
var users []User
dataStr, ok := resp.Data.(string)
if !ok {
fmt.Println("Error: Data is not a string")
return users, nil
}
scanner := bufio.NewScanner(strings.NewReader(dataStr))
for scanner.Scan() {
line := scanner.Text()
parts := strings.Split(line, ":")
if len(parts) < 7 {
continue // Skip malformed lines
}
username := parts[0]
uid := parts[2]
gid := parts[3]
homeDir := parts[5]
shell := parts[6]
user := User{
Username: username,
UID: uid,
GID: gid,
HomeDir: homeDir,
Shell: shell,
}
users = append(users, user)
}
if err := scanner.Err(); err != nil {
fmt.Println("Error reading command output:", err)
return users, nil
}
// Marshal to JSON and print
_, err = json.MarshalIndent(users, "", " ")
if err != nil {
fmt.Println("Error marshalling to JSON:", err)
return users, nil
}
return users, nil
}
func (c *SystemClient) GetGroups() ([]Group, error) {
resp, err := c.sendCommand(Command{
Action: "get_groups",
Params: nil,
})
if err != nil {
return nil, err
}
if !resp.Success {
return nil, fmt.Errorf(resp.Error)
}
var groups []Group
dataStr, ok := resp.Data.(string)
if !ok {
fmt.Println("Error: Data is not a string")
return groups, nil
}
scanner := bufio.NewScanner(strings.NewReader(dataStr))
for scanner.Scan() {
line := scanner.Text()
group := Group{
GroupName: line,
}
groups = append(groups, group)
}
if err := scanner.Err(); err != nil {
fmt.Println("Error reading command output:", err)
return groups, nil
}
// Marshal to JSON and print
_, err = json.MarshalIndent(groups, "", " ")
if err != nil {
fmt.Println("Error marshalling to JSON:", err)
return groups, nil
}
return groups, nil
}
func (c *SystemClient) GetUserGroups(username string) ([]Group, error) {
resp, err := c.sendCommand(Command{
Action: "get_user_groups",
Params: map[string]interface{}{
"username": username,
},
})
if err != nil {
return nil, err
}
if !resp.Success {
return nil, fmt.Errorf(resp.Error)
}
var groups []Group
dataStr, ok := resp.Data.([]interface{})
if !ok {
fmt.Println("Error: Data is not a string")
return groups, nil
}
for _, data := range dataStr {
str, ok := data.(string)
if !ok {
return nil, fmt.Errorf("data contains non-string element")
}
group := Group{
GroupName: str,
}
groups = append(groups, group)
}
// Marshal to JSON and print
_, err = json.MarshalIndent(groups, "", " ")
if err != nil {
fmt.Println("Error marshalling to JSON:", err)
return groups, nil
}
return groups, nil
}
func (c *SystemClient) AddUserToGroups(username string, groups []string) error {
// Loop through the groups and add the user to each group
for _, group := range groups {
// Implement logic to add the user to the group
resp, err := c.sendCommand(Command{
Action: "add_user_to_group",
Params: map[string]interface{}{
"username": username,
"group": group,
},
})
if err != nil {
return err
}
if !resp.Success {
return fmt.Errorf(resp.Error)
}
}
return nil
}
func (c *SystemClient) RemoveUserFromGroup(username, group string) error {
resp, err := c.sendCommand(Command{
Action: "remove_user_from_group",
Params: map[string]interface{}{
"username": username,
"group": group,
},
})
if err != nil {
return err
}
if !resp.Success {
return fmt.Errorf(resp.Error)
}
return nil
}
func (c *SystemClient) CreateUser(username, password string, group string, isAdmin bool, shell string) error {
resp, err := c.sendCommand(Command{
Action: "create_user",
Params: map[string]interface{}{
"username": username,
"password": password,
"group": group,
"is_admin": isAdmin,
"shell": shell,
},
})
if err != nil {
return err
}
if !resp.Success {
return fmt.Errorf(resp.Error)
}
return nil
}
func (c *SystemClient) ModifyUserPasswd(username string, password string) error {
resp, err := c.sendCommand(Command{
Action: "modify_user_passwd",
Params: map[string]interface{}{
"username": username,
"password": password,
},
})
if err != nil {
return err
}
if !resp.Success {
return fmt.Errorf(resp.Error)
}
return nil
}
func (c *SystemClient) DeleteUser(username string) error {
resp, err := c.sendCommand(Command{
Action: "delete_user",
Params: map[string]interface{}{
"username": username,
},
})
if err != nil {
return err
}
if !resp.Success {
return fmt.Errorf(resp.Error)
}
return nil
}
func (c *SystemClient) GetSambaConnections() ([]SambaConnection, error) {
resp, err := c.sendCommand(Command{
Action: "get_samba_status",
Params: nil,
})
if err != nil {
return nil, err
}
if !resp.Success {
return nil, fmt.Errorf(resp.Error)
}
var connections []SambaConnection
data, err := json.Marshal(resp.Data)
if err != nil {
return nil, err
}
if err := json.Unmarshal(data, &connections); err != nil {
return nil, err
}
return connections, nil
}
func (c *SystemClient) GetSambaGlobalSetting() (string, error) {
resp, err := c.sendCommand(Command{
Action: "get_samba_settings",
Params: nil,
})
if err != nil {
return "", err
}
if !resp.Success {
return "", fmt.Errorf(resp.Error)
}
settings_str, ok := resp.Data.(string)
if !ok {
fmt.Println("Error: Data is not a string")
return "", nil
}
return settings_str, nil
}
func (c *SystemClient) GetSambaSectionSetting() (string, error) {
resp, err := c.sendCommand(Command{
Action: "get_samba_settings",
Params: nil,
})
if err != nil {
return "", err
}
if !resp.Success {
return "", fmt.Errorf(resp.Error)
}
settings_str, ok := resp.Data.(string)
if !ok {
fmt.Println("Error: Data is not a string")
return "", nil
}
return settings_str, nil
}
func (c *SystemClient) UpdateSambaSectionSetting(fullSectionSettingsJSON string) error {
// Step 1: Get all current settings
settings, err := c.GetSambaSectionSetting()
if err != nil {
return fmt.Errorf("failed to fetch current Samba settings: %v", err)
}
// Step 2: Parse the settings JSON string into a map
var settingsMap map[string]interface{}
if err := json.Unmarshal([]byte(settings), &settingsMap); err != nil {
return fmt.Errorf("failed to parse Samba settings JSON: %v", err)
}
// Step 3: Parse the full new section settings JSON
var newSectionSettings map[string]interface{}
if err := json.Unmarshal([]byte(fullSectionSettingsJSON), &newSectionSettings); err != nil {
return fmt.Errorf("failed to parse new section settings JSON: %v", err)
}
// Step 4: Replace the entire "sections" field
settingsMap["sections"] = newSectionSettings
// Step 5: Convert updated settings back to JSON
updatedSettings, err := json.Marshal(settingsMap)
if err != nil {
return fmt.Errorf("failed to marshal updated settings to JSON: %v", err)
}
// Step 6: Send the updated settings using `update_section_setting`
resp, err := c.sendCommand(Command{
Action: "update_section_setting",
Params: map[string]interface{}{"config": string(updatedSettings)},
})
if err != nil {
return fmt.Errorf("failed to send updated settings: %v", err)
}
if !resp.Success {
return fmt.Errorf("failed to update section settings: %v", resp.Error)
}
return nil
}
func (c *SystemClient) UpdateSambaGlobalSetting(fullGlobalSettingsJSON string) error {
// Step 1: Get all current settings
settings, err := c.GetSambaGlobalSetting()
if err != nil {
return fmt.Errorf("failed to fetch current Samba settings: %v", err)
}
// Step 2: Parse the settings JSON string into a map
var settingsMap map[string]interface{}
if err := json.Unmarshal([]byte(settings), &settingsMap); err != nil {
return fmt.Errorf("failed to parse Samba settings JSON: %v", err)
}
// Step 3: Parse the full new global settings JSON
var newGlobalSettings map[string]interface{}
if err := json.Unmarshal([]byte(fullGlobalSettingsJSON), &newGlobalSettings); err != nil {
return fmt.Errorf("failed to parse new global settings JSON: %v", err)
}
// Step 4: Replace the entire "global" field
settingsMap["global"] = newGlobalSettings
// Step 5: Convert updated settings back to JSON
updatedSettings, err := json.Marshal(settingsMap)
if err != nil {
return fmt.Errorf("failed to marshal updated settings to JSON: %v", err)
}
// Step 6: Send the updated settings using `update_section_setting`
resp, err := c.sendCommand(Command{
Action: "update_section_setting",
Params: map[string]interface{}{"config": string(updatedSettings)},
})
if err != nil {
return fmt.Errorf("failed to send updated settings: %v", err)
}
if !resp.Success {
return fmt.Errorf("failed to update global settings: %v", resp.Error)
}
return nil
}
func (c *SystemClient) GetSambaServiceInfo() (string, error) {
resp, err := c.sendCommand(Command{
Action: "get_samba_service_info",
Params: nil,
})
if err != nil {
return "", err
}
if !resp.Success {
return "", fmt.Errorf(resp.Error)
}
dataStr, ok := resp.Data.(string)
if !ok {
fmt.Println("Error: Data is not a string")
return "", nil
}
return dataStr, nil
}
func (c *SystemClient) RestartSambaService() error {
resp, err := c.sendCommand(Command{
Action: "restart_samba_service",
Params: nil,
})
if err != nil {
return err
}
if !resp.Success {
return fmt.Errorf(resp.Error)
}
return nil
}