Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release - Fix path traversal bug for sqlite, new clickhouse options, and support for OpenAI-like URLs #329

Merged
merged 41 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
898d894
add openai compatible provider
Dec 2, 2024
b12bc69
Merge branch 'clidey:main' into main
learningpro Dec 2, 2024
15fa9ca
Merge branch 'main' into main
learningpro Dec 20, 2024
95026e8
add additional options for clickhouse support, HTTP protocol, TLS mod…
Slach Dec 21, 2024
1411fcf
Merge pull request #300 from Slach/main
hkdeman Jan 8, 2025
b994967
Merge pull request #252 from learningpro/main
hkdeman Jan 8, 2025
27f106b
fix variant A and B for path traversal
modelorona Jan 23, 2025
cb5b9bf
remove string processing code
modelorona Jan 24, 2025
cfda05a
update directory to end with slash
modelorona Jan 25, 2025
9c15d79
initial fix for mysql to use the driver Config object to build the ds…
modelorona Jan 25, 2025
cb871a0
change to hostPath check to account for length
modelorona Jan 25, 2025
380544c
removed the hostPath for now. removed & from collation before passing…
modelorona Jan 25, 2025
9e8669a
add back func for reading in params behind isProfile guard
modelorona Jan 25, 2025
903c223
postgres dsn builder surrounds all params with single quotes now to t…
modelorona Jan 25, 2025
f2d6de1
redis addr built using net.JoinHostPort
modelorona Jan 25, 2025
dd94d97
modify mongodb to connect using clientOptions
modelorona Jan 25, 2025
520d862
query escape for elasticsearch
modelorona Jan 25, 2025
33a56d1
disable clickhouse sslmode as it's not fully complete. update elastic…
modelorona Jan 25, 2025
3f6fcab
Update issue templates
modelorona Jan 26, 2025
547336a
Merge commit from fork
modelorona Jan 27, 2025
0e75ff3
parse port as num and fail otherwise, remove collation option from fr…
modelorona Jan 27, 2025
6f1ebf3
update clickhouse config
modelorona Jan 27, 2025
2d47a83
update postgres handling to escape all single quotes to avoid jumping…
modelorona Jan 27, 2025
5978412
fix clickhouse setup to allow for both port 9000 (tcp) and port 8123 …
modelorona Jan 27, 2025
8d67b76
Merge commit from fork
modelorona Jan 27, 2025
f67f843
feat(core,frontend): add alias logic
hkdeman Jan 28, 2025
76e0cad
Merge pull request #331 from clidey/hk/issues/alias
hkdeman Jan 28, 2025
e2f0ed9
feat(frontend): fix table header logic to have unique ids
hkdeman Jan 28, 2025
114522f
feat(frontend): fix up undefined
hkdeman Jan 28, 2025
410561a
Merge pull request #332 from clidey/hk/issues/scratchpad-wrong-columns
hkdeman Jan 28, 2025
bef215f
feat(frontend): replace monaco editor with code mirror for offline pa…
hkdeman Jan 28, 2025
df37d60
feat(editor): fix theming
hkdeman Jan 28, 2025
e7d8228
feat(frontend): fix markdown library issue
hkdeman Jan 28, 2025
c27f796
Merge pull request #333 from clidey/hk/issues/switch-to-code-mirror
hkdeman Jan 28, 2025
46a7956
feat(frontend): add loader and loading states
hkdeman Jan 28, 2025
33c2cd4
feat(frontend): add loader and loading states
hkdeman Jan 28, 2025
e19fe5a
Revert "feat(frontend): add loader and loading states"
hkdeman Jan 28, 2025
35efc89
feat(frontend): remove class names logic
hkdeman Feb 3, 2025
8960083
Merge pull request #336 from clidey/hk/issues/loading-states
hkdeman Feb 5, 2025
d807c72
add clickhouse table addition operators + label name
modelorona Feb 5, 2025
89fb514
feat(frontend): fix table # number and editor default sql and disable…
hkdeman Feb 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: Bug report
about: Create a report to help us improve
about: Create a report to help us improve WhoDB.
title: "[BUG] - {your title here}"
labels: bug
assignees: ''
Expand All @@ -24,15 +24,16 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
- OS that WhoDB is running on: [e.g. Ubuntu]
- How you're running WhoDB: [e.g, Docker, exe, manually]
- Browser: [e.g. chrome, safari]
- Version: [e.g. 22]

**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
- Browser: [e.g. stock browser, safari]
- Version: [e.g. 22]

**Additional context**
Add any other context about the problem here.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: Feature request
about: Suggest an idea for this project
about: Suggest an idea for this project.
title: "[FR] - {your title here}"
labels: enhancement
assignees: ''
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,17 @@ Get up and running with WhoDB quickly using Docker:
docker run -it -p 8080:8080 clidey/whodb
```


To run WhoDB with an OpenAI compatible service, you should assign some environments.
```sh
docker run -it -e USE_CUSTOM_MODELS=1 -e CUSTOM_MODELS=gpt-4o,gpt-3.5,others -e OPENAI_BASE_URL=http://your_base_url/v1 -p 8080:8080 clidey/whodb
```

If you are using a remote Ollama server, please start Docker with Ollama Environments like this:
```sh
docker run -it -e WHODB_OLLAMA_HOST=YOUR_OLLAMA_HOST -e WHODB_OLLAMA_PORT=YOUR_OLLAMA_PORT -p 8080:8080 clidey/whodb
```


Or, use Docker Compose:
```sh
version: "3.8"
Expand Down
5 changes: 2 additions & 3 deletions core/src/llm/chatgpt_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"strings"
)

const chatGPTEndpoint = "https://api.openai.com/v1"

func prepareChatGPTRequest(c *LLMClient, prompt string, model LLMModel, receiverChan *chan string) (string, []byte, map[string]string, error) {
requestBody, err := json.Marshal(map[string]interface{}{
Expand All @@ -20,7 +19,7 @@ func prepareChatGPTRequest(c *LLMClient, prompt string, model LLMModel, receiver
if err != nil {
return "", nil, nil, err
}
url := fmt.Sprintf("%v/chat/completions", chatGPTEndpoint)
url := fmt.Sprintf("%v/chat/completions", getOpenAICompatibleBaseURL())
headers := map[string]string{
"Authorization": fmt.Sprintf("Bearer %s", c.APIKey),
"Content-Type": "application/json",
Expand All @@ -29,7 +28,7 @@ func prepareChatGPTRequest(c *LLMClient, prompt string, model LLMModel, receiver
}

func prepareChatGPTModelsRequest(apiKey string) (string, map[string]string) {
url := fmt.Sprintf("%v/models", chatGPTEndpoint)
url := fmt.Sprintf("%v/models", getOpenAICompatibleBaseURL())
headers := map[string]string{
"Authorization": fmt.Sprintf("Bearer %s", apiKey),
"Content-Type": "application/json",
Expand Down
31 changes: 30 additions & 1 deletion core/src/llm/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ package llm

import (
"fmt"

"strings"
"os"
"github.com/clidey/whodb/core/src/common"
"github.com/clidey/whodb/core/src/env"
)
Expand All @@ -24,3 +25,31 @@ func getOllamaEndpoint() string {

return fmt.Sprintf("http://%v:%v/api", host, port)
}

func getOpenAICompatibleBaseURL() string {
defaultBaseURL := "https://api.openai.com/v1"
baseURL := os.Getenv("OPENAI_BASE_URL")
if baseURL == "" {
baseURL = defaultBaseURL
}
return baseURL
}

func getCustomModels() ([]string, error) {
modelsStr := os.Getenv("CUSTOM_MODELS")
if modelsStr == "" {
return []string{}, nil
}

models := strings.Split(modelsStr, ",")

for i := range models {
models[i] = strings.TrimSpace(models[i])
}
return models, nil
}

func ShouldUseCustomModels() bool {
useCustomModels := os.Getenv("USE_CUSTOM_MODELS")
return useCustomModels == "1"
}
3 changes: 3 additions & 0 deletions core/src/llm/llm_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ func (c *LLMClient) GetSupportedModels() ([]string, error) {
url, headers = prepareOllamaModelsRequest()
case ChatGPT_LLMType:
url, headers = prepareChatGPTModelsRequest(c.APIKey)
if ShouldUseCustomModels() {
return getCustomModels()
}
case Anthropic_LLMType:
return getAnthropicModels(c.APIKey)
default:
Expand Down
4 changes: 2 additions & 2 deletions core/src/plugins/clickhouse/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
query += fmt.Sprintf("\nSETTINGS %s", strings.Join(settingsClauses, ", "))
}

err = conn.Exec(context.Background(), query)
_, err = conn.ExecContext(context.Background(), query)
Dismissed Show dismissed Hide dismissed
if err != nil {
return false, fmt.Errorf("failed to create table: %w (query: %s)", err, query)
}
Expand Down Expand Up @@ -100,6 +100,6 @@
query := fmt.Sprintf("INSERT INTO %s.%s (%s) VALUES (%s)",
schema, storageUnit, strings.Join(columns, ", "), strings.Join(placeholders, ", "))

err = conn.Exec(context.Background(), query, args...)
_, err = conn.ExecContext(context.Background(), query, args...)
Dismissed Show dismissed Hide dismissed
return err == nil, err
}
12 changes: 6 additions & 6 deletions core/src/plugins/clickhouse/clickhouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import (
"context"
"database/sql"
"fmt"
"github.com/ClickHouse/clickhouse-go/v2/lib/driver"
"strconv"

"github.com/clidey/whodb/core/src/engine"
Expand All @@ -17,7 +17,7 @@
return false
}
defer conn.Close()
return conn.Ping(context.Background()) == nil
return conn.PingContext(context.Background()) == nil
}

func (p *ClickHousePlugin) GetDatabases(config *engine.PluginConfig) ([]string, error) {
Expand All @@ -27,7 +27,7 @@
}
defer conn.Close()

rows, err := conn.Query(context.Background(), "SHOW DATABASES")
rows, err := conn.QueryContext(context.Background(), "SHOW DATABASES")
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -66,7 +66,7 @@
WHERE database = '%s'
`, schema)

rows, err := conn.Query(context.Background(), query)
rows, err := conn.QueryContext(context.Background(), query)
Dismissed Show dismissed Hide dismissed
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -102,7 +102,7 @@
return storageUnits, nil
}

func getTableSchema(conn driver.Conn, schema string, tableName string) ([]engine.Record, error) {
func getTableSchema(conn *sql.DB, schema string, tableName string) ([]engine.Record, error) {
query := fmt.Sprintf(`
SELECT
name,
Expand All @@ -112,7 +112,7 @@
ORDER BY position
`, schema, tableName)

rows, err := conn.Query(context.Background(), query)
rows, err := conn.QueryContext(context.Background(), query)
Dismissed Show dismissed Hide dismissed
if err != nil {
return nil, err
}
Expand Down
58 changes: 47 additions & 11 deletions core/src/plugins/clickhouse/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ package clickhouse

import (
"context"
"crypto/tls"
"database/sql"
"fmt"
"github.com/clidey/whodb/core/src/log"
"strings"
"time"

"github.com/ClickHouse/clickhouse-go/v2"
Expand All @@ -11,29 +15,61 @@ import (
"github.com/clidey/whodb/core/src/engine"
)

func DB(config *engine.PluginConfig) (driver.Conn, error) {
port := common.GetRecordValueOrDefault(config.Credentials.Advanced, "Port", "9000")
const (
portKey = "Port"
sslModeKey = "SSL Mode"
httpProtocolKey = "HTTP Protocol"
readOnlyKey = "Readonly"
debugKey = "Debug"
)

func DB(config *engine.PluginConfig) (*sql.DB, error) {
port := common.GetRecordValueOrDefault(config.Credentials.Advanced, portKey, "9000")
sslMode := common.GetRecordValueOrDefault(config.Credentials.Advanced, sslModeKey, "disable")
httpProtocol := common.GetRecordValueOrDefault(config.Credentials.Advanced, httpProtocolKey, "disable")
readOnly := common.GetRecordValueOrDefault(config.Credentials.Advanced, readOnlyKey, "disable")
debug := common.GetRecordValueOrDefault(config.Credentials.Advanced, debugKey, "disable")
options := &clickhouse.Options{
Addr: []string{fmt.Sprintf("%s:%s", config.Credentials.Hostname, port)},
Auth: clickhouse.Auth{
Database: config.Credentials.Database,
Username: config.Credentials.Username,
Password: config.Credentials.Password,
},
Settings: clickhouse.Settings{
"max_execution_time": 60,
},
DialTimeout: time.Second * 30,
MaxOpenConns: 5,
MaxIdleConns: 5,
ConnMaxLifetime: time.Hour,
ConnOpenStrategy: clickhouse.ConnOpenInOrder,
Compression: &clickhouse.Compression{
}
if debug != "disable" {
options.Debug = true
}
if readOnly == "disable" {
options.Settings = clickhouse.Settings{
"max_execution_time": 60,
}
}
if strings.HasPrefix(port, "8") || httpProtocol != "disable" {
options.Protocol = clickhouse.HTTP
options.Compression = &clickhouse.Compression{
Method: clickhouse.CompressionGZIP,
}
} else {
options.Compression = &clickhouse.Compression{
Method: clickhouse.CompressionLZ4,
},
}
options.MaxOpenConns = 5
options.MaxIdleConns = 5
options.ConnMaxLifetime = time.Hour
}
if sslMode != "disable" {
options.TLS = &tls.Config{InsecureSkipVerify: sslMode == "relaxed" || sslMode == "none"}
}

return clickhouse.Open(options)
conn := clickhouse.OpenDB(options)
err := conn.PingContext(context.Background())
if err != nil {
log.Logger.Warnf("clickhouse.Ping() error: %v", err)
}
return conn, err
}

func getTableColumns(conn driver.Conn, schema, table string) ([]engine.Record, error) {
Expand Down
7 changes: 6 additions & 1 deletion core/src/plugins/clickhouse/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
import (
"context"
"fmt"
"github.com/clidey/whodb/core/src/common"
"strings"

"github.com/clidey/whodb/core/src/engine"
)

func (p *ClickHousePlugin) DeleteRow(config *engine.PluginConfig, schema string, storageUnit string, values map[string]string) (bool, error) {
readOnly := common.GetRecordValueOrDefault(config.Credentials.Advanced, readOnlyKey, "disable")
if readOnly != "disable" {
return false, fmt.Errorf("readonly mode don't allow DeleteRow")
}
conn, err := DB(config)
if err != nil {
return false, err
Expand Down Expand Up @@ -68,7 +73,7 @@
strings.Join(whereClauses, " AND "))

// Execute the query
err = conn.Exec(context.Background(), query, args...)
_, err = conn.ExecContext(context.Background(), query, args...)
Dismissed Show dismissed Hide dismissed
if err != nil {
return false, fmt.Errorf("delete failed: %w (query: %s, args: %+v)", err, query, args)
}
Expand Down
7 changes: 5 additions & 2 deletions core/src/plugins/clickhouse/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@
}
defer conn.Close()

rows, err := conn.Query(context.Background(), query, params)
rows, err := conn.QueryContext(context.Background(), query, params)
Dismissed Show dismissed Hide dismissed
if err != nil {
return nil, err
}
defer rows.Close()

columnTypes := rows.ColumnTypes()
columnTypes, err := rows.ColumnTypes()
if err != nil {
return nil, err
}
result := &engine.GetRowsResult{
Columns: make([]engine.Column, len(columnTypes)),
Rows: [][]string{},
Expand Down
7 changes: 6 additions & 1 deletion core/src/plugins/clickhouse/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
import (
"context"
"fmt"
"github.com/clidey/whodb/core/src/common"
"github.com/clidey/whodb/core/src/engine"
"strings"
"time"
)

func (p *ClickHousePlugin) UpdateStorageUnit(config *engine.PluginConfig, schema string, storageUnit string, values map[string]string) (bool, error) {
readOnly := common.GetRecordValueOrDefault(config.Credentials.Advanced, readOnlyKey, "disable")
if readOnly != "disable" {
return false, fmt.Errorf("readonly mode don't allow UpdateStorageUnit")
}
conn, err := DB(config)
if err != nil {
return false, err
Expand Down Expand Up @@ -99,7 +104,7 @@
strings.Join(setClauses, ", "),
strings.Join(whereClauses, " AND "))

err = conn.Exec(context.Background(), query, args...)
_, err = conn.ExecContext(context.Background(), query, args...)
Dismissed Show dismissed Hide dismissed
if err != nil {
return false, fmt.Errorf("update failed: %w", err)
}
Expand Down
Loading
Loading