privilege file argument

This commit is contained in:
James Cor
2022-06-07 16:32:42 -07:00
parent 00b6d19dd2
commit 91a4bfbe7b
8 changed files with 86 additions and 149 deletions

View File

@@ -25,7 +25,6 @@ import (
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/analyzer"
"github.com/dolthub/go-mysql-server/sql/information_schema"
"github.com/dolthub/go-mysql-server/sql/mysql_db"
"github.com/dolthub/vitess/go/vt/sqlparser"
"github.com/dolthub/dolt/go/cmd/dolt/cli"
@@ -49,13 +48,12 @@ type SqlEngine struct {
}
type SqlEngineConfig struct {
InitialDb string
IsReadOnly bool
MySQLDbFilePath string
PrivFilePath string
ServerUser string
ServerPass string
Autocommit bool
InitialDb string
IsReadOnly bool
PrivFilePath string
ServerUser string
ServerPass string
Autocommit bool
}
// NewSqlEngine returns a SqlEngine
@@ -85,38 +83,20 @@ func NewSqlEngine(
b := env.GetDefaultInitBranch(mrEnv.Config())
pro := dsqle.NewDoltDatabaseProvider(b, mrEnv.FileSystem(), all...)
// Set mysql.db file path from server
mysql_file_handler.SetMySQLDbFilePath(config.MySQLDbFilePath)
// Load in MySQL Db from file, if it exists
// Load in privileges from file, if it exists
mysql_file_handler.SetPrivilegeFilePath(config.PrivFilePath)
data, err := mysql_file_handler.LoadData()
if err != nil {
return nil, err
}
// Use privilege file iff mysql.db file DNE
var users []*mysql_db.User
var roles []*mysql_db.RoleEdge
// Create temporary users if no privileges in config
var tempUsers []gms.TemporaryUser
if len(data) == 0 {
// Set privilege file path from server
if config.PrivFilePath != "" {
mysql_file_handler.SetPrivilegeFilePath(config.PrivFilePath)
}
// Load privileges from privilege file
users, roles, err = mysql_file_handler.LoadPrivileges()
if err != nil {
return nil, err
}
// Create temporary users if no privileges in config
if len(users) == 0 && len(config.ServerUser) > 0 {
tempUsers = append(tempUsers, gms.TemporaryUser{
Username: config.ServerUser,
Password: config.ServerPass,
})
}
if len(data) == 0 && len(config.ServerUser) > 0 {
tempUsers = append(tempUsers, gms.TemporaryUser{
Username: config.ServerUser,
Password: config.ServerPass,
})
}
// Set up engine
@@ -125,12 +105,7 @@ func NewSqlEngine(
if err = engine.Analyzer.Catalog.MySQLDb.LoadData(sql.NewEmptyContext(), data); err != nil {
return nil, err
}
// Load Privilege data iff mysql db didn't exist
if len(data) == 0 {
if err = engine.Analyzer.Catalog.MySQLDb.LoadPrivilegeData(sql.NewEmptyContext(), users, roles); err != nil {
return nil, err
}
}
// Set persist callbacks
engine.Analyzer.Catalog.MySQLDb.SetPersistCallback(mysql_file_handler.SaveData)

View File

@@ -17,6 +17,7 @@ package commands
import (
"context"
"fmt"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/mysql_file_handler"
"io"
"os"
"os/signal"
@@ -82,17 +83,18 @@ By default this command uses the dolt database in the current working directory,
}
const (
QueryFlag = "query"
FormatFlag = "result-format"
saveFlag = "save"
executeFlag = "execute"
listSavedFlag = "list-saved"
messageFlag = "message"
BatchFlag = "batch"
multiDBDirFlag = "multi-db-dir"
continueFlag = "continue"
fileInputFlag = "file"
welcomeMsg = `# Welcome to the DoltSQL shell.
QueryFlag = "query"
FormatFlag = "result-format"
saveFlag = "save"
executeFlag = "execute"
listSavedFlag = "list-saved"
messageFlag = "message"
BatchFlag = "batch"
multiDBDirFlag = "multi-db-dir"
continueFlag = "continue"
fileInputFlag = "file"
privilegeFilePathFlag = "privilege-file"
welcomeMsg = `# Welcome to the DoltSQL shell.
# Statements must be terminated with ';'.
# "exit" or "quit" (or Ctrl-D) to exit.`
)
@@ -143,6 +145,7 @@ func (cmd SqlCmd) ArgParser() *argparser.ArgParser {
ap.SupportsString(multiDBDirFlag, "", "directory", "Defines a directory whose subdirectories should all be dolt data repositories accessible as independent databases within ")
ap.SupportsFlag(continueFlag, "c", "continue running queries on an error. Used for batch mode only.")
ap.SupportsString(fileInputFlag, "", "input file", "Execute statements from the file given")
ap.SupportsString(privilegeFilePathFlag, "", "Privilege File", "Points to the file that privileges will be loaded from, in addition to being overwritten when privileges have been modified.")
return ap
}
@@ -172,6 +175,9 @@ func (cmd SqlCmd) Exec(ctx context.Context, commandStr string, args []string, dE
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
}
privsFp, _ := apr.GetValue(privilegeFilePathFlag)
mysql_file_handler.SetPrivilegeFilePath(privsFp)
// We need a username and password for many SQL commands, so set defaults if they don't exist
dEnv.Config.SetFailsafes(env.DefaultFailsafeConfig)
@@ -378,13 +384,12 @@ func execShell(
initialDb string,
) errhand.VerboseError {
config := &engine.SqlEngineConfig{
InitialDb: initialDb,
IsReadOnly: false,
MySQLDbFilePath: "",
PrivFilePath: "",
ServerUser: "root",
ServerPass: "",
Autocommit: true,
InitialDb: initialDb,
IsReadOnly: false,
PrivFilePath: "",
ServerUser: "root",
ServerPass: "",
Autocommit: true,
}
se, err := engine.NewSqlEngine(
ctx,
@@ -413,13 +418,12 @@ func execBatch(
initialDb string,
) errhand.VerboseError {
config := &engine.SqlEngineConfig{
InitialDb: initialDb,
IsReadOnly: false,
MySQLDbFilePath: "",
PrivFilePath: "",
ServerUser: "root",
ServerPass: "",
Autocommit: true,
InitialDb: initialDb,
IsReadOnly: false,
PrivFilePath: "",
ServerUser: "root",
ServerPass: "",
Autocommit: true,
}
se, err := engine.NewSqlEngine(
ctx,
@@ -465,13 +469,12 @@ func execMultiStatements(
initialDb string,
) errhand.VerboseError {
config := &engine.SqlEngineConfig{
InitialDb: initialDb,
IsReadOnly: false,
MySQLDbFilePath: "",
PrivFilePath: "",
ServerUser: "root",
ServerPass: "",
Autocommit: true,
InitialDb: initialDb,
IsReadOnly: false,
PrivFilePath: "",
ServerUser: "root",
ServerPass: "",
Autocommit: true,
}
se, err := engine.NewSqlEngine(
ctx,
@@ -504,13 +507,12 @@ func execQuery(
initialDb string,
) errhand.VerboseError {
config := &engine.SqlEngineConfig{
InitialDb: initialDb,
IsReadOnly: false,
MySQLDbFilePath: "",
PrivFilePath: "",
ServerUser: "root",
ServerPass: "",
Autocommit: true,
InitialDb: initialDb,
IsReadOnly: false,
PrivFilePath: "",
ServerUser: "root",
ServerPass: "",
Autocommit: true,
}
se, err := engine.NewSqlEngine(
ctx,

View File

@@ -167,13 +167,12 @@ func Serve(
// Create SQL Engine with users
config := &engine.SqlEngineConfig{
InitialDb: "",
IsReadOnly: isReadOnly,
MySQLDbFilePath: serverConfig.MySQLDbFilePath(),
PrivFilePath: serverConfig.PrivilegeFilePath(),
ServerUser: serverConfig.User(),
ServerPass: serverConfig.Password(),
Autocommit: serverConfig.AutoCommit(),
InitialDb: "",
IsReadOnly: isReadOnly,
PrivFilePath: serverConfig.PrivilegeFilePath(),
ServerUser: serverConfig.User(),
ServerPass: serverConfig.Password(),
Autocommit: serverConfig.AutoCommit(),
}
sqlEngine, err := engine.NewSqlEngine(
ctx,

View File

@@ -49,8 +49,6 @@ const (
defaultDataDir = "."
defaultMetricsHost = ""
defaultMetricsPort = -1
defaultMySQLDbFilePath = "./.dolt/mysql.db"
defaultPrivilegeFilePath = "privs.json"
)
const (
@@ -127,8 +125,6 @@ type ServerConfig interface {
// PrivilegeFilePath returns the path to the file which contains all needed privilege information in the form of a
// JSON string.
PrivilegeFilePath() string
// MySQLDbFilePath returns the path to the file which contains the information for a MySQL db.
MySQLDbFilePath() string
}
type commandLineServerConfig struct {
@@ -149,7 +145,6 @@ type commandLineServerConfig struct {
requireSecureTransport bool
persistenceBehavior string
privilegeFilePath string
mysqlDbFilePath string
}
var _ ServerConfig = (*commandLineServerConfig)(nil)
@@ -246,10 +241,6 @@ func (cfg *commandLineServerConfig) PrivilegeFilePath() string {
return cfg.privilegeFilePath
}
func (cfg *commandLineServerConfig) MySQLDbFilePath() string {
return cfg.mysqlDbFilePath
}
// DatabaseNamesAndPaths returns an array of env.EnvNameAndPathObjects corresponding to the databases to be loaded in
// a multiple db configuration. If nil is returned the server will look for a database in the current directory and
// give it a name automatically.
@@ -351,8 +342,6 @@ func DefaultServerConfig() *commandLineServerConfig {
queryParallelism: defaultQueryParallelism,
persistenceBehavior: defaultPersistenceBahavior,
dataDir: defaultDataDir,
privilegeFilePath: defaultPrivilegeFilePath,
mysqlDbFilePath: defaultMySQLDbFilePath,
}
}

View File

@@ -118,7 +118,6 @@ type YAMLConfig struct {
DataDirStr *string `yaml:"data_dir"`
MetricsConfig MetricsYAMLConfig `yaml:"metrics"`
PrivilegeFile *string `yaml:"privilege_file"`
MySQLDbFile *string `yaml:"mysql_db_file"`
}
var _ ServerConfig = YAMLConfig{}
@@ -325,13 +324,6 @@ func (cfg YAMLConfig) PrivilegeFilePath() string {
return ""
}
func (cfg YAMLConfig) MySQLDbFilePath() string {
if cfg.MySQLDbFile != nil {
return *cfg.MySQLDbFile
}
return ""
}
// QueryParallelism returns the parallelism that should be used by the go-mysql-server analyzer
func (cfg YAMLConfig) QueryParallelism() int {
if cfg.PerformanceConfig.QueryParallelism == nil {

View File

@@ -52,13 +52,12 @@ func NewSqlEngineReader(ctx context.Context, dEnv *env.DoltEnv, tableName string
})
config := &engine.SqlEngineConfig{
InitialDb: dbName,
IsReadOnly: false,
MySQLDbFilePath: "",
PrivFilePath: "",
ServerUser: "root",
ServerPass: "",
Autocommit: true,
InitialDb: dbName,
IsReadOnly: false,
PrivFilePath: "",
ServerUser: "root",
ServerPass: "",
Autocommit: true,
}
se, err := engine.NewSqlEngine(
ctx,

View File

@@ -79,13 +79,12 @@ func NewSqlEngineTableWriter(ctx context.Context, dEnv *env.DoltEnv, createTable
// Simplest path would have our import path be a layer over load data
config := &engine.SqlEngineConfig{
InitialDb: dbName,
IsReadOnly: false,
MySQLDbFilePath: "",
PrivFilePath: "",
ServerUser: "root",
ServerPass: "",
Autocommit: true,
InitialDb: dbName,
IsReadOnly: false,
PrivFilePath: "",
ServerUser: "root",
ServerPass: "",
Autocommit: true,
}
se, err := engine.NewSqlEngine(
ctx,

View File

@@ -28,7 +28,6 @@ import (
const defaultMySQLFilePath = "./.dolt/mysql.db"
var fileMutex = &sync.Mutex{}
var mysqlDbFilePath string
var privsFilePath string
// privDataJson is used to marshal/unmarshal the privilege data to/from JSON.
@@ -47,32 +46,17 @@ func SetPrivilegeFilePath(fp string) {
fileMutex.Lock()
defer fileMutex.Unlock()
// Panic if some strange unknown failure occurs (not just that it doesn't exist)
// Create file if it does not exist, panic if something goes wrong
_, err := os.Stat(fp)
if err != nil && !errors.Is(err, os.ErrNotExist) {
if err != nil && errors.Is(err, os.ErrNotExist) {
err = ioutil.WriteFile(fp, []byte{}, 0644)
}
if err != nil {
panic(err)
}
privsFilePath = fp
}
// SetMySQLDbFilePath sets the file path that will be used for saving and loading MySQL Db tables.
func SetMySQLDbFilePath(fp string) {
// look for default mysql db file path if none specified
if len(fp) == 0 {
fp = defaultMySQLFilePath
}
fileMutex.Lock()
defer fileMutex.Unlock()
// Panic if some strange unknown failure occurs (not just that it doesn't exist)
_, err := os.Stat(fp)
if err != nil && !errors.Is(err, os.ErrNotExist) {
panic(err)
}
mysqlDbFilePath = fp
}
// LoadPrivileges reads the file previously set on the file path and returns the privileges and role connections. If the
// file path has not been set, returns an empty slice for both, but does not error. This is so that the logic path can
// retain the calls regardless of whether a user wants privileges to be loaded or persisted.
@@ -103,16 +87,16 @@ func LoadPrivileges() ([]*mysql_db.User, []*mysql_db.RoleEdge, error) {
// LoadData reads the mysql.db file, returns nil if empty or not found
func LoadData() ([]byte, error) {
// use default mysql db file path if none specified
if len(mysqlDbFilePath) == 0 {
mysqlDbFilePath = defaultMySQLFilePath
// do nothing if no filepath specified
if len(privsFilePath) == 0 {
return nil, nil
}
fileMutex.Lock()
defer fileMutex.Unlock()
// read from mysqldbFilePath, error if something other than not-exists
buf, err := ioutil.ReadFile(mysqlDbFilePath)
buf, err := ioutil.ReadFile(privsFilePath)
if err != nil && !errors.Is(err, os.ErrNotExist) {
return nil, err
}
@@ -130,11 +114,9 @@ func SaveData(ctx *sql.Context, data []byte) error {
fileMutex.Lock()
defer fileMutex.Unlock()
// use default if empty filepath
if len(mysqlDbFilePath) == 0 {
mysqlDbFilePath = defaultMySQLFilePath
if len(privsFilePath) == 0 {
return errors.New("no privilege file specified, will not save any new users or grants")
}
// should create file if it doesn't exist
return ioutil.WriteFile(mysqlDbFilePath, data, 0777)
return ioutil.WriteFile(privsFilePath, data, 0777)
}