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  }