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

feat: enable username and password auth #57

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
38 changes: 0 additions & 38 deletions driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,41 +40,3 @@ func (d *databricksDriver) OpenConnector(dsn string) (driver.Connector, error) {

var _ driver.Driver = (*databricksDriver)(nil)
var _ driver.DriverContext = (*databricksDriver)(nil)

// type databricksDB struct {
// *sql.DB
// }

// func OpenDB(c driver.Connector) *databricksDB {
// db := sql.OpenDB(c)
// return &databricksDB{db}
// }

// func (db *databricksDB) QueryContextAsync(ctx context.Context, query string, args ...any) (rows *sql.Rows, queryId string, err error) {
// return nil, "", nil
// }

// func (db *databricksDB) ExecContextAsync(ctx context.Context, query string, args ...any) (result sql.Result, queryId string) {
// //go do something
// return nil, ""
// }

// func (db *databricksDB) CancelQuery(ctx context.Context, queryId string) error {
// //go do something
// return nil
// }

// func (db *databricksDB) GetQueryStatus(ctx context.Context, queryId string) error {
// //go do something
// return nil
// }

// func (db *databricksDB) FetchRows(ctx context.Context, queryId string) (rows *sql.Rows, err error) {
// //go do something
// return nil, nil
// }

// func (db *databricksDB) FetchResult(ctx context.Context, queryId string) (rows sql.Result, err error) {
// //go do something
// return nil, nil
// }
30 changes: 20 additions & 10 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/databricks/databricks-sql-go/internal/cli_service"
"github.com/databricks/databricks-sql-go/logger"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
)

// Driver Configurations
Expand Down Expand Up @@ -38,6 +39,10 @@ func (c *Config) ToEndpointURL() string {
var userInfo string
if c.AccessToken != "" {
userInfo = fmt.Sprintf("%s:%s@", "token", url.QueryEscape(c.AccessToken))
} else {
if c.Username != "" {
userInfo = fmt.Sprintf("%s:%s@", c.Username, url.QueryEscape(c.Password))
}
}
endpointUrl := fmt.Sprintf("%s://%s%s:%d%s", c.Protocol, userInfo, c.Host, c.Port, c.HTTPPath)
return endpointUrl
Expand Down Expand Up @@ -76,7 +81,9 @@ type UserConfig struct {
HTTPPath string // from databricks UI
Catalog string
Schema string
AccessToken string // from databricks UI
AccessToken string // from databricks UI
Username string
Password string
MaxRows int // max rows per page
QueryTimeout time.Duration // Timeout passed to server for query processing
UserAgentEntry string
Expand Down Expand Up @@ -110,6 +117,8 @@ func (ucfg UserConfig) DeepCopy() UserConfig {
Catalog: ucfg.Catalog,
Schema: ucfg.Schema,
AccessToken: ucfg.AccessToken,
Username: ucfg.Username,
Password: ucfg.Password,
MaxRows: ucfg.MaxRows,
QueryTimeout: ucfg.QueryTimeout,
UserAgentEntry: ucfg.UserAgentEntry,
Expand All @@ -125,6 +134,9 @@ func (ucfg UserConfig) WithDefaults() UserConfig {
if ucfg.Protocol == "" {
ucfg.Protocol = "https"
}
if ucfg.Port == 0 {
ucfg.Port = 443
}
ucfg.SessionParams = make(map[string]string)
return ucfg
}
Expand Down Expand Up @@ -168,17 +180,15 @@ func ParseDSN(dsn string) (UserConfig, error) {
}
ucfg.Port = port
name := parsedURL.User.Username()
pass, ok := parsedURL.User.Password()
if !ok {
log.Warn().Msg("password not set")
}
if name == "token" {
pass, ok := parsedURL.User.Password()
if ok {
ucfg.AccessToken = pass
} else {
return UserConfig{}, errors.New("invalid DSN: token not set")
}
ucfg.AccessToken = pass
} else {
if name != "" {
return UserConfig{}, errors.New("invalid DSN: basic auth not enabled")
}
ucfg.Username = name
ucfg.Password = pass
}
ucfg.HTTPPath = parsedURL.Path
params := parsedURL.Query()
Expand Down
28 changes: 22 additions & 6 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,27 +223,43 @@ func TestParseConfig(t *testing.T) {
wantURL: "https://token:[email protected]:443",
wantErr: false,
},
{
name: "with basic auth",
args: args{dsn: "jim:[email protected]:443/sql/1.0/endpoints/12346a5b5b0e123a"},
wantCfg: UserConfig{
Protocol: "https",
Host: "example.cloud.databricks.com",
Port: 443,
Username: "jim",
Password: "supersecret2",
MaxRows: 10000,
HTTPPath: "/sql/1.0/endpoints/12346a5b5b0e123a",
SessionParams: make(map[string]string),
},
wantURL: "https://jim:[email protected]:443/sql/1.0/endpoints/12346a5b5b0e123a",
wantErr: false,
},
{
name: "with wrong port",
args: args{dsn: "token:[email protected]:foo/sql/1.0/endpoints/12346a5b5b0e123a?catalog=default&schema=system&timeout=100&maxRows=1000"},
wantCfg: UserConfig{},
wantErr: true,
},
{
name: "missing port",
args: args{dsn: "token:[email protected]?catalog=default&schema=system&timeout=100&maxRows=1000"},
name: "with invalid maxRows",
args: args{dsn: "token:[email protected]:443/sql/1.0/endpoints/12346a5b5b0e123a?catalog=default&schema=system&timeout=100&maxRows=foo"},
wantCfg: UserConfig{},
wantErr: true,
},
{
name: "with wrong username",
args: args{dsn: "jim:[email protected]:443/sql/1.0/endpoints/12346a5b5b0e123a?catalog=default&schema=system&timeout=100&maxRows=1000"},
name: "with invalid timeout",
args: args{dsn: "token:[email protected]:443/sql/1.0/endpoints/12346a5b5b0e123a?catalog=default&schema=system&timeout=foo&maxRows=12"},
wantCfg: UserConfig{},
wantErr: true,
},
{
name: "with token but no secret",
args: args{dsn: "[email protected]:443/sql/1.0/endpoints/12346a5b5b0e123a?catalog=default&schema=system&timeout=100&maxRows=1000"},
name: "missing port",
args: args{dsn: "token:supersecret2@example.cloud.databricks.com?catalog=default&schema=system&timeout=100&maxRows=1000"},
wantCfg: UserConfig{},
wantErr: true,
},
Expand Down