新增代理服务的离线接口,优化认证逻辑,代理服务表添加状态字段
This commit is contained in:
@@ -71,6 +71,11 @@ func main() {
|
||||
return err
|
||||
}
|
||||
|
||||
proxySecret, err := bcrypt.GenerateFromPassword([]byte("proxy"), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = q.Client.
|
||||
Select(
|
||||
q.Client.ClientID,
|
||||
@@ -96,6 +101,17 @@ func main() {
|
||||
GrantClient: true,
|
||||
Spec: int32(client2.SpecTrusted),
|
||||
Name: "异步任务处理服务",
|
||||
}, &m.Client{
|
||||
ClientID: "proxy",
|
||||
ClientSecret: string(proxySecret),
|
||||
GrantClient: true,
|
||||
Spec: int32(client2.SpecTrusted),
|
||||
Name: "代理转发服务",
|
||||
}, &m.Client{
|
||||
ClientID: "edge",
|
||||
GrantClient: true,
|
||||
Spec: int32(client2.SpecWeb),
|
||||
Name: "代理边缘节点",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -516,14 +516,17 @@ create table proxy (
|
||||
version int not null,
|
||||
name varchar(255) not null unique,
|
||||
host varchar(255) not null,
|
||||
type int not null default 0,
|
||||
secret varchar(255),
|
||||
created_at timestamp default current_timestamp,
|
||||
updated_at timestamp default current_timestamp,
|
||||
type int not null,
|
||||
status int not null,
|
||||
created_at timestamp default current_timestamp,
|
||||
updated_at timestamp default current_timestamp,
|
||||
deleted_at timestamp
|
||||
);
|
||||
create index proxy_name_index on proxy (name);
|
||||
create index proxy_host_index on proxy (host);
|
||||
create index proxy_type_index on proxy (type);
|
||||
create index proxy_status_index on proxy (status);
|
||||
create index proxy_deleted_at_index on proxy (deleted_at);
|
||||
|
||||
-- proxy表字段注释
|
||||
@@ -534,6 +537,7 @@ comment on column proxy.name is '代理服务名称';
|
||||
comment on column proxy.host is '代理服务地址';
|
||||
comment on column proxy.type is '代理服务类型:1-三方,2-自有';
|
||||
comment on column proxy.secret is '代理服务密钥';
|
||||
comment on column proxy.status is '代理服务状态:0-离线,1-在线';
|
||||
comment on column proxy.created_at is '创建时间';
|
||||
comment on column proxy.updated_at is '更新时间';
|
||||
comment on column proxy.deleted_at is '删除时间';
|
||||
|
||||
@@ -43,11 +43,13 @@ func Protect(c *fiber.Ctx, types []PayloadType, permissions []string) (*Context,
|
||||
var header = c.Get("Authorization")
|
||||
var split = strings.Split(header, " ")
|
||||
if len(split) != 2 {
|
||||
slog.Debug("Authorization 头格式不正确")
|
||||
return nil, fiber.NewError(fiber.StatusUnauthorized, "无效的令牌")
|
||||
}
|
||||
|
||||
var token = split[1]
|
||||
var token = strings.TrimSpace(split[1])
|
||||
if token == "" {
|
||||
slog.Debug("提供的令牌为空")
|
||||
return nil, fiber.NewError(fiber.StatusUnauthorized, "无效的令牌")
|
||||
}
|
||||
|
||||
@@ -63,7 +65,7 @@ func Protect(c *fiber.Ctx, types []PayloadType, permissions []string) (*Context,
|
||||
}
|
||||
|
||||
case "Basic":
|
||||
if !slices.Contains(types, PayloadSecuredServer) {
|
||||
if !slices.Contains(types, PayloadInternalServer) {
|
||||
slog.Debug("禁止使用 Basic 认证方式")
|
||||
return nil, fiber.NewError(fiber.StatusUnauthorized, "无效的令牌")
|
||||
}
|
||||
@@ -74,18 +76,18 @@ func Protect(c *fiber.Ctx, types []PayloadType, permissions []string) (*Context,
|
||||
}
|
||||
|
||||
default:
|
||||
slog.Debug("无效的认证方式")
|
||||
slog.Debug("无效的认证方式", "method", split[0])
|
||||
return nil, fiber.NewError(fiber.StatusUnauthorized, "无效的令牌")
|
||||
}
|
||||
|
||||
// 检查权限
|
||||
if !slices.Contains(types, auth.Payload.Type) {
|
||||
slog.Debug("无效的认证主体")
|
||||
slog.Debug("无效的负载类型", "except", types, "actual", auth.Payload.Type)
|
||||
return nil, fiber.NewError(fiber.StatusForbidden, "没有权限")
|
||||
}
|
||||
|
||||
if len(permissions) > 0 && !auth.AnyPermission(permissions...) {
|
||||
slog.Debug("无效的认证权限")
|
||||
slog.Debug("无效的认证权限", "except", permissions, "actual", auth.Permissions)
|
||||
return nil, fiber.NewError(fiber.StatusForbidden, "没有权限")
|
||||
}
|
||||
|
||||
@@ -114,15 +116,12 @@ func authBasic(_ context.Context, token string) (*Context, error) {
|
||||
// 解析 Basic 认证信息
|
||||
var base, err = base64.RawURLEncoding.DecodeString(token)
|
||||
if err != nil {
|
||||
slog.Debug(err.Error())
|
||||
return nil, err
|
||||
return nil, errors.New("令牌格式错误,无法解析令牌")
|
||||
}
|
||||
|
||||
var split = strings.Split(string(base), ":")
|
||||
if len(split) != 2 {
|
||||
msg := "无法解析 Basic 认证信息"
|
||||
slog.Debug(msg)
|
||||
return nil, errors.New(msg)
|
||||
return nil, errors.New("令牌格式错误,必须是 <client_id>:<client_secret> 格式")
|
||||
}
|
||||
|
||||
var clientID = split[0]
|
||||
@@ -151,7 +150,7 @@ func authBasic(_ context.Context, token string) (*Context, error) {
|
||||
return &Context{
|
||||
Payload: Payload{
|
||||
Id: client.ID,
|
||||
Type: PayloadSecuredServer,
|
||||
Type: PayloadTypeFromClientSpec(client2.Spec(client.Spec)),
|
||||
Name: client.Name,
|
||||
Avatar: client.Icon,
|
||||
},
|
||||
|
||||
@@ -65,6 +65,8 @@ func (t PayloadType) ToStr() string {
|
||||
return "cpub"
|
||||
case PayloadSecuredServer:
|
||||
return "ccnf"
|
||||
case PayloadInternalServer:
|
||||
return "inte"
|
||||
default:
|
||||
return "none"
|
||||
}
|
||||
@@ -80,6 +82,8 @@ func PayloadTypeFromStr(name string) PayloadType {
|
||||
return PayloadPublicServer
|
||||
case "ccnf":
|
||||
return PayloadSecuredServer
|
||||
case "inte":
|
||||
return PayloadInternalServer
|
||||
default:
|
||||
return PayloadNone
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package handlers
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"gorm.io/gorm/clause"
|
||||
"log/slog"
|
||||
auth2 "platform/web/auth"
|
||||
proxy2 "platform/web/domains/proxy"
|
||||
g "platform/web/globals"
|
||||
@@ -10,7 +11,9 @@ import (
|
||||
q "platform/web/queries"
|
||||
)
|
||||
|
||||
type RegisterProxyReq struct {
|
||||
// region OnlineProxy
|
||||
|
||||
type OnlineProxyReq struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Version int `json:"version" validate:"required"`
|
||||
}
|
||||
@@ -26,13 +29,14 @@ func OnlineProxy(c *fiber.Ctx) (err error) {
|
||||
}
|
||||
|
||||
// 验证请求参数
|
||||
var req = new(RegisterProxyReq)
|
||||
var req = new(OnlineProxyReq)
|
||||
err = g.Validator.Validate(c, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建代理
|
||||
slog.Debug("注册转发服务", "ip", c.IP())
|
||||
err = q.Proxy.
|
||||
Clauses(clause.OnConflict{
|
||||
UpdateAll: true,
|
||||
@@ -45,6 +49,7 @@ func OnlineProxy(c *fiber.Ctx) (err error) {
|
||||
Version: int32(req.Version),
|
||||
Host: c.IP(),
|
||||
Type: int32(proxy2.TypeSelfHosted),
|
||||
Status: 1,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -52,3 +57,40 @@ func OnlineProxy(c *fiber.Ctx) (err error) {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region OfflineProxy
|
||||
|
||||
type OfflineProxyReq struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
}
|
||||
|
||||
func OfflineProxy(c *fiber.Ctx) (err error) {
|
||||
// 检查接口权限
|
||||
_, err = auth2.NewProtect(c).Payload(
|
||||
auth2.PayloadInternalServer,
|
||||
).Do()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 验证请求参数
|
||||
var req = new(OfflineProxyReq)
|
||||
err = g.Validator.Validate(c, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 下线转发服务
|
||||
_, err = q.Proxy.
|
||||
Where(q.Proxy.Name.Eq(req.Name)).
|
||||
UpdateSimple(q.Proxy.Status.Value(0))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
@@ -23,6 +23,7 @@ type Proxy struct {
|
||||
CreatedAt orm.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间
|
||||
UpdatedAt orm.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间
|
||||
Status int32 `gorm:"column:status;not null;comment:代理服务状态:0-离线,1-在线" json:"status"` // 代理服务状态:0-离线,1-在线
|
||||
Edges []Edge `gorm:"foreignKey:ProxyID;references:ID" json:"edges"`
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ func newProxy(db *gorm.DB, opts ...gen.DOOption) proxy {
|
||||
_proxy.CreatedAt = field.NewField(tableName, "created_at")
|
||||
_proxy.UpdatedAt = field.NewField(tableName, "updated_at")
|
||||
_proxy.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||
_proxy.Status = field.NewInt32(tableName, "status")
|
||||
_proxy.Edges = proxyHasManyEdges{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
@@ -60,6 +61,7 @@ type proxy struct {
|
||||
CreatedAt field.Field // 创建时间
|
||||
UpdatedAt field.Field // 更新时间
|
||||
DeletedAt field.Field // 删除时间
|
||||
Status field.Int32 // 代理服务状态:0-离线,1-在线
|
||||
Edges proxyHasManyEdges
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
@@ -86,6 +88,7 @@ func (p *proxy) updateTableName(table string) *proxy {
|
||||
p.CreatedAt = field.NewField(table, "created_at")
|
||||
p.UpdatedAt = field.NewField(table, "updated_at")
|
||||
p.DeletedAt = field.NewField(table, "deleted_at")
|
||||
p.Status = field.NewInt32(table, "status")
|
||||
|
||||
p.fillFieldMap()
|
||||
|
||||
@@ -102,7 +105,7 @@ func (p *proxy) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
}
|
||||
|
||||
func (p *proxy) fillFieldMap() {
|
||||
p.fieldMap = make(map[string]field.Expr, 10)
|
||||
p.fieldMap = make(map[string]field.Expr, 11)
|
||||
p.fieldMap["id"] = p.ID
|
||||
p.fieldMap["version"] = p.Version
|
||||
p.fieldMap["name"] = p.Name
|
||||
@@ -112,6 +115,7 @@ func (p *proxy) fillFieldMap() {
|
||||
p.fieldMap["created_at"] = p.CreatedAt
|
||||
p.fieldMap["updated_at"] = p.UpdatedAt
|
||||
p.fieldMap["deleted_at"] = p.DeletedAt
|
||||
p.fieldMap["status"] = p.Status
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@ func ApplyRouters(app *fiber.App) {
|
||||
// 网关
|
||||
proxy := api.Group("/proxy")
|
||||
proxy.Post("/online", handlers.OnlineProxy)
|
||||
proxy.Post("/offline", handlers.OfflineProxy)
|
||||
|
||||
// 节点
|
||||
edge := api.Group("/edge")
|
||||
|
||||
Reference in New Issue
Block a user