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  }