mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-05 10:58:34 +08:00
Go CLI: refactor (#16299)
``` RAGFlow(api/default)> list dataset 'e93ab2c04ad111f1b17438a74640adcc' documents; Total: 1 RAGFlow(api/default)> list datasets; RAGFlow(api/default)> list chats; Total: 2 RAGFlow(api/default)> list agents; Total: 1 RAGFlow(api/default)> list searches; Total: 1 RAGFlow(api/default)> list keys; +----------------------------------+---------------+----------------------------------+-----------------------------------------------------+---------------+ | beta | create_time | tenant_id | token | update_time | +----------------------------------+---------------+----------------------------------+-----------------------------------------------------+---------------+ | GKsLEdSUkl76gJz1k_4fJpSQRIlWsiki | 1782285917523 | 2ba4881420fa11f19e9c38a74640adcc | ragflow-JgnarFSCUiV99oOvvMDei7ZzZg1cVlqGd1AMHrHeKE4 | 1782285917523 | +----------------------------------+---------------+----------------------------------+-----------------------------------------------------+---------------+ RAGFlow(api/default)> create key; SUCCESS RAGFlow(api/default)> drop key 'ragflow-aA4R7AuUD158yh2LDh7IDBiqwOKFDKeTwUSQSLVdPdM'; SUCCESS ``` --------- Signed-off-by: Jin Hai <haijin.chn@gmail.com>
This commit is contained in:
@@ -24,7 +24,7 @@ import (
|
||||
|
||||
// region AUTH commands
|
||||
func (p *Parser) parseAdminLoginUser() (*Command, error) {
|
||||
cmd := NewCommand("login_user")
|
||||
cmd := NewCommand("admin_login_user")
|
||||
|
||||
p.nextToken() // consume LOGIN
|
||||
if p.curToken.Type != TokenAdmin {
|
||||
@@ -60,7 +60,7 @@ func (p *Parser) parseAdminLoginUser() (*Command, error) {
|
||||
}
|
||||
|
||||
func (p *Parser) parseAdminLogout() (*Command, error) {
|
||||
cmd := NewCommand("logout")
|
||||
cmd := NewCommand("admin_logout")
|
||||
p.nextToken()
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
@@ -70,7 +70,7 @@ func (p *Parser) parseAdminLogout() (*Command, error) {
|
||||
}
|
||||
|
||||
func (p *Parser) parseAdminPingServer() (*Command, error) {
|
||||
cmd := NewCommand("ping_server")
|
||||
cmd := NewCommand("admin_ping_server")
|
||||
p.nextToken()
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
@@ -1837,35 +1837,6 @@ func (p *Parser) parseAdminBenchmarkCommand() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAdminUserStatement() (*Command, error) {
|
||||
switch p.curToken.Type {
|
||||
case TokenPing:
|
||||
return p.parsePingServer()
|
||||
case TokenShow:
|
||||
return p.parseShowCommand()
|
||||
case TokenCreate:
|
||||
return p.parseCreateCommand()
|
||||
case TokenDrop:
|
||||
return p.parseDropCommand()
|
||||
case TokenSet:
|
||||
return p.parseSetCommand()
|
||||
case TokenUnset:
|
||||
return p.parseUnsetCommand()
|
||||
case TokenReset:
|
||||
return p.parseResetCommand()
|
||||
case TokenList:
|
||||
return p.parseListCommand()
|
||||
case TokenParse:
|
||||
return p.parseParseCommand()
|
||||
case TokenImport:
|
||||
return p.parseImportCommand()
|
||||
case TokenRetrieve:
|
||||
return p.parseRetrieveCommand()
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid user statement: %s", p.curToken.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseAdminStartService() (*Command, error) {
|
||||
p.nextToken() // consume START
|
||||
|
||||
|
||||
@@ -237,7 +237,7 @@ func (c *CLI) executeBenchmarkSilent(cmd *Command, iterations int) []*Response {
|
||||
resp, err = httpClient.Request("GET", "/system/ping", "web", nil, nil)
|
||||
case "list_user_datasets":
|
||||
resp, err = httpClient.Request("POST", "/kb/list", "web", nil, nil)
|
||||
case "list_datasets":
|
||||
case "api_list_datasets":
|
||||
userName, _ := cmd.Params["user_name"].(string)
|
||||
resp, err = httpClient.Request("GET", fmt.Sprintf("/admin/users/%s/datasets", userName), "admin", nil, nil)
|
||||
case "search_on_datasets":
|
||||
@@ -275,7 +275,7 @@ func isSuccess(resp *Response, commandType string) bool {
|
||||
switch commandType {
|
||||
case "ping":
|
||||
return resp.StatusCode == 200 && string(resp.Body) == "pong"
|
||||
case "list_user_datasets", "list_datasets", "search_on_datasets":
|
||||
case "list_user_datasets", "api_list_datasets", "search_on_datasets":
|
||||
// Check status code and JSON response code for dataset commands
|
||||
if resp.StatusCode != 200 {
|
||||
return false
|
||||
|
||||
@@ -827,25 +827,6 @@ func (c *CLI) RunSingleCommand(command *string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// VerifyAuth verifies authentication if needed
|
||||
func (c *CLI) NewVerifyAuth(username, password *string) error {
|
||||
// Otherwise, use username/password authentication
|
||||
if username == nil {
|
||||
return fmt.Errorf("username is required")
|
||||
}
|
||||
|
||||
if password == nil {
|
||||
return fmt.Errorf("password is required")
|
||||
}
|
||||
|
||||
// Create login command with username and password
|
||||
cmd := NewCommand("login_user")
|
||||
cmd.Params["email"] = *username
|
||||
cmd.Params["password"] = *password
|
||||
_, err := c.ExecuteCommand(cmd)
|
||||
return err
|
||||
}
|
||||
|
||||
// VerifyAuth verifies authentication if needed
|
||||
func (c *CLI) VerifyAuth(username, password string) error {
|
||||
// Otherwise, use username/password authentication
|
||||
@@ -858,10 +839,11 @@ func (c *CLI) VerifyAuth(username, password string) error {
|
||||
}
|
||||
|
||||
// Create login command with username and password
|
||||
cmd := NewCommand("login_user")
|
||||
cmd := NewCommand("login_user_on_startup")
|
||||
cmd.Params["email"] = username
|
||||
cmd.Params["password"] = password
|
||||
_, err := c.ExecuteCommand(cmd)
|
||||
|
||||
_, err := c.LoginUserByCommand(cmd)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -37,11 +37,11 @@ func (c *CLI) ExecuteCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
func (c *CLI) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) {
|
||||
switch cmd.Type {
|
||||
case "login_user":
|
||||
case "admin_login_user":
|
||||
return c.LoginUserByCommand(cmd)
|
||||
case "logout":
|
||||
case "admin_logout":
|
||||
return c.Logout()
|
||||
case "ping_server":
|
||||
case "admin_ping_server":
|
||||
return c.PingByCommand(cmd)
|
||||
case "benchmark":
|
||||
return c.RunBenchmark(cmd)
|
||||
@@ -284,23 +284,31 @@ func (c *CLI) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
func (c *CLI) ExecuteUserCommand(cmd *Command) (ResponseIf, error) {
|
||||
switch cmd.Type {
|
||||
case "register_user":
|
||||
case "api_register_user":
|
||||
return c.RegisterUser(cmd)
|
||||
case "login_user":
|
||||
case "api_login_user":
|
||||
return c.LoginUserByCommand(cmd)
|
||||
case "logout":
|
||||
case "api_logout":
|
||||
return c.Logout()
|
||||
case "ping_server":
|
||||
case "api_ping_server":
|
||||
return c.PingByCommand(cmd)
|
||||
// Configuration commands
|
||||
case "list_configs":
|
||||
case "api_list_configs":
|
||||
return c.ListConfigs(cmd)
|
||||
case "set_log_level":
|
||||
return c.SetLogLevel(cmd)
|
||||
case "benchmark":
|
||||
return c.RunBenchmark(cmd)
|
||||
case "list_datasets":
|
||||
return c.ListDatasets(cmd)
|
||||
case "api_list_datasets":
|
||||
return c.APIListDatasetsCommand(cmd)
|
||||
case "api_list_dataset_documents":
|
||||
return c.APIListDatasetDocumentsCommand(cmd)
|
||||
case "api_list_agents":
|
||||
return c.APIListAgentsCommand(cmd)
|
||||
case "api_list_chats":
|
||||
return c.APIListChatsCommand(cmd)
|
||||
case "api_list_searches":
|
||||
return c.APIListSearchesCommand(cmd)
|
||||
case "list_dataset_documents":
|
||||
return c.ListDatasetDocumentUserCommand(cmd)
|
||||
case "search_on_datasets":
|
||||
@@ -308,12 +316,12 @@ func (c *CLI) ExecuteUserCommand(cmd *Command) (ResponseIf, error) {
|
||||
case "search_help":
|
||||
printSearchHelp()
|
||||
return nil, nil
|
||||
case "create_token":
|
||||
return c.CreateToken(cmd)
|
||||
case "list_tokens":
|
||||
return c.ListTokens(cmd)
|
||||
case "drop_token":
|
||||
return c.DropToken(cmd)
|
||||
case "api_create_api_key":
|
||||
return c.APICreateAPIKeyCommand(cmd)
|
||||
case "api_list_api_keys":
|
||||
return c.APIListAPIKeysCommand(cmd)
|
||||
case "api_delete_api_key":
|
||||
return c.APIDeleteAPIKeyCommand(cmd)
|
||||
case "set_token":
|
||||
return c.SetToken(cmd)
|
||||
case "show_token":
|
||||
|
||||
@@ -143,13 +143,13 @@ func (p *Parser) parseUserCommand() (*Command, error) {
|
||||
|
||||
switch p.curToken.Type {
|
||||
case TokenLogin:
|
||||
return p.parseLoginUser()
|
||||
return p.parseAPILoginUser()
|
||||
case TokenLogout:
|
||||
return p.parseLogout()
|
||||
return p.parseAPILogout()
|
||||
case TokenPing:
|
||||
return p.parsePingServer()
|
||||
return p.parseAPIPingServer()
|
||||
case TokenList:
|
||||
return p.parseListCommand()
|
||||
return p.parseAPIListCommands()
|
||||
case TokenShow:
|
||||
return p.parseShowCommand()
|
||||
case TokenCreate:
|
||||
@@ -181,7 +181,7 @@ func (p *Parser) parseUserCommand() (*Command, error) {
|
||||
case TokenBenchmark:
|
||||
return p.parseBenchmarkCommand()
|
||||
case TokenRegister:
|
||||
return p.parseRegisterCommand()
|
||||
return p.parseAPIRegisterCommand()
|
||||
case TokenEnable:
|
||||
return p.parseEnableCommand()
|
||||
case TokenDisable:
|
||||
|
||||
@@ -180,6 +180,114 @@ func (r *ListDocumentsResponse) PrintOut() {
|
||||
}
|
||||
}
|
||||
|
||||
type ListAgentsResponse struct {
|
||||
Code int `json:"code"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
Message string `json:"message"`
|
||||
Duration float64
|
||||
OutputFormat OutputFormat
|
||||
}
|
||||
|
||||
func (r *ListAgentsResponse) Type() string {
|
||||
return "list_agents"
|
||||
}
|
||||
|
||||
func (r *ListAgentsResponse) TimeCost() float64 {
|
||||
return r.Duration
|
||||
}
|
||||
|
||||
func (r *ListAgentsResponse) SetOutputFormat(format OutputFormat) {
|
||||
r.OutputFormat = format
|
||||
}
|
||||
|
||||
func (r *ListAgentsResponse) PrintOut() {
|
||||
if r.Code == 0 {
|
||||
total := r.Data["total"].(float64)
|
||||
fmt.Printf("Total: %0.0f\n", total)
|
||||
docs := r.Data["canvas"].([]interface{})
|
||||
table := make([]map[string]interface{}, 0)
|
||||
for _, doc := range docs {
|
||||
table = append(table, doc.(map[string]interface{}))
|
||||
}
|
||||
PrintTableSimpleByFormat(table, r.OutputFormat)
|
||||
} else {
|
||||
fmt.Println("ERROR")
|
||||
fmt.Printf("%d, %s\n", r.Code, r.Message)
|
||||
}
|
||||
}
|
||||
|
||||
type ListChatsResponse struct {
|
||||
Code int `json:"code"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
Message string `json:"message"`
|
||||
Duration float64
|
||||
OutputFormat OutputFormat
|
||||
}
|
||||
|
||||
func (r *ListChatsResponse) Type() string {
|
||||
return "list_chats"
|
||||
}
|
||||
|
||||
func (r *ListChatsResponse) TimeCost() float64 {
|
||||
return r.Duration
|
||||
}
|
||||
|
||||
func (r *ListChatsResponse) SetOutputFormat(format OutputFormat) {
|
||||
r.OutputFormat = format
|
||||
}
|
||||
|
||||
func (r *ListChatsResponse) PrintOut() {
|
||||
if r.Code == 0 {
|
||||
total := r.Data["total"].(float64)
|
||||
fmt.Printf("Total: %0.0f\n", total)
|
||||
docs := r.Data["chats"].([]interface{})
|
||||
table := make([]map[string]interface{}, 0)
|
||||
for _, doc := range docs {
|
||||
table = append(table, doc.(map[string]interface{}))
|
||||
}
|
||||
PrintTableSimpleByFormat(table, r.OutputFormat)
|
||||
} else {
|
||||
fmt.Println("ERROR")
|
||||
fmt.Printf("%d, %s\n", r.Code, r.Message)
|
||||
}
|
||||
}
|
||||
|
||||
type ListSearchesResponse struct {
|
||||
Code int `json:"code"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
Message string `json:"message"`
|
||||
Duration float64
|
||||
OutputFormat OutputFormat
|
||||
}
|
||||
|
||||
func (r *ListSearchesResponse) Type() string {
|
||||
return "list_searches"
|
||||
}
|
||||
|
||||
func (r *ListSearchesResponse) TimeCost() float64 {
|
||||
return r.Duration
|
||||
}
|
||||
|
||||
func (r *ListSearchesResponse) SetOutputFormat(format OutputFormat) {
|
||||
r.OutputFormat = format
|
||||
}
|
||||
|
||||
func (r *ListSearchesResponse) PrintOut() {
|
||||
if r.Code == 0 {
|
||||
total := r.Data["total"].(float64)
|
||||
fmt.Printf("Total: %0.0f\n", total)
|
||||
docs := r.Data["search_apps"].([]interface{})
|
||||
table := make([]map[string]interface{}, 0)
|
||||
for _, doc := range docs {
|
||||
table = append(table, doc.(map[string]interface{}))
|
||||
}
|
||||
PrintTableSimpleByFormat(table, r.OutputFormat)
|
||||
} else {
|
||||
fmt.Println("ERROR")
|
||||
fmt.Printf("%d, %s\n", r.Code, r.Message)
|
||||
}
|
||||
}
|
||||
|
||||
type ChunkResponse struct {
|
||||
Code int `json:"code"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
|
||||
@@ -329,9 +329,9 @@ func (c *CLI) RegisterUser(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// ListDatasets lists datasets for current user (user mode)
|
||||
// APIListDatasetsCommand lists datasets for current user (user mode)
|
||||
// Returns (result_map, error) - result_map is non-nil for benchmark mode
|
||||
func (c *CLI) ListDatasets(cmd *Command) (ResponseIf, error) {
|
||||
func (c *CLI) APIListDatasetsCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
@@ -386,6 +386,186 @@ func (c *CLI) ListDatasets(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) APIListDatasetDocumentsCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
httpClient := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
// Determine auth kind based on whether API token is being used
|
||||
if httpClient.LoginToken == nil && !httpClient.useAPIToken {
|
||||
return nil, fmt.Errorf("no authorization")
|
||||
}
|
||||
|
||||
datasetID, ok := cmd.Params["dataset_id"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no dataset id")
|
||||
}
|
||||
|
||||
page := 1
|
||||
pageSize := 10
|
||||
keywords := ""
|
||||
returnEmptyMetadata := "true"
|
||||
url := fmt.Sprintf("/datasets/%s/documents?page=%d&page_size=%d&keywords=%s&return_empty_metadata=%s", datasetID, page, pageSize, keywords, returnEmptyMetadata)
|
||||
|
||||
// Normal mode
|
||||
resp, err := httpClient.Request("GET", url, "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list documents: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to list documents: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result ListDocumentsResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("list documents failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
result.Duration = resp.Duration
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// APIListAgentsCommand lists agents
|
||||
func (c *CLI) APIListAgentsCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
httpClient := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
|
||||
// Determine auth kind based on whether API token is being used
|
||||
if httpClient.LoginToken == nil && !c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].useAPIToken {
|
||||
return nil, fmt.Errorf("no authorization")
|
||||
}
|
||||
|
||||
authKind := "web"
|
||||
if httpClient.useAPIToken {
|
||||
authKind = "api"
|
||||
}
|
||||
|
||||
if httpClient.LoginToken != nil {
|
||||
authKind = "web"
|
||||
}
|
||||
|
||||
// Normal mode
|
||||
resp, err := httpClient.Request("GET", "/agents", authKind, nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list agents: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to list agents: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result ListAgentsResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("list agents failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
result.Duration = resp.Duration
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// APIListChatsCommand lists chats
|
||||
func (c *CLI) APIListChatsCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
httpClient := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
|
||||
// Determine auth kind based on whether API token is being used
|
||||
if httpClient.LoginToken == nil && !c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].useAPIToken {
|
||||
return nil, fmt.Errorf("no authorization")
|
||||
}
|
||||
|
||||
authKind := "web"
|
||||
if httpClient.useAPIToken {
|
||||
authKind = "api"
|
||||
}
|
||||
|
||||
if httpClient.LoginToken != nil {
|
||||
authKind = "web"
|
||||
}
|
||||
|
||||
// Normal mode
|
||||
resp, err := httpClient.Request("GET", "/chats", authKind, nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list chats: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to list chats: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result ListChatsResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("list chats failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
result.Duration = resp.Duration
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// APIListSearchesCommand lists searches
|
||||
func (c *CLI) APIListSearchesCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
httpClient := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
|
||||
// Determine auth kind based on whether API token is being used
|
||||
if httpClient.LoginToken == nil && !c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].useAPIToken {
|
||||
return nil, fmt.Errorf("no authorization")
|
||||
}
|
||||
|
||||
authKind := "web"
|
||||
if httpClient.useAPIToken {
|
||||
authKind = "api"
|
||||
}
|
||||
|
||||
if httpClient.LoginToken != nil {
|
||||
authKind = "web"
|
||||
}
|
||||
|
||||
// Normal mode
|
||||
resp, err := httpClient.Request("GET", "/searches", authKind, nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list searches: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to list searches: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result ListSearchesResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("list searches failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
result.Duration = resp.Duration
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// ListDatasetDocumentUserCommand lists dataset documents
|
||||
func (c *CLI) ListDatasetDocumentUserCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
@@ -734,25 +914,25 @@ func (c *CLI) SearchOnDatasets(cmd *Command) (ResponseIf, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// CreateToken creates a new API token
|
||||
func (c *CLI) CreateToken(cmd *Command) (ResponseIf, error) {
|
||||
// APICreateAPIKeyCommand creates a new API key
|
||||
func (c *CLI) APICreateAPIKeyCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
httpClient := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
resp, err := httpClient.Request("POST", "/system/tokens", "web", nil, nil)
|
||||
resp, err := httpClient.Request("POST", "/system/keys", "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create token: %w", err)
|
||||
return nil, fmt.Errorf("failed to create key: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to create token: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
return nil, fmt.Errorf("failed to create key: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var createResult CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &createResult); err != nil {
|
||||
return nil, fmt.Errorf("create token failed: invalid JSON (%w)", err)
|
||||
return nil, fmt.Errorf("create key failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if createResult.Code != 0 {
|
||||
@@ -761,30 +941,30 @@ func (c *CLI) CreateToken(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
var result SimpleResponse
|
||||
result.Code = 0
|
||||
result.Message = "Token created successfully"
|
||||
result.Message = "API Key created successfully"
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// ListTokens lists all API tokens for the current user
|
||||
func (c *CLI) ListTokens(cmd *Command) (ResponseIf, error) {
|
||||
// APIListAPIKeysCommand lists all API keys for the current user
|
||||
func (c *CLI) APIListAPIKeysCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
httpClient := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
resp, err := httpClient.Request("GET", "/system/tokens", "web", nil, nil)
|
||||
resp, err := httpClient.Request("GET", "/system/keys", "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list tokens: %w", err)
|
||||
return nil, fmt.Errorf("failed to list keys: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to list tokens: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
return nil, fmt.Errorf("failed to list keys: 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 tokens failed: invalid JSON (%w)", err)
|
||||
return nil, fmt.Errorf("list keys failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
@@ -794,29 +974,29 @@ func (c *CLI) ListTokens(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// DropToken deletes an API token
|
||||
func (c *CLI) DropToken(cmd *Command) (ResponseIf, error) {
|
||||
// APIDeleteAPIKeyCommand deletes an API key
|
||||
func (c *CLI) APIDeleteAPIKeyCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
token, ok := cmd.Params["token"].(string)
|
||||
apiKey, ok := cmd.Params["api_key"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("token not provided")
|
||||
return nil, fmt.Errorf("key not provided")
|
||||
}
|
||||
|
||||
resp, err := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("DELETE", fmt.Sprintf("/system/tokens/%s", token), "web", nil, nil)
|
||||
resp, err := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("DELETE", fmt.Sprintf("/system/keys/%s", apiKey), "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to drop token: %w", err)
|
||||
return nil, fmt.Errorf("failed to delete key: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to drop token: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
return nil, fmt.Errorf("failed to delete key: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("drop token failed: invalid JSON (%w)", err)
|
||||
return nil, fmt.Errorf("delete key failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
|
||||
@@ -17,8 +17,8 @@ func tokenTypeDescription(t int, tok Token) string {
|
||||
}
|
||||
|
||||
// Command parsers
|
||||
func (p *Parser) parseLogout() (*Command, error) {
|
||||
cmd := NewCommand("logout")
|
||||
func (p *Parser) parseAPILogout() (*Command, error) {
|
||||
cmd := NewCommand("api_logout")
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
@@ -27,8 +27,8 @@ func (p *Parser) parseLogout() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseLoginUser() (*Command, error) {
|
||||
cmd := NewCommand("login_user")
|
||||
func (p *Parser) parseAPILoginUser() (*Command, error) {
|
||||
cmd := NewCommand("api_login_user")
|
||||
|
||||
p.nextToken() // consume LOGIN
|
||||
if p.curToken.Type != TokenUser {
|
||||
@@ -46,7 +46,8 @@ func (p *Parser) parseLoginUser() (*Command, error) {
|
||||
// Optional: PASSWORD 'password'
|
||||
if p.curToken.Type == TokenPassword {
|
||||
p.nextToken()
|
||||
password, err := p.parseQuotedString()
|
||||
var password string
|
||||
password, err = p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -62,8 +63,8 @@ func (p *Parser) parseLoginUser() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parsePingServer() (*Command, error) {
|
||||
cmd := NewCommand("ping_server")
|
||||
func (p *Parser) parseAPIPingServer() (*Command, error) {
|
||||
cmd := NewCommand("api_ping_server")
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
@@ -72,8 +73,8 @@ func (p *Parser) parsePingServer() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseRegisterCommand() (*Command, error) {
|
||||
cmd := NewCommand("register_user")
|
||||
func (p *Parser) parseAPIRegisterCommand() (*Command, error) {
|
||||
cmd := NewCommand("api_register_user")
|
||||
|
||||
if err := p.expectPeek(TokenUser); err != nil {
|
||||
return nil, err
|
||||
@@ -119,42 +120,28 @@ func (p *Parser) parseRegisterCommand() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// LIST CONFIGS;
|
||||
// LIST PROVIDER 'provider_name' MODELS;
|
||||
// LIST PROVIDER 'provider_name' INSTANCE 'instance_name' MODELS
|
||||
// LIST MODELS;
|
||||
func (p *Parser) parseListCommand() (*Command, error) {
|
||||
func (p *Parser) parseAPIListCommands() (*Command, error) {
|
||||
p.nextToken() // consume LIST
|
||||
|
||||
switch p.curToken.Type {
|
||||
case TokenVars:
|
||||
p.nextToken()
|
||||
// Semicolon is optional for SHOW TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("list_variables"), nil
|
||||
case TokenConfigs:
|
||||
p.nextToken()
|
||||
// Semicolon is optional for SHOW TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("list_configs"), nil
|
||||
case TokenEnvs:
|
||||
p.nextToken()
|
||||
// Semicolon is optional for SHOW TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("list_environments"), nil
|
||||
return p.parseAPIListConfigs()
|
||||
case TokenDatasets:
|
||||
return p.parseListDatasets()
|
||||
case TokenDocuments:
|
||||
return p.parseListDatasetDocuments()
|
||||
return p.parseAPIListDatasets()
|
||||
case TokenDataset:
|
||||
return p.parseAPIListDatasetDocuments()
|
||||
case TokenAgents:
|
||||
return p.parseListAgents()
|
||||
case TokenTokens:
|
||||
return p.parseListTokens()
|
||||
return p.parseAPIListAgents()
|
||||
case TokenChats:
|
||||
return p.parseAPIListChats()
|
||||
case TokenSearches:
|
||||
return p.parseAPIListSearches()
|
||||
case TokenKeys:
|
||||
return p.parseAPIListAPIKeys()
|
||||
case TokenModel:
|
||||
return p.parseListModelProviders()
|
||||
case TokenSupported:
|
||||
@@ -171,13 +158,6 @@ func (p *Parser) parseListCommand() (*Command, error) {
|
||||
return p.parseListDefaultModels()
|
||||
case TokenAvailable:
|
||||
return p.parseListAvailableProviders()
|
||||
case TokenChats:
|
||||
p.nextToken()
|
||||
// Semicolon is optional for SHOW TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("list_user_chats"), nil
|
||||
case TokenFiles:
|
||||
return p.parseListFiles()
|
||||
case TokenQuotedString:
|
||||
@@ -189,8 +169,19 @@ func (p *Parser) parseListCommand() (*Command, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseListDatasets() (*Command, error) {
|
||||
cmd := NewCommand("list_datasets")
|
||||
// LIST CONFIGS;
|
||||
func (p *Parser) parseAPIListConfigs() (*Command, error) {
|
||||
p.nextToken()
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("api_list_configs"), nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAPIListDatasets() (*Command, error) {
|
||||
cmd := NewCommand("api_list_datasets")
|
||||
p.nextToken() // consume DATASETS
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
@@ -200,13 +191,9 @@ func (p *Parser) parseListDatasets() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseListDatasetDocuments() (*Command, error) {
|
||||
p.nextToken() // consume DOCUMENTS
|
||||
|
||||
if p.curToken.Type != TokenFrom {
|
||||
return nil, fmt.Errorf("expected FROM")
|
||||
}
|
||||
p.nextToken()
|
||||
// LIST DATASET 'dataset_name' DOCUMENTS;
|
||||
func (p *Parser) parseAPIListDatasetDocuments() (*Command, error) {
|
||||
p.nextToken() // consume DATASET
|
||||
|
||||
datasetID, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
@@ -214,17 +201,53 @@ func (p *Parser) parseListDatasetDocuments() (*Command, error) {
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
cmd := NewCommand("list_dataset_documents")
|
||||
if p.curToken.Type != TokenDocuments {
|
||||
return nil, fmt.Errorf("expected DOCUMENTS")
|
||||
}
|
||||
|
||||
cmd := NewCommand("api_list_dataset_documents")
|
||||
cmd.Params["dataset_id"] = datasetID
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAPIListAgents() (*Command, error) {
|
||||
p.nextToken() // consume AGENTS
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return NewCommand("api_list_agents"), nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAPIListChats() (*Command, error) {
|
||||
p.nextToken() // consume CHATS
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return NewCommand("api_list_chats"), nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAPIListSearches() (*Command, error) {
|
||||
p.nextToken() // consume SEARCHES
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return NewCommand("api_list_searches"), nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseGetMetadata() (*Command, error) {
|
||||
p.nextToken() // consume METADATA
|
||||
|
||||
@@ -273,38 +296,10 @@ func (p *Parser) parseGetMetadata() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseListAgents() (*Command, error) {
|
||||
p.nextToken() // consume AGENTS
|
||||
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
return NewCommand("list_user_agents"), nil
|
||||
}
|
||||
|
||||
if p.curToken.Type != TokenOf {
|
||||
return nil, fmt.Errorf("expected OF")
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
userName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd := NewCommand("list_agents")
|
||||
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) parseListTokens() (*Command, error) {
|
||||
p.nextToken() // consume TOKENS
|
||||
cmd := NewCommand("list_tokens")
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
func (p *Parser) parseAPIListAPIKeys() (*Command, error) {
|
||||
p.nextToken() // consume KEYS
|
||||
cmd := NewCommand("api_list_api_keys")
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -567,8 +562,8 @@ func (p *Parser) parseCreateCommand() (*Command, error) {
|
||||
return p.parseCreateDataset()
|
||||
case TokenChat:
|
||||
return p.parseCreateChat()
|
||||
case TokenToken:
|
||||
return p.parseCreateToken()
|
||||
case TokenKey:
|
||||
return p.parseAPICreateKey()
|
||||
case TokenChunkStore:
|
||||
return p.parseCreateChunkStore()
|
||||
case TokenMetadata:
|
||||
@@ -596,15 +591,15 @@ func (p *Parser) parseAddCommand() (*Command, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseCreateToken() (*Command, error) {
|
||||
p.nextToken() // consume TOKEN
|
||||
func (p *Parser) parseAPICreateKey() (*Command, error) {
|
||||
p.nextToken() // consume KEY
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional for UNSET KEY
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return NewCommand("create_token"), nil
|
||||
return NewCommand("api_create_api_key"), nil
|
||||
}
|
||||
|
||||
// Internal CLI for GO
|
||||
@@ -1213,8 +1208,8 @@ func (p *Parser) parseDropCommand() (*Command, error) {
|
||||
return p.parseDropDataset()
|
||||
case TokenChat:
|
||||
return p.parseDropChat()
|
||||
case TokenToken:
|
||||
return p.parseDropToken()
|
||||
case TokenKey:
|
||||
return p.parseAPIDeleteAPIKey()
|
||||
case TokenChunkStore:
|
||||
return p.parseDropChunkStore()
|
||||
case TokenMetadata:
|
||||
@@ -1262,30 +1257,18 @@ func (p *Parser) parseRemoveCommand() (*Command, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseDropToken() (*Command, error) {
|
||||
p.nextToken() // consume TOKEN
|
||||
func (p *Parser) parseAPIDeleteAPIKey() (*Command, error) {
|
||||
p.nextToken() // consume KEY
|
||||
|
||||
tokenValue, err := p.parseQuotedString()
|
||||
apiKey, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.nextToken()
|
||||
if p.curToken.Type != TokenOf {
|
||||
return nil, fmt.Errorf("expected OF")
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
userName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd := NewCommand("api_delete_api_key")
|
||||
cmd.Params["api_key"] = apiKey
|
||||
|
||||
cmd := NewCommand("drop_token")
|
||||
cmd.Params["token"] = tokenValue
|
||||
cmd.Params["user_name"] = userName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
@@ -3647,7 +3630,7 @@ func (p *Parser) parseBenchmarkCommand() (*Command, error) {
|
||||
func (p *Parser) parseUserStatement() (*Command, error) {
|
||||
switch p.curToken.Type {
|
||||
case TokenPing:
|
||||
return p.parsePingServer()
|
||||
return p.parseAPIPingServer()
|
||||
case TokenDelete:
|
||||
return p.parseDeleteCommand()
|
||||
case TokenShow:
|
||||
@@ -3663,7 +3646,7 @@ func (p *Parser) parseUserStatement() (*Command, error) {
|
||||
case TokenReset:
|
||||
return p.parseResetCommand()
|
||||
case TokenList:
|
||||
return p.parseListCommand()
|
||||
return p.parseAPIListCommands()
|
||||
case TokenParse:
|
||||
return p.parseParseCommand()
|
||||
case TokenImport:
|
||||
|
||||
@@ -26,16 +26,7 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// ListTokens list all API tokens for the current user's tenant
|
||||
// @Summary List API Tokens
|
||||
// @Description List all API tokens for the current user's tenant
|
||||
// @Tags system
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /api/v1/system/tokens [get]
|
||||
func (h *SystemHandler) ListTokens(c *gin.Context) {
|
||||
func (h *SystemHandler) ListAPIKeys(c *gin.Context) {
|
||||
// Get current user from context
|
||||
user, exists := c.Get("user")
|
||||
if !exists {
|
||||
@@ -68,12 +59,12 @@ func (h *SystemHandler) ListTokens(c *gin.Context) {
|
||||
|
||||
tenantID := tenants[0].TenantID
|
||||
|
||||
// Get tokens for the tenant
|
||||
tokens, err := h.systemService.ListAPITokens(tenantID)
|
||||
// Get keys for the tenant
|
||||
keys, err := h.systemService.ListAPIKeys(tenantID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"code": 500,
|
||||
"message": "Failed to list tokens",
|
||||
"message": "Failed to list keys",
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -81,21 +72,11 @@ func (h *SystemHandler) ListTokens(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": tokens,
|
||||
"data": keys,
|
||||
})
|
||||
}
|
||||
|
||||
// CreateToken creates a new API token for the current user's tenant
|
||||
// @Summary Create API Token
|
||||
// @Description Generate a new API token for the current user's tenant
|
||||
// @Tags system
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param name query string false "Name of the token"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /api/v1/system/tokens [post]
|
||||
func (h *SystemHandler) CreateToken(c *gin.Context) {
|
||||
func (h *SystemHandler) CreateKey(c *gin.Context) {
|
||||
// Get current user from context
|
||||
user, exists := c.Get("user")
|
||||
if !exists {
|
||||
@@ -129,7 +110,7 @@ func (h *SystemHandler) CreateToken(c *gin.Context) {
|
||||
tenantID := tenants[0].TenantID
|
||||
|
||||
// Parse request
|
||||
var req service.CreateAPITokenRequest
|
||||
var req service.CreateAPIKeyRequest
|
||||
if err := c.ShouldBind(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 400,
|
||||
@@ -138,12 +119,12 @@ func (h *SystemHandler) CreateToken(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Create token
|
||||
token, err := h.systemService.CreateAPIToken(tenantID, &req)
|
||||
// Create key
|
||||
key, err := h.systemService.CreateAPIKey(tenantID, &req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"code": 500,
|
||||
"message": "Failed to create token",
|
||||
"message": "Failed to create key",
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -151,21 +132,11 @@ func (h *SystemHandler) CreateToken(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": token,
|
||||
"data": key,
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteToken deletes an API token
|
||||
// @Summary Delete API Token
|
||||
// @Description Remove an API token for the current user's tenant
|
||||
// @Tags system
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param token path string true "The API token to remove"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /api/v1/system/tokens/{token} [delete]
|
||||
func (h *SystemHandler) DeleteToken(c *gin.Context) {
|
||||
func (h *SystemHandler) DeleteKey(c *gin.Context) {
|
||||
// Get current user from context
|
||||
user, exists := c.Get("user")
|
||||
if !exists {
|
||||
@@ -198,21 +169,21 @@ func (h *SystemHandler) DeleteToken(c *gin.Context) {
|
||||
|
||||
tenantID := tenants[0].TenantID
|
||||
|
||||
// Get token from path parameter
|
||||
token := c.Param("token")
|
||||
if token == "" {
|
||||
// Get key from path parameter
|
||||
key := c.Param("key")
|
||||
if key == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 400,
|
||||
"message": "Token is required",
|
||||
"message": "Key is required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Delete token
|
||||
if err := h.systemService.DeleteAPIToken(tenantID, token); err != nil {
|
||||
// Delete key
|
||||
if err = h.systemService.DeleteAPIKey(tenantID, key); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"code": 500,
|
||||
"message": "Failed to delete token",
|
||||
"message": "Failed to delete key",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -489,7 +489,7 @@ func (h *DocumentHandler) ListDocuments(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
|
||||
if !h.datasetService.Accessible(datasetID, userID) {
|
||||
jsonError(c, common.CodeAuthenticationError, "No authorization.")
|
||||
jsonError(c, common.CodeAuthenticationError, "No authorization to access the dataset.")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -554,11 +554,21 @@ func (r *Router) Setup(engine *gin.Engine) {
|
||||
tokens := system.Group("/tokens")
|
||||
{
|
||||
// list tokens /api/v1/system/tokens GET
|
||||
tokens.GET("", r.systemHandler.ListTokens)
|
||||
tokens.GET("", r.systemHandler.ListAPIKeys)
|
||||
// create token /api/v1/system/tokens POST
|
||||
tokens.POST("", r.systemHandler.CreateToken)
|
||||
// delete token /api/v1/system/tokens/:token DELETE
|
||||
tokens.DELETE("/:token", r.systemHandler.DeleteToken)
|
||||
tokens.POST("", r.systemHandler.CreateKey)
|
||||
// delete token /api/v1/system/tokens/:key DELETE
|
||||
tokens.DELETE("/:key", r.systemHandler.DeleteKey)
|
||||
}
|
||||
|
||||
keys := system.Group("/keys")
|
||||
{
|
||||
// list keys /api/v1/system/keys GET
|
||||
keys.GET("", r.systemHandler.ListAPIKeys)
|
||||
// create key /api/v1/system/keys POST
|
||||
keys.POST("", r.systemHandler.CreateKey)
|
||||
// delete key /api/v1/system/keys/:key DELETE
|
||||
keys.DELETE("/:key", r.systemHandler.DeleteKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ import (
|
||||
"ragflow/internal/utility"
|
||||
)
|
||||
|
||||
// TokenResponse token response
|
||||
type TokenResponse struct {
|
||||
// APIKeyResponse key response
|
||||
type APIKeyResponse struct {
|
||||
TenantID string `json:"tenant_id"`
|
||||
Token string `json:"token"`
|
||||
DialogID *string `json:"dialog_id,omitempty"`
|
||||
@@ -33,83 +33,82 @@ type TokenResponse struct {
|
||||
UpdateTime *int64 `json:"update_time,omitempty"`
|
||||
}
|
||||
|
||||
// ListAPITokens list all API tokens for a tenant
|
||||
func (s *SystemService) ListAPITokens(tenantID string) ([]*TokenResponse, error) {
|
||||
// ListAPIKeys list all API keys for a tenant
|
||||
func (s *SystemService) ListAPIKeys(tenantID string) ([]*APIKeyResponse, error) {
|
||||
APITokenDAO := dao.NewAPITokenDAO()
|
||||
tokens, err := APITokenDAO.GetByTenantID(tenantID)
|
||||
keys, err := APITokenDAO.GetByTenantID(tenantID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
responses := make([]*TokenResponse, len(tokens))
|
||||
for i, token := range tokens {
|
||||
beta := token.Beta
|
||||
responses := make([]*APIKeyResponse, len(keys))
|
||||
for i, key := range keys {
|
||||
beta := key.Beta
|
||||
if beta == nil || *beta == "" {
|
||||
generatedBeta := utility.GenerateBetaAPIToken(utility.GenerateAPIToken())
|
||||
if err := dao.DB.Model(&entity.APIToken{}).
|
||||
Where("tenant_id = ? AND token = ?", tenantID, token.Token).
|
||||
if err = dao.DB.Model(&entity.APIToken{}).
|
||||
Where("tenant_id = ? AND token = ?", tenantID, key.Token).
|
||||
Updates(map[string]interface{}{
|
||||
"beta": generatedBeta,
|
||||
}).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
beta = &generatedBeta
|
||||
token.Beta = beta
|
||||
key.Beta = beta
|
||||
}
|
||||
|
||||
responses[i] = &TokenResponse{
|
||||
TenantID: token.TenantID,
|
||||
Token: token.Token,
|
||||
DialogID: token.DialogID,
|
||||
Source: token.Source,
|
||||
responses[i] = &APIKeyResponse{
|
||||
TenantID: key.TenantID,
|
||||
Token: key.Token,
|
||||
DialogID: key.DialogID,
|
||||
Source: key.Source,
|
||||
Beta: beta,
|
||||
CreateTime: token.CreateTime,
|
||||
UpdateTime: token.UpdateTime,
|
||||
CreateTime: key.CreateTime,
|
||||
UpdateTime: key.UpdateTime,
|
||||
}
|
||||
}
|
||||
|
||||
return responses, nil
|
||||
}
|
||||
|
||||
// CreateAPITokenRequest create token request
|
||||
type CreateAPITokenRequest struct {
|
||||
// CreateAPIKeyRequest create key request
|
||||
type CreateAPIKeyRequest struct {
|
||||
Name string `json:"name" form:"name"`
|
||||
}
|
||||
|
||||
// CreateAPIToken creates a new API token for a tenant
|
||||
func (s *SystemService) CreateAPIToken(tenantID string, req *CreateAPITokenRequest) (*TokenResponse, error) {
|
||||
// CreateAPIKey creates a new API key for a tenant
|
||||
func (s *SystemService) CreateAPIKey(tenantID string, req *CreateAPIKeyRequest) (*APIKeyResponse, error) {
|
||||
APITokenDAO := dao.NewAPITokenDAO()
|
||||
|
||||
// Generate token and beta values
|
||||
// token: "ragflow-" + secrets.token_urlsafe(32)
|
||||
// Generate key and beta values
|
||||
// key: "ragflow-" + secrets.token_urlsafe(32)
|
||||
APIToken := utility.GenerateAPIToken()
|
||||
// beta: generate_confirmation_token().replace("ragflow-", "")[:32]
|
||||
betaAPIKey := utility.GenerateBetaAPIToken(utility.GenerateAPIToken())
|
||||
|
||||
APITokenData := &entity.APIToken{
|
||||
APIKeyData := &entity.APIToken{
|
||||
TenantID: tenantID,
|
||||
Token: APIToken,
|
||||
Beta: &betaAPIKey,
|
||||
}
|
||||
|
||||
if err := APITokenDAO.Create(APITokenData); err != nil {
|
||||
if err := APITokenDAO.Create(APIKeyData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &TokenResponse{
|
||||
TenantID: APITokenData.TenantID,
|
||||
Token: APITokenData.Token,
|
||||
DialogID: APITokenData.DialogID,
|
||||
Source: APITokenData.Source,
|
||||
Beta: APITokenData.Beta,
|
||||
CreateTime: APITokenData.CreateTime,
|
||||
UpdateTime: APITokenData.UpdateTime,
|
||||
return &APIKeyResponse{
|
||||
TenantID: APIKeyData.TenantID,
|
||||
Token: APIKeyData.Token,
|
||||
DialogID: APIKeyData.DialogID,
|
||||
Source: APIKeyData.Source,
|
||||
Beta: APIKeyData.Beta,
|
||||
CreateTime: APIKeyData.CreateTime,
|
||||
UpdateTime: APIKeyData.UpdateTime,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteAPIToken deletes an API token by tenant ID and token value
|
||||
func (s *SystemService) DeleteAPIToken(tenantID, token string) error {
|
||||
func (s *SystemService) DeleteAPIKey(tenantID, key string) error {
|
||||
APITokenDAO := dao.NewAPITokenDAO()
|
||||
_, err := APITokenDAO.DeleteByTenantIDAndToken(tenantID, token)
|
||||
_, err := APITokenDAO.DeleteByTenantIDAndToken(tenantID, key)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ type ChatWithKBNames struct {
|
||||
|
||||
// ListChatsResponse list chats response
|
||||
type ListChatsResponse struct {
|
||||
Total int64 `json:"total"`
|
||||
Chats []*ChatWithKBNames `json:"chats"`
|
||||
}
|
||||
|
||||
@@ -107,6 +108,7 @@ func (s *ChatService) ListChats(userID, status, keywords string, page, pageSize
|
||||
}
|
||||
|
||||
return &ListChatsResponse{
|
||||
Total: total,
|
||||
Chats: chatsWithKBNames,
|
||||
}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user