Go: add statistics command (#16119)

### What problem does this PR solve?

Prepare for enterprise command

### Type of change

- [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-06-18 15:21:44 +08:00
committed by GitHub
parent 351b61a243
commit 20d11648a4
12 changed files with 2889 additions and 465 deletions

View File

@@ -0,0 +1,851 @@
//
// Copyright 2026 The InfiniFlow Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package admin
import (
"errors"
"net/http"
"ragflow/internal/common"
"strconv"
"github.com/gin-gonic/gin"
)
// ListRoles handle list roles
func (h *Handler) ListRoles(c *gin.Context) {
roles, err := h.service.ListRoles()
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
if roles == nil {
roles = []map[string]interface{}{}
}
success(c, gin.H{
"roles": roles,
"total": len(roles),
}, "")
}
// CreateRoleHTTPRequest create role request
type CreateRoleHTTPRequest struct {
RoleName string `json:"role_name" binding:"required"`
Description string `json:"description"`
}
// CreateRole handle create role
func (h *Handler) CreateRole(c *gin.Context) {
var req CreateRoleHTTPRequest
if err := c.ShouldBindJSON(&req); err != nil {
errorResponse(c, "Role name is required", 400)
return
}
role, err := h.service.CreateRole(req.RoleName, req.Description)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, role, "")
}
// GetRole handle get role
func (h *Handler) GetRole(c *gin.Context) {
roleName := c.Param("role_name")
if roleName == "" {
errorResponse(c, "Role name is required", 400)
return
}
role, err := h.service.GetRole(roleName)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, role, "")
}
// UpdateRoleHTTPRequest update role request
type UpdateRoleHTTPRequest struct {
Description string `json:"description" binding:"required"`
}
// UpdateRole handle update role
func (h *Handler) UpdateRole(c *gin.Context) {
roleName := c.Param("role_name")
if roleName == "" {
errorResponse(c, "Role name is required", 400)
return
}
var req UpdateRoleHTTPRequest
if err := c.ShouldBindJSON(&req); err != nil {
errorResponse(c, "Role description is required", 400)
return
}
role, err := h.service.UpdateRole(roleName, req.Description)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, role, "")
}
// DeleteRole handle delete role
func (h *Handler) DeleteRole(c *gin.Context) {
roleName := c.Param("role_name")
if roleName == "" {
errorResponse(c, "Role name is required", 400)
return
}
if err := h.service.DeleteRole(roleName); err != nil {
errorResponse(c, err.Error(), 500)
return
}
successNoData(c, "")
}
// GetRolePermission handle get role permission
func (h *Handler) GetRolePermission(c *gin.Context) {
roleName := c.Param("role_name")
if roleName == "" {
errorResponse(c, "Role name is required", 400)
return
}
permissions, err := h.service.GetRolePermission(roleName)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, permissions, "")
}
// GrantRolePermissionHTTPRequest grant role permission request
type GrantRolePermissionHTTPRequest struct {
Actions []string `json:"actions" binding:"required"`
Resource string `json:"resource" binding:"required"`
}
// GrantRolePermission handle grant role permission
func (h *Handler) GrantRolePermission(c *gin.Context) {
roleName := c.Param("role_name")
if roleName == "" {
errorResponse(c, "Role name is required", 400)
return
}
var req GrantRolePermissionHTTPRequest
if err := c.ShouldBindJSON(&req); err != nil {
errorResponse(c, "Permission is required", 400)
return
}
result, err := h.service.GrantRolePermission(roleName, req.Actions, req.Resource)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, result, "")
}
// RevokeRolePermissionHTTPRequest revoke role permission request
type RevokeRolePermissionHTTPRequest struct {
Actions []string `json:"actions" binding:"required"`
Resource string `json:"resource" binding:"required"`
}
// RevokeRolePermission handle revoke role permission
func (h *Handler) RevokeRolePermission(c *gin.Context) {
roleName := c.Param("role_name")
if roleName == "" {
errorResponse(c, "Role name is required", 400)
return
}
var req RevokeRolePermissionHTTPRequest
if err := c.ShouldBindJSON(&req); err != nil {
errorResponse(c, "Permission is required", 400)
return
}
result, err := h.service.RevokeRolePermission(roleName, req.Actions, req.Resource)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, result, "")
}
type ShowUserActivityRequest struct {
Days int `json:"days"`
Email string `json:"email"`
}
// ShowUserActivity handle show user activity
func (h *Handler) ShowUserActivity(c *gin.Context) {
var req ShowUserActivityRequest
if err := c.ShouldBindJSON(&req); err != nil {
println("JSON bind error: %v (type: %T)", err, err)
c.JSON(http.StatusOK, gin.H{
"code": common.CodeBadRequest,
"message": err.Error(),
})
return
}
userActivity, err := h.service.ShowUserActivity(req.Email, req.Days)
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, userActivity, "")
}
type ShowUserDatasetSummaryRequest struct {
Dataset string `json:"dataset"`
}
// ShowUserDatasetSummary handle show user dataset summary
func (h *Handler) ShowUserDatasetSummary(c *gin.Context) {
var req ShowUserDatasetSummaryRequest
if err := c.ShouldBindJSON(&req); err != nil {
println("JSON bind error: %v (type: %T)", err, err)
c.JSON(http.StatusOK, gin.H{
"code": common.CodeBadRequest,
"message": err.Error(),
})
return
}
username := c.Param("username")
if username == "" {
errorResponse(c, "Username is required", 400)
return
}
userDatasetSummary, err := h.service.ShowUserDatasetSummary(username, req.Dataset)
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, userDatasetSummary, "")
}
// ShowUserSummary handle show user summary
func (h *Handler) ShowUserSummary(c *gin.Context) {
username := c.Param("username")
if username == "" {
errorResponse(c, "Username is required", 400)
return
}
userSummary, err := h.service.ShowUserSummary(username)
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, userSummary, "")
}
// ShowUserStorage handle show user storage
func (h *Handler) ShowUserStorage(c *gin.Context) {
username := c.Param("username")
if username == "" {
errorResponse(c, "Username is required", 400)
return
}
userStorage, err := h.service.ShowUserStorage(username)
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, userStorage, "")
}
// ShowUserQuota handle show user quota
func (h *Handler) ShowUserQuota(c *gin.Context) {
username := c.Param("username")
if username == "" {
errorResponse(c, "Username is required", 400)
return
}
userQuota, err := h.service.ShowUserQuota(username)
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, userQuota, "")
}
// ShowUserIndex handle show user index
func (h *Handler) ShowUserIndex(c *gin.Context) {
username := c.Param("username")
if username == "" {
errorResponse(c, "Username is required", 400)
return
}
userIndex, err := h.service.ShowUserIndex(username)
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, userIndex, "")
}
// UpdateUserRoleHTTPRequest update user role request
type UpdateUserRoleHTTPRequest struct {
RoleName string `json:"role_name" binding:"required"`
}
// UpdateUserRole handle update user role
func (h *Handler) UpdateUserRole(c *gin.Context) {
username := c.Param("username")
if username == "" {
errorResponse(c, "Username is required", 400)
return
}
var req UpdateUserRoleHTTPRequest
if err := c.ShouldBindJSON(&req); err != nil {
errorResponse(c, "Role name is required", 400)
return
}
result, err := h.service.UpdateUserRole(username, req.RoleName)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, result, "")
}
// ShowUserPermission handle show user permission
func (h *Handler) ShowUserPermission(c *gin.Context) {
username := c.Param("username")
if username == "" {
errorResponse(c, "Username is required", 400)
return
}
permissions, err := h.service.ShowUserPermission(username)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, permissions, "")
}
// ShowUsersSummary handle show users summary
func (h *Handler) ShowUsersSummary(c *gin.Context) {
usersSummary, err := h.service.ShowUsersSummary()
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, usersSummary, "")
}
type ShowUsersActivityRequest struct {
Days *int `json:"days"`
Window *int `json:"window"`
}
// ShowUsersActivity handle show users activity
func (h *Handler) ShowUsersActivity(c *gin.Context) {
var req ShowUsersActivityRequest
if err := c.ShouldBindJSON(&req); err != nil {
println("JSON bind error: %v (type: %T)", err, err)
c.JSON(http.StatusOK, gin.H{
"code": common.CodeBadRequest,
"message": err.Error(),
})
return
}
usersActivity, err := h.service.ShowUsersActivity(req.Days, req.Window)
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, usersActivity, "")
}
type ListUsersReportsRequest struct {
Status *string `json:"status"`
Days *int `json:"days"`
Plan *string `json:"plan"`
}
// ListUsersReports handle show users reports
func (h *Handler) ListUsersReports(c *gin.Context) {
var req ListUsersReportsRequest
if err := c.ShouldBindJSON(&req); err != nil {
println("JSON bind error: %v (type: %T)", err, err)
c.JSON(http.StatusOK, gin.H{
"code": common.CodeBadRequest,
"message": err.Error(),
})
return
}
var err error
pageIndex := 0
pageIndexStr := c.Param("page")
if pageIndexStr != "" {
pageIndex, err = strconv.Atoi(pageIndexStr)
if err != nil {
errorResponse(c, "Page index must be an integer", 400)
return
}
}
pageSize := 10
pageSizeStr := c.Param("page_size")
if pageSizeStr != "" {
pageSize, err = strconv.Atoi(pageSizeStr)
if err != nil {
errorResponse(c, "Page size must be an integer", 400)
return
}
}
usersReports, err := h.service.ListUsersReports(pageIndex, pageSize, req.Status, req.Plan, req.Days)
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, usersReports, "")
}
// ListUsersStorage handle show users storage
func (h *Handler) ListUsersStorage(c *gin.Context) {
var err error
pageIndex := 0
pageIndexStr := c.Param("page")
if pageIndexStr != "" {
pageIndex, err = strconv.Atoi(pageIndexStr)
if err != nil {
errorResponse(c, "Page index must be an integer", 400)
return
}
}
pageSize := 10
pageSizeStr := c.Param("page_size")
if pageSizeStr != "" {
pageSize, err = strconv.Atoi(pageSizeStr)
if err != nil {
errorResponse(c, "Page size must be an integer", 400)
return
}
}
top := 10
topStr := c.Param("top")
if topStr != "" {
top, err = strconv.Atoi(topStr)
if err != nil {
errorResponse(c, "Top must be an integer", 400)
}
}
usersStorage, err := h.service.ListUsersStorage(pageIndex, pageSize, top)
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, usersStorage, "")
}
// ListUsersDocuments handle show users documents
func (h *Handler) ListUsersDocuments(c *gin.Context) {
var err error
pageIndex := 0
pageIndexStr := c.Param("page")
if pageIndexStr != "" {
pageIndex, err = strconv.Atoi(pageIndexStr)
if err != nil {
errorResponse(c, "Page index must be an integer", 400)
return
}
}
pageSize := 10
pageSizeStr := c.Param("page_size")
if pageSizeStr != "" {
pageSize, err = strconv.Atoi(pageSizeStr)
if err != nil {
errorResponse(c, "Page size must be an integer", 400)
return
}
}
top := 10
topStr := c.Param("top")
if topStr != "" {
top, err = strconv.Atoi(topStr)
if err != nil {
errorResponse(c, "Top must be an integer", 400)
}
}
usersDocuments, err := h.service.ListUsersDocuments(pageIndex, pageSize, top)
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, usersDocuments, "")
}
// ListUsersIndex handle show users index
func (h *Handler) ListUsersIndex(c *gin.Context) {
var err error
pageIndex := 0
pageIndexStr := c.Param("page")
if pageIndexStr != "" {
pageIndex, err = strconv.Atoi(pageIndexStr)
if err != nil {
errorResponse(c, "Page index must be an integer", 400)
return
}
}
pageSize := 10
pageSizeStr := c.Param("page_size")
if pageSizeStr != "" {
pageSize, err = strconv.Atoi(pageSizeStr)
if err != nil {
errorResponse(c, "Page size must be an integer", 400)
return
}
}
top := 10
topStr := c.Param("top")
if topStr != "" {
top, err = strconv.Atoi(topStr)
if err != nil {
errorResponse(c, "Top must be an integer", 400)
}
}
usersIndex, err := h.service.ListUsersIndex(pageIndex, pageSize, top)
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, usersIndex, "")
}
type ListUsersQuotaRequest struct {
QuotaThreshold *int `json:"quota_threshold"`
Plan *string `json:"plan"`
Days *int `json:"days"`
}
// ListUsersQuota handle show users quota
func (h *Handler) ListUsersQuota(c *gin.Context) {
var request ListUsersQuotaRequest
if err := c.ShouldBindJSON(&request); err != nil {
println("JSON bind error: %v (type: %T)", err, err)
c.JSON(http.StatusOK, gin.H{
"code": common.CodeBadRequest,
"message": err.Error(),
})
return
}
var err error
pageIndex := 0
pageIndexStr := c.Param("page")
if pageIndexStr != "" {
pageIndex, err = strconv.Atoi(pageIndexStr)
if err != nil {
errorResponse(c, "Page index must be an integer", 400)
return
}
}
pageSize := 10
pageSizeStr := c.Param("page_size")
if pageSizeStr != "" {
pageSize, err = strconv.Atoi(pageSizeStr)
if err != nil {
errorResponse(c, "Page size must be an integer", 400)
return
}
}
top := 10
topStr := c.Param("top")
if topStr != "" {
top, err = strconv.Atoi(topStr)
if err != nil {
errorResponse(c, "Top must be an integer", 400)
}
}
usersQuota, err := h.service.ListUsersQuota(pageIndex, pageSize, top, request.QuotaThreshold, request.Plan, request.Days)
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, usersQuota, "")
}
// ShowUsersQuotaSummary handle show users quota summary
func (h *Handler) ShowUsersQuotaSummary(c *gin.Context) {
usersQuotaSummary, err := h.service.ShowUsersQuotaSummary()
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, usersQuotaSummary, "")
}
// ShowDataSummary handle show data summary
func (h *Handler) ShowDataSummary(c *gin.Context) {
dataSummary, err := h.service.ShowDataSummary()
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, dataSummary, "")
}
// ShowDataOrphan handle show data orphan
func (h *Handler) ShowDataOrphan(c *gin.Context) {
dataOrphan, err := h.service.ShowDataOrphan()
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, dataOrphan, "")
}
// ShowDataStorage handle show data storage
func (h *Handler) ShowDataStorage(c *gin.Context) {
dataStorage, err := h.service.ShowDataStorage()
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, dataStorage, "")
}
// ShowDataIndex handle show data index
func (h *Handler) ShowDataIndex(c *gin.Context) {
dataIndex, err := h.service.ShowDataIndex()
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, dataIndex, "")
}
type PurgeOrphanDataRequest struct {
Preview bool `json:"preview"`
}
// PurgeOrphanData handle purge orphan data
func (h *Handler) PurgeOrphanData(c *gin.Context) {
var request PurgeOrphanDataRequest
if err := c.ShouldBindJSON(&request); err != nil {
println("JSON bind error: %v (type: %T)", err, err)
c.JSON(http.StatusOK, gin.H{
"code": common.CodeBadRequest,
"message": err.Error(),
})
return
}
result, err := h.service.PurgeOrphanData(request.Preview)
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, result, "Orphan data purged successfully")
}
type PurgeUserDataRequest struct {
Preview bool `json:"preview"`
}
// PurgeUserData handle purge user data
func (h *Handler) PurgeUserData(c *gin.Context) {
var request PurgeUserDataRequest
if err := c.ShouldBindJSON(&request); err != nil {
println("JSON bind error: %v (type: %T)", err, err)
c.JSON(http.StatusOK, gin.H{
"code": common.CodeBadRequest,
"message": err.Error(),
})
return
}
username := c.Param("username")
if username == "" {
errorResponse(c, "Username is required", 400)
return
}
result, err := h.service.PurgeUserData(username, request.Preview)
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, result, "")
}
type PurgeUsersDataRequest struct {
Preview bool `json:"preview"`
Days int `json:"days"`
Plan *string `json:"plan"`
UserStatus *string `json:"user_status"`
}
// PurgeUsersData handle purge users data
func (h *Handler) PurgeUsersData(c *gin.Context) {
var request PurgeUsersDataRequest
if err := c.ShouldBindJSON(&request); err != nil {
println("JSON bind error: %v (type: %T)", err, err)
c.JSON(http.StatusOK, gin.H{
"code": common.CodeBadRequest,
"message": err.Error(),
})
return
}
result, err := h.service.PurgeUsersData(request.Preview, request.Days, request.Plan, request.UserStatus)
if err != nil {
if errors.Is(err, common.ErrUserNotFound) {
errorResponse(c, "User not found", 404)
return
}
errorResponse(c, err.Error(), 500)
return
}
success(c, result, "")
}

View File

@@ -0,0 +1,489 @@
//
// Copyright 2026 The InfiniFlow Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package admin
import (
"ragflow/internal/common"
"ragflow/internal/dao"
"ragflow/internal/entity"
)
// Role management methods
// ListRoles list all roles
func (s *Service) ListRoles() ([]map[string]interface{}, error) {
// TODO: Implement list roles
return []map[string]interface{}{}, nil
}
// CreateRole create a new role
func (s *Service) CreateRole(roleName, description string) (map[string]interface{}, error) {
// TODO: Implement create role
return map[string]interface{}{}, nil
}
// GetRole get role details
func (s *Service) GetRole(roleName string) (map[string]interface{}, error) {
// TODO: Implement get role
return map[string]interface{}{}, nil
}
// UpdateRole update role
func (s *Service) UpdateRole(roleName, description string) (map[string]interface{}, error) {
// TODO: Implement update role
return map[string]interface{}{}, nil
}
// DeleteRole delete role
func (s *Service) DeleteRole(roleName string) error {
// TODO: Implement delete role
return nil
}
// GetRolePermission get role permissions
func (s *Service) GetRolePermission(roleName string) ([]map[string]interface{}, error) {
// TODO: Implement get role permissions
return []map[string]interface{}{}, nil
}
// GrantRolePermission grant permission to role
func (s *Service) GrantRolePermission(roleName string, actions []string, resource string) (map[string]interface{}, error) {
// TODO: Implement grant role permission
return map[string]interface{}{}, nil
}
// RevokeRolePermission revoke permission from role
func (s *Service) RevokeRolePermission(roleName string, actions []string, resource string) (map[string]interface{}, error) {
// TODO: Implement revoke role permission
return map[string]interface{}{}, nil
}
// ShowUserActivity show user activity for enterprise edition
func (s *Service) ShowUserActivity(email string, days int) (map[string]interface{}, error) {
// Query user by email
var user entity.User
err := dao.DB.Where("email = ?", email).First(&user).Error
if err != nil {
return nil, common.ErrUserNotFound
}
result := map[string]interface{}{
"email": user.Email,
"nickname": user.Nickname,
"days": days,
"error": "'show user activity' is implemented in enterprise edition",
}
return result, nil
}
// ShowUserDatasetSummary show user dataset summary for enterprise edition
func (s *Service) ShowUserDatasetSummary(email, dataset string) (map[string]interface{}, error) {
// Query user by email
var user entity.User
err := dao.DB.Where("email = ?", email).First(&user).Error
if err != nil {
return nil, common.ErrUserNotFound
}
result := map[string]interface{}{
"email": user.Email,
"nickname": user.Nickname,
"dataset": dataset,
"error": "'show user dataset summary' is implemented in enterprise edition",
}
return result, nil
}
// GetUserSummary get user summary for enterprise edition
func (s *Service) ShowUserSummary(email string) (map[string]interface{}, error) {
// Query user by email
var user entity.User
err := dao.DB.Where("email = ?", email).First(&user).Error
if err != nil {
return nil, common.ErrUserNotFound
}
result := map[string]interface{}{
"email": user.Email,
"nickname": user.Nickname,
"error": "'show user summary' is implemented in enterprise edition",
}
return result, nil
}
// ShowUserStorage show user storage for enterprise edition
func (s *Service) ShowUserStorage(email string) (map[string]interface{}, error) {
// Query user by email
var user entity.User
err := dao.DB.Where("email = ?", email).First(&user).Error
if err != nil {
return nil, common.ErrUserNotFound
}
result := map[string]interface{}{
"email": user.Email,
"nickname": user.Nickname,
"error": "'show user storage' is implemented in enterprise edition",
}
return result, nil
}
// ShowUserQuota show user quota for enterprise edition
func (s *Service) ShowUserQuota(email string) (map[string]interface{}, error) {
// Query user by email
var user entity.User
err := dao.DB.Where("email = ?", email).First(&user).Error
if err != nil {
return nil, common.ErrUserNotFound
}
result := map[string]interface{}{
"email": user.Email,
"nickname": user.Nickname,
"error": "'show user quota' is implemented in enterprise edition",
}
return result, nil
}
// ShowUserIndex show user index for enterprise edition
func (s *Service) ShowUserIndex(email string) (map[string]interface{}, error) {
// Query user by email
var user entity.User
err := dao.DB.Where("email = ?", email).First(&user).Error
if err != nil {
return nil, common.ErrUserNotFound
}
result := map[string]interface{}{
"email": user.Email,
"nickname": user.Nickname,
"error": "'show user index' is implemented in enterprise edition",
}
return result, nil
}
// UpdateUserRole update user role
func (s *Service) UpdateUserRole(email, roleName string) (map[string]interface{}, error) {
// Query user by email
var user entity.User
err := dao.DB.Where("email = ?", email).First(&user).Error
if err != nil {
return nil, common.ErrUserNotFound
}
result := map[string]interface{}{
"command": "update_user_role",
"role": roleName,
"email": user.Email,
"nickname": user.Nickname,
"error": "'update user role' is implemented in enterprise edition",
}
return result, nil
}
// ShowUserPermission show user permissions for enterprise edition
func (s *Service) ShowUserPermission(email string) (map[string]interface{}, error) {
// Query user by email
var user entity.User
err := dao.DB.Where("email = ?", email).First(&user).Error
if err != nil {
return nil, common.ErrUserNotFound
}
result := map[string]interface{}{
"command": "show_user_permission",
"email": user.Email,
"nickname": user.Nickname,
"error": "'show user permission' is implemented in enterprise edition",
}
return result, nil
}
// ShowUsersSummary show users summary for enterprise edition
func (s *Service) ShowUsersSummary() (map[string]interface{}, error) {
result := map[string]interface{}{
"command": "show_users_summary",
"error": "'show users summary' is implemented in enterprise edition",
}
return result, nil
}
// ShowUsersActivity show users activity for enterprise edition
func (s *Service) ShowUsersActivity(days, windows *int) (map[string]interface{}, error) {
daysInt := 0
if days != nil {
daysInt = *days
}
windowsInt := 0
if windows != nil {
windowsInt = *windows
}
result := map[string]interface{}{
"days": daysInt,
"windows": windowsInt,
"command": "show_users_activity",
"error": "'show users activity' is implemented in enterprise edition",
}
return result, nil
}
func (s *Service) ListUsersEnterprise(pageIndex, pageSize int, status, orderBy, plan *string, top, days, quota *int) ([]map[string]interface{}, error) {
item := map[string]interface{}{}
if status != nil {
item["status"] = *status
}
if orderBy != nil {
item["order_by"] = *orderBy
}
if plan != nil {
item["plan"] = *plan
}
if top != nil {
item["top"] = *top
}
if days != nil {
item["days"] = *days
}
if quota != nil {
item["quota"] = *quota
}
var result []map[string]interface{}
result = append(result, item)
return result, nil
}
// ListUsersReports list users reports for enterprise edition
func (s *Service) ListUsersReports(pageIndex, pageSize int, status, plan *string, days *int) (map[string]interface{}, error) {
statusStr := "all"
if status != nil {
statusStr = *status
}
planStr := "all"
daysInt := 0
if days != nil {
daysInt = *days
}
if plan != nil {
planStr = *plan
}
result := map[string]interface{}{
"page_index": pageIndex,
"page_size": pageSize,
"status": statusStr,
"plan": planStr,
"days": daysInt,
"command": "list_users_reports",
"error": "'List users reports' is implemented in enterprise edition",
}
return result, nil
}
// ListUsersStorage list users storage for enterprise edition
func (s *Service) ListUsersStorage(pageIndex, pageSize, top int) (map[string]interface{}, error) {
result := map[string]interface{}{
"page_index": pageIndex,
"page_size": pageSize,
"top": top,
"command": "list_users_storage",
"error": "'List users storage' is implemented in enterprise edition",
}
return result, nil
}
// ListUsersDocuments list users documents for enterprise edition
func (s *Service) ListUsersDocuments(pageIndex, pageSize, top int) (map[string]interface{}, error) {
result := map[string]interface{}{
"page_index": pageIndex,
"page_size": pageSize,
"top": top,
"command": "list_users_documents",
"error": "'List users documents' is implemented in enterprise edition",
}
return result, nil
}
// ListUsersIndex list users index for enterprise edition
func (s *Service) ListUsersIndex(pageIndex, pageSize, top int) (map[string]interface{}, error) {
result := map[string]interface{}{
"page_index": pageIndex,
"page_size": pageSize,
"top": top,
"command": "list_users_index",
"error": "'List users index' is implemented in enterprise edition",
}
return result, nil
}
// ListUsersQuota list users quota for enterprise edition
func (s *Service) ListUsersQuota(pageIndex, pageSize, top int, quotaThreshold *int, plan *string, days *int) (map[string]interface{}, error) {
quotaThresholdInt := 0
if quotaThreshold != nil {
quotaThresholdInt = *quotaThreshold
}
planStr := "all"
daysInt := 0
if days != nil {
daysInt = *days
}
if plan != nil {
planStr = *plan
}
result := map[string]interface{}{
"page_index": pageIndex,
"page_size": pageSize,
"top": top,
"quota_threshold": quotaThresholdInt,
"plan": planStr,
"days": daysInt,
"command": "list_users_quota",
"error": "'List users quota' is implemented in enterprise edition",
}
return result, nil
}
// ShowUsersQuotaSummary show users quota summary for enterprise edition
func (s *Service) ShowUsersQuotaSummary() (map[string]interface{}, error) {
result := map[string]interface{}{
"command": "show_users_quota_summary",
"error": "'Show users quota summary' is implemented in enterprise edition",
}
return result, nil
}
// ShowDataSummary show data summary for enterprise edition
func (s *Service) ShowDataSummary() (map[string]interface{}, error) {
result := map[string]interface{}{
"command": "show_data_summary",
"error": "'Show data summary' is implemented in enterprise edition",
}
return result, nil
}
// ShowDataOrphan show data orphan for enterprise edition
func (s *Service) ShowDataOrphan() (map[string]interface{}, error) {
result := map[string]interface{}{
"command": "show_data_orphan",
"error": "'Show data orphan' is implemented in enterprise edition",
}
return result, nil
}
// ShowDataStorage show data storage for enterprise edition
func (s *Service) ShowDataStorage() (map[string]interface{}, error) {
result := map[string]interface{}{
"command": "show_data_storage",
"error": "'Show data storage' is implemented in enterprise edition",
}
return result, nil
}
// ShowDataIndex show data index for enterprise edition
func (s *Service) ShowDataIndex() (map[string]interface{}, error) {
result := map[string]interface{}{
"command": "show_data_index",
"error": "'Show data index' is implemented in enterprise edition",
}
return result, nil
}
// PurgeOrphanData purge orphan data for enterprise edition
func (s *Service) PurgeOrphanData(preview bool) (map[string]interface{}, error) {
result := map[string]interface{}{
"command": "purge_orphan_data",
"preview": preview,
"error": "'Purge orphan data' is implemented in enterprise edition",
}
return result, nil
}
// PurgeUserData purge user data for enterprise edition
func (s *Service) PurgeUserData(email string, preview bool) (map[string]interface{}, error) {
// Query user by email
var user entity.User
err := dao.DB.Where("email = ?", email).First(&user).Error
if err != nil {
return nil, common.ErrUserNotFound
}
result := map[string]interface{}{
"email": user.Email,
"nickname": user.Nickname,
"preview": preview,
"error": "'Purge user data' is implemented in enterprise edition",
}
return result, nil
}
// PurgeUsersData purge users data for enterprise edition
func (s *Service) PurgeUsersData(preview bool, days int, userPlan *string, userActivity *string) (map[string]interface{}, error) {
plan := "all"
activity := "all"
if userPlan != nil {
plan = *userPlan
}
if userActivity != nil {
activity = *userActivity
}
result := map[string]interface{}{
"command": "purge_users_data",
"preview": preview,
"days": days,
"plan": plan,
"activity": activity,
"error": "'Purge users data' is implemented in enterprise edition",
}
return result, nil
}

View File

@@ -205,15 +205,65 @@ func (h *Handler) AuthCheck(c *gin.Context) {
successNoData(c, "Admin is authorized")
}
// ListUsersRequest list users request
type ListUsersRequest struct {
Enterprise *bool `json:"enterprise"`
UserStatus *string `json:"user_status"`
OrderBy *string `json:"order_by"`
Top *int `json:"top"`
Days *int `json:"days"`
Quota *int `json:"quota"`
Plan *string `json:"plan"`
}
// ListUsers handle list users
func (h *Handler) ListUsers(c *gin.Context) {
users, err := h.service.ListUsers()
if err != nil {
errorResponse(c, err.Error(), 500)
return
var err error
var pageInt int
page := c.Param("page")
if page == "" {
pageInt = 0
} else {
pageInt, err = strconv.Atoi(page)
if err != nil {
errorResponse(c, "Page must be an integer", 400)
return
}
}
var pageSizeInt int
pageSize := c.Param("page_size")
if pageSize == "" {
pageSizeInt = 0
} else {
pageSizeInt, err = strconv.Atoi(pageSize)
if err != nil {
errorResponse(c, "Page size must be an integer", 400)
return
}
}
var req ListUsersRequest
var users []map[string]interface{}
if err = c.ShouldBindJSON(&req); err != nil {
users, err = h.service.ListUsers(pageInt, pageSizeInt)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, users, "Get all users")
} else {
users, err = h.service.ListUsersEnterprise(pageInt, pageSizeInt, req.UserStatus, req.OrderBy, req.Plan, req.Top, req.Days, req.Quota)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, users, "list users")
}
success(c, users, "Get all users")
}
// CreateUserHTTPRequest create user request
@@ -478,228 +528,6 @@ func (h *Handler) DeleteUserAPIToken(c *gin.Context) {
successNoData(c, "API key deleted successfully")
}
// ListRoles handle list roles
func (h *Handler) ListRoles(c *gin.Context) {
roles, err := h.service.ListRoles()
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
if roles == nil {
roles = []map[string]interface{}{}
}
success(c, gin.H{
"roles": roles,
"total": len(roles),
}, "")
}
// CreateRoleHTTPRequest create role request
type CreateRoleHTTPRequest struct {
RoleName string `json:"role_name" binding:"required"`
Description string `json:"description"`
}
// CreateRole handle create role
func (h *Handler) CreateRole(c *gin.Context) {
var req CreateRoleHTTPRequest
if err := c.ShouldBindJSON(&req); err != nil {
errorResponse(c, "Role name is required", 400)
return
}
role, err := h.service.CreateRole(req.RoleName, req.Description)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, role, "")
}
// GetRole handle get role
func (h *Handler) GetRole(c *gin.Context) {
roleName := c.Param("role_name")
if roleName == "" {
errorResponse(c, "Role name is required", 400)
return
}
role, err := h.service.GetRole(roleName)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, role, "")
}
// UpdateRoleHTTPRequest update role request
type UpdateRoleHTTPRequest struct {
Description string `json:"description" binding:"required"`
}
// UpdateRole handle update role
func (h *Handler) UpdateRole(c *gin.Context) {
roleName := c.Param("role_name")
if roleName == "" {
errorResponse(c, "Role name is required", 400)
return
}
var req UpdateRoleHTTPRequest
if err := c.ShouldBindJSON(&req); err != nil {
errorResponse(c, "Role description is required", 400)
return
}
role, err := h.service.UpdateRole(roleName, req.Description)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, role, "")
}
// DeleteRole handle delete role
func (h *Handler) DeleteRole(c *gin.Context) {
roleName := c.Param("role_name")
if roleName == "" {
errorResponse(c, "Role name is required", 400)
return
}
if err := h.service.DeleteRole(roleName); err != nil {
errorResponse(c, err.Error(), 500)
return
}
successNoData(c, "")
}
// GetRolePermission handle get role permission
func (h *Handler) GetRolePermission(c *gin.Context) {
roleName := c.Param("role_name")
if roleName == "" {
errorResponse(c, "Role name is required", 400)
return
}
permissions, err := h.service.GetRolePermission(roleName)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, permissions, "")
}
// GrantRolePermissionHTTPRequest grant role permission request
type GrantRolePermissionHTTPRequest struct {
Actions []string `json:"actions" binding:"required"`
Resource string `json:"resource" binding:"required"`
}
// GrantRolePermission handle grant role permission
func (h *Handler) GrantRolePermission(c *gin.Context) {
roleName := c.Param("role_name")
if roleName == "" {
errorResponse(c, "Role name is required", 400)
return
}
var req GrantRolePermissionHTTPRequest
if err := c.ShouldBindJSON(&req); err != nil {
errorResponse(c, "Permission is required", 400)
return
}
result, err := h.service.GrantRolePermission(roleName, req.Actions, req.Resource)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, result, "")
}
// RevokeRolePermissionHTTPRequest revoke role permission request
type RevokeRolePermissionHTTPRequest struct {
Actions []string `json:"actions" binding:"required"`
Resource string `json:"resource" binding:"required"`
}
// RevokeRolePermission handle revoke role permission
func (h *Handler) RevokeRolePermission(c *gin.Context) {
roleName := c.Param("role_name")
if roleName == "" {
errorResponse(c, "Role name is required", 400)
return
}
var req RevokeRolePermissionHTTPRequest
if err := c.ShouldBindJSON(&req); err != nil {
errorResponse(c, "Permission is required", 400)
return
}
result, err := h.service.RevokeRolePermission(roleName, req.Actions, req.Resource)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, result, "")
}
// UpdateUserRoleHTTPRequest update user role request
type UpdateUserRoleHTTPRequest struct {
RoleName string `json:"role_name" binding:"required"`
}
// UpdateUserRole handle update user role
func (h *Handler) UpdateUserRole(c *gin.Context) {
username := c.Param("username")
if username == "" {
errorResponse(c, "Username is required", 400)
return
}
var req UpdateUserRoleHTTPRequest
if err := c.ShouldBindJSON(&req); err != nil {
errorResponse(c, "Role name is required", 400)
return
}
result, err := h.service.UpdateUserRole(username, req.RoleName)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, result, "")
}
// GetUserPermission handle get user permission
func (h *Handler) GetUserPermission(c *gin.Context) {
username := c.Param("username")
if username == "" {
errorResponse(c, "Username is required", 400)
return
}
permissions, err := h.service.GetUserPermission(username)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, permissions, "")
}
// GetServices handle get all services
func (h *Handler) GetServices(c *gin.Context) {
services, err := h.service.ListServices()

View File

@@ -71,6 +71,31 @@ func (r *Router) Setup(engine *gin.Engine) {
protected.GET("/users/:username/datasets", r.handler.GetUserDatasets)
protected.GET("/users/:username/agents", r.handler.GetUserAgents)
// For enterprise edition
protected.GET("/users/:username/activity", r.handler.ShowUserActivity)
protected.GET("/users/:username/dataset", r.handler.ShowUserDatasetSummary)
protected.GET("/users/:username/summary", r.handler.ShowUserSummary)
protected.GET("/users/:username/storage", r.handler.ShowUserStorage)
protected.GET("/users/:username/quota", r.handler.ShowUserQuota)
protected.GET("/users/:username/index", r.handler.ShowUserIndex)
protected.PUT("/users/:username/role", r.handler.UpdateUserRole)
protected.GET("/users/:username/permission", r.handler.ShowUserPermission)
protected.GET("/users/summary", r.handler.ShowUsersSummary)
protected.GET("/users/activity", r.handler.ShowUsersActivity)
protected.GET("/users/reports", r.handler.ListUsersReports)
protected.GET("/users/storage", r.handler.ListUsersStorage)
protected.GET("/users/documents", r.handler.ListUsersDocuments)
protected.GET("/users/index", r.handler.ListUsersIndex)
protected.GET("/users/quota", r.handler.ListUsersQuota)
protected.GET("/users/quota/summary", r.handler.ShowUsersQuotaSummary)
protected.GET("/data/summary", r.handler.ShowDataSummary)
protected.GET("/data/orphan", r.handler.ShowDataOrphan)
protected.GET("/data/storage", r.handler.ShowDataStorage)
protected.GET("/data/index", r.handler.ShowDataIndex)
protected.DELETE("/data/orphan", r.handler.PurgeOrphanData)
protected.DELETE("/users/:username/data", r.handler.PurgeUserData)
protected.DELETE("/users/data", r.handler.PurgeUsersData)
// API Keys
protected.GET("/users/:username/keys", r.handler.ListUserAPITokens)
protected.GET("/users/:username/tokens", r.handler.ListUserAPITokens)
@@ -89,10 +114,6 @@ func (r *Router) Setup(engine *gin.Engine) {
protected.POST("/roles/:role_name/permission", r.handler.GrantRolePermission)
protected.DELETE("/roles/:role_name/permission", r.handler.RevokeRolePermission)
// User roles and permissions
protected.PUT("/users/:username/role", r.handler.UpdateUserRole)
protected.GET("/users/:username/permission", r.handler.GetUserPermission)
// Service management
protected.GET("/services", r.handler.GetServices)
protected.GET("/service_types/:service_type", r.handler.GetServicesByType)

View File

@@ -211,8 +211,8 @@ func generateRandomHex(n int) string {
}
// ListUsers list all users
func (s *Service) ListUsers() ([]map[string]interface{}, error) {
users, _, err := s.userDAO.List(0, 0)
func (s *Service) ListUsers(page, pageSize int) ([]map[string]interface{}, error) {
users, _, err := s.userDAO.List(page*pageSize, pageSize)
if err != nil {
return nil, err
}
@@ -1020,68 +1020,6 @@ func (s *Service) DeleteUserAPIToken(username, key string) error {
return nil
}
// Role management methods
// ListRoles list all roles
func (s *Service) ListRoles() ([]map[string]interface{}, error) {
// TODO: Implement list roles
return []map[string]interface{}{}, nil
}
// CreateRole create a new role
func (s *Service) CreateRole(roleName, description string) (map[string]interface{}, error) {
// TODO: Implement create role
return map[string]interface{}{}, nil
}
// GetRole get role details
func (s *Service) GetRole(roleName string) (map[string]interface{}, error) {
// TODO: Implement get role
return map[string]interface{}{}, nil
}
// UpdateRole update role
func (s *Service) UpdateRole(roleName, description string) (map[string]interface{}, error) {
// TODO: Implement update role
return map[string]interface{}{}, nil
}
// DeleteRole delete role
func (s *Service) DeleteRole(roleName string) error {
// TODO: Implement delete role
return nil
}
// GetRolePermission get role permissions
func (s *Service) GetRolePermission(roleName string) ([]map[string]interface{}, error) {
// TODO: Implement get role permissions
return []map[string]interface{}{}, nil
}
// GrantRolePermission grant permission to role
func (s *Service) GrantRolePermission(roleName string, actions []string, resource string) (map[string]interface{}, error) {
// TODO: Implement grant role permission
return map[string]interface{}{}, nil
}
// RevokeRolePermission revoke permission from role
func (s *Service) RevokeRolePermission(roleName string, actions []string, resource string) (map[string]interface{}, error) {
// TODO: Implement revoke role permission
return map[string]interface{}{}, nil
}
// UpdateUserRole update user role
func (s *Service) UpdateUserRole(username, roleName string) ([]map[string]interface{}, error) {
// TODO: Implement update user role
return []map[string]interface{}{}, nil
}
// GetUserPermission get user permissions
func (s *Service) GetUserPermission(username string) ([]map[string]interface{}, error) {
// TODO: Implement get user permissions
return []map[string]interface{}{}, nil
}
// ListServices get all services
func (s *Service) ListServices() ([]map[string]interface{}, error) {
allConfigs := server.GetAllConfigs()