Service list and minio status (#13480)

### What problem does this PR solve?

1. Resolve standard user can access admin service
2. Get RAGFlow service status
3. Fix minio status fetching

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
- [x] New Feature (non-breaking change which adds functionality)

---------

Signed-off-by: Jin Hai <haijin.chn@gmail.com>
This commit is contained in:
Jin Hai
2026-03-10 09:56:43 +08:00
committed by GitHub
parent 4f507c0058
commit 4fe706876c
6 changed files with 64 additions and 19 deletions

View File

@ -80,9 +80,6 @@ func main() {
logger.Info("Server mode", zap.String("mode", cfg.Server.Mode))
// Print all configuration settings
server.PrintAll()
// Set Gin mode
if cfg.Server.Mode == "release" {
gin.SetMode(gin.ReleaseMode)

View File

@ -644,7 +644,10 @@ func (h *Handler) GetUserPermission(c *gin.Context) {
func (h *Handler) GetServices(c *gin.Context) {
services, err := h.service.GetAllServices()
if err != nil {
errorResponse(c, err.Error(), 500)
c.JSON(http.StatusInternalServerError, gin.H{
"code": common.CodeServerError,
"message": err.Error(),
})
return
}
@ -932,6 +935,14 @@ func (h *Handler) AuthMiddleware() gin.HandlerFunc {
return
}
if !*user.IsSuperuser {
c.JSON(http.StatusForbidden, gin.H{
"code": common.CodeForbidden,
"message": "Permission denied",
})
return
}
c.Set("user", user)
c.Set("user_id", user.ID)
c.Set("email", user.Email)

View File

@ -18,17 +18,17 @@ var GlobalServerStatusStore = &ServerStatusStore{
}
// UpdateStatus updates or adds a server status
func (s *ServerStatusStore) UpdateStatus(serverID string, status *common.BaseMessage) {
func (s *ServerStatusStore) UpdateStatus(serverName string, status *common.BaseMessage) {
s.mu.Lock()
defer s.mu.Unlock()
s.servers[serverID] = status
s.servers[serverName] = status
}
// GetStatus gets a single server status
func (s *ServerStatusStore) GetStatus(serverID string) (*common.BaseMessage, bool) {
func (s *ServerStatusStore) GetStatus(serverName string) (*common.BaseMessage, bool) {
s.mu.RLock()
defer s.mu.RUnlock()
status, ok := s.servers[serverID]
status, ok := s.servers[serverName]
return status, ok
}

View File

@ -46,6 +46,7 @@ func (r *Router) Setup(engine *gin.Engine) {
// Public routes
admin.GET("/ping", r.handler.Ping)
admin.POST("/login", r.handler.Login)
admin.GET("/logout", r.handler.Logout)
admin.POST("/reports", r.handler.Reports)
@ -55,7 +56,6 @@ func (r *Router) Setup(engine *gin.Engine) {
{
// Auth
protected.GET("/auth", r.handler.AuthCheck)
protected.GET("/logout", r.handler.Logout)
// User management
protected.GET("/users", r.handler.ListUsers)

View File

@ -31,6 +31,7 @@ import (
"ragflow/internal/model"
"ragflow/internal/server"
"ragflow/internal/utility"
"strconv"
"time"
)
@ -282,20 +283,37 @@ func (s *Service) GetAllServices() ([]map[string]interface{}, error) {
var result []map[string]interface{}
for _, configDict := range allConfigs {
// Get service details to check status
serviceDetail, err := s.GetServiceDetails(configDict)
if err == nil {
if status, ok := serviceDetail["status"]; ok {
configDict["status"] = status
serviceType := configDict["service_type"]
if serviceType != "ragflow_server" {
// Get service details to check status
serviceDetail, err := s.GetServiceDetails(configDict)
if err == nil {
if status, ok := serviceDetail["status"]; ok {
configDict["status"] = status
} else {
configDict["status"] = "timeout"
}
} else {
configDict["status"] = "timeout"
}
} else {
configDict["status"] = "timeout"
result = append(result, configDict)
}
result = append(result, configDict)
}
id := len(result)
serverList := GlobalServerStatusStore.GetAllStatuses()
for _, serverStatus := range serverList {
serverItem := make(map[string]interface{})
serverItem["name"] = serverStatus.ServerName
serverItem["service_type"] = serverStatus.ServerType
serverItem["id"] = id
id++
serverItem["host"] = serverStatus.Host
serverItem["port"] = serverStatus.Port
serverItem["status"] = "alive"
result = append(result, serverItem)
}
return result, nil
}
@ -540,6 +558,7 @@ func (s *Service) checkMinioAlive(name string) (map[string]interface{}, error) {
// Get minio config from allConfigs
var host string
var port int
var secure bool
var verify bool = true
@ -550,6 +569,16 @@ func (s *Service) checkMinioAlive(name string) (map[string]interface{}, error) {
if h, ok := config["host"].(string); ok {
host = h
}
if p, ok := config["port"].(int); ok {
port = p
} else if p, ok := config["port"].(float64); ok {
port = int(p)
} else if p, ok := config["port"].(string); ok {
if parsedPort, err := strconv.Atoi(p); err == nil {
port = parsedPort
}
}
// Get secure from extra config
if extra, ok := config["extra"].(map[string]interface{}); ok {
if s, ok := extra["secure"].(bool); ok {
@ -569,7 +598,10 @@ func (s *Service) checkMinioAlive(name string) (map[string]interface{}, error) {
// Default host
if host == "" {
host = "localhost:9000"
host = "localhost"
}
if port == 0 {
port = 9000
}
// Determine scheme
@ -578,7 +610,7 @@ func (s *Service) checkMinioAlive(name string) (map[string]interface{}, error) {
scheme = "https"
}
url := fmt.Sprintf("%s://%s/minio/health/live", scheme, host)
url := fmt.Sprintf("%s://%s:%d/minio/health/live", scheme, host, port)
// Create HTTP client with timeout
client := &http.Client{

View File

@ -60,6 +60,10 @@ func (h *KnowledgebaseHandler) getUserID(c *gin.Context) (string, common.ErrorCo
return "", code, err
}
if *user.IsSuperuser {
return "", common.CodeForbidden, ErrForbidden
}
return user.ID, common.CodeSuccess, nil
}
@ -97,6 +101,7 @@ var (
ErrMissingAuth = &HTTPError{Code: common.CodeUnauthorized, Message: "Missing Authorization header"}
// ErrInvalidToken indicates invalid access token
ErrInvalidToken = &HTTPError{Code: common.CodeUnauthorized, Message: "Invalid access token"}
ErrForbidden = &HTTPError{Code: common.CodeForbidden, Message: "Forbidden user"}
)
// CreateKB handles the create knowledge base request