Files
goauto/server/app/goauto/clientkey/handler.go
T

128 lines
3.2 KiB
Go

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})
}