Files
Prism/internal/api/handlers_apikeys.go
T
rose_cat707 fc3a66dc83
CI / docker (push) Has been cancelled
CI / test (push) Has been cancelled
feat: Prism HTTP/SOCKS5 代理网关及管理台
Go 控制面(SQLite + REST API)嵌入 Mihomo 数据面,Vue 3 多语言 Web 管理台。
含订阅/节点/规则/出站/监控/日志、OpenAPI、API Key、Gitea Actions CI(runs-on: ubuntu-latest)
与开源文档;镜像发布至 git.rc707blog.top Container Registry。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-23 13:41:56 +08:00

97 lines
2.3 KiB
Go

package api
import (
"net/http"
"strconv"
"strings"
"github.com/gin-gonic/gin"
"github.com/prism/proxy/internal/auth"
)
type createAPIKeyReq struct {
Name string `json:"name"`
}
func (s *Server) listAPIKeys(c *gin.Context) {
items, err := s.app.Store.ListAPIKeys(c.Request.Context())
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"items": items})
}
func (s *Server) createAPIKey(c *gin.Context) {
var req createAPIKeyReq
_ = c.ShouldBindJSON(&req)
name := strings.TrimSpace(req.Name)
if name == "" {
name = "default"
}
raw, err := auth.GenerateAPIKey()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
item, err := s.app.Store.CreateAPIKey(
c.Request.Context(),
name,
auth.APIKeyDisplayPrefix(raw),
auth.HashAPIKey(raw),
)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
_ = s.app.Store.AddAuditLog(c.Request.Context(), "create", "api_key", name)
c.JSON(http.StatusCreated, gin.H{
"id": item.ID,
"name": item.Name,
"key": raw,
"key_prefix": item.KeyPrefix,
"created_at": item.CreatedAt,
})
}
func (s *Server) deleteAPIKey(c *gin.Context) {
id, _ := strconv.ParseInt(c.Param("id"), 10, 64)
if err := s.app.Store.DeleteAPIKey(c.Request.Context(), id); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
_ = s.app.Store.AddAuditLog(c.Request.Context(), "delete", "api_key", strconv.FormatInt(id, 10))
c.JSON(http.StatusOK, gin.H{"ok": true})
}
func (s *Server) authorizeRequest(c *gin.Context, settings map[string]string) bool {
if settings["auth_enabled"] != "true" {
return true
}
ctx := c.Request.Context()
if key := strings.TrimSpace(c.GetHeader("X-API-Key")); key != "" {
if ok, _ := s.app.Store.VerifyAPIKey(ctx, auth.HashAPIKey(key)); ok {
return true
}
}
header := c.GetHeader("Authorization")
if !strings.HasPrefix(header, "Bearer ") {
return false
}
token := strings.TrimSpace(strings.TrimPrefix(header, "Bearer "))
if token == "" {
return false
}
if auth.IsAPIKeyFormat(token) {
ok, _ := s.app.Store.VerifyAPIKey(ctx, auth.HashAPIKey(token))
return ok
}
return verifyToken(settings["admin_password"], token)
}