| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- package admin
- import (
- "net/http"
- "net/netip"
- "strconv"
- "strings"
- "github.com/Wei-Shaw/sub2api/internal/pkg/response"
- "github.com/Wei-Shaw/sub2api/internal/service"
- "github.com/gin-gonic/gin"
- )
- var ingressRejectReasons = map[string]struct{}{
- "query_api_key_deprecated": {}, "api_key_required": {}, "invalid_api_key": {},
- "invalid_auth_rate_limited": {},
- "api_key_auth_overloaded": {},
- "api_key_disabled": {}, "ip_restricted": {}, "user_inactive": {}, "group_deleted": {},
- "group_disabled": {}, "group_not_allowed": {}, "group_unassigned": {}, "other": {},
- }
- var ingressRejectRouteFamilies = map[string]struct{}{
- "antigravity": {}, "gemini": {}, "codex": {}, "messages": {}, "responses": {},
- "chat_completions": {}, "images": {}, "videos": {}, "embeddings": {}, "models": {}, "other": {},
- }
- var ingressRejectProtocols = map[string]struct{}{
- "google": {}, "anthropic": {}, "openai": {}, "gateway": {}, "other": {},
- }
- // ListIngressRejects returns bounded security aggregates, never raw credentials or request bodies.
- func (h *OpsHandler) ListIngressRejects(c *gin.Context) {
- if h.opsService == nil {
- response.Error(c, http.StatusServiceUnavailable, "Ops service not available")
- return
- }
- page, pageSize := response.ParsePagination(c)
- if pageSize > 200 {
- pageSize = 200
- }
- startTime, endTime, err := parseOpsTimeRange(c, "1h")
- if err != nil {
- response.BadRequest(c, err.Error())
- return
- }
- filter := &service.OpsIngressRejectFilter{Page: page, PageSize: pageSize}
- if !startTime.IsZero() {
- filter.StartTime = &startTime
- }
- if !endTime.IsZero() {
- filter.EndTime = &endTime
- }
- if filter.RejectReason, err = parseIngressRejectEnum(c, "reason", ingressRejectReasons); err != nil {
- response.BadRequest(c, err.Error())
- return
- }
- if filter.RouteFamily, err = parseIngressRejectEnum(c, "route_family", ingressRejectRouteFamilies); err != nil {
- response.BadRequest(c, err.Error())
- return
- }
- if filter.Protocol, err = parseIngressRejectEnum(c, "protocol", ingressRejectProtocols); err != nil {
- response.BadRequest(c, err.Error())
- return
- }
- if raw := strings.TrimSpace(c.Query("client_ip")); raw != "" {
- addr, parseErr := netip.ParseAddr(raw)
- if parseErr != nil {
- response.BadRequest(c, "Invalid client_ip")
- return
- }
- addr = addr.Unmap()
- if addr.Is6() {
- addr = netip.PrefixFrom(addr, 64).Masked().Addr()
- }
- filter.ClientIP = addr.String()
- }
- if filter.UserID, err = parseOptionalPositiveID(c, "user_id"); err != nil {
- response.BadRequest(c, err.Error())
- return
- }
- if filter.APIKeyID, err = parseOptionalPositiveID(c, "api_key_id"); err != nil {
- response.BadRequest(c, err.Error())
- return
- }
- result, err := h.opsService.ListIngressRejects(c.Request.Context(), filter)
- if err != nil {
- response.ErrorFrom(c, err)
- return
- }
- response.Success(c, result)
- }
- func (h *OpsHandler) GetIngressRejectHealth(c *gin.Context) {
- if h.opsService == nil {
- response.Error(c, http.StatusServiceUnavailable, "Ops service not available")
- return
- }
- if err := h.opsService.RequireMonitoringEnabled(c.Request.Context()); err != nil {
- response.ErrorFrom(c, err)
- return
- }
- response.Success(c, h.opsService.GetIngressRejectHealth())
- }
- func parseIngressRejectEnum(c *gin.Context, name string, allowed map[string]struct{}) (string, error) {
- value := strings.TrimSpace(c.Query(name))
- if value == "" {
- return "", nil
- }
- if _, ok := allowed[value]; !ok {
- return "", &ingressRejectQueryError{message: "Invalid " + name}
- }
- return value, nil
- }
- func parseOptionalPositiveID(c *gin.Context, name string) (*int64, error) {
- raw := strings.TrimSpace(c.Query(name))
- if raw == "" {
- return nil, nil
- }
- value, err := strconv.ParseInt(raw, 10, 64)
- if err != nil || value <= 0 {
- return nil, &ingressRejectQueryError{message: "Invalid " + name}
- }
- return &value, nil
- }
- type ingressRejectQueryError struct{ message string }
- func (e *ingressRejectQueryError) Error() string { return e.message }
|