128 lines
3.2 KiB
Go
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})
|
|
}
|