♻️重构了部分代码

This commit is contained in:
coward 2024-03-13 17:05:02 +08:00
parent 7716a15dbb
commit 7c48551989
15 changed files with 125 additions and 29 deletions

View File

@ -29,14 +29,18 @@ func JWT() JwtClaims {
// @receiver Jwt // @receiver Jwt
// @return token // @return token
// @return err // @return err
func (j JwtClaims) GenerateToken(userId string) (token string, err error) { func (j JwtClaims) GenerateToken(userId string) (token string, expireTime *jwt.NumericDate, err error) {
timeNow := time.Now().Local()
expireTime = jwt.NewNumericDate(timeNow.Add(7 * time.Hour))
notBefore := jwt.NewNumericDate(timeNow)
issuedAt := jwt.NewNumericDate(timeNow)
claims := JwtClaims{ claims := JwtClaims{
ID: userId, ID: userId,
RegisteredClaims: jwt.RegisteredClaims{ RegisteredClaims: jwt.RegisteredClaims{
Subject: "wireguard-dashboard", Subject: "wireguard-dashboard",
ExpiresAt: jwt.NewNumericDate(time.Now().Local().Add(7 * time.Hour)), ExpiresAt: expireTime,
NotBefore: jwt.NewNumericDate(time.Now().Local()), NotBefore: notBefore,
IssuedAt: jwt.NewNumericDate(time.Now().Local()), IssuedAt: issuedAt,
}, },
} }
@ -44,7 +48,7 @@ func (j JwtClaims) GenerateToken(userId string) (token string, err error) {
token, err = t.SignedString([]byte(Secret)) token, err = t.SignedString([]byte(Secret))
if err != nil { if err != nil {
log.Errorf("生成token失败: %v", err.Error()) log.Errorf("生成token失败: %v", err.Error())
return "", errors.New("生成token失败") return "", nil, errors.New("生成token失败")
} }
client.Redis.Set(context.Background(), fmt.Sprintf("%s:%s", constant.Token, userId), token, 7*time.Hour) client.Redis.Set(context.Background(), fmt.Sprintf("%s:%s", constant.Token, userId), token, 7*time.Hour)

View File

@ -1,8 +1,11 @@
package api package api
import ( import (
"gitee.ltd/lxh/logger/log"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"wireguard-dashboard/http/param" "wireguard-dashboard/http/param"
"wireguard-dashboard/model/entity"
"wireguard-dashboard/queues"
"wireguard-dashboard/repository" "wireguard-dashboard/repository"
"wireguard-dashboard/utils" "wireguard-dashboard/utils"
) )
@ -44,4 +47,23 @@ func (clients) Save(c *gin.Context) {
return return
} }
info, ok := c.Get("user")
if !ok {
utils.GinResponse(c).FailedWithMsg("获取信息失败")
return
}
_, err := repository.Client().Save(p, info.(*entity.User).Id)
if err != nil {
utils.GinResponse(c).FailedWithMsg("操作失败")
return
}
go func() {
if err = queues.PutAsyncWireguardConfigFile(p.ServerId); err != nil {
log.Errorf("[新增/编辑客户端]同步配置文件失败: %v", err.Error())
}
}()
utils.GinResponse(c).OK()
} }

View File

@ -65,7 +65,7 @@ func (server) SaveServer(c *gin.Context) {
go func() { go func() {
if err = queues.PutAsyncWireguardConfigFile(serverId); err != nil { if err = queues.PutAsyncWireguardConfigFile(serverId); err != nil {
log.Errorf("投递同步配置文件任务失败: %s", err.Error()) log.Errorf("[新增/编辑]投递同步配置文件任务失败: %s", err.Error())
} }
}() }()

View File

@ -56,15 +56,16 @@ func (user) Login(c *gin.Context) {
} }
// 生成token // 生成token
token, err := component.JWT().GenerateToken(user.Id) token, expireTime, err := component.JWT().GenerateToken(user.Id)
if err != nil { if err != nil {
utils.GinResponse(c).FailedWithMsg("登陆失败") utils.GinResponse(c).FailedWithMsg("登陆失败")
return return
} }
utils.GinResponse(c).OKWithData(map[string]any{ utils.GinResponse(c).OKWithData(map[string]any{
"token": token, "token": token,
"type": "Bearer", "type": "Bearer",
"expireAt": expireTime.Unix(),
}) })
} }

View File

@ -20,7 +20,7 @@ type SaveUser struct {
Avatar string `json:"avatar" form:"avatar" binding:"omitempty"` // 头像 Avatar string `json:"avatar" form:"avatar" binding:"omitempty"` // 头像
Email string `json:"email" form:"email" binding:"omitempty"` // 联系邮箱 Email string `json:"email" form:"email" binding:"omitempty"` // 联系邮箱
Password string `json:"password" form:"password" binding:"omitempty"` // 密码 Password string `json:"password" form:"password" binding:"omitempty"` // 密码
IsAdmin constant.UserType `json:"isAdmin" form:"isAdmin" binding:"required"` // 是否为管理员 0 - 否 | 1 - 是 IsAdmin constant.UserType `json:"isAdmin" form:"isAdmin" binding:"omitempty"` // 是否为管理员 0 - 否 | 1 - 是
Status constant.UserStatus `json:"status" form:"status" binding:"required"` // 用户状态 0 - 禁用 | 1 - 正常 Status constant.UserStatus `json:"status" form:"status" binding:"required"` // 用户状态 0 - 禁用 | 1 - 正常
} }

View File

@ -28,6 +28,7 @@ type Client struct {
} }
type Keys struct { type Keys struct {
PrivateKey string `json:"privateKey"` PrivateKey string `json:"privateKey"`
PublicKey string `json:"publicKey"` PublicKey string `json:"publicKey"`
PresharedKey string `json:"presharedKey"`
} }

View File

@ -1,11 +1,11 @@
package vo package vo
type ServerSetting struct { type ServerSetting struct {
EndpointAddress string `json:"endpointAddress"` EndpointAddress string `json:"endpointAddress"`
DnsServers []string `json:"dnsServers"` DnsServer string `json:"dnsServer"`
MTU int `json:"MTU"` MTU int `json:"MTU"`
PersistentKeepalive int `json:"persistentKeepalive"` PersistentKeepalive int `json:"persistentKeepalive"`
FirewallMark string `json:"firewallMark"` FirewallMark string `json:"firewallMark"`
Table string `json:"table"` Table string `json:"table"`
ConfigFilePath string `json:"configFilePath"` ConfigFilePath string `json:"configFilePath"`
} }

View File

@ -80,7 +80,7 @@ func asyncWireguardConfigFile() {
Name: v.Name, Name: v.Name,
Email: v.Email, Email: v.Email,
PublicKey: clientKey.PublicKey, PublicKey: clientKey.PublicKey,
PresharedKey: clientKey.PrivateKey, PresharedKey: clientKey.PresharedKey,
AllowedIPS: v.AllowedIps, AllowedIPS: v.AllowedIps,
PersistentKeepalive: strconv.Itoa(globalSetting.PersistentKeepalive), PersistentKeepalive: strconv.Itoa(globalSetting.PersistentKeepalive),
Endpoint: v.Endpoint, Endpoint: v.Endpoint,

View File

@ -2,9 +2,13 @@ package repository
import ( import (
"encoding/json" "encoding/json"
"github.com/spf13/cast"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"gorm.io/gorm" "gorm.io/gorm"
"wireguard-dashboard/client" "wireguard-dashboard/client"
"wireguard-dashboard/http/param" "wireguard-dashboard/http/param"
"wireguard-dashboard/model/entity"
"wireguard-dashboard/model/template_data"
"wireguard-dashboard/model/vo" "wireguard-dashboard/model/vo"
"wireguard-dashboard/utils" "wireguard-dashboard/utils"
) )
@ -49,7 +53,69 @@ func (r clientRepo) List(p param.ClientList) (data []vo.Client, total int64, err
// @description: 新增/编辑客户端 // @description: 新增/编辑客户端
// @receiver r // @receiver r
// @param p // @param p
// @param adminId
// @return err // @return err
func (r clientRepo) Save(p param.SaveClient) (err error) { func (r clientRepo) Save(p param.SaveClient, adminId string) (client *entity.Client, err error) {
return nil
ent := &entity.Client{
Base: entity.Base{
Id: p.Id,
},
ServerId: p.ServerId,
Name: p.Name,
Email: p.Email,
SubnetRange: p.SubnetRange,
IpAllocation: p.IpAllocation,
AllowedIps: p.AllowedIPS,
ExtraAllowedIps: p.ExtraAllowedIPS,
Endpoint: p.Endpoint,
UseServerDns: p.UseServerDNS,
EnableAfterCreation: p.EnabledAfterCreation,
UserId: adminId,
Enabled: cast.ToBool(p.Enabled),
}
// id不为空更新信息
if p.Id != "" {
keys, _ := json.Marshal(p.Keys)
ent.Keys = string(keys)
if err = r.Model(&entity.Client{}).Where("id = ?", p.Id).Updates(ent).Error; err != nil {
return
}
return
}
// 为空,新增
privateKey, err := wgtypes.GeneratePrivateKey()
if err != nil {
return
}
publicKey := privateKey.PublicKey().String()
presharedKey, err := wgtypes.GenerateKey()
if err != nil {
return
}
keys := template_data.Keys{
PublicKey: publicKey,
PresharedKey: presharedKey.String(),
}
keysStr, _ := json.Marshal(keys)
ent = &entity.Client{
ServerId: p.ServerId,
Name: p.Name,
Email: p.Email,
SubnetRange: p.SubnetRange,
IpAllocation: p.IpAllocation,
AllowedIps: p.AllowedIPS,
ExtraAllowedIps: p.ExtraAllowedIPS,
Endpoint: p.Endpoint,
UseServerDns: p.UseServerDNS,
EnableAfterCreation: p.EnabledAfterCreation,
Keys: string(keysStr),
UserId: adminId,
}
err = r.Model(&entity.Client{}).Create(ent).Error
return
} }

View File

@ -8,7 +8,7 @@ import (
// CaptchaApi // CaptchaApi
// @description: 验证码 // @description: 验证码
// @param r // @param r
func CaptchaApi(r *gin.Engine) { func CaptchaApi(r *gin.RouterGroup) {
captcha := r.Group("captcha") captcha := r.Group("captcha")
{ {
captcha.GET("", api.Captcha().GenerateCaptcha) // 生成验证码 captcha.GET("", api.Captcha().GenerateCaptcha) // 生成验证码

View File

@ -6,9 +6,10 @@ import (
"wireguard-dashboard/middleware" "wireguard-dashboard/middleware"
) )
func ClientApi(r *gin.Engine) { func ClientApi(r *gin.RouterGroup) {
apiGroup := r.Group("client", middleware.Authorization()) apiGroup := r.Group("client", middleware.Authorization())
{ {
apiGroup.GET("list", api.Client().List) // 客户端列表 apiGroup.GET("list", api.Client().List) // 客户端列表
apiGroup.POST("save", api.Client().Save) // 新增/编辑客户端
} }
} }

View File

@ -2,7 +2,7 @@ package route
import "github.com/gin-gonic/gin" import "github.com/gin-gonic/gin"
type Option func(engine *gin.Engine) type Option func(engine *gin.RouterGroup)
var options []Option var options []Option
@ -18,7 +18,7 @@ func InitRouter() *gin.Engine {
r.Use(gin.Logger()) r.Use(gin.Logger())
for _, opt := range options { for _, opt := range options {
opt(r) opt(r.Group("api"))
} }
return r return r

View File

@ -6,7 +6,7 @@ import (
"wireguard-dashboard/middleware" "wireguard-dashboard/middleware"
) )
func ServerApi(r *gin.Engine) { func ServerApi(r *gin.RouterGroup) {
apiGroup := r.Group("server", middleware.Authorization()) apiGroup := r.Group("server", middleware.Authorization())
{ {
apiGroup.GET("", api.Server().GetServer) // 获取服务端信息 apiGroup.GET("", api.Server().GetServer) // 获取服务端信息

View File

@ -6,7 +6,7 @@ import (
"wireguard-dashboard/middleware" "wireguard-dashboard/middleware"
) )
func UserApi(r *gin.Engine) { func UserApi(r *gin.RouterGroup) {
// 登陆相关API // 登陆相关API
login := r.Group("/login") login := r.Group("/login")
{ {

1
utils/wireguard.go Normal file
View File

@ -0,0 +1 @@
package utils