5 Commits

4 changed files with 85 additions and 20 deletions

View File

@@ -40,12 +40,13 @@ http 调用 clients 的初始化函数
jsonb 类型转换问题,考虑一个高效的 any 到 struct 转换工具
慢速请求底层调用埋点监控
- redis
- gorm
- 三方接口
冷数据迁移方案
## 业务逻辑
### 订单关闭的几种方式
@@ -64,7 +65,8 @@ jsonb 类型转换问题,考虑一个高效的 any 到 struct 转换工具
### 节点分配与存储逻辑
提取:
提取
- 检查用户套餐与白名单
- 选中代理
- 找到当前可用端口最多的代理
@@ -76,6 +78,7 @@ jsonb 类型转换问题,考虑一个高效的 any 到 struct 转换工具
- 分别提交连接与配置请求
释放:
- 根据批次查出所有端口与相关节点
- 分别提交断开与关闭请求
- 释放端口

16
publish.ps1 Normal file
View File

@@ -0,0 +1,16 @@
if (-not $args) {
Write-Error "需要指定版本号"
exit 1
}
$confrim = Read-Host "构建版本为 [platform:$($args[0])],是否继续?(y/n)"
if ($confrim -ne "y") {
Write-Host "已取消构建"
exit 0
}
docker build -t 43.226.58.254:53000/lanhu/platform:latest .
docker build -t 43.226.58.254:53000/lanhu/platform:$($args[0]) .
docker push 43.226.58.254:53000/lanhu/platform:latest
docker push 43.226.58.254:53000/lanhu/platform:$($args[0])

View File

@@ -353,6 +353,9 @@ func authPassword(c *fiber.Ctx, auth *AuthCtx, req *TokenReq, now time.Time) (*m
admin.LastLogin = u.P(time.Now())
admin.LastLoginIP = ip
admin.LastLoginUA = ua
default:
return nil, ErrAuthorizeInvalidRequest
}
// 生成会话
@@ -364,12 +367,7 @@ func authPassword(c *fiber.Ctx, auth *AuthCtx, req *TokenReq, now time.Time) (*m
AccessToken: uuid.NewString(),
AccessTokenExpires: now.Add(time.Duration(env.SessionAccessExpire) * time.Second),
}
if user != nil {
session.UserID = &user.ID
}
if admin != nil {
session.AdminID = &admin.ID
}
if req.Remember {
session.RefreshToken = u.P(uuid.NewString())
session.RefreshTokenExpires = u.P(now.Add(time.Duration(env.SessionRefreshExpire) * time.Second))
@@ -377,18 +375,20 @@ func authPassword(c *fiber.Ctx, auth *AuthCtx, req *TokenReq, now time.Time) (*m
// 保存用户更新和会话
err = q.Q.Transaction(func(tx *q.Query) error {
if err := SaveSession(tx, session); err != nil {
return err
}
if user != nil {
if err := tx.User.Save(user); err != nil {
return err
}
session.UserID = &user.ID
}
if admin != nil {
if err := tx.Admin.Save(admin); err != nil {
return err
}
session.AdminID = &admin.ID
}
if err := SaveSession(tx, session); err != nil {
return err
}
return nil
})
@@ -490,12 +490,23 @@ type RevokeReq struct {
// Introspect 令牌检查端点
func Introspect(ctx *fiber.Ctx) error {
// 验证权限
authCtx, err := GetAuthCtx(ctx).PermitUser()
if err != nil {
return err
authCtx := GetAuthCtx(ctx)
// 尝试验证用户权限
if _, err := authCtx.PermitUser(); err == nil {
return introspectUser(ctx, authCtx)
}
// 尝试验证管理员权限
if _, err := authCtx.PermitAdmin(); err == nil {
return introspectAdmin(ctx, authCtx)
}
return ErrAuthenticateForbidden
}
// introspectUser 获取并返回用户信息
func introspectUser(ctx *fiber.Ctx, authCtx *AuthCtx) error {
// 获取用户信息
profile, err := q.User.
Where(q.User.ID.Eq(authCtx.User.ID)).
@@ -519,12 +530,33 @@ func Introspect(ctx *fiber.Ctx) error {
if profile.IDNo != nil && *profile.IDNo != "" {
profile.IDNo = u.P(maskIdNo(*profile.IDNo))
}
return ctx.JSON(IntrospectResp{*profile, hasPassword})
return ctx.JSON(struct {
m.User
HasPassword bool `json:"has_password"` // 是否设置了密码
}{*profile, hasPassword})
}
type IntrospectResp struct {
m.User
HasPassword bool `json:"has_password"` // 是否设置了密码
// introspectAdmin 获取并返回管理员信息
func introspectAdmin(ctx *fiber.Ctx, authCtx *AuthCtx) error {
// 获取管理员信息
profile, err := q.Admin.
Where(q.Admin.ID.Eq(authCtx.Admin.ID)).
Omit(q.Admin.DeletedAt).
Take()
if err != nil {
return err
}
// 不返回密码
profile.Password = ""
// 掩码敏感信息
if profile.Phone != nil && *profile.Phone != "" {
profile.Phone = u.P(maskPhone(*profile.Phone))
}
return ctx.JSON(profile)
}
func maskPhone(phone string) string {

View File

@@ -28,12 +28,21 @@ func PageUserByAdmin(c *fiber.Ctx) error {
// 查询用户列表
users, total, err := q.User.
Preload(q.User.Admin).
Omit(q.User.Password).
FindByPage(req.GetOffset(), req.GetLimit())
if err != nil {
return err
}
for _, user := range users {
if user.Admin != nil {
user.Admin = &m.Admin{
Name: user.Admin.Name,
}
}
}
// 返回结果
return c.JSON(core.PageResp{
Total: int(total),
@@ -163,8 +172,13 @@ func UpdatePassword(c *fiber.Ctx) error {
return err
}
// 验证手机号
if req.Phone != authCtx.User.Phone {
return fiber.NewError(fiber.StatusBadRequest, "手机号码不正确")
}
// 验证手机令牌
if req.Phone == "" || req.Code == "" {
if req.Code == "" {
return fiber.NewError(fiber.StatusBadRequest, "手机号码和验证码不能为空")
}
err = s.Verifier.VerifySms(c.Context(), req.Phone, req.Code)