github.com/willmadison/cli@v6.40.1-0.20181018160101-29d5937903ff+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  	ConfigVersion            int                `json:"ConfigVersion"`
    12  	Target                   string             `json:"Target"`
    13  	APIVersion               string             `json:"APIVersion"`
    14  	AuthorizationEndpoint    string             `json:"AuthorizationEndpoint"`
    15  	DopplerEndpoint          string             `json:"DopplerEndPoint"`
    16  	UAAEndpoint              string             `json:"UaaEndpoint"`
    17  	RoutingEndpoint          string             `json:"RoutingAPIEndpoint"`
    18  	AccessToken              string             `json:"AccessToken"`
    19  	SSHOAuthClient           string             `json:"SSHOAuthClient"`
    20  	UAAOAuthClient           string             `json:"UAAOAuthClient"`
    21  	UAAOAuthClientSecret     string             `json:"UAAOAuthClientSecret"`
    22  	UAAGrantType             string             `json:"UAAGrantType"`
    23  	RefreshToken             string             `json:"RefreshToken"`
    24  	TargetedOrganization     Organization       `json:"OrganizationFields"`
    25  	TargetedSpace            Space              `json:"SpaceFields"`
    26  	SkipSSLValidation        bool               `json:"SSLDisabled"`
    27  	AsyncTimeout             int                `json:"AsyncTimeout"`
    28  	Trace                    string             `json:"Trace"`
    29  	ColorEnabled             string             `json:"ColorEnabled"`
    30  	Locale                   string             `json:"Locale"`
    31  	PluginRepositories       []PluginRepository `json:"PluginRepos"`
    32  	MinCLIVersion            string             `json:"MinCLIVersion"`
    33  	MinRecommendedCLIVersion string             `json:"MinRecommendedCLIVersion"`
    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  	QuotaDefinition QuotaDefinition `json:"QuotaDefinition"`
    41  }
    42  
    43  // QuotaDefinition contains information about the organization's quota.
    44  type QuotaDefinition struct {
    45  	GUID                    string `json:"guid"`
    46  	Name                    string `json:"name"`
    47  	MemoryLimit             int    `json:"memory_limit"`
    48  	InstanceMemoryLimit     int    `json:"instance_memory_limit"`
    49  	TotalRoutes             int    `json:"total_routes"`
    50  	TotalServices           int    `json:"total_services"`
    51  	NonBasicServicesAllowed bool   `json:"non_basic_services_allowed"`
    52  	AppInstanceLimit        int    `json:"app_instance_limit"`
    53  	TotalReservedRoutePorts int    `json:"total_reserved_route_ports"`
    54  }
    55  
    56  // Space contains basic information about the targeted space.
    57  type Space struct {
    58  	GUID     string `json:"GUID"`
    59  	Name     string `json:"Name"`
    60  	AllowSSH bool   `json:"AllowSSH"`
    61  }
    62  
    63  // User represents the user information provided by the JWT access token.
    64  type User struct {
    65  	Name string
    66  }
    67  
    68  // AccessToken returns the access token for making authenticated API calls.
    69  func (config *Config) AccessToken() string {
    70  	return config.ConfigFile.AccessToken
    71  }
    72  
    73  // APIVersion returns the CC API Version.
    74  func (config *Config) APIVersion() string {
    75  	return config.ConfigFile.APIVersion
    76  }
    77  
    78  // CurrentUser returns user information decoded from the JWT access token in
    79  // .cf/config.json.
    80  func (config *Config) CurrentUser() (User, error) {
    81  	return decodeUserFromJWT(config.ConfigFile.AccessToken)
    82  }
    83  
    84  // CurrentUserName returns the name of a user as returned by CurrentUser()
    85  func (config *Config) CurrentUserName() (string, error) {
    86  	user, err := config.CurrentUser()
    87  	if err != nil {
    88  		return "", err
    89  	}
    90  	return user.Name, nil
    91  }
    92  
    93  // HasTargetedOrganization returns true if the organization is set.
    94  func (config *Config) HasTargetedOrganization() bool {
    95  	return config.ConfigFile.TargetedOrganization.GUID != ""
    96  }
    97  
    98  // HasTargetedSpace returns true if the space is set.
    99  func (config *Config) HasTargetedSpace() bool {
   100  	return config.ConfigFile.TargetedSpace.GUID != ""
   101  }
   102  
   103  // MinCLIVersion returns the minimum CLI version requried by the CC.
   104  func (config *Config) MinCLIVersion() string {
   105  	return config.ConfigFile.MinCLIVersion
   106  }
   107  
   108  // OverallPollingTimeout returns the overall polling timeout for async
   109  // operations. The time is based off of:
   110  //   1. The config file's AsyncTimeout value (integer) is > 0
   111  //   2. Defaults to the DefaultOverallPollingTimeout
   112  func (config *Config) OverallPollingTimeout() time.Duration {
   113  	if config.ConfigFile.AsyncTimeout == 0 {
   114  		return DefaultOverallPollingTimeout
   115  	}
   116  	return time.Duration(config.ConfigFile.AsyncTimeout) * time.Minute
   117  }
   118  
   119  // RefreshToken returns the refresh token for getting a new access token.
   120  func (config *Config) RefreshToken() string {
   121  	return config.ConfigFile.RefreshToken
   122  }
   123  
   124  // SetAccessToken sets the current access token.
   125  func (config *Config) SetAccessToken(accessToken string) {
   126  	config.ConfigFile.AccessToken = accessToken
   127  }
   128  
   129  // SetOrganizationInformation sets the currently targeted organization.
   130  func (config *Config) SetOrganizationInformation(guid string, name string) {
   131  	config.ConfigFile.TargetedOrganization.GUID = guid
   132  	config.ConfigFile.TargetedOrganization.Name = name
   133  	config.ConfigFile.TargetedOrganization.QuotaDefinition = QuotaDefinition{}
   134  }
   135  
   136  // SetRefreshToken sets the current refresh token.
   137  func (config *Config) SetRefreshToken(refreshToken string) {
   138  	config.ConfigFile.RefreshToken = refreshToken
   139  }
   140  
   141  // SetSpaceInformation sets the currently targeted space.
   142  func (config *Config) SetSpaceInformation(guid string, name string, allowSSH bool) {
   143  	config.ConfigFile.TargetedSpace.GUID = guid
   144  	config.ConfigFile.TargetedSpace.Name = 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.ConfigFile.MinCLIVersion = 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  func decodeUserFromJWT(accessToken string) (User, error) {
   259  	if accessToken == "" {
   260  		return User{}, nil
   261  	}
   262  
   263  	token, err := jws.ParseJWT([]byte(accessToken[7:]))
   264  	if err != nil {
   265  		return User{}, err
   266  	}
   267  
   268  	claims := token.Claims()
   269  
   270  	var ID string
   271  	if claims.Has("user_name") {
   272  		ID = claims.Get("user_name").(string)
   273  	} else {
   274  		ID = claims.Get("client_id").(string)
   275  	}
   276  	return User{
   277  		Name: ID,
   278  	}, nil
   279  }