forked from pathwar/pathwar
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add 'sql adduser --email [...]' cli command + refactor cobra
- Loading branch information
Showing
10 changed files
with
318 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package cli | ||
|
||
import ( | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/pflag" | ||
) | ||
|
||
type Command interface { | ||
CobraCommand(Commands) *cobra.Command | ||
|
||
LoadDefaultOptions() error | ||
|
||
ParseFlags(*pflag.FlagSet) | ||
} | ||
|
||
type Commands map[string]Command |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package server | ||
|
||
import ( | ||
"encoding/json" | ||
|
||
"github.com/spf13/cobra" | ||
"github.com/spf13/pflag" | ||
"github.com/spf13/viper" | ||
"go.uber.org/zap" | ||
|
||
"pathwar.pw/pkg/cli" | ||
"pathwar.pw/sql" | ||
) | ||
|
||
type serverOptions struct { | ||
sql sql.Options | ||
|
||
GRPCBind string | ||
HTTPBind string | ||
JWTKey string | ||
WithReflection bool | ||
} | ||
|
||
func (opts serverOptions) String() string { | ||
out, _ := json.Marshal(opts) | ||
return string(out) | ||
} | ||
|
||
func Commands() cli.Commands { | ||
return cli.Commands{ | ||
"server": &serverCommand{}, | ||
} | ||
} | ||
|
||
type serverCommand struct{ opts serverOptions } | ||
|
||
func (cmd *serverCommand) LoadDefaultOptions() error { return viper.Unmarshal(&cmd.opts) } | ||
func (cmd *serverCommand) ParseFlags(flags *pflag.FlagSet) { | ||
flags.StringVar(&cmd.opts.GRPCBind, "grpc-bind", ":9111", "gRPC server address") | ||
flags.StringVar(&cmd.opts.HTTPBind, "http-bind", ":8000", "HTTP server address") | ||
flags.StringVar(&cmd.opts.JWTKey, "jwt-key", "", "JWT secure key") | ||
flags.BoolVarP(&cmd.opts.WithReflection, "grpc-reflection", "", false, "enable gRPC reflection") | ||
if err := viper.BindPFlags(flags); err != nil { | ||
zap.L().Warn("failed to bind viper flags", zap.Error(err)) | ||
} | ||
} | ||
func (cmd *serverCommand) CobraCommand(commands cli.Commands) *cobra.Command { | ||
cc := &cobra.Command{ | ||
Use: "server", | ||
RunE: func(_ *cobra.Command, args []string) error { | ||
opts := cmd.opts | ||
opts.sql = sql.GetOptions(commands) | ||
return server(&opts) | ||
}, | ||
} | ||
cmd.ParseFlags(cc.Flags()) | ||
commands["sql"].ParseFlags(cc.Flags()) | ||
return cc | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package sql | ||
|
||
import ( | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/pflag" | ||
"github.com/spf13/viper" | ||
"go.uber.org/zap" | ||
"pathwar.pw/pkg/cli" | ||
) | ||
|
||
type Options struct { | ||
Path string `mapstructure:"path"` | ||
} | ||
|
||
func Commands() cli.Commands { | ||
return cli.Commands{ | ||
"sql": &sqlCommand{}, | ||
"sql dump": &dumpCommand{}, | ||
"sql adduser": &adduserCommand{}, | ||
} | ||
} | ||
|
||
func GetOptions(commands cli.Commands) Options { | ||
return commands["sql"].(*sqlCommand).opts | ||
} | ||
|
||
type sqlCommand struct{ opts Options } | ||
|
||
func (cmd *sqlCommand) LoadDefaultOptions() error { return viper.Unmarshal(&cmd.opts) } | ||
func (cmd *sqlCommand) ParseFlags(flags *pflag.FlagSet) { | ||
flags.StringVarP(&cmd.opts.Path, "sql-path", "", "/tmp/pathwar.db", "SQL db path") | ||
if err := viper.BindPFlags(flags); err != nil { | ||
zap.L().Warn("failed to bind viper flags", zap.Error(err)) | ||
} | ||
} | ||
func (cmd *sqlCommand) CobraCommand(commands cli.Commands) *cobra.Command { | ||
command := &cobra.Command{ | ||
Use: "sql", | ||
} | ||
command.AddCommand(commands["sql dump"].CobraCommand(commands)) | ||
command.AddCommand(commands["sql adduser"].CobraCommand(commands)) | ||
return command | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package sql | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/spf13/cobra" | ||
"github.com/spf13/pflag" | ||
"github.com/spf13/viper" | ||
"go.uber.org/zap" | ||
"pathwar.pw/entity" | ||
"pathwar.pw/pkg/cli" | ||
) | ||
|
||
type adduserOptions struct { | ||
sql Options `mapstructure:"sql"` | ||
|
||
email string `mapstructure:"email"` | ||
username string `mapstructure:"username"` | ||
password string `mapstructure:"password"` | ||
} | ||
|
||
type adduserCommand struct{ opts adduserOptions } | ||
|
||
func (cmd *adduserCommand) CobraCommand(commands cli.Commands) *cobra.Command { | ||
cc := &cobra.Command{ | ||
Use: "adduser", | ||
Args: func(_ *cobra.Command, args []string) error { | ||
if cmd.opts.email == "" { | ||
return errors.New("--email is mandatory") | ||
} | ||
return nil | ||
}, | ||
RunE: func(_ *cobra.Command, args []string) error { | ||
opts := cmd.opts | ||
opts.sql = GetOptions(commands) | ||
return runAdduser(opts) | ||
}, | ||
} | ||
cmd.ParseFlags(cc.Flags()) | ||
commands["sql"].ParseFlags(cc.Flags()) | ||
return cc | ||
} | ||
func (cmd *adduserCommand) LoadDefaultOptions() error { return viper.Unmarshal(&cmd.opts) } | ||
func (cmd *adduserCommand) ParseFlags(flags *pflag.FlagSet) { | ||
flags.StringVarP(&cmd.opts.email, "email", "", "", "valid email address") | ||
flags.StringVarP(&cmd.opts.username, "username", "", "", "random value if empty") | ||
flags.StringVarP(&cmd.opts.password, "password", "", "", "random value if empty") | ||
if err := viper.BindPFlags(flags); err != nil { | ||
zap.L().Warn("failed to bind viper flags", zap.Error(err)) | ||
} | ||
} | ||
|
||
func runAdduser(opts adduserOptions) error { | ||
db, err := FromOpts(&opts.sql) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
user := entity.User{ | ||
Email: opts.email, | ||
Username: opts.username, | ||
PasswordSalt: "FIXME: randomize", | ||
} | ||
user.PasswordHash = "FIXME: generate" | ||
|
||
// FIXME: randomize username, password if empty | ||
// FIXME: verify email address validity | ||
// FIXME: verify email address spam/blacklist | ||
// FIXME: user.Validate() | ||
|
||
if err := db.Create(&user).Error; err != nil { | ||
return err | ||
} | ||
|
||
out, err := json.MarshalIndent(user, "", " ") | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Println(string(out)) | ||
|
||
return nil | ||
} |
Oops, something went wrong.