github.com/ablease/cli@v6.37.1-0.20180613014814-3adbb7d7fb19+incompatible/cf/configuration/coreconfig/config_repository.go (about)

     1  package coreconfig
     2  
     3  import (
     4  	"strings"
     5  	"sync"
     6  
     7  	"code.cloudfoundry.org/cli/cf/configuration"
     8  	"code.cloudfoundry.org/cli/cf/models"
     9  	"code.cloudfoundry.org/cli/version"
    10  	"github.com/blang/semver"
    11  )
    12  
    13  type ConfigRepository struct {
    14  	CFCLIVersion string
    15  	data         *Data
    16  	mutex        *sync.RWMutex
    17  	initOnce     *sync.Once
    18  	persistor    configuration.Persistor
    19  	onError      func(error)
    20  }
    21  
    22  type CCInfo struct {
    23  	APIVersion               string `json:"api_version"`
    24  	AuthorizationEndpoint    string `json:"authorization_endpoint"`
    25  	DopplerEndpoint          string `json:"doppler_logging_endpoint"`
    26  	MinCLIVersion            string `json:"min_cli_version"`
    27  	MinRecommendedCLIVersion string `json:"min_recommended_cli_version"`
    28  	SSHOAuthClient           string `json:"app_ssh_oauth_client"`
    29  	RoutingAPIEndpoint       string `json:"routing_endpoint"`
    30  }
    31  
    32  func NewRepositoryFromFilepath(filepath string, errorHandler func(error)) Repository {
    33  	if errorHandler == nil {
    34  		return nil
    35  	}
    36  	return NewRepositoryFromPersistor(configuration.NewDiskPersistor(filepath), errorHandler)
    37  }
    38  
    39  func NewRepositoryFromPersistor(persistor configuration.Persistor, errorHandler func(error)) Repository {
    40  	data := NewData()
    41  	if !persistor.Exists() {
    42  		//set default plugin repo
    43  		data.PluginRepos = append(data.PluginRepos, models.PluginRepo{
    44  			Name: "CF-Community",
    45  			URL:  "https://plugins.cloudfoundry.org",
    46  		})
    47  	}
    48  
    49  	return &ConfigRepository{
    50  		data:      data,
    51  		mutex:     new(sync.RWMutex),
    52  		initOnce:  new(sync.Once),
    53  		persistor: persistor,
    54  		onError:   errorHandler,
    55  	}
    56  }
    57  
    58  type Reader interface {
    59  	APIEndpoint() string
    60  	APIVersion() string
    61  	HasAPIEndpoint() bool
    62  
    63  	AuthenticationEndpoint() string
    64  	DopplerEndpoint() string
    65  	UaaEndpoint() string
    66  	RoutingAPIEndpoint() string
    67  	AccessToken() string
    68  	UAAOAuthClient() string
    69  	UAAOAuthClientSecret() string
    70  	SSHOAuthClient() string
    71  	RefreshToken() string
    72  
    73  	OrganizationFields() models.OrganizationFields
    74  	HasOrganization() bool
    75  
    76  	SpaceFields() models.SpaceFields
    77  	HasSpace() bool
    78  
    79  	Username() string
    80  	UserGUID() string
    81  	UserEmail() string
    82  	IsLoggedIn() bool
    83  	IsSSLDisabled() bool
    84  	IsMinAPIVersion(semver.Version) bool
    85  	IsMinCLIVersion(string) bool
    86  	MinCLIVersion() string
    87  	MinRecommendedCLIVersion() string
    88  	CLIVersion() string
    89  
    90  	AsyncTimeout() uint
    91  	Trace() string
    92  
    93  	ColorEnabled() string
    94  
    95  	Locale() string
    96  
    97  	PluginRepos() []models.PluginRepo
    98  }
    99  
   100  //go:generate counterfeiter . ReadWriter
   101  
   102  type ReadWriter interface {
   103  	Reader
   104  	ClearSession()
   105  	SetAccessToken(string)
   106  	SetAPIEndpoint(string)
   107  	SetAPIVersion(string)
   108  	SetAsyncTimeout(uint)
   109  	SetAuthenticationEndpoint(string)
   110  	SetCLIVersion(string)
   111  	SetColorEnabled(string)
   112  	SetDopplerEndpoint(string)
   113  	SetLocale(string)
   114  	SetMinCLIVersion(string)
   115  	SetMinRecommendedCLIVersion(string)
   116  	SetOrganizationFields(models.OrganizationFields)
   117  	SetPluginRepo(models.PluginRepo)
   118  	SetRefreshToken(string)
   119  	SetRoutingAPIEndpoint(string)
   120  	SetSpaceFields(models.SpaceFields)
   121  	SetSSHOAuthClient(string)
   122  	SetSSLDisabled(bool)
   123  	SetTrace(string)
   124  	SetUaaEndpoint(string)
   125  	SetUAAGrantType(string)
   126  	SetUAAOAuthClient(string)
   127  	SetUAAOAuthClientSecret(string)
   128  	UAAGrantType() string
   129  	UnSetPluginRepo(int)
   130  }
   131  
   132  //go:generate counterfeiter . Repository
   133  
   134  type Repository interface {
   135  	ReadWriter
   136  	Close()
   137  }
   138  
   139  // ACCESS CONTROL
   140  
   141  func (c *ConfigRepository) init() {
   142  	c.initOnce.Do(func() {
   143  		err := c.persistor.Load(c.data)
   144  		if err != nil {
   145  			c.onError(err)
   146  		}
   147  	})
   148  }
   149  
   150  func (c *ConfigRepository) read(cb func()) {
   151  	c.mutex.RLock()
   152  	defer c.mutex.RUnlock()
   153  	c.init()
   154  
   155  	cb()
   156  }
   157  
   158  func (c *ConfigRepository) write(cb func()) {
   159  	c.mutex.Lock()
   160  	defer c.mutex.Unlock()
   161  	c.init()
   162  
   163  	cb()
   164  
   165  	err := c.persistor.Save(c.data)
   166  	if err != nil {
   167  		c.onError(err)
   168  	}
   169  }
   170  
   171  // CLOSERS
   172  
   173  func (c *ConfigRepository) Close() {
   174  	c.read(func() {
   175  		// perform a read to ensure write lock has been cleared
   176  	})
   177  }
   178  
   179  // GETTERS
   180  
   181  func (c *ConfigRepository) APIVersion() (apiVersion string) {
   182  	c.read(func() {
   183  		apiVersion = c.data.APIVersion
   184  	})
   185  	return
   186  }
   187  
   188  func (c *ConfigRepository) AuthenticationEndpoint() (authEndpoint string) {
   189  	c.read(func() {
   190  		authEndpoint = c.data.AuthorizationEndpoint
   191  	})
   192  	return
   193  }
   194  
   195  func (c *ConfigRepository) DopplerEndpoint() (dopplerEndpoint string) {
   196  	c.read(func() {
   197  		dopplerEndpoint = c.data.DopplerEndPoint
   198  	})
   199  
   200  	return
   201  }
   202  
   203  func (c *ConfigRepository) UaaEndpoint() (uaaEndpoint string) {
   204  	c.read(func() {
   205  		uaaEndpoint = c.data.UaaEndpoint
   206  	})
   207  	return
   208  }
   209  
   210  func (c *ConfigRepository) RoutingAPIEndpoint() (routingAPIEndpoint string) {
   211  	c.read(func() {
   212  		routingAPIEndpoint = c.data.RoutingAPIEndpoint
   213  	})
   214  	return
   215  }
   216  
   217  func (c *ConfigRepository) APIEndpoint() string {
   218  	var apiEndpoint string
   219  	c.read(func() {
   220  		apiEndpoint = c.data.Target
   221  	})
   222  	apiEndpoint = strings.TrimRight(apiEndpoint, "/")
   223  
   224  	return apiEndpoint
   225  }
   226  
   227  func (c *ConfigRepository) HasAPIEndpoint() (hasEndpoint bool) {
   228  	c.read(func() {
   229  		hasEndpoint = c.data.APIVersion != "" && c.data.Target != ""
   230  	})
   231  	return
   232  }
   233  
   234  func (c *ConfigRepository) AccessToken() (accessToken string) {
   235  	c.read(func() {
   236  		accessToken = c.data.AccessToken
   237  	})
   238  	return
   239  }
   240  
   241  func (c *ConfigRepository) UAAOAuthClient() (clientID string) {
   242  	c.read(func() {
   243  		clientID = c.data.UAAOAuthClient
   244  	})
   245  	return
   246  }
   247  
   248  func (c *ConfigRepository) UAAOAuthClientSecret() (clientID string) {
   249  	c.read(func() {
   250  		clientID = c.data.UAAOAuthClientSecret
   251  	})
   252  	return
   253  }
   254  
   255  func (c *ConfigRepository) SSHOAuthClient() (clientID string) {
   256  	c.read(func() {
   257  		clientID = c.data.SSHOAuthClient
   258  	})
   259  	return
   260  }
   261  
   262  func (c *ConfigRepository) RefreshToken() (refreshToken string) {
   263  	c.read(func() {
   264  		refreshToken = c.data.RefreshToken
   265  	})
   266  	return
   267  }
   268  
   269  func (c *ConfigRepository) OrganizationFields() (org models.OrganizationFields) {
   270  	c.read(func() {
   271  		org = c.data.OrganizationFields
   272  	})
   273  	return
   274  }
   275  
   276  func (c *ConfigRepository) SpaceFields() (space models.SpaceFields) {
   277  	c.read(func() {
   278  		space = c.data.SpaceFields
   279  	})
   280  	return
   281  }
   282  
   283  func (c *ConfigRepository) UserEmail() (email string) {
   284  	c.read(func() {
   285  		email = NewTokenInfo(c.data.AccessToken).Email
   286  	})
   287  	return
   288  }
   289  
   290  func (c *ConfigRepository) UserGUID() (guid string) {
   291  	c.read(func() {
   292  		guid = NewTokenInfo(c.data.AccessToken).UserGUID
   293  	})
   294  	return
   295  }
   296  
   297  func (c *ConfigRepository) Username() (name string) {
   298  	c.read(func() {
   299  		name = NewTokenInfo(c.data.AccessToken).Username
   300  	})
   301  	return
   302  }
   303  
   304  func (c *ConfigRepository) IsLoggedIn() (loggedIn bool) {
   305  	c.read(func() {
   306  		loggedIn = c.data.AccessToken != ""
   307  	})
   308  	return
   309  }
   310  
   311  func (c *ConfigRepository) HasOrganization() (hasOrg bool) {
   312  	c.read(func() {
   313  		hasOrg = c.data.OrganizationFields.GUID != "" && c.data.OrganizationFields.Name != ""
   314  	})
   315  	return
   316  }
   317  
   318  func (c *ConfigRepository) HasSpace() (hasSpace bool) {
   319  	c.read(func() {
   320  		hasSpace = c.data.SpaceFields.GUID != "" && c.data.SpaceFields.Name != ""
   321  	})
   322  	return
   323  }
   324  
   325  func (c *ConfigRepository) IsSSLDisabled() (isSSLDisabled bool) {
   326  	c.read(func() {
   327  		isSSLDisabled = c.data.SSLDisabled
   328  	})
   329  	return
   330  }
   331  
   332  // SetCLIVersion should only be used in testing
   333  func (c *ConfigRepository) SetCLIVersion(v string) {
   334  	c.CFCLIVersion = v
   335  }
   336  
   337  func (c *ConfigRepository) CLIVersion() string {
   338  	if c.CFCLIVersion == "" {
   339  		return version.VersionString()
   340  	} else {
   341  		return c.CFCLIVersion
   342  	}
   343  }
   344  
   345  func (c *ConfigRepository) IsMinAPIVersion(requiredVersion semver.Version) bool {
   346  	var apiVersion string
   347  	c.read(func() {
   348  		apiVersion = c.data.APIVersion
   349  	})
   350  
   351  	actualVersion, err := semver.Make(apiVersion)
   352  	if err != nil {
   353  		return false
   354  	}
   355  	return actualVersion.GTE(requiredVersion)
   356  }
   357  
   358  func (c *ConfigRepository) IsMinCLIVersion(checkVersion string) bool {
   359  	if checkVersion == version.DefaultVersion {
   360  		return true
   361  	}
   362  	var minCLIVersion string
   363  	c.read(func() {
   364  		minCLIVersion = c.data.MinCLIVersion
   365  	})
   366  	if minCLIVersion == "" {
   367  		return true
   368  	}
   369  
   370  	actualVersion, err := semver.Make(checkVersion)
   371  	if err != nil {
   372  		return false
   373  	}
   374  	requiredVersion, err := semver.Make(minCLIVersion)
   375  	if err != nil {
   376  		return false
   377  	}
   378  	return actualVersion.GTE(requiredVersion)
   379  }
   380  
   381  func (c *ConfigRepository) MinCLIVersion() (minCLIVersion string) {
   382  	c.read(func() {
   383  		minCLIVersion = c.data.MinCLIVersion
   384  	})
   385  	return
   386  }
   387  
   388  func (c *ConfigRepository) MinRecommendedCLIVersion() (minRecommendedCLIVersion string) {
   389  	c.read(func() {
   390  		minRecommendedCLIVersion = c.data.MinRecommendedCLIVersion
   391  	})
   392  	return
   393  }
   394  
   395  func (c *ConfigRepository) AsyncTimeout() (timeout uint) {
   396  	c.read(func() {
   397  		timeout = c.data.AsyncTimeout
   398  	})
   399  	return
   400  }
   401  
   402  func (c *ConfigRepository) Trace() (trace string) {
   403  	c.read(func() {
   404  		trace = c.data.Trace
   405  	})
   406  	return
   407  }
   408  
   409  func (c *ConfigRepository) ColorEnabled() (enabled string) {
   410  	c.read(func() {
   411  		enabled = c.data.ColorEnabled
   412  	})
   413  	return
   414  }
   415  
   416  func (c *ConfigRepository) Locale() (locale string) {
   417  	c.read(func() {
   418  		locale = c.data.Locale
   419  	})
   420  	return
   421  }
   422  
   423  func (c *ConfigRepository) PluginRepos() (repos []models.PluginRepo) {
   424  	c.read(func() {
   425  		repos = c.data.PluginRepos
   426  	})
   427  	return
   428  }
   429  
   430  // SETTERS
   431  
   432  func (c *ConfigRepository) ClearSession() {
   433  	c.write(func() {
   434  		c.data.AccessToken = ""
   435  		c.data.RefreshToken = ""
   436  		c.data.OrganizationFields = models.OrganizationFields{}
   437  		c.data.SpaceFields = models.SpaceFields{}
   438  	})
   439  }
   440  
   441  func (c *ConfigRepository) SetAPIEndpoint(endpoint string) {
   442  	c.write(func() {
   443  		c.data.Target = endpoint
   444  	})
   445  }
   446  
   447  func (c *ConfigRepository) SetAPIVersion(version string) {
   448  	c.write(func() {
   449  		c.data.APIVersion = version
   450  	})
   451  }
   452  
   453  func (c *ConfigRepository) SetMinCLIVersion(version string) {
   454  	c.write(func() {
   455  		c.data.MinCLIVersion = version
   456  	})
   457  }
   458  
   459  func (c *ConfigRepository) SetMinRecommendedCLIVersion(version string) {
   460  	c.write(func() {
   461  		c.data.MinRecommendedCLIVersion = version
   462  	})
   463  }
   464  
   465  func (c *ConfigRepository) SetAuthenticationEndpoint(endpoint string) {
   466  	c.write(func() {
   467  		c.data.AuthorizationEndpoint = endpoint
   468  	})
   469  }
   470  
   471  func (c *ConfigRepository) SetDopplerEndpoint(endpoint string) {
   472  	c.write(func() {
   473  		c.data.DopplerEndPoint = endpoint
   474  	})
   475  }
   476  
   477  func (c *ConfigRepository) SetUaaEndpoint(uaaEndpoint string) {
   478  	c.write(func() {
   479  		c.data.UaaEndpoint = uaaEndpoint
   480  	})
   481  }
   482  
   483  func (c *ConfigRepository) SetRoutingAPIEndpoint(routingAPIEndpoint string) {
   484  	c.write(func() {
   485  		c.data.RoutingAPIEndpoint = routingAPIEndpoint
   486  	})
   487  }
   488  
   489  func (c *ConfigRepository) SetAccessToken(token string) {
   490  	c.write(func() {
   491  		c.data.AccessToken = token
   492  	})
   493  }
   494  
   495  func (c *ConfigRepository) SetUAAOAuthClient(clientID string) {
   496  	c.write(func() {
   497  		c.data.UAAOAuthClient = clientID
   498  	})
   499  }
   500  
   501  func (c *ConfigRepository) SetUAAOAuthClientSecret(clientID string) {
   502  	c.write(func() {
   503  		c.data.UAAOAuthClientSecret = clientID
   504  	})
   505  }
   506  
   507  func (c *ConfigRepository) SetSSHOAuthClient(clientID string) {
   508  	c.write(func() {
   509  		c.data.SSHOAuthClient = clientID
   510  	})
   511  }
   512  
   513  func (c *ConfigRepository) SetRefreshToken(token string) {
   514  	c.write(func() {
   515  		c.data.RefreshToken = token
   516  	})
   517  }
   518  
   519  func (c *ConfigRepository) SetOrganizationFields(org models.OrganizationFields) {
   520  	c.write(func() {
   521  		c.data.OrganizationFields = org
   522  	})
   523  }
   524  
   525  func (c *ConfigRepository) SetSpaceFields(space models.SpaceFields) {
   526  	c.write(func() {
   527  		c.data.SpaceFields = space
   528  	})
   529  }
   530  
   531  func (c *ConfigRepository) SetSSLDisabled(disabled bool) {
   532  	c.write(func() {
   533  		c.data.SSLDisabled = disabled
   534  	})
   535  }
   536  
   537  func (c *ConfigRepository) SetAsyncTimeout(timeout uint) {
   538  	c.write(func() {
   539  		c.data.AsyncTimeout = timeout
   540  	})
   541  }
   542  
   543  func (c *ConfigRepository) SetTrace(value string) {
   544  	c.write(func() {
   545  		c.data.Trace = value
   546  	})
   547  }
   548  
   549  func (c *ConfigRepository) SetColorEnabled(enabled string) {
   550  	c.write(func() {
   551  		c.data.ColorEnabled = enabled
   552  	})
   553  }
   554  
   555  func (c *ConfigRepository) SetLocale(locale string) {
   556  	c.write(func() {
   557  		c.data.Locale = locale
   558  	})
   559  }
   560  
   561  func (c *ConfigRepository) SetPluginRepo(repo models.PluginRepo) {
   562  	c.write(func() {
   563  		c.data.PluginRepos = append(c.data.PluginRepos, repo)
   564  	})
   565  }
   566  
   567  func (c *ConfigRepository) UnSetPluginRepo(index int) {
   568  	c.write(func() {
   569  		c.data.PluginRepos = append(c.data.PluginRepos[:index], c.data.PluginRepos[index+1:]...)
   570  	})
   571  }
   572  
   573  func (c *ConfigRepository) UAAGrantType() string {
   574  	grantType := ""
   575  	c.read(func() {
   576  		grantType = c.data.UAAGrantType
   577  	})
   578  	return grantType
   579  }
   580  
   581  func (c *ConfigRepository) SetUAAGrantType(grantType string) {
   582  	c.write(func() {
   583  		c.data.UAAGrantType = grantType
   584  	})
   585  }