-
Notifications
You must be signed in to change notification settings - Fork 0
/
cf.go
110 lines (106 loc) · 3.48 KB
/
cf.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package util
import (
"encoding/json"
"fmt"
"github.com/cloudfoundry-community/go-cfclient"
"github.com/golang-jwt/jwt"
"github.com/rabobank/scheduler-service-broker/conf"
"github.com/rabobank/scheduler-service-broker/model"
"io/ioutil"
"os"
"time"
)
func GetCFClient() *cfclient.Client {
var err error
c := &cfclient.Config{
ApiAddress: conf.CfApiURL,
ClientID: conf.ClientId,
ClientSecret: conf.ClientSecret,
SkipSslValidation: true,
}
fmt.Printf("getting cf client from %s...", conf.CfApiURL)
var client *cfclient.Client
if client, err = cfclient.NewClient(c); err != nil {
fmt.Printf("\nfailed getting cf client:%s\n", err)
os.Exit(8)
} else {
fmt.Println("done")
// refresh the client every hour to get a new refresh token
go func() {
channel := time.Tick(time.Duration(conf.TokenRefreshInterval) * time.Minute)
for range channel {
if client, err = cfclient.NewClient(c); err != nil {
fmt.Printf("failed to refresh cf client, error is %s\n", err)
} else {
fmt.Println("refreshed cf client, got new token")
CfClient = *client
}
}
}()
}
return client
}
// IsUserAuthorisedForSpace - It takes the jwt, extracts the userId from it,
//
// then queries cf (/v3/roles) to check if that user has at least developer or manager role for the give space
func IsUserAuthorisedForSpace(token jwt.Token, spaceGuid string) bool {
userId := token.Claims.(jwt.MapClaims)["user_id"].(string)
scopes := token.Claims.(jwt.MapClaims)["scope"].([]interface{})
if Contains(scopes, "cloud_controller.admin") {
return true
}
req := CfClient.NewRequest("GET", fmt.Sprintf("/v3/roles?types=space_developer,space_manager&space_guids=%s&user_guids=%s", spaceGuid, userId))
if resp, err := CfClient.DoRequest(req); err != nil {
fmt.Printf("failed to query Cloud Controller for roles: %s\n", err)
return false
} else {
var body []byte
if body, err = ioutil.ReadAll(resp.Body); err != nil {
fmt.Printf("failed to read response from /v3/roles query to Cloud Controller: %s\n", err)
return false
} else {
var v3RolesResponse model.GenericV3Response
if err = json.Unmarshal(body, &v3RolesResponse); err != nil {
fmt.Printf("failed to parse response from /v3/roles query to Cloud Controller: %s\n", err)
return false
} else {
PrintfIfDebug("found %d roles for userId %s and spaceguid %s\n", v3RolesResponse.Pagination.TotalResults, userId, spaceGuid)
if v3RolesResponse.Pagination.TotalResults == 0 {
return false
}
return true
}
}
}
}
func IsAppBoundToSchedulerService(appguid string) bool {
req := CfClient.NewRequest("GET", "/v3/service_plans?service_offering_names=scheduler") // TODO make the service name configurable?
if resp, err := CfClient.DoRequest(req); err != nil {
fmt.Println(err)
return false
} else {
body, _ := ioutil.ReadAll(resp.Body)
response := model.GenericV3Response{}
if err = json.Unmarshal(body, &response); err != nil {
fmt.Println(err)
return false
} else {
planguid := response.Resources[0].Guid
req = CfClient.NewRequest("GET", fmt.Sprintf("/v3/service_credential_bindings?app_guids=%s&service_plan_guids=%s", appguid, planguid))
if resp, err = CfClient.DoRequest(req); err != nil {
fmt.Println(err)
} else {
body, _ = ioutil.ReadAll(resp.Body)
if err = json.Unmarshal(body, &response); err != nil {
fmt.Println(err)
return false
} else {
if len(response.Resources) == 1 {
return true
}
}
}
}
}
return false
}