diff --git a/component/wireguard.go b/component/wireguard.go index cefd323..64c84f4 100644 --- a/component/wireguard.go +++ b/component/wireguard.go @@ -97,8 +97,8 @@ func (w WireguardComponent) GenerateClientFile(clientInfo *model.Client, server var outPath = "/tmp/" + fmt.Sprintf("%s.conf", clientInfo.Name) var templatePath = "./template/wg.client.conf" if os.Getenv("GIN_MODE") != "release" { - outPath = "E:\\Workspace\\Go\\wireguard-dashboard\\template\\" + fmt.Sprintf("%s.conf", clientInfo.Name) - templatePath = "E:\\Workspace\\Go\\wireguard-dashboard\\template\\wg.client.conf" + outPath = "E:\\Workspace\\Go\\wireguard-ui\\template\\tmp\\" + fmt.Sprintf("%s.conf", clientInfo.Name) + templatePath = "E:\\Workspace\\Go\\wireguard-ui\\template\\conf\\wg.client.conf" } err = Template().Execute(templatePath, outPath, execData) diff --git a/cron/cron.go b/cron/cron.go new file mode 100644 index 0000000..0cb6242 --- /dev/null +++ b/cron/cron.go @@ -0,0 +1 @@ +package cron diff --git a/http/api/setting.go b/http/api/setting.go index 67b5646..3450e47 100644 --- a/http/api/setting.go +++ b/http/api/setting.go @@ -1,11 +1,13 @@ package api import ( + "encoding/json" "gitee.ltd/lxh/logger/log" "github.com/gin-gonic/gin" "slices" "wireguard-ui/http/param" "wireguard-ui/http/response" + "wireguard-ui/http/vo" "wireguard-ui/model" "wireguard-ui/script" "wireguard-ui/service" @@ -113,3 +115,48 @@ func (setting) GetAllSetting(c *gin.Context) { func (setting) GetPublicAddr(c *gin.Context) { response.R(c).OkWithData(utils.Network().GetHostPublicIP()) } + +// Export +// @description: 导出配置 +// @receiver setting +// @param c +func (setting) Export(c *gin.Context) { + // 获取当前登陆用户 + var loginUser *vo.User + if loginUser = GetCurrentLoginUser(c); c.IsAborted() { + return + } + + if loginUser.Account != "admin" { + response.R(c).FailedWithError("非法操作,你被捕啦!") + return + } + + // 获取配置 + data, err := service.Setting().Export() + if err != nil { + response.R(c).FailedWithError(err) + return + } + + // 生成配置文件 + dataBytes, _ := json.Marshal(data) + filepath, err := utils.FileUtils().GenerateFile("config.json", dataBytes) + if err != nil { + response.R(c).FailedWithError(err) + return + } + + c.Header("Content-Type", "application/octet-stream") + c.Header("Content-Disposition", "attachment; filename="+filepath) + c.Header("Content-Transfer-Encoding", "binary") + c.Header("Connection", "keep-alive") + c.File(filepath) + //if err = os.Remove(filepath); err != nil { + // log.Errorf("删除临时文件失败: %s", err.Error()) + //} +} + +func (setting) Import(c *gin.Context) { + +} diff --git a/http/router/setting.go b/http/router/setting.go index 1e976da..9cd3a3e 100644 --- a/http/router/setting.go +++ b/http/router/setting.go @@ -17,5 +17,6 @@ func SettingApi(r *gin.RouterGroup) { setting.GET("", api.Setting().GetSetting) // 获取指定配置 setting.GET("/all", api.Setting().GetAllSetting) // 获取全部配置 setting.GET("/public-addr", api.Setting().GetPublicAddr) // 获取公网IP + setting.GET("/export", api.Setting().Export) // 导出配置文件 } } diff --git a/http/vo/setting.go b/http/vo/setting.go index aece1d6..6925e6f 100644 --- a/http/vo/setting.go +++ b/http/vo/setting.go @@ -7,3 +7,46 @@ type SettingItem struct { Data string `json:"data"` Describe string `json:"describe"` } + +type Export struct { + Global Global `json:"global"` + Server Server `json:"server"` + Clients []Client `json:"clients"` +} + +type Global struct { + MTU int `json:"MTU"` + ConfigFilePath string `json:"configFilePath"` + DnsServer []string `json:"dnsServer"` + EndpointAddress string `json:"endpointAddress"` + FirewallMark string `json:"firewallMark"` + PersistentKeepalive int `json:"persistentKeepalive"` + Table string `json:"table"` +} + +type Server struct { + IpScope []string `json:"ipScope"` + ListenPort int `json:"listenPort"` + PrivateKey string `json:"privateKey"` + PublicKey string `json:"publicKey"` + PostUpScript string `json:"postUpScript"` + PostDownScript string `json:"postDownScript"` +} + +type Client struct { + Name string `json:"name"` + Email string `json:"email"` + SubnetRange string `json:"subnetRange"` + IpAllocation []string `json:"ipAllocation"` + AllowedIps []string `json:"allowedIps"` + ExtraAllowedIps []string `json:"extraAllowedIps"` + Endpoint string `json:"endpoint"` + UseServerDns int `json:"useServerDns"` + Keys struct { + PresharedKey string `json:"presharedKey"` + PrivateKey string `json:"privateKey"` + PublicKey string `json:"publicKey"` + } `json:"keys"` + Enabled int `json:"enabled"` + OfflineMonitoring int `json:"offlineMonitoring"` +} diff --git a/model/wireguard.go b/model/wireguard.go index bdf3e13..82ed45e 100644 --- a/model/wireguard.go +++ b/model/wireguard.go @@ -22,3 +22,16 @@ type Client struct { func (Client) TableName() string { return "t_client" } + +// Watcher +// @description: 监听日志 +type Watcher struct { + Base + ClientId string `json:"clientId" gorm:"type:char(36);not null;comment:'客户端id'"` + NotifyResult string `json:"notifyResult" gorm:"type:text;default null;comment:'通知结果'"` + IsSend int `json:"isSend" gorm:"type:tinyint(1);default 0;comment:'是否已通知'"` +} + +func (Watcher) TableName() string { + return "t_watcher" +} diff --git a/service/setting.go b/service/setting.go index c7a2fd4..6ca7296 100644 --- a/service/setting.go +++ b/service/setting.go @@ -3,6 +3,7 @@ package service import ( "encoding/json" "gorm.io/gorm" + "strings" gdb "wireguard-ui/global/client" "wireguard-ui/http/vo" "wireguard-ui/model" @@ -84,3 +85,60 @@ func (s setting) GetAllSetting(blackList []string) (data []vo.SettingItem, err e err = s.Model(&model.Setting{}).Select("code, data, describe").Where("code not in ?", blackList).Find(&data).Error return } + +// Export +// @description: 导出 +// @receiver s +// @return data +// @return err +func (s setting) Export() (data vo.Export, err error) { + // 先查询global配置 + var gs, ss *model.Setting + if err = s.Model(&model.Setting{}).Where("code = ?", "WG_SETTING").Take(&gs).Error; err != nil { + return + } + if err = json.Unmarshal([]byte(gs.Data), &data.Global); err != nil { + return + } + + // 查询server配置 + if err = s.Model(&model.Setting{}).Where("code = ?", "WG_SERVER").Take(&ss).Error; err != nil { + return + } + if err = json.Unmarshal([]byte(ss.Data), &data.Server); err != nil { + return + } + + // 查询client配置 + var clients []vo.ClientItem + if err = s.Model(&model.Client{}).Select("id,name,email,ip_allocation as ip_allocation_str," + + "allowed_ips as allowed_ips_str,extra_allowed_ips as extra_allowed_ips_str," + + "endpoint,use_server_dns,keys as keys_str," + + "enabled,offline_monitoring").Order("created_at DESC").Find(&clients).Error; err != nil { + return + } + + for i, v := range clients { + if v.KeysStr != "" { + _ = json.Unmarshal([]byte(v.KeysStr), &clients[i].Keys) + } + if v.IpAllocationStr != "" { + clients[i].IpAllocation = strings.Split(v.IpAllocationStr, ",") + } + if v.AllowedIpsStr != "" { + clients[i].AllowedIps = strings.Split(v.AllowedIpsStr, ",") + } else { + clients[i].AllowedIps = []string{} + } + if v.ExtraAllowedIpsStr != "" { + clients[i].ExtraAllowedIps = strings.Split(v.ExtraAllowedIpsStr, ",") + } else { + clients[i].ExtraAllowedIps = []string{} + } + } + + cj, _ := json.Marshal(clients) + _ = json.Unmarshal(cj, &data.Clients) + + return +} diff --git a/utils/file.go b/utils/file.go new file mode 100644 index 0000000..d38e9e1 --- /dev/null +++ b/utils/file.go @@ -0,0 +1,28 @@ +package utils + +import ( + "fmt" + "os" +) + +type fileUtils struct{} + +func FileUtils() fileUtils { + return fileUtils{} +} + +// GenerateFile +// @description: 生成文件 +// @receiver fileUtils +// @param filename 文件名称 +// @param content 文件内容 +// @return error +func (fileUtils) GenerateFile(filename string, content []byte) (filepath string, err error) { + path := "/tmp/" + if os.Getenv("GIN_MODE") != "release" { + path = "E:\\Workspace\\Go\\wireguard-ui\\template\\tmp\\" + } + filepath = fmt.Sprintf("%s%s", path, filename) + err = os.WriteFile(filepath, content, 0777) + return filepath, err +} diff --git a/web/src/api/setting.js b/web/src/api/setting.js new file mode 100644 index 0000000..a8cdf78 --- /dev/null +++ b/web/src/api/setting.js @@ -0,0 +1,5 @@ +import { request } from '@/utils' + +export default { + exportConfig: () => request.get('/setting/export'), // 获取当前登陆用户信息 +} diff --git a/web/src/layout/components/header/components/Export.vue b/web/src/layout/components/header/components/Export.vue new file mode 100644 index 0000000..6ee6e41 --- /dev/null +++ b/web/src/layout/components/header/components/Export.vue @@ -0,0 +1,40 @@ + + + diff --git a/web/src/layout/components/header/index.vue b/web/src/layout/components/header/index.vue index 1f381eb..afc87fa 100644 --- a/web/src/layout/components/header/index.vue +++ b/web/src/layout/components/header/index.vue @@ -3,7 +3,12 @@