github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/cmd/juju/user/info.go (about) 1 // Copyright 2012-2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for infos. 3 4 package user 5 6 import ( 7 "github.com/juju/cmd" 8 "github.com/juju/errors" 9 "github.com/juju/gnuflag" 10 "github.com/juju/utils/clock" 11 "gopkg.in/juju/names.v2" 12 13 "github.com/juju/juju/api/usermanager" 14 "github.com/juju/juju/apiserver/params" 15 "github.com/juju/juju/cmd/juju/common" 16 "github.com/juju/juju/cmd/modelcmd" 17 "github.com/juju/juju/cmd/output" 18 ) 19 20 var helpSummary = ` 21 Show information about a user.`[1:] 22 23 var helpDetails = ` 24 By default, the YAML format is used and the user name is the current 25 user. 26 27 28 Examples: 29 juju show-user 30 juju show-user jsmith 31 juju show-user --format json 32 juju show-user --format yaml 33 34 See also: 35 add-user 36 register 37 users`[1:] 38 39 // UserInfoAPI defines the API methods that the info command uses. 40 type UserInfoAPI interface { 41 UserInfo([]string, usermanager.IncludeDisabled) ([]params.UserInfo, error) 42 Close() error 43 } 44 45 // infoCommandBase is a common base for 'juju show-user' and 'juju users'. 46 type infoCommandBase struct { 47 modelcmd.ControllerCommandBase 48 api UserInfoAPI 49 clock clock.Clock 50 exactTime bool 51 out cmd.Output 52 } 53 54 func (c *infoCommandBase) SetFlags(f *gnuflag.FlagSet) { 55 f.BoolVar(&c.exactTime, "exact-time", false, "Use full timestamp for connection times") 56 } 57 58 func NewShowUserCommand() cmd.Command { 59 return modelcmd.WrapController(&infoCommand{ 60 infoCommandBase: infoCommandBase{ 61 clock: clock.WallClock, 62 }, 63 }) 64 } 65 66 // infoCommand retrieves information about a single user. 67 type infoCommand struct { 68 infoCommandBase 69 Username string 70 } 71 72 // UserInfo defines the serialization behaviour of the user information. 73 type UserInfo struct { 74 Username string `yaml:"user-name" json:"user-name"` 75 DisplayName string `yaml:"display-name,omitempty" json:"display-name,omitempty"` 76 Access string `yaml:"access" json:"access"` 77 DateCreated string `yaml:"date-created,omitempty" json:"date-created,omitempty"` 78 LastConnection string `yaml:"last-connection,omitempty" json:"last-connection,omitempty"` 79 Disabled bool `yaml:"disabled,omitempty" json:"disabled,omitempty"` 80 } 81 82 // Info implements Command.Info. 83 func (c *infoCommand) Info() *cmd.Info { 84 return &cmd.Info{ 85 Name: "show-user", 86 Args: "[<user name>]", 87 Purpose: helpSummary, 88 Doc: helpDetails, 89 } 90 } 91 92 // SetFlags implements Command.SetFlags. 93 func (c *infoCommand) SetFlags(f *gnuflag.FlagSet) { 94 c.infoCommandBase.SetFlags(f) 95 c.out.AddFlags(f, "yaml", output.DefaultFormatters) 96 } 97 98 // Init implements Command.Init. 99 func (c *infoCommand) Init(args []string) (err error) { 100 c.Username, err = cmd.ZeroOrOneArgs(args) 101 return err 102 } 103 104 func (c *infoCommandBase) getUserInfoAPI() (UserInfoAPI, error) { 105 if c.api != nil { 106 return c.api, nil 107 } 108 return c.NewUserManagerAPIClient() 109 } 110 111 // Run implements Command.Run. 112 func (c *infoCommand) Run(ctx *cmd.Context) (err error) { 113 client, err := c.getUserInfoAPI() 114 if err != nil { 115 return err 116 } 117 defer client.Close() 118 username := c.Username 119 if username == "" { 120 accountDetails, err := c.ClientStore().AccountDetails(c.ControllerName()) 121 if err != nil { 122 return err 123 } 124 username = accountDetails.User 125 } 126 result, err := client.UserInfo([]string{username}, false) 127 if err != nil { 128 return err 129 } 130 // Don't output the params type, be explicit. We convert before checking 131 // length because we want to reuse the conversion function, and we are 132 // pretty sure that there is one value there. 133 output := c.apiUsersToUserInfoSlice(result) 134 if len(output) != 1 { 135 return errors.Errorf("expected 1 result, got %d", len(output)) 136 } 137 return c.out.Write(ctx, output[0]) 138 } 139 140 func (c *infoCommandBase) apiUsersToUserInfoSlice(users []params.UserInfo) []UserInfo { 141 var output []UserInfo 142 var now = c.clock.Now() 143 for _, info := range users { 144 outInfo := UserInfo{ 145 Username: info.Username, 146 DisplayName: info.DisplayName, 147 Access: info.Access, 148 Disabled: info.Disabled, 149 } 150 // TODO(wallyworld) record login information about external users. 151 if names.NewUserTag(info.Username).IsLocal() { 152 outInfo.LastConnection = common.LastConnection(info.LastConnection, now, c.exactTime) 153 if c.exactTime { 154 outInfo.DateCreated = info.DateCreated.String() 155 } else { 156 outInfo.DateCreated = common.UserFriendlyDuration(info.DateCreated, now) 157 } 158 } 159 output = append(output, outInfo) 160 } 161 162 return output 163 }