@@ -46,23 +46,40 @@ type Config struct {
46
46
}
47
47
48
48
type ccResponse struct {
49
- NextURL string `json:"next_url"`
50
- Resources []resource `json:"resources"`
51
- TotalResults int `json:"total_results"`
49
+ Pagination pagination `json:"pagination"`
50
+ Resources []resource `json:"resources"`
51
+ }
52
+
53
+ type pagination struct {
54
+ Next href `json:"next"`
55
+ }
56
+
57
+ type href struct {
58
+ Href string `json:"href"`
52
59
}
53
60
54
61
type resource struct {
55
- Metadata metadata `json:"metadata"`
56
- Entity entity `json:"entity"`
62
+ GUID string `json:"guid"`
63
+ Name string `json:"name,omitempty"`
64
+ Type string `json:"type,omitempty"`
65
+ Relationships relationships `json:"relationships"`
57
66
}
58
67
59
- type metadata struct {
60
- GUID string `json:"guid"`
68
+ type relationships struct {
69
+ Organization relOrganization `json:"organization"`
70
+ Space relSpace `json:"space"`
71
+ }
72
+
73
+ type relOrganization struct {
74
+ Data data `json:"data"`
61
75
}
62
76
63
- type entity struct {
64
- Name string `json:"name"`
65
- OrganizationGUID string `json:"organization_guid"`
77
+ type relSpace struct {
78
+ Data data `json:"data"`
79
+ }
80
+
81
+ type data struct {
82
+ GUID string `json:"guid"`
66
83
}
67
84
68
85
type space struct {
@@ -77,6 +94,18 @@ type org struct {
77
94
GUID string
78
95
}
79
96
97
+ type infoResp struct {
98
+ Links links `json:"links"`
99
+ }
100
+
101
+ type links struct {
102
+ Login login `json:"login"`
103
+ }
104
+
105
+ type login struct {
106
+ Href string `json:"href"`
107
+ }
108
+
80
109
func (c * Config ) Open (id string , logger log.Logger ) (connector.Connector , error ) {
81
110
var err error
82
111
@@ -94,7 +123,7 @@ func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error)
94
123
}
95
124
96
125
apiURL := strings .TrimRight (c .APIURL , "/" )
97
- apiResp , err := cloudfoundryConn .httpClient .Get (fmt . Sprintf ( "%s/v2/info" , apiURL ) )
126
+ apiResp , err := cloudfoundryConn .httpClient .Get (apiURL )
98
127
if err != nil {
99
128
logger .Errorf ("failed-to-send-request-to-cloud-controller-api" , err )
100
129
return nil , err
@@ -108,10 +137,11 @@ func (c *Config) Open(id string, logger log.Logger) (connector.Connector, error)
108
137
return nil , err
109
138
}
110
139
111
- var apiResult map [string ]interface {}
140
+ var apiResult infoResp
141
+
112
142
json .NewDecoder (apiResp .Body ).Decode (& apiResult )
113
143
114
- uaaURL := strings .TrimRight (apiResult [ "authorization_endpoint" ].( string ) , "/" )
144
+ uaaURL := strings .TrimRight (apiResult . Links . Login . Href , "/" )
115
145
uaaResp , err := cloudfoundryConn .httpClient .Get (fmt .Sprintf ("%s/.well-known/openid-configuration" , uaaURL ))
116
146
if err != nil {
117
147
logger .Errorf ("failed-to-send-request-to-uaa-api" , err )
@@ -191,40 +221,39 @@ func (c *cloudfoundryConnector) LoginURL(scopes connector.Scopes, callbackURL, s
191
221
return oauth2Config .AuthCodeURL (state ), nil
192
222
}
193
223
194
- func fetchRoleSpaces (baseURL , path , role string , client * http.Client ) ([]space , error ) {
195
- resources , err := fetchResources (baseURL , path , client )
196
- if err != nil {
197
- return nil , fmt .Errorf ("failed to fetch resources: %v" , err )
198
- }
224
+ func filterUserOrgsSpaces (userOrgsSpaces []resource , orgs []resource , spaces []resource ) ([]org , []space ) {
225
+ var filteredOrgs []org
226
+ var filteredSpaces []space
199
227
200
- spaces := make ([] space , len ( resources ) )
201
- for i , resource := range resources {
202
- spaces [ i ] = space {
203
- Name : resource . Entity . Name ,
204
- GUID : resource . Metadata . GUID ,
205
- OrgGUID : resource . Entity . OrganizationGUID ,
206
- Role : role ,
228
+ orgMap := make (map [ string ] org )
229
+ spaceMap := make ( map [ string ] space )
230
+
231
+ for _ , org_resource := range orgs {
232
+ orgMap [ org_resource . GUID ] = org {
233
+ Name : org_resource . Name ,
234
+ GUID : org_resource . GUID ,
207
235
}
208
236
}
209
237
210
- return spaces , nil
211
- }
212
-
213
- func fetchOrgs (baseURL , path string , client * http.Client ) ([]org , error ) {
214
- resources , err := fetchResources (baseURL , path , client )
215
- if err != nil {
216
- return nil , fmt .Errorf ("failed to fetch resources: %v" , err )
238
+ for _ , space_resource := range spaces {
239
+ spaceMap [space_resource .GUID ] = space {
240
+ Name : space_resource .Name ,
241
+ GUID : space_resource .GUID ,
242
+ OrgGUID : space_resource .Relationships .Organization .Data .GUID ,
243
+ }
217
244
}
218
245
219
- orgs := make ([]org , len (resources ))
220
- for i , resource := range resources {
221
- orgs [i ] = org {
222
- Name : resource .Entity .Name ,
223
- GUID : resource .Metadata .GUID ,
246
+ for _ , userOrgSpace := range userOrgsSpaces {
247
+ if space , ok := spaceMap [userOrgSpace .Relationships .Space .Data .GUID ]; ok {
248
+ space .Role = strings .TrimPrefix (userOrgSpace .Type , "space_" )
249
+ filteredSpaces = append (filteredSpaces , space )
250
+ }
251
+ if org , ok := orgMap [userOrgSpace .Relationships .Organization .Data .GUID ]; ok {
252
+ filteredOrgs = append (filteredOrgs , org )
224
253
}
225
254
}
226
255
227
- return orgs , nil
256
+ return filteredOrgs , filteredSpaces
228
257
}
229
258
230
259
func fetchResources (baseURL , path string , client * http.Client ) ([]resource , error ) {
@@ -249,12 +278,12 @@ func fetchResources(baseURL, path string, client *http.Client) ([]resource, erro
249
278
response := ccResponse {}
250
279
err = json .NewDecoder (resp .Body ).Decode (& response )
251
280
if err != nil {
252
- return nil , fmt .Errorf ("failed to parse spaces : %v" , err )
281
+ return nil , fmt .Errorf ("failed to parse response : %v" , err )
253
282
}
254
283
255
284
resources = append (resources , response .Resources ... )
256
285
257
- path = response .NextURL
286
+ path = strings . TrimPrefix ( response .Pagination . Next . Href , baseURL )
258
287
if path == "" {
259
288
break
260
289
}
@@ -349,36 +378,30 @@ func (c *cloudfoundryConnector) HandleCallback(s connector.Scopes, r *http.Reque
349
378
identity .EmailVerified , _ = userInfoResult ["email_verified" ].(bool )
350
379
351
380
var (
352
- devPath = fmt .Sprintf ("/v2/users/%s/spaces" , identity .UserID )
353
- auditorPath = fmt .Sprintf ("/v2/users/%s/audited_spaces" , identity .UserID )
354
- managerPath = fmt .Sprintf ("/v2/users/%s/managed_spaces" , identity .UserID )
355
- orgsPath = fmt .Sprintf ("/v2/users/%s/organizations" , identity .UserID )
381
+ orgsPath = "/v3/organizations"
382
+ spacesPath = "/v3/spaces"
383
+ userOrgsSpacesPath = fmt .Sprintf ("/v3/roles?user_guids=%s&types=space_developer,space_manager,space_auditor,organization_user" , identity .UserID )
356
384
)
357
385
358
386
if s .Groups {
359
- orgs , err := fetchOrgs (c .apiURL , orgsPath , client )
387
+ userOrgsSpaces , err := fetchResources (c .apiURL , userOrgsSpacesPath , client )
360
388
if err != nil {
361
- return identity , fmt .Errorf ("failed to fetch organizaitons : %v" , err )
389
+ return identity , fmt .Errorf ("failed to fetch user organizations : %v" , err )
362
390
}
363
391
364
- developerSpaces , err := fetchRoleSpaces (c .apiURL , devPath , "developer" , client )
392
+ orgs , err := fetchResources (c .apiURL , orgsPath , client )
365
393
if err != nil {
366
- return identity , fmt .Errorf ("failed to fetch spaces for developer roles: %v" , err )
367
- }
368
-
369
- auditorSpaces , err := fetchRoleSpaces (c .apiURL , auditorPath , "auditor" , client )
370
- if err != nil {
371
- return identity , fmt .Errorf ("failed to fetch spaces for developer roles: %v" , err )
394
+ return identity , fmt .Errorf ("failed to fetch organizaitons: %v" , err )
372
395
}
373
396
374
- managerSpaces , err := fetchRoleSpaces (c .apiURL , managerPath , "manager" , client )
397
+ spaces , err := fetchResources (c .apiURL , spacesPath , client )
375
398
if err != nil {
376
- return identity , fmt .Errorf ("failed to fetch spaces for developer roles : %v" , err )
399
+ return identity , fmt .Errorf ("failed to fetch spaces: %v" , err )
377
400
}
378
401
379
- developerSpaces = append ( developerSpaces , append ( auditorSpaces , managerSpaces ... ) ... )
402
+ developerOrgs , developerSpaces := filterUserOrgsSpaces ( userOrgsSpaces , orgs , spaces )
380
403
381
- identity .Groups = getGroupsClaims (orgs , developerSpaces )
404
+ identity .Groups = getGroupsClaims (developerOrgs , developerSpaces )
382
405
}
383
406
384
407
if s .OfflineAccess {
0 commit comments