github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/util/configv3/json_config.go (about) 1 package configv3 2 3 import ( 4 "time" 5 6 "github.com/SermoDigital/jose/jws" 7 ) 8 9 // JSONConfig represents .cf/config.json. 10 type JSONConfig struct { 11 AccessToken string `json:"AccessToken"` 12 APIVersion string `json:"APIVersion"` 13 AsyncTimeout int `json:"AsyncTimeout"` 14 AuthorizationEndpoint string `json:"AuthorizationEndpoint"` 15 ColorEnabled string `json:"ColorEnabled"` 16 ConfigVersion int `json:"ConfigVersion"` 17 DopplerEndpoint string `json:"DopplerEndPoint"` 18 Locale string `json:"Locale"` 19 MinCLIVersion string `json:"MinCLIVersion"` 20 MinRecommendedCLIVersion string `json:"MinRecommendedCLIVersion"` 21 TargetedOrganization Organization `json:"OrganizationFields"` 22 PluginRepositories []PluginRepository `json:"PluginRepos"` 23 RefreshToken string `json:"RefreshToken"` 24 RoutingEndpoint string `json:"RoutingAPIEndpoint"` 25 TargetedSpace Space `json:"SpaceFields"` 26 SSHOAuthClient string `json:"SSHOAuthClient"` 27 SkipSSLValidation bool `json:"SSLDisabled"` 28 Target string `json:"Target"` 29 Trace string `json:"Trace"` 30 UAAEndpoint string `json:"UaaEndpoint"` 31 UAAGrantType string `json:"UAAGrantType"` 32 UAAOAuthClient string `json:"UAAOAuthClient"` 33 UAAOAuthClientSecret string `json:"UAAOAuthClientSecret"` 34 } 35 36 // Organization contains basic information about the targeted organization. 37 type Organization struct { 38 GUID string `json:"GUID"` 39 Name string `json:"Name"` 40 } 41 42 // Space contains basic information about the targeted space. 43 type Space struct { 44 GUID string `json:"GUID"` 45 Name string `json:"Name"` 46 AllowSSH bool `json:"AllowSSH"` 47 } 48 49 // User represents the user information provided by the JWT access token. 50 type User struct { 51 Name string 52 GUID string 53 Origin string 54 IsClient bool 55 } 56 57 // AccessToken returns the access token for making authenticated API calls. 58 func (config *Config) AccessToken() string { 59 return config.ConfigFile.AccessToken 60 } 61 62 // APIVersion returns the CC API Version. 63 func (config *Config) APIVersion() string { 64 return config.ConfigFile.APIVersion 65 } 66 67 // CurrentUser returns user information decoded from the JWT access token in 68 // .cf/config.json. 69 func (config *Config) CurrentUser() (User, error) { 70 return decodeUserFromJWT(config.ConfigFile.AccessToken) 71 } 72 73 // CurrentUserName returns the name of a user as returned by CurrentUser() 74 func (config *Config) CurrentUserName() (string, error) { 75 user, err := config.CurrentUser() 76 if err != nil { 77 return "", err 78 } 79 return user.Name, nil 80 } 81 82 // HasTargetedOrganization returns true if the organization is set. 83 func (config *Config) HasTargetedOrganization() bool { 84 return config.ConfigFile.TargetedOrganization.GUID != "" 85 } 86 87 // HasTargetedSpace returns true if the space is set. 88 func (config *Config) HasTargetedSpace() bool { 89 return config.ConfigFile.TargetedSpace.GUID != "" 90 } 91 92 // MinCLIVersion returns the minimum CLI version required by the CC. 93 func (config *Config) MinCLIVersion() string { 94 return config.ConfigFile.MinCLIVersion 95 } 96 97 // OverallPollingTimeout returns the overall polling timeout for async 98 // operations. The time is based off of: 99 // 1. The config file's AsyncTimeout value (integer) is > 0 100 // 2. Defaults to the DefaultOverallPollingTimeout 101 func (config *Config) OverallPollingTimeout() time.Duration { 102 if config.ConfigFile.AsyncTimeout == 0 { 103 return DefaultOverallPollingTimeout 104 } 105 return time.Duration(config.ConfigFile.AsyncTimeout) * time.Minute 106 } 107 108 // RefreshToken returns the refresh token for getting a new access token. 109 func (config *Config) RefreshToken() string { 110 return config.ConfigFile.RefreshToken 111 } 112 113 // RoutingEndpoint returns the endpoint for the router API 114 func (config *Config) RoutingEndpoint() string { 115 return config.ConfigFile.RoutingEndpoint 116 } 117 118 // SetAccessToken sets the current access token. 119 func (config *Config) SetAccessToken(accessToken string) { 120 config.ConfigFile.AccessToken = accessToken 121 } 122 123 // SetMinCLIVersion sets the minimum CLI version required by the CC. 124 func (config *Config) SetMinCLIVersion(minVersion string) { 125 config.ConfigFile.MinCLIVersion = minVersion 126 } 127 128 // SetOrganizationInformation sets the currently targeted organization. 129 func (config *Config) SetOrganizationInformation(guid string, name string) { 130 config.ConfigFile.TargetedOrganization.GUID = guid 131 config.ConfigFile.TargetedOrganization.Name = name 132 } 133 134 // SetRefreshToken sets the current refresh token. 135 func (config *Config) SetRefreshToken(refreshToken string) { 136 config.ConfigFile.RefreshToken = refreshToken 137 } 138 139 // SetSpaceInformation sets the currently targeted space. 140 // The "AllowSSH" field is not returned by v3, and is never read from the config. 141 // Persist `true` to maintain compatibility in the config file. 142 // TODO: this field should be removed entirely in v7 143 func (config *Config) SetSpaceInformation(guid string, name string, allowSSH bool) { 144 config.V7SetSpaceInformation(guid, name) 145 config.ConfigFile.TargetedSpace.AllowSSH = allowSSH 146 } 147 148 // SetTargetInformation sets the currently targeted CC API and related other 149 // related API URLs. 150 func (config *Config) SetTargetInformation(api string, apiVersion string, auth string, minCLIVersion string, doppler string, routing string, skipSSLValidation bool) { 151 config.ConfigFile.Target = api 152 config.ConfigFile.APIVersion = apiVersion 153 config.ConfigFile.AuthorizationEndpoint = auth 154 config.SetMinCLIVersion(minCLIVersion) 155 config.ConfigFile.DopplerEndpoint = doppler 156 config.ConfigFile.RoutingEndpoint = routing 157 config.ConfigFile.SkipSSLValidation = skipSSLValidation 158 159 config.UnsetOrganizationAndSpaceInformation() 160 } 161 162 // SetTokenInformation sets the current token/user information. 163 func (config *Config) SetTokenInformation(accessToken string, refreshToken string, sshOAuthClient string) { 164 config.ConfigFile.AccessToken = accessToken 165 config.ConfigFile.RefreshToken = refreshToken 166 config.ConfigFile.SSHOAuthClient = sshOAuthClient 167 } 168 169 // SetUAAClientCredentials sets the client credentials. 170 func (config *Config) SetUAAClientCredentials(client string, clientSecret string) { 171 config.ConfigFile.UAAOAuthClient = client 172 config.ConfigFile.UAAOAuthClientSecret = clientSecret 173 } 174 175 // SetUAAEndpoint sets the UAA endpoint that is obtained from hitting 176 // <AuthorizationEndpoint>/login. 177 func (config *Config) SetUAAEndpoint(uaaEndpoint string) { 178 config.ConfigFile.UAAEndpoint = uaaEndpoint 179 } 180 181 // SetUAAGrantType sets the UAA grant type for logging in and refreshing the 182 // token. 183 func (config *Config) SetUAAGrantType(uaaGrantType string) { 184 config.ConfigFile.UAAGrantType = uaaGrantType 185 } 186 187 // SkipSSLValidation returns whether or not to skip SSL validation when 188 // targeting an API endpoint. 189 func (config *Config) SkipSSLValidation() bool { 190 return config.ConfigFile.SkipSSLValidation 191 } 192 193 // SSHOAuthClient returns the OAuth client id used for SSHing into 194 // application/process containers. 195 func (config *Config) SSHOAuthClient() string { 196 return config.ConfigFile.SSHOAuthClient 197 } 198 199 // Target returns the CC API URL. 200 func (config *Config) Target() string { 201 return config.ConfigFile.Target 202 } 203 204 // TargetedOrganization returns the currently targeted organization. 205 func (config *Config) TargetedOrganization() Organization { 206 return config.ConfigFile.TargetedOrganization 207 } 208 209 // TargetedOrganizationName returns the name of the targeted organization. 210 func (config *Config) TargetedOrganizationName() string { 211 return config.TargetedOrganization().Name 212 } 213 214 // TargetedSpace returns the currently targeted space. 215 func (config *Config) TargetedSpace() Space { 216 return config.ConfigFile.TargetedSpace 217 } 218 219 // UAAGrantType returns the grant type of the supplied UAA credentials. 220 func (config *Config) UAAGrantType() string { 221 return config.ConfigFile.UAAGrantType 222 } 223 224 // UAAOAuthClient returns the CLI's UAA client ID. 225 func (config *Config) UAAOAuthClient() string { 226 return config.ConfigFile.UAAOAuthClient 227 } 228 229 // UAAOAuthClientSecret returns the CLI's UAA client secret. 230 func (config *Config) UAAOAuthClientSecret() string { 231 return config.ConfigFile.UAAOAuthClientSecret 232 } 233 234 // UnsetOrganizationAndSpaceInformation resets the organization and space 235 // values to default. 236 func (config *Config) UnsetOrganizationAndSpaceInformation() { 237 config.SetOrganizationInformation("", "") 238 config.UnsetSpaceInformation() 239 } 240 241 // UnsetSpaceInformation resets the space values to default. 242 func (config *Config) UnsetSpaceInformation() { 243 config.SetSpaceInformation("", "", false) 244 } 245 246 // UnsetUserInformation resets the access token, refresh token, UAA grant type, 247 // UAA client credentials, and targeted org/space information. 248 func (config *Config) UnsetUserInformation() { 249 config.SetAccessToken("") 250 config.SetRefreshToken("") 251 config.SetUAAGrantType("") 252 config.SetUAAClientCredentials(DefaultUAAOAuthClient, DefaultUAAOAuthClientSecret) 253 254 config.UnsetOrganizationAndSpaceInformation() 255 256 } 257 258 // V7SetSpaceInformation sets the currently targeted space. 259 func (config *Config) V7SetSpaceInformation(guid string, name string) { 260 config.ConfigFile.TargetedSpace.GUID = guid 261 config.ConfigFile.TargetedSpace.Name = name 262 } 263 264 func decodeUserFromJWT(accessToken string) (User, error) { 265 if accessToken == "" { 266 return User{}, nil 267 } 268 269 token, err := jws.ParseJWT([]byte(accessToken[7:])) 270 if err != nil { 271 return User{}, err 272 } 273 274 claims := token.Claims() 275 276 var name, GUID, origin string 277 var isClient bool 278 if claims.Has("user_name") { 279 name = claims.Get("user_name").(string) 280 GUID = claims.Get("user_id").(string) 281 origin = claims.Get("origin").(string) 282 isClient = false 283 } else { 284 name = claims.Get("client_id").(string) 285 GUID = name 286 isClient = true 287 } 288 289 return User{ 290 Name: name, 291 GUID: GUID, 292 Origin: origin, 293 IsClient: isClient, 294 }, nil 295 }