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