mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-03 09:11:59 +08:00
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:
851
internal/admin/enterprise_handler.go
Normal file
851
internal/admin/enterprise_handler.go
Normal 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, "")
|
||||
}
|
||||
489
internal/admin/enterprise_service.go
Normal file
489
internal/admin/enterprise_service.go
Normal 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
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -732,50 +732,6 @@ func (c *CLI) SetVariable(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// ListUsers lists all users (admin mode only)
|
||||
// Returns (result_map, error) - result_map is non-nil for benchmark mode
|
||||
func (c *CLI) ListUsers(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
// Check for benchmark iterations
|
||||
iterations := 1
|
||||
if val, ok := cmd.Params["iterations"].(int); ok && val > 1 {
|
||||
iterations = val
|
||||
}
|
||||
|
||||
if iterations > 1 {
|
||||
// Benchmark mode - return raw result for benchmark stats
|
||||
return c.AdminServerClient.RequestWithIterations("GET", "/admin/users", "admin", nil, nil, iterations)
|
||||
}
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", "/admin/users", "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list users: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to list users: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("list users failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
for _, user := range result.Data {
|
||||
delete(user, "create_date")
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// DropUser deletes a user (admin mode only)
|
||||
func (c *CLI) DropUser(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
@@ -809,39 +765,6 @@ func (c *CLI) DropUser(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// Show user show user (admin mode only)
|
||||
func (c *CLI) ShowUser(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", fmt.Sprintf("/admin/users/%s", userName), "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to show user: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to show user: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("show user failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// ListUserDatasets lists datasets for a specific user (admin mode)
|
||||
// Returns (result_map, error) - result_map is non-nil for benchmark mode
|
||||
func (c *CLI) ListUserDatasets(cmd *Command) (ResponseIf, error) {
|
||||
@@ -1612,3 +1535,786 @@ func (c *CLI) AdminRemoveServiceCommand(cmd *Command) (ResponseIf, error) {
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// Show user show user (admin mode only)
|
||||
func (c *CLI) AdminShowUserInfoCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
apiURL := fmt.Sprintf("/admin/users/%s", userName)
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to show user: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to show user: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("show user failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminShowUserActivityCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
days, ok := cmd.Params["days"].(int)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("days not provided")
|
||||
}
|
||||
|
||||
email, ok := cmd.Params["user_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"days": days,
|
||||
"email": email,
|
||||
}
|
||||
|
||||
apiURL := fmt.Sprintf("/admin/users/%s/activity", email)
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get user activity: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to get user activity: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("get user activity failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminShowUserSummaryCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
apiURL := fmt.Sprintf("/admin/users/%s/summary", userName)
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get statistics: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to get user summary: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("get user summary failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminShowUserDatasetCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
dataset, ok := cmd.Params["dataset_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("dataset_name not provided")
|
||||
}
|
||||
|
||||
email, ok := cmd.Params["user_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"dataset": dataset,
|
||||
}
|
||||
|
||||
apiURL := fmt.Sprintf("/admin/users/%s/dataset", email)
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get user dataset: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to get user dataset: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("get user dataset failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminShowUserStorageCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
email, ok := cmd.Params["user_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
apiURL := fmt.Sprintf("/admin/users/%s/storage", email)
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get user storage: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to get user storage: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("get user storage failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminShowUserQuotaCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
email, ok := cmd.Params["user_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
apiURL := fmt.Sprintf("/admin/users/%s/quota", email)
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get user storage: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to get user storage: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("get user storage failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminShowUserIndexCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
email, ok := cmd.Params["user_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
apiURL := fmt.Sprintf("/admin/users/%s/index", email)
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get user storage: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to get user storage: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("get user storage failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminShowUserPermissionCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
email, ok := cmd.Params["user_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
apiURL := fmt.Sprintf("/admin/users/%s/permission", email)
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get user permission: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to get user permission: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("get user permission failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminShowUsersSummaryCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
apiURL := "/admin/users/summary"
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get users summary: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to get users summary: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("get users summary failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminShowUsersActivityCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
days, ok := cmd.Params["days"].(int)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("days not provided")
|
||||
}
|
||||
window, ok := cmd.Params["window"].(int)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("window not provided")
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"days": days,
|
||||
"window": window,
|
||||
}
|
||||
|
||||
apiURL := "/admin/users/activity"
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get users activity: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to get users activity: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("get users activity failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// ListUsers lists all users (admin mode only)
|
||||
// Returns (result_map, error) - result_map is non-nil for benchmark mode
|
||||
func (c *CLI) AdminListUsersCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
// Check for benchmark iterations
|
||||
iterations := 1
|
||||
if val, ok := cmd.Params["iterations"].(int); ok && val > 1 {
|
||||
iterations = val
|
||||
}
|
||||
|
||||
if iterations > 1 {
|
||||
// Benchmark mode - return raw result for benchmark stats
|
||||
return c.AdminServerClient.RequestWithIterations("GET", "/admin/users", "admin", nil, nil, iterations)
|
||||
}
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", "/admin/users", "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list users: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to list users: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("list users failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
for _, user := range result.Data {
|
||||
delete(user, "create_date")
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminListUsersConditionCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
var orderBy *string
|
||||
var userStatus *string
|
||||
var top *int
|
||||
var plan *string
|
||||
var quota *int
|
||||
var days *int
|
||||
|
||||
orderByStr, ok := cmd.Params["order_by"].(string)
|
||||
if ok {
|
||||
orderBy = &orderByStr
|
||||
}
|
||||
userStatusStr, ok := cmd.Params["user_status"].(string)
|
||||
if ok {
|
||||
userStatus = &userStatusStr
|
||||
}
|
||||
topInt, ok := cmd.Params["top"].(int)
|
||||
if ok {
|
||||
top = &topInt
|
||||
}
|
||||
planStr, ok := cmd.Params["plan"].(string)
|
||||
if ok {
|
||||
plan = &planStr
|
||||
}
|
||||
quotaInt, ok := cmd.Params["quota"].(int)
|
||||
if ok {
|
||||
quota = "aInt
|
||||
}
|
||||
daysInt, ok := cmd.Params["days"].(int)
|
||||
if ok {
|
||||
days = &daysInt
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"enterprise": true,
|
||||
"order_by": orderBy,
|
||||
"user_status": userStatus,
|
||||
"top": top,
|
||||
"plan": plan,
|
||||
"quota": quota,
|
||||
"days": days,
|
||||
}
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", "/admin/users", "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list users: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to list users: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("list users failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminShowDataSummaryCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
apiURL := "/admin/data/summary"
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get users summary: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to get users summary: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("get users summary failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminShowDataOrphanCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
apiURL := "/admin/data/orphan"
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get orphan data: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to get orphan data: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("get orphan data failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminShowDataStorageCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
apiURL := "/admin/data/storage"
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get data storage: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to get data storage: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("get data storage failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminShowDataIndexCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
apiURL := "/admin/data/index"
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get data index: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to get data index: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("get data index failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminShowQuotaSummaryCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
apiURL := "/admin/users/quota/summary"
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get users quota summary: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to get users quota summary: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("get users quota summary failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminPurgeOrphanCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
preview, ok := cmd.Params["preview"].(bool)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("preview not provided")
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"preview": preview,
|
||||
}
|
||||
|
||||
apiURL := "/admin/data/orphan"
|
||||
|
||||
resp, err := c.AdminServerClient.Request("DELETE", apiURL, "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to purge orphan data: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to purge orphan data: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("purge orphan data failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminPurgeUserCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
preview, ok := cmd.Params["preview"].(bool)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("preview not provided")
|
||||
}
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"preview": preview,
|
||||
}
|
||||
|
||||
apiURL := fmt.Sprintf("/admin/users/%s/data", userName)
|
||||
|
||||
resp, err := c.AdminServerClient.Request("DELETE", apiURL, "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to purge user %s: %w", userName, err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to purge user %s: HTTP %d, body: %s", userName, resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("purge user %s failed: invalid JSON (%w)", userName, err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminPurgeUsersCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
var preview bool
|
||||
var ok bool
|
||||
var planName string
|
||||
var planNamePtr *string
|
||||
var userStatus string
|
||||
var userStatusPtr *string
|
||||
var days int
|
||||
|
||||
preview, ok = cmd.Params["preview"].(bool)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("preview not provided")
|
||||
}
|
||||
|
||||
planName, ok = cmd.Params["plan_name"].(string)
|
||||
if ok {
|
||||
planNamePtr = &planName
|
||||
}
|
||||
|
||||
userStatus, ok = cmd.Params["user_status"].(string)
|
||||
if ok {
|
||||
userStatusPtr = &userStatus
|
||||
}
|
||||
|
||||
days, ok = cmd.Params["days"].(int)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("days not provided")
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"preview": preview,
|
||||
"days": days,
|
||||
"plan": planNamePtr,
|
||||
"user_status": userStatusPtr,
|
||||
}
|
||||
|
||||
apiURL := "/admin/users/data"
|
||||
|
||||
resp, err := c.AdminServerClient.Request("DELETE", apiURL, "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to purge users data: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to purge users data: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("purge users data failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
@@ -137,12 +137,7 @@ func (p *Parser) parseAdminListCommand() (*Command, error) {
|
||||
}
|
||||
return NewCommand("list_services"), nil
|
||||
case TokenUsers:
|
||||
p.nextToken()
|
||||
// Semicolon is optional for SHOW TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("list_users"), nil
|
||||
return p.parseAdminListUsersCommand()
|
||||
case TokenRoles:
|
||||
p.nextToken()
|
||||
// Semicolon is optional for SHOW TOKEN
|
||||
@@ -467,31 +462,11 @@ func (p *Parser) parseAdminShowCommand() (*Command, error) {
|
||||
|
||||
switch p.curToken.Type {
|
||||
case TokenVersion:
|
||||
p.nextToken()
|
||||
// Semicolon is optional for SHOW TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("show_version"), nil
|
||||
case TokenToken:
|
||||
p.nextToken()
|
||||
// Semicolon is optional for SHOW TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("show_token"), nil
|
||||
return p.parseAdminShowVersionCommand()
|
||||
case TokenCurrent:
|
||||
p.nextToken()
|
||||
|
||||
// Semicolon is optional for SHOW TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("show_current"), nil
|
||||
case TokenUser:
|
||||
return p.parseShowUser()
|
||||
return p.parseAdminShowCurrentCommand()
|
||||
case TokenRole:
|
||||
return p.parseShowRole()
|
||||
return p.parseAdminShowRoleCommand()
|
||||
case TokenVar:
|
||||
return p.parseShowVariable()
|
||||
case TokenService:
|
||||
@@ -504,6 +479,14 @@ func (p *Parser) parseAdminShowCommand() (*Command, error) {
|
||||
return p.parseUserShowAdmin()
|
||||
case TokenAPI:
|
||||
return p.parseUserShowAPI()
|
||||
case TokenUser:
|
||||
return p.parseAdminShowUserCommand()
|
||||
case TokenUsers:
|
||||
return p.parseAdminShowUsersCommand()
|
||||
case TokenData:
|
||||
return p.parseAdminShowDataCommand()
|
||||
case TokenQuota:
|
||||
return p.parseAdminShowQuotaCommand()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown SHOW target: %s", p.curToken.Value)
|
||||
}
|
||||
@@ -545,7 +528,7 @@ func (p *Parser) parseAdminShowUser() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAdminShowRole() (*Command, error) {
|
||||
func (p *Parser) parseAdminShowRoleCommand() (*Command, error) {
|
||||
p.nextToken() // consume ROLE
|
||||
roleName, err := p.parseIdentifier()
|
||||
if err != nil {
|
||||
@@ -1925,3 +1908,590 @@ func (p *Parser) parseAdminRemoveCommand() (*Command, error) {
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// SHOW VERSION;
|
||||
func (p *Parser) parseAdminShowVersionCommand() (*Command, error) {
|
||||
p.nextToken() // consume VERSION
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return NewCommand("show_version"), nil
|
||||
}
|
||||
|
||||
// SHOW CURRENT;
|
||||
func (p *Parser) parseAdminShowCurrentCommand() (*Command, error) {
|
||||
p.nextToken() // consume CURRENT
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return NewCommand("show_current"), nil
|
||||
}
|
||||
|
||||
// SHOW USER 'user@example.com';
|
||||
// SHOW USER 'user@example.com' DATASET 'dataset_name';
|
||||
// SHOW USER 'user@example.com' SUMMARY;
|
||||
// SHOW USER 'user@example.com' STORAGE;
|
||||
// SHOW USER 'user@example.com' QUOTA;
|
||||
// SHOW USER 'user@example.com' INDEX;
|
||||
func (p *Parser) parseAdminShowUserCommand() (*Command, error) {
|
||||
p.nextToken() // consume USER
|
||||
|
||||
userName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
switch p.curToken.Type {
|
||||
case TokenActivity:
|
||||
return p.parseAdminShowActivityCommand(userName)
|
||||
case TokenSummary:
|
||||
return p.parseAdminShowUserSummaryCommand(userName)
|
||||
case TokenDataset:
|
||||
return p.parseAdminShowUserDataSetCommand(userName)
|
||||
case TokenStorage:
|
||||
return p.parseAdminShowUserStorageCommand(userName)
|
||||
case TokenQuota:
|
||||
return p.parseAdminShowUserQuotaCommand(userName)
|
||||
case TokenIndex:
|
||||
return p.parseAdminShowUserIndexCommand(userName)
|
||||
case TokenPermission:
|
||||
return p.parseAdminShowUserPermissionCommand(userName)
|
||||
default:
|
||||
return p.parseAdminShowUserInfoCommand(userName)
|
||||
}
|
||||
}
|
||||
|
||||
// SHOW USER 'user@example.com';
|
||||
func (p *Parser) parseAdminShowUserInfoCommand(userName string) (*Command, error) {
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
cmd := NewCommand("admin_show_user_info_command")
|
||||
cmd.Params["user_name"] = userName
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// SHOW USER 'user@example.com' ACTIVITY DAYS 30;
|
||||
func (p *Parser) parseAdminShowActivityCommand(userName string) (*Command, error) {
|
||||
p.nextToken() // consume ACTIVITY
|
||||
|
||||
var days int
|
||||
var err error
|
||||
|
||||
if p.curToken.Type == TokenDays {
|
||||
p.nextToken() // consume DAYS
|
||||
days, err = p.parseNumber()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if days < 1 {
|
||||
return nil, fmt.Errorf("invalid number of DAYS")
|
||||
}
|
||||
p.nextToken()
|
||||
} else {
|
||||
days = 7
|
||||
}
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
cmd := NewCommand("admin_show_user_activity_command")
|
||||
cmd.Params["user_name"] = userName
|
||||
cmd.Params["days"] = days
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// SHOW USER 'user@example.com' SUMMARY;
|
||||
func (p *Parser) parseAdminShowUserSummaryCommand(userName string) (*Command, error) {
|
||||
p.nextToken() // consume SUMMARY
|
||||
|
||||
cmd := NewCommand("admin_show_user_summary_command")
|
||||
cmd.Params["user_name"] = userName
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// SHOW USER 'user@example.com' DATASET 'dataset_name';
|
||||
func (p *Parser) parseAdminShowUserDataSetCommand(userName string) (*Command, error) {
|
||||
p.nextToken() // consume DATASET
|
||||
|
||||
var tree = false
|
||||
var datasetName string
|
||||
var err error
|
||||
datasetName, err = p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
if p.curToken.Type == TokenTree {
|
||||
tree = true
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
cmd := NewCommand("admin_show_user_dataset_command")
|
||||
cmd.Params["user_name"] = userName
|
||||
if datasetName != "" {
|
||||
cmd.Params["dataset_name"] = datasetName
|
||||
}
|
||||
if tree {
|
||||
cmd.Params["tree"] = true
|
||||
}
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// SHOW USER 'user@example.com' STORAGE;
|
||||
func (p *Parser) parseAdminShowUserStorageCommand(userName string) (*Command, error) {
|
||||
p.nextToken() // consume STORAGE
|
||||
|
||||
cmd := NewCommand("admin_show_user_storage_command")
|
||||
cmd.Params["user_name"] = userName
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// SHOW USER 'user@example.com' QUOTA;
|
||||
func (p *Parser) parseAdminShowUserQuotaCommand(userName string) (*Command, error) {
|
||||
p.nextToken() // consume QUOTA
|
||||
|
||||
cmd := NewCommand("admin_show_user_quota_command")
|
||||
cmd.Params["user_name"] = userName
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// SHOW USER 'user@example.com' INDEX;
|
||||
func (p *Parser) parseAdminShowUserIndexCommand(userName string) (*Command, error) {
|
||||
p.nextToken() // consume INDEX
|
||||
|
||||
cmd := NewCommand("admin_show_user_index_command")
|
||||
cmd.Params["user_name"] = userName
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// SHOW USER 'user@example.com' PERMISSION;
|
||||
func (p *Parser) parseAdminShowUserPermissionCommand(userName string) (*Command, error) {
|
||||
p.nextToken() // consume PERMISSION
|
||||
|
||||
cmd := NewCommand("admin_show_user_permission_command")
|
||||
cmd.Params["user_name"] = userName
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// SHOW USERS SUMMARY;
|
||||
// SHOW USERS ACTIVITY;
|
||||
func (p *Parser) parseAdminShowUsersCommand() (*Command, error) {
|
||||
p.nextToken() // consume USERS
|
||||
|
||||
switch p.curToken.Type {
|
||||
case TokenSummary:
|
||||
p.nextToken()
|
||||
cmd := NewCommand("admin_show_users_summary_command")
|
||||
return cmd, nil
|
||||
case TokenActivity:
|
||||
return p.parseAdminShowUsersActivityCommand()
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid command")
|
||||
}
|
||||
}
|
||||
|
||||
// SHOW USERS ACTIVITY WINDOW 2 DAYS 30;
|
||||
func (p *Parser) parseAdminShowUsersActivityCommand() (*Command, error) {
|
||||
p.nextToken() // consume ACTIVITY
|
||||
|
||||
var days int
|
||||
var err error
|
||||
var windowSize int
|
||||
|
||||
commandLoop:
|
||||
for {
|
||||
switch p.curToken.Type {
|
||||
case TokenDays:
|
||||
p.nextToken()
|
||||
days, err = p.parseNumber()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if days < 1 {
|
||||
return nil, fmt.Errorf("invalid number of DAYS")
|
||||
}
|
||||
p.nextToken()
|
||||
case TokenWindow:
|
||||
p.nextToken()
|
||||
windowSize, err = p.parseNumber()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if windowSize < 0 {
|
||||
return nil, fmt.Errorf("invalid number of WINDOWS")
|
||||
}
|
||||
p.nextToken()
|
||||
case TokenSemicolon:
|
||||
p.nextToken()
|
||||
break commandLoop // done
|
||||
default:
|
||||
// No more options to process
|
||||
break commandLoop
|
||||
}
|
||||
}
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
cmd := NewCommand("admin_show_users_activity_command")
|
||||
cmd.Params["days"] = days
|
||||
cmd.Params["window"] = windowSize
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// LIST USERS;
|
||||
// LIST USERS ACTIVE 30 DAYS; // default 7 days
|
||||
// LIST USERS INACTIVE 30 DAYS; // default 7 days
|
||||
// LIST USERS STORAGE TOP 10;
|
||||
// LIST USERS DOCUMENTS TOP 10;
|
||||
// LIST USERS INDEX TOP 10;
|
||||
// LIST USERS QUOTA TOP 10;
|
||||
// LIST USERS QUOTA OVER;
|
||||
// LIST USERS PLAN 'plan_name' QUOTA OVER DAYS 30; // default 7 days
|
||||
// LIST USERS PLAN 'plan_name' DAYS 30; // default 7 days
|
||||
func (p *Parser) parseAdminListUsersCommand() (*Command, error) {
|
||||
p.nextToken() // consume USERS
|
||||
|
||||
var orderBy string
|
||||
var userStatus string
|
||||
var top *int
|
||||
var plan *string
|
||||
var quota *int
|
||||
var days *int
|
||||
condition := false
|
||||
commandLoop:
|
||||
for {
|
||||
switch p.curToken.Type {
|
||||
case TokenTop:
|
||||
condition = true
|
||||
p.nextToken()
|
||||
topInt, err := p.parseNumber()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if topInt < 0 {
|
||||
return nil, fmt.Errorf("invalid number of TOP")
|
||||
}
|
||||
p.nextToken()
|
||||
top = &topInt
|
||||
case TokenDays:
|
||||
condition = true
|
||||
p.nextToken()
|
||||
daysInt, err := p.parseNumber()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if daysInt < 0 {
|
||||
return nil, fmt.Errorf("invalid number of DAYS")
|
||||
}
|
||||
p.nextToken()
|
||||
days = &daysInt
|
||||
case TokenPlan:
|
||||
condition = true
|
||||
p.nextToken()
|
||||
planStr, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if planStr == "" {
|
||||
return nil, fmt.Errorf("invalid plan")
|
||||
}
|
||||
plan = &planStr
|
||||
p.nextToken()
|
||||
case TokenQuota:
|
||||
condition = true
|
||||
p.nextToken()
|
||||
quotaInt, err := p.parseNumber()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if quotaInt < 0 {
|
||||
return nil, fmt.Errorf("invalid number of QUOTA")
|
||||
}
|
||||
quota = "aInt
|
||||
p.nextToken()
|
||||
case TokenDocuments, TokenIndex, TokenStorage:
|
||||
condition = true
|
||||
if orderBy != "" {
|
||||
return nil, fmt.Errorf("order by already set")
|
||||
}
|
||||
orderBy = p.curToken.Value
|
||||
p.nextToken()
|
||||
case TokenActive, TokenInactive:
|
||||
condition = true
|
||||
userStatus = p.curToken.Value
|
||||
p.nextToken()
|
||||
case TokenSemicolon:
|
||||
p.nextToken()
|
||||
break commandLoop // done
|
||||
default:
|
||||
// No more options to process
|
||||
break commandLoop
|
||||
}
|
||||
}
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
if !condition {
|
||||
return NewCommand("admin_list_users_command"), nil
|
||||
}
|
||||
|
||||
cmd := NewCommand("admin_list_users_condition_command")
|
||||
if orderBy != "" {
|
||||
cmd.Params["order_by"] = orderBy
|
||||
}
|
||||
if userStatus != "" {
|
||||
cmd.Params["user_status"] = userStatus
|
||||
}
|
||||
if top != nil {
|
||||
cmd.Params["top"] = *top
|
||||
}
|
||||
if plan != nil {
|
||||
cmd.Params["plan"] = *plan
|
||||
}
|
||||
if quota != nil {
|
||||
cmd.Params["quota"] = *quota
|
||||
}
|
||||
if days != nil {
|
||||
cmd.Params["days"] = *days
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// SHOW DATA SUMMARY;
|
||||
// SHOW DATA ORPHAN;
|
||||
// SHOW DATA STORAGE;
|
||||
// SHOW DATA INDEX;
|
||||
func (p *Parser) parseAdminShowDataCommand() (*Command, error) {
|
||||
p.nextToken() // consume ALL
|
||||
|
||||
var cmd *Command
|
||||
switch p.curToken.Type {
|
||||
case TokenSummary:
|
||||
p.nextToken()
|
||||
cmd = NewCommand("admin_show_data_summary_command")
|
||||
case TokenOrphan:
|
||||
p.nextToken()
|
||||
cmd = NewCommand("admin_show_data_orphan_command")
|
||||
case TokenStorage:
|
||||
p.nextToken()
|
||||
cmd = NewCommand("admin_show_data_storage_command")
|
||||
case TokenIndex:
|
||||
p.nextToken()
|
||||
cmd = NewCommand("admin_show_data_index_command")
|
||||
default:
|
||||
return nil, fmt.Errorf("expected SUMMARY, ORPHAN, STORAGE, INDEX, TASKS, QUOTA_SUMMARY after ALL")
|
||||
}
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// SHOW QUOTA SUMMARY;
|
||||
func (p *Parser) parseAdminShowQuotaCommand() (*Command, error) {
|
||||
p.nextToken() // consume QUOTA
|
||||
|
||||
var cmd *Command
|
||||
switch p.curToken.Type {
|
||||
case TokenSummary:
|
||||
p.nextToken()
|
||||
cmd = NewCommand("admin_show_quota_summary_command")
|
||||
default:
|
||||
return nil, fmt.Errorf("expected SUMMARY after QUOTA")
|
||||
}
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// PURGE PREVIEW ORPHAN
|
||||
// PURGE ORPHAN
|
||||
|
||||
// PURGE PREVIEW USER 'user@example.com';
|
||||
// PURGE USER
|
||||
|
||||
// PURGE PREVIEW USERS PLAN 'plan_name' DAYS 30; // default 7 days
|
||||
// PURGE USERS PLAN 'plan_name' DAYS 30;
|
||||
|
||||
// PURGE PREVIEW USERS INACTIVE PLAN 'plan_name' DAYS 30;
|
||||
// PURGE USERS INACTIVE PLAN 'plan_name' DAYS 30;
|
||||
func (p *Parser) parseAdminPurgeCommand() (*Command, error) {
|
||||
p.nextToken() // consume PURGE
|
||||
var preview = false
|
||||
if p.curToken.Type == TokenPreview {
|
||||
p.nextToken()
|
||||
preview = true
|
||||
}
|
||||
|
||||
switch p.curToken.Type {
|
||||
case TokenOrphan:
|
||||
return p.parseAdminPurgeOrphanCommand(preview)
|
||||
case TokenUser:
|
||||
return p.parseAdminPurgeUserCommand(preview)
|
||||
case TokenUsers:
|
||||
return p.parseAdminPurgeUsersCommand(preview)
|
||||
default:
|
||||
return nil, fmt.Errorf("expected PREVIEW, USER, USERS after PURGE")
|
||||
}
|
||||
}
|
||||
|
||||
// PURGE PREVIEW ORPHAN
|
||||
// PURGE ORPHAN
|
||||
func (p *Parser) parseAdminPurgeOrphanCommand(preview bool) (*Command, error) {
|
||||
p.nextToken() // consume ORPHAN
|
||||
|
||||
cmd := NewCommand("admin_purge_orphan_command")
|
||||
cmd.Params["preview"] = preview
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// PURGE PREVIEW USER 'user@example.com';
|
||||
// PURGE USER 'user@example.com';
|
||||
func (p *Parser) parseAdminPurgeUserCommand(preview bool) (*Command, error) {
|
||||
p.nextToken() // consume USER
|
||||
|
||||
userName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd := NewCommand("admin_purge_user_command")
|
||||
cmd.Params["preview"] = preview
|
||||
cmd.Params["user_name"] = userName
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// PURGE PREVIEW USERS PLAN 'plan_name' DAYS 30; // default 7 days
|
||||
// PURGE USERS PLAN 'plan_name' DAYS 30;
|
||||
// PURGE PREVIEW USERS INACTIVE PLAN 'plan_name' DAYS 30;
|
||||
// PURGE USERS INACTIVE PLAN 'plan_name' DAYS 30;
|
||||
func (p *Parser) parseAdminPurgeUsersCommand(preview bool) (*Command, error) {
|
||||
p.nextToken() // consume USERS
|
||||
|
||||
var userStatus *string = nil
|
||||
var days *int = nil
|
||||
var planName *string = nil
|
||||
|
||||
commandLoop:
|
||||
for {
|
||||
switch p.curToken.Type {
|
||||
case TokenPlan:
|
||||
p.nextToken()
|
||||
if planName != nil {
|
||||
return nil, fmt.Errorf("duplicate PLAN after USERS")
|
||||
}
|
||||
plan, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
planName = &plan
|
||||
p.nextToken()
|
||||
case TokenDays:
|
||||
p.nextToken()
|
||||
if days != nil {
|
||||
return nil, fmt.Errorf("duplicate DAYS after USERS")
|
||||
}
|
||||
dayCount, err := p.parseNumber()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
days = &dayCount
|
||||
p.nextToken()
|
||||
case TokenInactive:
|
||||
p.nextToken()
|
||||
if userStatus != nil {
|
||||
return nil, fmt.Errorf("duplicate INACTIVE or ACTIVE after USERS")
|
||||
}
|
||||
inactiveStatus := "inactive"
|
||||
userStatus = &inactiveStatus
|
||||
case TokenActive:
|
||||
p.nextToken()
|
||||
if userStatus != nil {
|
||||
return nil, fmt.Errorf("duplicate INACTIVE or ACTIVE after USERS")
|
||||
}
|
||||
activeStatus := "active"
|
||||
userStatus = &activeStatus
|
||||
case TokenSemicolon:
|
||||
p.nextToken()
|
||||
break commandLoop // done
|
||||
default:
|
||||
// No more options to process
|
||||
break commandLoop
|
||||
}
|
||||
}
|
||||
|
||||
cmd := NewCommand("admin_purge_users_command")
|
||||
cmd.Params["preview"] = preview
|
||||
if planName != nil {
|
||||
cmd.Params["plan_name"] = *planName
|
||||
}
|
||||
if userStatus != nil {
|
||||
cmd.Params["user_status"] = *userStatus
|
||||
}
|
||||
if days != nil {
|
||||
cmd.Params["days"] = *days
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
@@ -45,8 +45,6 @@ func (c *CLI) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) {
|
||||
return c.PingByCommand(cmd)
|
||||
case "benchmark":
|
||||
return c.RunBenchmark(cmd)
|
||||
case "list_users":
|
||||
return c.ListUsers(cmd)
|
||||
case "list_services":
|
||||
return c.ListServices(cmd)
|
||||
case "grant_admin":
|
||||
@@ -67,8 +65,6 @@ func (c *CLI) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) {
|
||||
return c.ShowAdminVersion(cmd)
|
||||
case "show_current":
|
||||
return c.ShowCommonCurrent(cmd)
|
||||
case "show_user":
|
||||
return c.ShowUser(cmd)
|
||||
case "list_variables":
|
||||
return c.ListVariables(cmd)
|
||||
case "show_variable":
|
||||
@@ -123,6 +119,46 @@ func (c *CLI) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) {
|
||||
return c.UserShowMessageQueueCommand(cmd)
|
||||
case "admin_remove_service_command":
|
||||
return c.AdminRemoveServiceCommand(cmd)
|
||||
case "admin_show_user_info_command":
|
||||
return c.AdminShowUserInfoCommand(cmd)
|
||||
case "admin_show_user_activity_command":
|
||||
return c.AdminShowUserActivityCommand(cmd)
|
||||
case "admin_show_user_summary_command":
|
||||
return c.AdminShowUserSummaryCommand(cmd)
|
||||
case "admin_show_user_dataset_command":
|
||||
return c.AdminShowUserDatasetCommand(cmd)
|
||||
case "admin_show_user_storage_command":
|
||||
return c.AdminShowUserStorageCommand(cmd)
|
||||
case "admin_show_user_quota_command":
|
||||
return c.AdminShowUserQuotaCommand(cmd)
|
||||
case "admin_show_user_index_command":
|
||||
return c.AdminShowUserIndexCommand(cmd)
|
||||
case "admin_show_user_permission_command":
|
||||
return c.AdminShowUserPermissionCommand(cmd)
|
||||
case "admin_show_users_summary_command":
|
||||
return c.AdminShowUsersSummaryCommand(cmd)
|
||||
case "admin_show_users_activity_command":
|
||||
return c.AdminShowUsersActivityCommand(cmd)
|
||||
case "admin_list_users_command":
|
||||
return c.AdminListUsersCommand(cmd)
|
||||
case "admin_list_users_condition_command":
|
||||
return c.AdminListUsersConditionCommand(cmd)
|
||||
case "admin_show_quota_summary_command":
|
||||
return c.AdminShowQuotaSummaryCommand(cmd)
|
||||
case "admin_show_data_summary_command":
|
||||
return c.AdminShowDataSummaryCommand(cmd)
|
||||
case "admin_show_data_orphan_command":
|
||||
return c.AdminShowDataOrphanCommand(cmd)
|
||||
case "admin_show_data_storage_command":
|
||||
return c.AdminShowDataStorageCommand(cmd)
|
||||
case "admin_show_data_index_command":
|
||||
return c.AdminShowDataIndexCommand(cmd)
|
||||
case "admin_purge_orphan_command":
|
||||
return c.AdminPurgeOrphanCommand(cmd)
|
||||
case "admin_purge_user_command":
|
||||
return c.AdminPurgeUserCommand(cmd)
|
||||
case "admin_purge_users_command":
|
||||
return c.AdminPurgeUsersCommand(cmd)
|
||||
// TODO: Implement other commands
|
||||
case "show_admin_server":
|
||||
return c.ShowAdminServer(cmd)
|
||||
|
||||
@@ -219,6 +219,8 @@ func (l *Lexer) lookupIdent(ident string) Token {
|
||||
return Token{Type: TokenAlter, Value: ident}
|
||||
case "ACTIVE":
|
||||
return Token{Type: TokenActive, Value: ident}
|
||||
case "INACTIVE":
|
||||
return Token{Type: TokenInactive, Value: ident}
|
||||
case "ADMIN":
|
||||
return Token{Type: TokenAdmin, Value: ident}
|
||||
case "SERVER":
|
||||
@@ -487,6 +489,32 @@ func (l *Lexer) lookupIdent(ident string) Token {
|
||||
return Token{Type: TokenPending, Value: ident}
|
||||
case "NOACK":
|
||||
return Token{Type: TokenNoACK, Value: ident}
|
||||
case "ANALYZE":
|
||||
return Token{Type: TokenAnalyze, Value: ident}
|
||||
case "SUMMARY":
|
||||
return Token{Type: TokenSummary, Value: ident}
|
||||
case "STORAGE":
|
||||
return Token{Type: TokenStorage, Value: ident}
|
||||
case "QUOTA":
|
||||
return Token{Type: TokenQuota, Value: ident}
|
||||
case "TREE":
|
||||
return Token{Type: TokenTree, Value: ident}
|
||||
case "ORPHAN":
|
||||
return Token{Type: TokenOrphan, Value: ident}
|
||||
case "DAYS":
|
||||
return Token{Type: TokenDays, Value: ident}
|
||||
case "WINDOW":
|
||||
return Token{Type: TokenWindow, Value: ident}
|
||||
case "ACTIVITY":
|
||||
return Token{Type: TokenActivity, Value: ident}
|
||||
case "PURGE":
|
||||
return Token{Type: TokenPurge, Value: ident}
|
||||
case "PREVIEW":
|
||||
return Token{Type: TokenPreview, Value: ident}
|
||||
case "PLAN":
|
||||
return Token{Type: TokenPlan, Value: ident}
|
||||
case "DATA":
|
||||
return Token{Type: TokenData, Value: ident}
|
||||
case "LOG":
|
||||
return Token{Type: TokenLog, Value: ident}
|
||||
case "LEVEL":
|
||||
|
||||
@@ -138,6 +138,8 @@ func (p *Parser) parseAdminCommand() (*Command, error) {
|
||||
return p.parseAdminSaveCommand()
|
||||
case TokenUse:
|
||||
return p.parseAdminUseCommand()
|
||||
case TokenPurge:
|
||||
return p.parseAdminPurgeCommand()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown command: %s", p.curToken.Value)
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ const (
|
||||
TokenUser
|
||||
TokenAlter
|
||||
TokenActive
|
||||
TokenInactive
|
||||
TokenAdmin
|
||||
TokenServer
|
||||
TokenAPI
|
||||
@@ -175,6 +176,19 @@ const (
|
||||
TokenPull
|
||||
TokenPending
|
||||
TokenNoACK
|
||||
TokenAnalyze
|
||||
TokenSummary
|
||||
TokenStorage
|
||||
TokenQuota
|
||||
TokenTree
|
||||
TokenOrphan
|
||||
TokenDays
|
||||
TokenWindow
|
||||
TokenActivity
|
||||
TokenData
|
||||
TokenPurge
|
||||
TokenPlan
|
||||
TokenPreview
|
||||
TokenLog
|
||||
TokenLevel
|
||||
TokenDebug
|
||||
|
||||
@@ -442,12 +442,7 @@ func (p *Parser) parseShowCommand() (*Command, error) {
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return NewCommand("show_current"), nil
|
||||
case TokenUser:
|
||||
return p.parseShowUser()
|
||||
case TokenRole:
|
||||
return p.parseShowRole()
|
||||
case TokenVar:
|
||||
return p.parseShowVariable()
|
||||
case TokenService:
|
||||
@@ -473,60 +468,6 @@ func (p *Parser) parseShowCommand() (*Command, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseShowUser() (*Command, error) {
|
||||
p.nextToken() // consume USER
|
||||
|
||||
// Check for PERMISSION
|
||||
if p.curToken.Type == TokenPermission {
|
||||
p.nextToken()
|
||||
userName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd := NewCommand("show_user_permission")
|
||||
cmd.Params["user_name"] = userName
|
||||
p.nextToken()
|
||||
// Semicolon is optional for SHOW TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
userName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd := NewCommand("show_user")
|
||||
cmd.Params["user_name"] = userName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseShowRole() (*Command, error) {
|
||||
p.nextToken() // consume ROLE
|
||||
roleName, err := p.parseIdentifier()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd := NewCommand("show_role")
|
||||
cmd.Params["role_name"] = roleName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseShowVariable() (*Command, error) {
|
||||
p.nextToken() // consume VAR
|
||||
varName, err := p.parseIdentifier()
|
||||
|
||||
Reference in New Issue
Block a user