github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/apiserver/usermanager/usermanager.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package usermanager 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/loggo" 9 "github.com/juju/names" 10 11 "github.com/juju/juju/apiserver/common" 12 "github.com/juju/juju/apiserver/params" 13 "github.com/juju/juju/state" 14 ) 15 16 var logger = loggo.GetLogger("juju.apiserver.usermanager") 17 18 func init() { 19 common.RegisterStandardFacade("UserManager", 0, NewUserManagerAPI) 20 } 21 22 // UserManager defines the methods on the usermanager API end point. 23 type UserManager interface { 24 AddUser(args params.AddUsers) (params.AddUserResults, error) 25 DisableUser(args params.Entities) (params.ErrorResults, error) 26 EnableUser(args params.Entities) (params.ErrorResults, error) 27 SetPassword(args params.EntityPasswords) (params.ErrorResults, error) 28 UserInfo(args params.UserInfoRequest) (params.UserInfoResults, error) 29 } 30 31 // UserManagerAPI implements the user manager interface and is the concrete 32 // implementation of the api end point. 33 type UserManagerAPI struct { 34 state *state.State 35 authorizer common.Authorizer 36 check *common.BlockChecker 37 } 38 39 var _ UserManager = (*UserManagerAPI)(nil) 40 41 func NewUserManagerAPI( 42 st *state.State, 43 resources *common.Resources, 44 authorizer common.Authorizer, 45 ) (*UserManagerAPI, error) { 46 if !authorizer.AuthClient() { 47 return nil, common.ErrPerm 48 } 49 50 return &UserManagerAPI{ 51 state: st, 52 authorizer: authorizer, 53 check: common.NewBlockChecker(st), 54 }, nil 55 } 56 57 func (api *UserManagerAPI) permissionCheck(user names.UserTag) error { 58 // TODO(thumper): PERMISSIONS Change this permission check when we have 59 // real permissions. For now, only the owner of the initial environment is 60 // able to add users. 61 initialEnv, err := api.state.StateServerEnvironment() 62 if err != nil { 63 return errors.Trace(err) 64 } 65 if user != initialEnv.Owner() { 66 return errors.Trace(common.ErrPerm) 67 } 68 return nil 69 } 70 71 // AddUser adds a user. 72 func (api *UserManagerAPI) AddUser(args params.AddUsers) (params.AddUserResults, error) { 73 result := params.AddUserResults{ 74 Results: make([]params.AddUserResult, len(args.Users)), 75 } 76 if err := api.check.ChangeAllowed(); err != nil { 77 return result, errors.Trace(err) 78 } 79 80 if len(args.Users) == 0 { 81 return result, nil 82 } 83 loggedInUser, err := api.getLoggedInUser() 84 if err != nil { 85 return result, errors.Wrap(err, common.ErrPerm) 86 } 87 // TODO(thumper): PERMISSIONS Change this permission check when we have 88 // real permissions. For now, only the owner of the initial environment is 89 // able to add users. 90 if err := api.permissionCheck(loggedInUser); err != nil { 91 return result, errors.Trace(err) 92 } 93 for i, arg := range args.Users { 94 user, err := api.state.AddUser(arg.Username, arg.DisplayName, arg.Password, loggedInUser.Id()) 95 if err != nil { 96 err = errors.Annotate(err, "failed to create user") 97 result.Results[i].Error = common.ServerError(err) 98 } else { 99 result.Results[i].Tag = user.Tag().String() 100 } 101 } 102 return result, nil 103 } 104 105 func (api *UserManagerAPI) getUser(tag string) (*state.User, error) { 106 userTag, err := names.ParseUserTag(tag) 107 if err != nil { 108 return nil, errors.Trace(err) 109 } 110 user, err := api.state.User(userTag) 111 if err != nil { 112 return nil, errors.Wrap(err, common.ErrPerm) 113 } 114 return user, nil 115 } 116 117 // EnableUser enables one or more users. If the user is already enabled, 118 // the action is consided a success. 119 func (api *UserManagerAPI) EnableUser(users params.Entities) (params.ErrorResults, error) { 120 if err := api.check.ChangeAllowed(); err != nil { 121 return params.ErrorResults{}, errors.Trace(err) 122 } 123 return api.enableUserImpl(users, "enable", (*state.User).Enable) 124 } 125 126 // DisableUser disables one or more users. If the user is already disabled, 127 // the action is consided a success. 128 func (api *UserManagerAPI) DisableUser(users params.Entities) (params.ErrorResults, error) { 129 if err := api.check.ChangeAllowed(); err != nil { 130 return params.ErrorResults{}, errors.Trace(err) 131 } 132 return api.enableUserImpl(users, "disable", (*state.User).Disable) 133 } 134 135 func (api *UserManagerAPI) enableUserImpl(args params.Entities, action string, method func(*state.User) error) (params.ErrorResults, error) { 136 result := params.ErrorResults{ 137 Results: make([]params.ErrorResult, len(args.Entities)), 138 } 139 if len(args.Entities) == 0 { 140 return result, nil 141 } 142 loggedInUser, err := api.getLoggedInUser() 143 if err != nil { 144 return result, errors.Wrap(err, common.ErrPerm) 145 } 146 // TODO(thumper): PERMISSIONS Change this permission check when we have 147 // real permissions. For now, only the owner of the initial environment is 148 // able to add users. 149 if err := api.permissionCheck(loggedInUser); err != nil { 150 return result, errors.Trace(err) 151 } 152 153 for i, arg := range args.Entities { 154 user, err := api.getUser(arg.Tag) 155 if err != nil { 156 result.Results[i].Error = common.ServerError(err) 157 continue 158 } 159 err = method(user) 160 if err != nil { 161 result.Results[i].Error = common.ServerError(errors.Errorf("failed to %s user: %s", action, err)) 162 } 163 } 164 return result, nil 165 } 166 167 // UserInfo returns information on a user. 168 func (api *UserManagerAPI) UserInfo(request params.UserInfoRequest) (params.UserInfoResults, error) { 169 var infoForUser = func(user *state.User) params.UserInfoResult { 170 return params.UserInfoResult{ 171 Result: ¶ms.UserInfo{ 172 Username: user.Name(), 173 DisplayName: user.DisplayName(), 174 CreatedBy: user.CreatedBy(), 175 DateCreated: user.DateCreated(), 176 LastConnection: user.LastLogin(), 177 Disabled: user.IsDisabled(), 178 }, 179 } 180 } 181 182 var results params.UserInfoResults 183 argCount := len(request.Entities) 184 if argCount == 0 { 185 users, err := api.state.AllUsers(request.IncludeDisabled) 186 if err != nil { 187 return results, errors.Trace(err) 188 } 189 for _, user := range users { 190 results.Results = append(results.Results, infoForUser(user)) 191 } 192 return results, nil 193 } 194 195 results.Results = make([]params.UserInfoResult, argCount) 196 for i, arg := range request.Entities { 197 user, err := api.getUser(arg.Tag) 198 if err != nil { 199 results.Results[i].Error = common.ServerError(err) 200 continue 201 } 202 results.Results[i] = infoForUser(user) 203 } 204 205 return results, nil 206 } 207 208 func (api *UserManagerAPI) setPassword(loggedInUser names.UserTag, arg params.EntityPassword, adminUser bool) error { 209 user, err := api.getUser(arg.Tag) 210 if err != nil { 211 return errors.Trace(err) 212 } 213 if loggedInUser != user.UserTag() && !adminUser { 214 return errors.Trace(common.ErrPerm) 215 } 216 if arg.Password == "" { 217 return errors.New("can not use an empty password") 218 } 219 err = user.SetPassword(arg.Password) 220 if err != nil { 221 return errors.Annotate(err, "failed to set password") 222 } 223 return nil 224 } 225 226 // SetPassword changes the stored password for the specified users. 227 func (api *UserManagerAPI) SetPassword(args params.EntityPasswords) (params.ErrorResults, error) { 228 if err := api.check.ChangeAllowed(); err != nil { 229 return params.ErrorResults{}, errors.Trace(err) 230 } 231 result := params.ErrorResults{ 232 Results: make([]params.ErrorResult, len(args.Changes)), 233 } 234 if len(args.Changes) == 0 { 235 return result, nil 236 } 237 loggedInUser, err := api.getLoggedInUser() 238 if err != nil { 239 return result, common.ErrPerm 240 } 241 permErr := api.permissionCheck(loggedInUser) 242 adminUser := permErr == nil 243 for i, arg := range args.Changes { 244 if err := api.setPassword(loggedInUser, arg, adminUser); err != nil { 245 result.Results[i].Error = common.ServerError(err) 246 } 247 } 248 return result, nil 249 } 250 251 func (api *UserManagerAPI) getLoggedInUser() (names.UserTag, error) { 252 switch tag := api.authorizer.GetAuthTag().(type) { 253 case names.UserTag: 254 return tag, nil 255 default: 256 return names.UserTag{}, errors.New("authorizer not a user") 257 } 258 }