91 lines
2.1 KiB
Go
91 lines
2.1 KiB
Go
package handlers
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"0451meishiditu/backend/internal/models"
|
|
"0451meishiditu/backend/internal/resp"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type apiKeyCreateReq struct {
|
|
Name string `json:"name" binding:"required"`
|
|
}
|
|
|
|
func (h *Handlers) APIKeyList(c *gin.Context) {
|
|
page, pageSize := parsePage(c.Query("page"), c.Query("page_size"))
|
|
|
|
q := h.db.Model(&models.APIKey{})
|
|
var total int64
|
|
if err := q.Count(&total).Error; err != nil {
|
|
resp.Fail(c, http.StatusInternalServerError, "db error")
|
|
return
|
|
}
|
|
|
|
var items []models.APIKey
|
|
if err := q.Order("id desc").Limit(pageSize).Offset((page - 1) * pageSize).Find(&items).Error; err != nil {
|
|
resp.Fail(c, http.StatusInternalServerError, "db error")
|
|
return
|
|
}
|
|
|
|
resp.OKMeta(c, items, gin.H{
|
|
"page": page,
|
|
"page_size": pageSize,
|
|
"total": total,
|
|
"total_page": calcTotalPage(total, pageSize),
|
|
})
|
|
}
|
|
|
|
func (h *Handlers) APIKeyCreate(c *gin.Context) {
|
|
var req apiKeyCreateReq
|
|
if err := c.ShouldBindJSON(&req); err != nil || strings.TrimSpace(req.Name) == "" {
|
|
resp.Fail(c, http.StatusBadRequest, "invalid payload")
|
|
return
|
|
}
|
|
|
|
plain := "ak_" + randomHex(24)
|
|
sum := sha256.Sum256([]byte(plain))
|
|
hash := hex.EncodeToString(sum[:])
|
|
prefix := plain
|
|
if len(prefix) > 10 {
|
|
prefix = prefix[:10]
|
|
}
|
|
|
|
item := models.APIKey{
|
|
Name: strings.TrimSpace(req.Name),
|
|
Prefix: prefix,
|
|
HashSHA256: hash,
|
|
Status: "active",
|
|
}
|
|
if err := h.db.Create(&item).Error; err != nil {
|
|
resp.Fail(c, http.StatusBadRequest, "create failed")
|
|
return
|
|
}
|
|
|
|
resp.OK(c, gin.H{
|
|
"id": item.ID,
|
|
"name": item.Name,
|
|
"prefix": item.Prefix,
|
|
"status": item.Status,
|
|
"key": plain, // 仅返回一次,前端应提示保存
|
|
})
|
|
}
|
|
|
|
func (h *Handlers) APIKeyRevoke(c *gin.Context) {
|
|
id, _ := strconv.ParseUint(c.Param("id"), 10, 64)
|
|
now := time.Now()
|
|
if err := h.db.Model(&models.APIKey{}).
|
|
Where("id = ? and status = 'active'", uint(id)).
|
|
Updates(map[string]any{"status": "revoked", "revoked_at": &now}).Error; err != nil {
|
|
resp.Fail(c, http.StatusInternalServerError, "revoke failed")
|
|
return
|
|
}
|
|
resp.OK(c, gin.H{"revoked": true})
|
|
}
|