package handlers
import (
"net/http"
"strconv"
"strings"
"github.com/bestruirui/octopus/internal/model"
"github.com/bestruirui/octopus/internal/op"
"github.com/bestruirui/octopus/internal/server/auth"
"github.com/bestruirui/octopus/internal/server/middleware"
"github.com/bestruirui/octopus/internal/server/resp"
"github.com/bestruirui/octopus/internal/server/router"
"github.com/gin-gonic/gin"
"github.com/samber/lo"
)
func init() {
router.NewGroupRouter("/api/v1/apikey").
Use(middleware.Auth()).
Use(middleware.RequireJSON()).
AddRoute(
router.NewRoute("/create", http.MethodPost).
Handle(createAPIKey),
).
AddRoute(
router.NewRoute("/list", http.MethodGet).
Handle(listAPIKey),
).
AddRoute(
router.NewRoute("/update", http.MethodPost).
Handle(updateAPIKey),
).
AddRoute(
router.NewRoute("/delete/:id", http.MethodDelete).
Handle(deleteAPIKey),
)
router.NewGroupRouter("/api/v1/apikey").
Use(middleware.APIKeyAuth()).
AddRoute(
router.NewRoute("/stats", http.MethodGet).
Handle(getStatsAPIKeyById),
).
AddRoute(
router.NewRoute("/login", http.MethodGet).
Handle(loginAPIKey),
)
}
func createAPIKey(c *gin.Context) {
var req model.APIKey
if err := c.ShouldBindJSON(&req); err != nil {
resp.Error(c, http.StatusBadRequest, resp.ErrInvalidJSON)
return
}
req.APIKey = auth.GenerateAPIKey()
if err := op.APIKeyCreate(&req, c.Request.Context()); err != nil {
resp.Error(c, http.StatusInternalServerError, err.Error())
return
}
resp.Success(c, req)
}
func listAPIKey(c *gin.Context) {
apiKeys, err := op.APIKeyList(c.Request.Context())
if err != nil {
resp.Error(c, http.StatusInternalServerError, err.Error())
return
}
resp.Success(c, apiKeys)
}
func updateAPIKey(c *gin.Context) {
var req model.APIKey
if err := c.ShouldBindJSON(&req); err != nil {
resp.Error(c, http.StatusBadRequest, resp.ErrInvalidJSON)
return
}
if err := op.APIKeyUpdate(&req, c.Request.Context()); err != nil {
resp.Error(c, http.StatusInternalServerError, err.Error())
return
}
resp.Success(c, req)
}
func deleteAPIKey(c *gin.Context) {
id := c.Param("id")
idNum, err := strconv.Atoi(id)
if err != nil {
resp.Error(c, http.StatusBadRequest, resp.ErrInvalidParam)
return
}
if err := op.APIKeyDelete(idNum, c.Request.Context()); err != nil {
resp.Error(c, http.StatusInternalServerError, err.Error())
return
}
resp.Success(c, nil)
}
func getStatsAPIKeyById(c *gin.Context) {
id := c.GetInt("api_key_id")
stats := op.StatsAPIKeyGet(id)
info, err := op.APIKeyGet(id, c.Request.Context())
if err != nil {
resp.Error(c, http.StatusInternalServerError, err.Error())
return
}
models, err := op.GroupListModel(c.Request.Context())
if err != nil {
resp.Error(c, http.StatusInternalServerError, err.Error())
return
}
var modelsString string
if info.SupportedModels == "" {
modelsString = strings.Join(models, ", ")
} else {
supportedModels := lo.Map(strings.Split(info.SupportedModels, ","), func(s string, _ int) string {
return strings.TrimSpace(s)
})
models = lo.Filter(models, func(m string, _ int) bool {
return lo.Contains(supportedModels, m)
})
modelsString = strings.Join(models, ", ")
}
info.SupportedModels = modelsString
resp.Success(c, map[string]any{
"stats": stats,
"info": info,
})
}
func loginAPIKey(c *gin.Context) {
resp.Success(c, nil)
}