520 lines
11 KiB
Go
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
|
|
}
|