package clientkey import ( "encoding/json" "errors" "io" "net/http" "strconv" "github.com/gin-gonic/gin" "github.com/go-admin-team/go-admin-core/sdk/pkg" "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user" "gorm.io/gorm" ) type Handler struct { DB *gorm.DB Modules []Module } func (h Handler) service(c *gin.Context) (Service, bool) { db := h.DB var err error if db == nil { db, err = pkg.GetOrm(c) } if err != nil || db == nil { failure(c, errors.New("database unavailable")) return Service{}, false } c.Header("Cache-Control", "no-store") return Service{db, h.Modules}, true } func failure(c *gin.Context, err error) { status, message := 500, "服务端处理失败" switch { case errors.Is(err, ErrInvalid): status, message = 422, ErrInvalid.Error() case errors.Is(err, ErrConflict): status, message = 409, ErrConflict.Error() case errors.Is(err, gorm.ErrRecordNotFound): status, message = 404, "密钥不存在" } c.AbortWithStatusJSON(status, gin.H{"code": status, "message": message}) } func (h Handler) Catalog(c *gin.Context) { c.JSON(200, gin.H{"code": 200, "data": h.Modules}) } func (h Handler) List(c *gin.Context) { s, ok := h.service(c) if !ok { return } page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) if page < 1 { page = 1 } size := 20 var total int64 var keys []Key if err := s.DB.WithContext(c.Request.Context()).Model(&Key{}).Count(&total).Error; err != nil { failure(c, err) return } if err := s.DB.WithContext(c.Request.Context()).Order("id DESC").Offset((page - 1) * size).Limit(size).Find(&keys).Error; err != nil { failure(c, err) return } items := make([]View, 0, len(keys)) for _, k := range keys { items = append(items, view(k)) } c.JSON(200, gin.H{"code": 200, "data": gin.H{"items": items, "total": total, "page": page, "pageSize": size}}) } func decode(c *gin.Context, v any) bool { c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, 64<<10) d := json.NewDecoder(c.Request.Body) d.DisallowUnknownFields() if d.Decode(v) != nil || d.Decode(&struct{}{}) != io.EOF { failure(c, ErrInvalid) return false } return true } func (h Handler) Create(c *gin.Context) { var req struct { Name string `json:"name"` Grants []Grant `json:"grants"` } if !decode(c, &req) { return } s, ok := h.service(c) if !ok { return } result, secret, err := s.Create(c.Request.Context(), req.Name, req.Grants, uint64(user.GetUserId(c))) if err != nil { failure(c, err) return } c.JSON(200, gin.H{"code": 200, "data": gin.H{"key": result, "secret": secret}}) } func (h Handler) Edit(c *gin.Context) { h.update(c, false) } func (h Handler) Disable(c *gin.Context) { h.update(c, true) } func (h Handler) update(c *gin.Context, disable bool) { id, err := strconv.ParseUint(c.Param("keyId"), 10, 64) if err != nil { failure(c, ErrInvalid) return } var req struct { Version uint64 `json:"version"` Grants []Grant `json:"grants"` } if !decode(c, &req) { return } s, ok := h.service(c) if !ok { return } result, err := s.Update(c.Request.Context(), id, req.Version, uint64(user.GetUserId(c)), req.Grants, disable) if err != nil { failure(c, err) return } c.JSON(200, gin.H{"code": 200, "data": result}) }