123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- package main
- import (
- "bufio"
- "flag"
- "fmt"
- "io"
- "os"
- "strings"
- paneldb "git.lattuga.net/boyska/feedpanel/db"
- "github.com/go-pg/pg"
- "github.com/howeyc/gopass"
- )
- type commandFunc func([]string) error
- var globalOptions struct {
- verbose bool
- pgOptions pg.Options
- }
- var cmdMap map[string]commandFunc
- func init() {
- cmdMap = map[string]commandFunc{
- "batch": cmdBatch,
- "setup": cmdSetup,
- "adduser": cmdAddUser,
- "listusers": cmdListUsers,
- }
- }
- func getDB() paneldb.DB {
- pgdb := pg.Connect(&globalOptions.pgOptions)
- db := paneldb.DB{PgDB: pgdb}
- return db
- }
- func cmdSetup(args []string) error {
- db := getDB()
- err := db.Setup()
- if err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- if globalOptions.verbose {
- fmt.Println("Tables created")
- }
- os.Exit(0)
- return nil
- }
- func askPassword() (string, error) {
- fmt.Print("New password: ")
- pass, err := gopass.GetPasswd()
- if err != nil {
- return "", err
- }
- fmt.Print("Retype new password: ")
- pass2, err := gopass.GetPasswd()
- if err != nil {
- return "", err
- }
- if string(pass) != string(pass2) {
- return "", fmt.Errorf("Passwords differ")
- }
- return string(pass), nil
- }
- func cmdAddUser(args []string) error {
- flagset := flag.NewFlagSet(args[0], flag.ExitOnError)
- password := flagset.String("password", "", "set password from command line; INSECURE!")
- flagset.Parse(args[1:])
- if len(flagset.Args()) < 2 {
- fmt.Fprintf(os.Stderr, "Usage: %s [options] USER EMAIL\n", args[0])
- flagset.PrintDefaults()
- os.Exit(2)
- }
- user := flagset.Args()[0]
- email := flagset.Args()[1]
- if *password == "" {
- pass, err := askPassword()
- if err != nil {
- fmt.Fprintln(os.Stderr, "Error:", err)
- os.Exit(1)
- }
- *password = string(pass)
- }
- db := getDB()
- err := db.UserAdd(user, email, *password)
- if err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- if globalOptions.verbose {
- fmt.Printf("Success: user %s added\n", user)
- }
- os.Exit(0)
- return nil
- }
- func composeListUserOutput(user paneldb.User, usernameFlag, emailFlag, dateCreatedFlag bool) {
- var row string
- if usernameFlag {
- row += user.UserName
- if emailFlag || dateCreatedFlag {
- row += "\t"
- }
- }
- if emailFlag {
- row += user.Email
- if dateCreatedFlag {
- row += "\t"
- }
- }
- if dateCreatedFlag {
- row += user.DateCreated
- }
- fmt.Fprintln(os.Stdout, row)
- }
- func cmdListUsers(args []string) error {
- flagset := flag.NewFlagSet(args[0], flag.ExitOnError)
- usernameFlag := flagset.Bool("no-nick", true, "skip printing usernames")
- emailFlag := flagset.Bool("no-email", true, "skip printing emails")
- dateCreatedFlag := flagset.Bool("created", false, "print date of user creation")
- headerFlag := flagset.Bool("no-header", false, "skip printing the header")
- flagset.Parse(args[1:])
- db := getDB()
- users, err := db.GetUsers()
- if err != nil {
- fmt.Fprintln(os.Stderr, "Error:", err)
- os.Exit(1)
- }
- // Printing the header
- if !*headerFlag {
- header := paneldb.User{
- UserName: "username",
- Email: "email",
- DateCreated: "date_created",
- }
- separator := paneldb.User{
- UserName: "--------",
- Email: "-----",
- DateCreated: "------------",
- }
- composeListUserOutput(header, *usernameFlag, *emailFlag, *dateCreatedFlag)
- composeListUserOutput(separator, *usernameFlag, *emailFlag, *dateCreatedFlag)
- }
- // Printing the user list
- for _, user := range users {
- composeListUserOutput(user, *usernameFlag, *emailFlag, *dateCreatedFlag)
- }
- return nil
- }
- func usage(w io.Writer) {
- fmt.Fprintf(w, "Usage: %s SUBCOMMAND [command args...]\n", os.Args[0])
- fmt.Fprintln(w, "\nSubcommands:")
- for cmdName, _ := range cmdMap {
- fmt.Fprintln(w, " -", cmdName)
- }
- }
- func runLine(args []string) {
- cmdName := args[0]
- cmdFunc, ok := cmdMap[cmdName]
- if !ok {
- fmt.Fprintf(os.Stderr, "Invalid command `%s`\n", cmdName)
- usage(os.Stderr)
- os.Exit(2)
- }
- err := cmdFunc(args)
- if err != nil {
- fmt.Fprintln(os.Stderr, "Error")
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- }
- func cmdBatch(args []string) error {
- scanner := bufio.NewScanner(os.Stdin)
- for scanner.Scan() {
- line := scanner.Text()
- runLine(strings.Split(line, " "))
- }
- if scanner.Err() != nil {
- fmt.Fprintln(os.Stderr, "Error reading stdin:", scanner.Err())
- os.Exit(1)
- }
- os.Exit(0)
- return nil
- }
- func main() {
- flag.StringVar(&globalOptions.pgOptions.User, "db-user", "panel", "The user to connect to database to")
- flag.StringVar(&globalOptions.pgOptions.Password, "db-pass", "", "database password")
- flag.StringVar(&globalOptions.pgOptions.Database, "db-name", "feeds", "database name")
- flag.StringVar(&globalOptions.pgOptions.Addr, "db-addr", "127.0.0.1:5432", "database network address")
- flag.BoolVar(&globalOptions.verbose, "verbose", false, "verbose output")
- flag.Parse()
- if len(flag.Args()) < 1 {
- fmt.Fprintln(os.Stderr, "Not enough arguments!")
- usage(os.Stderr)
- os.Exit(2)
- }
- runLine(flag.Args())
- os.Exit(0)
- }
|