package main import ( "flag" "fmt" "os" "path/filepath" ) func main() { if len(os.Args) < 2 { printUsage() os.Exit(1) } sub := os.Args[1] switch sub { case "list": cmdList(os.Args[2:]) case "add": cmdOrgAdd(os.Args[2:]) case "rm": cmdOrgRm(os.Args[2:]) case "domain": cmdDomain(os.Args[2:]) case "user": cmdUser(os.Args[2:]) default: fmt.Fprintf(os.Stderr, "Unknown command: %s\n", sub) printUsage() os.Exit(1) } } func printUsage() { fmt.Fprintf(os.Stderr, `Usage: orgadmin [args] Commands: list List all organizations and their domains add Add a new organization rm Remove an organization domain add Add a domain to an organization domain rm Remove a domain from an organization user add Add a new user user rm Remove a user user list List all users user assign Assign a user to an organization user unassign Remove a user from an organization `) } func cmdList(args []string) { fs := flag.NewFlagSet("list", flag.ExitOnError) dbPath := fs.String("db", filepath.Join(".", "data", "pdf_wizard.db"), "Path to SQLite database") fs.Parse(args) dbConn, err := openDB(*dbPath) if err != nil { fatal("Opening database: %v", err) } defer dbConn.Close() orgs, err := getOrgs(dbConn) if err != nil { fatal("Listing orgs: %v", err) } if len(orgs) == 0 { fmt.Println("No organizations configured.") return } for _, org := range orgs { fmt.Printf("Org #%d: %s\n", org.ID, org.Name) domains, err := getOrgDomains(dbConn, org.ID) if err != nil { fmt.Printf(" (error listing domains: %v)\n", err) continue } if len(domains) == 0 { fmt.Printf(" (no domains)\n") } else { for _, d := range domains { fmt.Printf(" %s\n", d.Domain) } } } } func cmdOrgAdd(args []string) { fs := flag.NewFlagSet("add", flag.ExitOnError) dbPath := fs.String("db", filepath.Join(".", "data", "pdf_wizard.db"), "Path to SQLite database") fs.Parse(args) if fs.NArg() == 0 { fmt.Fprintf(os.Stderr, "Usage: orgadmin add \n") os.Exit(1) } name := fs.Arg(0) dbConn, err := openDB(*dbPath) if err != nil { fatal("Opening database: %v", err) } defer dbConn.Close() org, err := createOrg(dbConn, name) if err != nil { fatal("Creating org: %v", err) } fmt.Printf("Created org #%d: %s\n", org.ID, org.Name) } func cmdOrgRm(args []string) { fs := flag.NewFlagSet("rm", flag.ExitOnError) dbPath := fs.String("db", filepath.Join(".", "data", "pdf_wizard.db"), "Path to SQLite database") fs.Parse(args) if fs.NArg() == 0 { fmt.Fprintf(os.Stderr, "Usage: orgadmin rm \n") os.Exit(1) } name := fs.Arg(0) dbConn, err := openDB(*dbPath) if err != nil { fatal("Opening database: %v", err) } defer dbConn.Close() org, err := getOrgByName(dbConn, name) if err != nil { fatal("Looking up org: %v", err) } if org == nil { fmt.Fprintf(os.Stderr, "Org not found: %s\n", name) os.Exit(1) } if err := deleteOrg(dbConn, org.ID); err != nil { fatal("Deleting org: %v", err) } fmt.Printf("Deleted org #%d: %s\n", org.ID, org.Name) } func cmdDomain(args []string) { if len(args) < 1 { fmt.Fprintf(os.Stderr, "Usage: orgadmin domain ...\n") os.Exit(1) } switch args[0] { case "add": cmdDomainAdd(args[1:]) case "rm": cmdDomainRm(args[1:]) default: fmt.Fprintf(os.Stderr, "Unknown domain subcommand: %s\n", args[0]) os.Exit(1) } } func cmdDomainAdd(args []string) { fs := flag.NewFlagSet("domain-add", flag.ExitOnError) dbPath := fs.String("db", filepath.Join(".", "data", "pdf_wizard.db"), "Path to SQLite database") fs.Parse(args) if fs.NArg() < 2 { fmt.Fprintf(os.Stderr, "Usage: orgadmin domain add \n") os.Exit(1) } orgName := fs.Arg(0) domain := fs.Arg(1) dbConn, err := openDB(*dbPath) if err != nil { fatal("Opening database: %v", err) } defer dbConn.Close() org, err := getOrgByName(dbConn, orgName) if err != nil { fatal("Looking up org: %v", err) } if org == nil { fmt.Fprintf(os.Stderr, "Org not found: %s\n", orgName) os.Exit(1) } _, err = addOrgDomain(dbConn, org.ID, domain) if err != nil { fatal("Adding domain: %v", err) } fmt.Printf("Added domain %s to org #%d (%s)\n", domain, org.ID, org.Name) } func cmdDomainRm(args []string) { fs := flag.NewFlagSet("domain-rm", flag.ExitOnError) dbPath := fs.String("db", filepath.Join(".", "data", "pdf_wizard.db"), "Path to SQLite database") fs.Parse(args) if fs.NArg() < 2 { fmt.Fprintf(os.Stderr, "Usage: orgadmin domain rm \n") os.Exit(1) } orgName := fs.Arg(0) domain := fs.Arg(1) dbConn, err := openDB(*dbPath) if err != nil { fatal("Opening database: %v", err) } defer dbConn.Close() org, err := getOrgByName(dbConn, orgName) if err != nil { fatal("Looking up org: %v", err) } if org == nil { fmt.Fprintf(os.Stderr, "Org not found: %s\n", orgName) os.Exit(1) } if err := deleteOrgDomain(dbConn, org.ID, domain); err != nil { fatal("Deleting domain: %v", err) } fmt.Printf("Removed domain %s from org #%d (%s)\n", domain, org.ID, org.Name) } func cmdUser(args []string) { if len(args) < 1 { fmt.Fprintf(os.Stderr, "Usage: orgadmin user ...\n") os.Exit(1) } switch args[0] { case "add": cmdUserAdd(args[1:]) case "rm": cmdUserRm(args[1:]) case "list": cmdUserList(args[1:]) case "assign": cmdUserAssign(args[1:]) case "unassign": cmdUserUnassign(args[1:]) default: fmt.Fprintf(os.Stderr, "Unknown user subcommand: %s\n", args[0]) os.Exit(1) } } func cmdUserAdd(args []string) { fs := flag.NewFlagSet("user-add", flag.ExitOnError) dbPath := fs.String("db", filepath.Join(".", "data", "pdf_wizard.db"), "Path to SQLite database") fs.Parse(args) if fs.NArg() < 2 { fmt.Fprintf(os.Stderr, "Usage: orgadmin user add \n") os.Exit(1) } username := fs.Arg(0) password := fs.Arg(1) dbConn, err := openDB(*dbPath) if err != nil { fatal("Opening database: %v", err) } defer dbConn.Close() user, err := createUser(dbConn, username, password) if err != nil { fatal("Creating user: %v", err) } fmt.Printf("Created user #%d: %s\n", user.ID, user.Username) } func cmdUserRm(args []string) { fs := flag.NewFlagSet("user-rm", flag.ExitOnError) dbPath := fs.String("db", filepath.Join(".", "data", "pdf_wizard.db"), "Path to SQLite database") fs.Parse(args) if fs.NArg() < 1 { fmt.Fprintf(os.Stderr, "Usage: orgadmin user rm \n") os.Exit(1) } username := fs.Arg(0) dbConn, err := openDB(*dbPath) if err != nil { fatal("Opening database: %v", err) } defer dbConn.Close() user, err := getUserByName(dbConn, username) if err != nil { fatal("Looking up user: %v", err) } if user == nil { fmt.Fprintf(os.Stderr, "User not found: %s\n", username) os.Exit(1) } if err := deleteUser(dbConn, user.ID); err != nil { fatal("Deleting user: %v", err) } fmt.Printf("Deleted user #%d: %s\n", user.ID, user.Username) } func cmdUserList(args []string) { fs := flag.NewFlagSet("user-list", flag.ExitOnError) dbPath := fs.String("db", filepath.Join(".", "data", "pdf_wizard.db"), "Path to SQLite database") fs.Parse(args) dbConn, err := openDB(*dbPath) if err != nil { fatal("Opening database: %v", err) } defer dbConn.Close() users, err := getUsers(dbConn) if err != nil { fatal("Listing users: %v", err) } if len(users) == 0 { fmt.Println("No users configured.") return } for _, user := range users { fmt.Printf("User #%d: %s\n", user.ID, user.Username) orgs, err := getUserOrgs(dbConn, user.ID) if err != nil { fmt.Printf(" (error listing orgs: %v)\n", err) continue } if len(orgs) == 0 { fmt.Printf(" (no orgs)\n") } else { for _, o := range orgs { fmt.Printf(" Org #%d: %s\n", o.ID, o.Name) } } } } func cmdUserAssign(args []string) { fs := flag.NewFlagSet("user-assign", flag.ExitOnError) dbPath := fs.String("db", filepath.Join(".", "data", "pdf_wizard.db"), "Path to SQLite database") fs.Parse(args) if fs.NArg() < 2 { fmt.Fprintf(os.Stderr, "Usage: orgadmin user assign \n") os.Exit(1) } username := fs.Arg(0) orgName := fs.Arg(1) dbConn, err := openDB(*dbPath) if err != nil { fatal("Opening database: %v", err) } defer dbConn.Close() user, err := getUserByName(dbConn, username) if err != nil { fatal("Looking up user: %v", err) } if user == nil { fmt.Fprintf(os.Stderr, "User not found: %s\n", username) os.Exit(1) } org, err := getOrgByName(dbConn, orgName) if err != nil { fatal("Looking up org: %v", err) } if org == nil { fmt.Fprintf(os.Stderr, "Org not found: %s\n", orgName) os.Exit(1) } if err := assignUserToOrg(dbConn, user.ID, org.ID); err != nil { fatal("Assigning user to org: %v", err) } fmt.Printf("Assigned user #%d (%s) to org #%d (%s)\n", user.ID, user.Username, org.ID, org.Name) } func cmdUserUnassign(args []string) { fs := flag.NewFlagSet("user-unassign", flag.ExitOnError) dbPath := fs.String("db", filepath.Join(".", "data", "pdf_wizard.db"), "Path to SQLite database") fs.Parse(args) if fs.NArg() < 2 { fmt.Fprintf(os.Stderr, "Usage: orgadmin user unassign \n") os.Exit(1) } username := fs.Arg(0) orgName := fs.Arg(1) dbConn, err := openDB(*dbPath) if err != nil { fatal("Opening database: %v", err) } defer dbConn.Close() user, err := getUserByName(dbConn, username) if err != nil { fatal("Looking up user: %v", err) } if user == nil { fmt.Fprintf(os.Stderr, "User not found: %s\n", username) os.Exit(1) } org, err := getOrgByName(dbConn, orgName) if err != nil { fatal("Looking up org: %v", err) } if org == nil { fmt.Fprintf(os.Stderr, "Org not found: %s\n", orgName) os.Exit(1) } if err := removeUserFromOrg(dbConn, user.ID, org.ID); err != nil { fatal("Removing user from org: %v", err) } fmt.Printf("Removed user #%d (%s) from org #%d (%s)\n", user.ID, user.Username, org.ID, org.Name) } func fatal(format string, args ...interface{}) { fmt.Fprintf(os.Stderr, "Error: "+format+"\n", args...) os.Exit(1) }