1package cfclient 2 3import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 "net/url" 10 11 "github.com/pkg/errors" 12) 13 14type UserRequest struct { 15 Guid string `json:"guid"` 16 DefaultSpaceGuid string `json:"default_space_guid,omitempty"` 17} 18 19type Users []User 20 21type User struct { 22 Guid string `json:"guid"` 23 CreatedAt string `json:"created_at"` 24 UpdatedAt string `json:"updated_at"` 25 Admin bool `json:"admin"` 26 Active bool `json:"active"` 27 DefaultSpaceGUID string `json:"default_space_guid"` 28 Username string `json:"username"` 29 SpacesURL string `json:"spaces_url"` 30 OrgsURL string `json:"organizations_url"` 31 ManagedOrgsURL string `json:"managed_organizations_url"` 32 BillingManagedOrgsURL string `json:"billing_managed_organizations_url"` 33 AuditedOrgsURL string `json:"audited_organizations_url"` 34 ManagedSpacesURL string `json:"managed_spaces_url"` 35 AuditedSpacesURL string `json:"audited_spaces_url"` 36 c *Client 37} 38 39type UserResource struct { 40 Meta Meta `json:"metadata"` 41 Entity User `json:"entity"` 42} 43 44type UserResponse struct { 45 Count int `json:"total_results"` 46 Pages int `json:"total_pages"` 47 NextUrl string `json:"next_url"` 48 Resources []UserResource `json:"resources"` 49} 50 51// GetUserByGUID retrieves the user with the provided guid. 52func (c *Client) GetUserByGUID(guid string) (User, error) { 53 var userRes UserResource 54 r := c.NewRequest("GET", "/v2/users/"+guid) 55 resp, err := c.DoRequest(r) 56 if err != nil { 57 return User{}, err 58 } 59 body, err := ioutil.ReadAll(resp.Body) 60 defer resp.Body.Close() 61 if err != nil { 62 return User{}, err 63 } 64 err = json.Unmarshal(body, &userRes) 65 if err != nil { 66 return User{}, err 67 } 68 return c.mergeUserResource(userRes), nil 69} 70 71func (c *Client) ListUsersByQuery(query url.Values) (Users, error) { 72 var users []User 73 requestUrl := "/v2/users?" + query.Encode() 74 for { 75 userResp, err := c.getUserResponse(requestUrl) 76 if err != nil { 77 return []User{}, err 78 } 79 for _, user := range userResp.Resources { 80 user.Entity.Guid = user.Meta.Guid 81 user.Entity.CreatedAt = user.Meta.CreatedAt 82 user.Entity.UpdatedAt = user.Meta.UpdatedAt 83 user.Entity.c = c 84 users = append(users, user.Entity) 85 } 86 requestUrl = userResp.NextUrl 87 if requestUrl == "" { 88 break 89 } 90 } 91 return users, nil 92} 93 94func (c *Client) ListUsers() (Users, error) { 95 return c.ListUsersByQuery(nil) 96} 97 98func (c *Client) ListUserSpaces(userGuid string) ([]Space, error) { 99 return c.fetchSpaces(fmt.Sprintf("/v2/users/%s/spaces", userGuid)) 100} 101 102func (c *Client) ListUserAuditedSpaces(userGuid string) ([]Space, error) { 103 return c.fetchSpaces(fmt.Sprintf("/v2/users/%s/audited_spaces", userGuid)) 104} 105 106func (c *Client) ListUserManagedSpaces(userGuid string) ([]Space, error) { 107 return c.fetchSpaces(fmt.Sprintf("/v2/users/%s/managed_spaces", userGuid)) 108} 109 110func (c *Client) ListUserOrgs(userGuid string) ([]Org, error) { 111 return c.fetchOrgs(fmt.Sprintf("/v2/users/%s/organizations", userGuid)) 112} 113 114func (c *Client) ListUserManagedOrgs(userGuid string) ([]Org, error) { 115 return c.fetchOrgs(fmt.Sprintf("/v2/users/%s/managed_organizations", userGuid)) 116} 117 118func (c *Client) ListUserAuditedOrgs(userGuid string) ([]Org, error) { 119 return c.fetchOrgs(fmt.Sprintf("/v2/users/%s/audited_organizations", userGuid)) 120} 121 122func (c *Client) ListUserBillingManagedOrgs(userGuid string) ([]Org, error) { 123 return c.fetchOrgs(fmt.Sprintf("/v2/users/%s/billing_managed_organizations", userGuid)) 124} 125 126func (c *Client) CreateUser(req UserRequest) (User, error) { 127 buf := bytes.NewBuffer(nil) 128 err := json.NewEncoder(buf).Encode(req) 129 if err != nil { 130 return User{}, err 131 } 132 r := c.NewRequestWithBody("POST", "/v2/users", buf) 133 resp, err := c.DoRequest(r) 134 if err != nil { 135 return User{}, err 136 } 137 if resp.StatusCode != http.StatusCreated { 138 return User{}, errors.Wrapf(err, "Error creating user, response code: %d", resp.StatusCode) 139 } 140 body, err := ioutil.ReadAll(resp.Body) 141 defer resp.Body.Close() 142 if err != nil { 143 return User{}, err 144 } 145 var userResource UserResource 146 err = json.Unmarshal(body, &userResource) 147 if err != nil { 148 return User{}, err 149 } 150 user := userResource.Entity 151 user.Guid = userResource.Meta.Guid 152 user.c = c 153 return user, nil 154} 155 156func (c *Client) DeleteUser(userGuid string) error { 157 resp, err := c.DoRequest(c.NewRequest("DELETE", fmt.Sprintf("/v2/users/%s", userGuid))) 158 if err != nil { 159 return err 160 } 161 if resp.StatusCode != http.StatusNoContent { 162 return errors.Wrapf(err, "Error deleting user %s, response code: %d", userGuid, resp.StatusCode) 163 } 164 return nil 165} 166 167func (u Users) GetUserByUsername(username string) User { 168 for _, user := range u { 169 if user.Username == username { 170 return user 171 } 172 } 173 return User{} 174} 175 176func (c *Client) getUserResponse(requestUrl string) (UserResponse, error) { 177 var userResp UserResponse 178 r := c.NewRequest("GET", requestUrl) 179 resp, err := c.DoRequest(r) 180 if err != nil { 181 return UserResponse{}, errors.Wrap(err, "Error requesting users") 182 } 183 resBody, err := ioutil.ReadAll(resp.Body) 184 defer resp.Body.Close() 185 if err != nil { 186 return UserResponse{}, errors.Wrap(err, "Error reading user request") 187 } 188 err = json.Unmarshal(resBody, &userResp) 189 if err != nil { 190 return UserResponse{}, errors.Wrap(err, "Error unmarshalling user") 191 } 192 return userResp, nil 193} 194 195func (c *Client) mergeUserResource(u UserResource) User { 196 u.Entity.Guid = u.Meta.Guid 197 u.Entity.CreatedAt = u.Meta.CreatedAt 198 u.Entity.UpdatedAt = u.Meta.UpdatedAt 199 u.Entity.c = c 200 return u.Entity 201} 202