github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/state/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 "fmt" 8 9 "github.com/juju/errors" 10 "github.com/juju/loggo" 11 "github.com/juju/names" 12 13 "github.com/juju/juju/state" 14 "github.com/juju/juju/state/api/params" 15 "github.com/juju/juju/state/apiserver/common" 16 ) 17 18 var logger = loggo.GetLogger("juju.state.apiserver.usermanager") 19 20 // UserManager defines the methods on the usermanager API end point. 21 type UserManager interface { 22 AddUser(arg params.ModifyUsers) (params.ErrorResults, error) 23 RemoveUser(arg params.Entities) (params.ErrorResults, error) 24 } 25 26 // UserManagerAPI implements the user manager interface and is the concrete 27 // implementation of the api end point. 28 type UserManagerAPI struct { 29 state *state.State 30 authorizer common.Authorizer 31 getCanWrite common.GetAuthFunc 32 getCanRead common.GetAuthFunc 33 } 34 35 var _ UserManager = (*UserManagerAPI)(nil) 36 37 func NewUserManagerAPI( 38 st *state.State, 39 authorizer common.Authorizer, 40 ) (*UserManagerAPI, error) { 41 if !authorizer.AuthClient() { 42 return nil, common.ErrPerm 43 } 44 45 // TODO(mattyw) - replace stub with real canWrite function 46 getCanWrite := common.AuthAlways(true) 47 48 // TODO(waigani) - replace stub with real canRead function 49 getCanRead := common.AuthAlways(true) 50 return &UserManagerAPI{ 51 state: st, 52 authorizer: authorizer, 53 getCanWrite: getCanWrite, 54 getCanRead: getCanRead}, 55 nil 56 } 57 58 func (api *UserManagerAPI) AddUser(args params.ModifyUsers) (params.ErrorResults, error) { 59 result := params.ErrorResults{ 60 Results: make([]params.ErrorResult, len(args.Changes)), 61 } 62 if len(args.Changes) == 0 { 63 return result, nil 64 } 65 canWrite, err := api.getCanWrite() 66 if err != nil { 67 result.Results[0].Error = common.ServerError(err) 68 return result, err 69 } 70 user := api.getLoggedInUser() 71 if user == nil { 72 return result, fmt.Errorf("api connection is not through a user") 73 } 74 for i, arg := range args.Changes { 75 if !canWrite(arg.Tag) { 76 result.Results[0].Error = common.ServerError(common.ErrPerm) 77 continue 78 } 79 username := arg.Username 80 if username == "" { 81 username = arg.Tag 82 } 83 _, err := api.state.AddUser(username, arg.DisplayName, arg.Password, user.Name()) 84 if err != nil { 85 err = errors.Annotate(err, "failed to create user") 86 result.Results[i].Error = common.ServerError(err) 87 continue 88 } 89 } 90 return result, nil 91 } 92 93 func (api *UserManagerAPI) RemoveUser(args params.Entities) (params.ErrorResults, error) { 94 result := params.ErrorResults{ 95 Results: make([]params.ErrorResult, len(args.Entities)), 96 } 97 if len(args.Entities) == 0 { 98 return result, nil 99 } 100 canWrite, err := api.getCanWrite() 101 if err != nil { 102 return result, err 103 } 104 for i, arg := range args.Entities { 105 if !canWrite(arg.Tag) { 106 result.Results[i].Error = common.ServerError(common.ErrPerm) 107 continue 108 } 109 user, err := api.state.User(arg.Tag) 110 if err != nil { 111 result.Results[i].Error = common.ServerError(common.ErrPerm) 112 continue 113 } 114 err = user.Deactivate() 115 if err != nil { 116 result.Results[i].Error = common.ServerError(fmt.Errorf("Failed to remove user: %s", err)) 117 continue 118 } 119 } 120 return result, nil 121 } 122 123 // UserInfo returns information on a user. 124 func (api *UserManagerAPI) UserInfo(args params.Entities) (params.UserInfoResults, error) { 125 results := params.UserInfoResults{ 126 Results: make([]params.UserInfoResult, len(args.Entities)), 127 } 128 129 canRead, err := api.getCanRead() 130 if err != nil { 131 return results, err 132 } 133 for i, userArg := range args.Entities { 134 if !canRead(userArg.Tag) { 135 results.Results[i].Error = common.ServerError(common.ErrPerm) 136 continue 137 } 138 tag, err := names.ParseTag(userArg.Tag, names.UserTagKind) 139 if err != nil { 140 results.Results[0].Error = common.ServerError(err) 141 continue 142 } 143 username := tag.Id() 144 145 user, err := api.state.User(username) 146 var result params.UserInfoResult 147 if err != nil { 148 if errors.IsNotFound(err) { 149 result.Error = common.ServerError(common.ErrPerm) 150 } else { 151 result.Error = common.ServerError(err) 152 } 153 } else { 154 info := params.UserInfo{ 155 Username: username, 156 DisplayName: user.DisplayName(), 157 CreatedBy: user.CreatedBy(), 158 DateCreated: user.DateCreated(), 159 LastConnection: user.LastConnection(), 160 } 161 result.Result = &info 162 } 163 results.Results[i] = result 164 } 165 166 return results, nil 167 } 168 169 func (api *UserManagerAPI) getLoggedInUser() *state.User { 170 entity := api.authorizer.GetAuthEntity() 171 if user, ok := entity.(*state.User); ok { 172 return user 173 } 174 return nil 175 }