mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-28 03:38:11 +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:
@@ -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