Skip to content

Commit

Permalink
user: Add mysql user db implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
amass01 committed May 30, 2021
1 parent 76d31f7 commit bcd5d46
Show file tree
Hide file tree
Showing 9 changed files with 1,127 additions and 18 deletions.
5 changes: 4 additions & 1 deletion politeiad/backendv2/tstorebe/store/mysql/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/decred/politeia/politeiad/backendv2/tstorebe/store"
"github.com/decred/politeia/util"

// MySQL driver.
_ "github.com/go-sql-driver/mysql"
)

Expand Down Expand Up @@ -278,7 +279,9 @@ func (s *mysql) Close() {
s.db.Close()
}

func New(appDir, host, user, password, dbname string) (*mysql, error) {
// New connects to a mysql instance using the given connection params,
// and returns pointer to the created mysql struct.
func New(host, user, password, dbname string) (*mysql, error) {
// The password is required to derive the encryption key
if password == "" {
return nil, fmt.Errorf("password not provided")
Expand Down
4 changes: 2 additions & 2 deletions politeiad/backendv2/tstorebe/tstore/tstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const (
// store to a leveldb instance.
DBTypeLevelDB = "leveldb"

// DBTypeLevelDB is a config option that sets the backing key-value
// DBTypeMySQL is a config option that sets the backing key-value
// store to a MySQL instance.
DBTypeMySQL = "mysql"

Expand Down Expand Up @@ -227,7 +227,7 @@ func New(appDir, dataDir string, anp *chaincfg.Params, tlogHost, tlogPass, dbTyp
case DBTypeMySQL:
// Example db name: testnet3_unvetted_kv
dbName := fmt.Sprintf("%v_kv", anp.Name)
kvstore, err = mysql.New(appDir, dbHost, dbUser, dbPass, dbName)
kvstore, err = mysql.New(dbHost, dbUser, dbPass, dbName)
if err != nil {
return nil, err
}
Expand Down
61 changes: 48 additions & 13 deletions politeiawww/cmd/politeiawww_dbutil/politeiawww_dbutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/decred/politeia/politeiawww/user"
"github.com/decred/politeia/politeiawww/user/cockroachdb"
"github.com/decred/politeia/politeiawww/user/localdb"
"github.com/decred/politeia/politeiawww/user/mysqldb"
"github.com/decred/politeia/util"
"github.com/google/uuid"
_ "github.com/jinzhu/gorm/dialects/postgres"
Expand Down Expand Up @@ -60,6 +61,7 @@ var (
// Database options
level = flag.Bool("leveldb", false, "")
cockroach = flag.Bool("cockroachdb", false, "")
mysql = flag.Bool("mysqldb", false, "")

// Application options
testnet = flag.Bool("testnet", false, "")
Expand Down Expand Up @@ -593,6 +595,21 @@ func validateCockroachParams() error {
return nil
}

func validateMysqlParams() error {
// Validate host.
_, err := url.Parse(*host)
if err != nil {
return fmt.Errorf("parse host '%v': %v", *host, err)
}

// Ensure encryption key file exists.
if !util.FileExists(*encryptionKey) {
return fmt.Errorf("file not found %v", *encryptionKey)
}

return nil
}

func cmdVerifyIdentities() error {
args := flag.Args()
if len(args) != 1 {
Expand Down Expand Up @@ -736,36 +753,41 @@ func _main() error {
} else {
network = chaincfg.MainNetParams().Name
}
// Validate database selection
if *level && *cockroach {
return fmt.Errorf("database choice cannot be both " +
"-leveldb and -cockroachdb")

// Validate database selection.
switch {
case *mysql && *cockroach, *level && *mysql, *level && *cockroach,
*level && *cockroach && *mysql:
fmt.Println(mysql, cockroach)
return fmt.Errorf("multiple database flags; must use one of the " +
"following: -leveldb, -mysqldb or -cockroachdb")
}

switch {
case *addCredits || *setAdmin || *stubUsers || *resetTotp:
// These commands must be run with -cockroachdb or -leveldb
if !*level && !*cockroach {
// These commands must be run with -cockroachdb, -mysqldb or -leveldb.
if !*level && !*cockroach && !*mysql {
return fmt.Errorf("missing database flag; must use " +
"either -leveldb or -cockroachdb")
"-leveldb, -cockroachdb or -mysqldb")
}
case *dump:
// These commands must be run with -leveldb
// These commands must be run with -leveldb.
if !*level {
return fmt.Errorf("missing database flag; must use " +
"-leveldb with this command")
}
case *verifyIdentities, *setEmail:
// These commands must be run with -cockroachdb
// These commands must be run with either -cockroachdb or
// -mysqldb.
if !*cockroach || *level {
return fmt.Errorf("invalid database flag; must use " +
"-cockroachdb with this command")
"either -mysqldb or -cockroachdb with this command")
}
case *migrate || *createKey:
// These commands must be run without a database flag
if *level || *cockroach {
// These commands must be run without a database flag.
if *level || *cockroach || *mysql {
return fmt.Errorf("unexpected database flag found; " +
"remove database flag -leveldb and -cockroachdb")
"remove database flag -leveldb, -mysqldb and -cockroachdb")
}
}

Expand Down Expand Up @@ -801,6 +823,19 @@ func _main() error {
}
userDB = db
defer userDB.Close()

case *mysql:
err := validateMysqlParams()
if err != nil {
return err
}
db, err := mysqldb.New(*host, network, *encryptionKey)
if err != nil {
return fmt.Errorf("new mysqldb: %v", err)
}
userDB = db
defer userDB.Close()

}

// Run command
Expand Down
40 changes: 38 additions & 2 deletions politeiawww/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ const (
// User database options
userDBLevel = "leveldb"
userDBCockroach = "cockroachdb"
userDBMysql = "mysqldb"

defaultUserDB = userDBLevel
)
Expand Down Expand Up @@ -667,7 +668,7 @@ func loadConfig() (*config.Config, []string, error) {
}

case userDBCockroach:
// Cockroachdb required these settings
// Cockroachdb requires these settings.
switch {
case cfg.DBHost == "":
return nil, nil, fmt.Errorf("dbhost param is required")
Expand Down Expand Up @@ -731,9 +732,44 @@ func loadConfig() (*config.Config, []string, error) {
}
}

case userDBMysql:
// Mysql requires database host setting.
if cfg.DBHost == "" {
return nil, nil, fmt.Errorf("dbhost param is required")
}

// Validate user database host.
_, err = url.Parse(cfg.DBHost)
if err != nil {
return nil, nil, fmt.Errorf("parse dbhost: %v", err)
}

// Validate user database encryption keys.
cfg.EncryptionKey = util.CleanAndExpandPath(cfg.EncryptionKey)
cfg.OldEncryptionKey = util.CleanAndExpandPath(cfg.OldEncryptionKey)

if cfg.EncryptionKey != "" && !util.FileExists(cfg.EncryptionKey) {
return nil, nil, fmt.Errorf("file not found %v", cfg.EncryptionKey)
}

if cfg.OldEncryptionKey != "" {
switch {
case cfg.EncryptionKey == "":
return nil, nil, fmt.Errorf("old encryption key param " +
"cannot be used without encryption key param")

case cfg.EncryptionKey == cfg.OldEncryptionKey:
return nil, nil, fmt.Errorf("old encryption key param " +
"and encryption key param must be different")

case !util.FileExists(cfg.OldEncryptionKey):
return nil, nil, fmt.Errorf("file not found %v", cfg.OldEncryptionKey)
}
}

default:
return nil, nil, fmt.Errorf("invalid userdb '%v'; must "+
"be either leveldb or cockroachdb", cfg.UserDB)
"be leveldb, cockroachdb or mysqldb", cfg.UserDB)
}

// Verify paywall settings
Expand Down
21 changes: 21 additions & 0 deletions politeiawww/user/mysqldb/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package mysqldb

import "github.com/decred/slog"

// log is a logger that is initialized with no output filters. This
// means the package will not perform any logging by default until the caller
// requests it.
var log = slog.Disabled

// DisableLog disables all library log output. Logging output is disabled
// by default until either UseLogger or SetLogWriter are called.
func DisableLog() {
log = slog.Disabled
}

// UseLogger uses a specified Logger to output package logging info.
// This should be used in preference to SetLogWriter if the caller is also
// using slog.
func UseLogger(logger slog.Logger) {
log = logger
}
Loading

0 comments on commit bcd5d46

Please sign in to comment.