@@ -2,10 +2,13 @@ package main | |||||
import ( | import ( | ||||
"fmt" | "fmt" | ||||
"io/ioutil" | |||||
"os" | "os" | ||||
"path/filepath" | "path/filepath" | ||||
"strings" | "strings" | ||||
"text/tabwriter" | |||||
"github.com/hashicorp/go-multierror" | |||||
"github.com/writeas/writeas-cli/api" | "github.com/writeas/writeas-cli/api" | ||||
"github.com/writeas/writeas-cli/commands" | "github.com/writeas/writeas-cli/commands" | ||||
"github.com/writeas/writeas-cli/config" | "github.com/writeas/writeas-cli/config" | ||||
@@ -196,3 +199,78 @@ func cmdLogOut(c *cli.Context) error { | |||||
return nil | return nil | ||||
} | } | ||||
func cmdAccounts(c *cli.Context) error { | |||||
// get user config dir | |||||
userDir := config.UserDataDir(c.App.ExtraInfo()["configDir"]) | |||||
// load defaults | |||||
cfg, err := config.LoadConfig(userDir) | |||||
if err != nil { | |||||
return cli.NewExitError("Could not load default user configuration", 1) | |||||
} | |||||
defaultUser := cfg.Default.User | |||||
defaultHost := cfg.Default.Host | |||||
if parts := strings.Split(defaultHost, "://"); len(parts) > 1 { | |||||
defaultHost = parts[1] | |||||
} | |||||
// get each host dir | |||||
files, err := ioutil.ReadDir(userDir) | |||||
if err != nil { | |||||
return cli.NewExitError("Could not read user configuration directory", 1) | |||||
} | |||||
// accounts will be a slice of slices of string. the first string in | |||||
// a subslice should always be the hostname | |||||
accounts := [][]string{} | |||||
for _, file := range files { | |||||
if file.IsDir() { | |||||
dirName := file.Name() | |||||
// get each user in host dir | |||||
users, err := usersFromDir(filepath.Join(userDir, dirName)) | |||||
if err != nil { | |||||
log.Info(c, "Failed to get users from %s: %v", dirName, err) | |||||
continue | |||||
} | |||||
if len(users) != 0 { | |||||
// append the slice of users as a new slice in accounts w/ the host prepended | |||||
accounts = append(accounts, append([]string{dirName}, users...)) | |||||
} | |||||
} | |||||
} | |||||
// print out all logged in accounts | |||||
tw := tabwriter.NewWriter(os.Stdout, 10, 2, 2, ' ', tabwriter.TabIndent) | |||||
if len(accounts) == 0 && (c.Bool("v") || c.Bool("verbose") || c.GlobalBool("v") || c.GlobalBool("verbose")) { | |||||
fmt.Fprintf(tw, "%s\t", "No authenticated accounts found.\n") | |||||
} | |||||
for _, userList := range accounts { | |||||
host := userList[0] | |||||
for _, username := range userList[1:] { | |||||
if host == defaultHost && username == defaultUser { | |||||
fmt.Fprintf(tw, "[%s]\t%s (default)\n", host, username) | |||||
continue | |||||
} | |||||
fmt.Fprintf(tw, "[%s]\t%s\n", host, username) | |||||
} | |||||
} | |||||
return tw.Flush() | |||||
} | |||||
func usersFromDir(path string) ([]string, error) { | |||||
users := make([]string, 0, 4) | |||||
files, err := ioutil.ReadDir(path) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
var errs error | |||||
for _, file := range files { | |||||
if file.IsDir() { | |||||
_, err := os.Stat(filepath.Join(path, file.Name(), "user.json")) | |||||
if err != nil { | |||||
err = multierror.Append(errs, err) | |||||
continue | |||||
} | |||||
users = append(users, file.Name()) | |||||
} | |||||
} | |||||
return users, errs | |||||
} |
@@ -182,6 +182,16 @@ func main() { | |||||
}, | }, | ||||
}, | }, | ||||
}, { | }, { | ||||
Name: "accounts", | |||||
Usage: "List all currently logged in accounts", | |||||
Action: cmdAccounts, | |||||
Flags: []cli.Flag{ | |||||
cli.BoolFlag{ | |||||
Name: "verbose, v", | |||||
Usage: "Make the operation more talkative", | |||||
}, | |||||
}, | |||||
}, { | |||||
Name: "auth", | Name: "auth", | ||||
Usage: "Authenticate with a WriteFreely instance", | Usage: "Authenticate with a WriteFreely instance", | ||||
Action: cmdAuth, | Action: cmdAuth, | ||||
@@ -5,6 +5,7 @@ require ( | |||||
github.com/atotto/clipboard v0.1.1 | github.com/atotto/clipboard v0.1.1 | ||||
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 | github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 | ||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect | github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect | ||||
github.com/hashicorp/go-multierror v1.0.0 | |||||
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c | github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c | ||||
github.com/jtolds/gls v4.2.1+incompatible // indirect | github.com/jtolds/gls v4.2.1+incompatible // indirect | ||||
github.com/microcosm-cc/bluemonday v1.0.1 // indirect | github.com/microcosm-cc/bluemonday v1.0.1 // indirect | ||||
@@ -12,6 +12,10 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM | |||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= | github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= | ||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= | github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= | ||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= | |||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= | |||||
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= | |||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= | |||||
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c h1:kQWxfPIHVLbgLzphqk3QUflDy9QdksZR4ygR807bpy0= | github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c h1:kQWxfPIHVLbgLzphqk3QUflDy9QdksZR4ygR807bpy0= | ||||
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= | github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= | ||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= | github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= | ||||