111 lines
2.8 KiB
Go
111 lines
2.8 KiB
Go
package apis
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/go-admin-team/go-admin-core/sdk/api"
|
|
"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
|
|
"go-admin/app/admin/models"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
type APIKey struct{ api.Api }
|
|
|
|
func (e APIKey) List(c *gin.Context) {
|
|
e.MakeContext(c)
|
|
db := primaryDB()
|
|
rows := make([]models.APIKey, 0)
|
|
if err := db.Order("id desc").Find(&rows).Error; err != nil {
|
|
e.Error(500, err, "读取密钥失败,请重试")
|
|
return
|
|
}
|
|
e.OK(rows, "查询成功")
|
|
}
|
|
func (e APIKey) Create(c *gin.Context) {
|
|
e.MakeContext(c)
|
|
c.Header("Cache-Control", "no-store")
|
|
var in struct {
|
|
Name string `json:"name"`
|
|
}
|
|
if c.ShouldBindJSON(&in) != nil || strings.TrimSpace(in.Name) == "" || utf8.RuneCountInString(strings.TrimSpace(in.Name)) > 128 {
|
|
e.Error(400, fmt.Errorf("name required"), "参数错误")
|
|
return
|
|
}
|
|
b := make([]byte, 32)
|
|
if _, err := rand.Read(b); err != nil {
|
|
e.Error(500, err, "生成失败")
|
|
return
|
|
}
|
|
plain := hex.EncodeToString(b)
|
|
h := sha256.Sum256([]byte(plain))
|
|
row := models.APIKey{Name: strings.TrimSpace(in.Name), KeyHash: hex.EncodeToString(h[:]), Enabled: true}
|
|
row.KeyValue = plain
|
|
row.CreateBy = user.GetUserId(c)
|
|
db := primaryDB()
|
|
if err := db.Create(&row).Error; err != nil {
|
|
e.Error(500, err, "创建失败")
|
|
return
|
|
}
|
|
e.OK(gin.H{"id": row.Id, "name": row.Name, "apiKey": plain}, "创建成功")
|
|
}
|
|
func (e APIKey) Toggle(c *gin.Context) {
|
|
e.MakeContext(c)
|
|
id, err := strconv.Atoi(c.Param("id"))
|
|
if err != nil || id <= 0 {
|
|
e.Error(400, fmt.Errorf("invalid id"), "无效的密钥编号")
|
|
return
|
|
}
|
|
var row models.APIKey
|
|
db := primaryDB()
|
|
if db.First(&row, id).Error != nil {
|
|
e.Error(404, fmt.Errorf("not found"), "不存在")
|
|
return
|
|
}
|
|
row.Enabled = !row.Enabled
|
|
if err := db.Save(&row).Error; err != nil {
|
|
e.Error(500, err, "更新失败,请刷新后重试")
|
|
return
|
|
}
|
|
e.OK(row, "更新成功")
|
|
}
|
|
func (e APIKey) Delete(c *gin.Context) {
|
|
e.MakeContext(c)
|
|
id, err := strconv.Atoi(c.Param("id"))
|
|
if err != nil || id <= 0 {
|
|
e.Error(400, fmt.Errorf("invalid id"), "无效的密钥编号")
|
|
return
|
|
}
|
|
db := primaryDB()
|
|
result := db.Delete(&models.APIKey{}, id)
|
|
if result.Error != nil {
|
|
e.Error(500, fmt.Errorf("delete failed"), "删除失败")
|
|
return
|
|
}
|
|
if result.RowsAffected == 0 {
|
|
e.Error(404, fmt.Errorf("not found"), "密钥不存在")
|
|
return
|
|
}
|
|
e.OK(nil, "删除成功")
|
|
}
|
|
func ValidateAPIKey(c *gin.Context) bool {
|
|
v := apiKey(c)
|
|
if v == "" {
|
|
return false
|
|
}
|
|
h := sha256.Sum256([]byte(v))
|
|
var row models.APIKey
|
|
db := primaryDB()
|
|
if db.Where("key_hash = ? AND enabled = ?", hex.EncodeToString(h[:]), true).First(&row).Error != nil {
|
|
return false
|
|
}
|
|
now := time.Now()
|
|
db.Model(&row).Updates(map[string]interface{}{"last_used_at": now})
|
|
return true
|
|
}
|