github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+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  		t := NewTokenInfo(c.data.AccessToken)
   300  		if t.Username != "" {
   301  			name = t.Username
   302  		} else {
   303  			name = t.ClientID
   304  		}
   305  	})
   306  	return
   307  }
   308  
   309  func (c *ConfigRepository) IsLoggedIn() (loggedIn bool) {
   310  	c.read(func() {
   311  		loggedIn = c.data.AccessToken != ""
   312  	})
   313  	return
   314  }
   315  
   316  func (c *ConfigRepository) HasOrganization() (hasOrg bool) {
   317  	c.read(func() {
   318  		hasOrg = c.data.OrganizationFields.GUID != "" && c.data.OrganizationFields.Name != ""
   319  	})
   320  	return
   321  }
   322  
   323  func (c *ConfigRepository) HasSpace() (hasSpace bool) {
   324  	c.read(func() {
   325  		hasSpace = c.data.SpaceFields.GUID != "" && c.data.SpaceFields.Name != ""
   326  	})
   327  	return
   328  }
   329  
   330  func (c *ConfigRepository) IsSSLDisabled() (isSSLDisabled bool) {
   331  	c.read(func() {
   332  		isSSLDisabled = c.data.SSLDisabled
   333  	})
   334  	return
   335  }
   336  
   337  // SetCLIVersion should only be used in testing
   338  func (c *ConfigRepository) SetCLIVersion(v string) {
   339  	c.CFCLIVersion = v
   340  }
   341  
   342  func (c *ConfigRepository) CLIVersion() string {
   343  	if c.CFCLIVersion == "" {
   344  		return version.VersionString()
   345  	} else {
   346  		return c.CFCLIVersion
   347  	}
   348  }
   349  
   350  func (c *ConfigRepository) IsMinAPIVersion(requiredVersion semver.Version) bool {
   351  	var apiVersion string
   352  	c.read(func() {
   353  		apiVersion = c.data.APIVersion
   354  	})
   355  
   356  	actualVersion, err := semver.Make(apiVersion)
   357  	if err != nil {
   358  		return false
   359  	}
   360  	return actualVersion.GTE(requiredVersion)
   361  }
   362  
   363  func (c *ConfigRepository) IsMinCLIVersion(checkVersion string) bool {
   364  	if checkVersion == version.DefaultVersion {
   365  		return true
   366  	}
   367  	var minCLIVersion string
   368  	c.read(func() {
   369  		minCLIVersion = c.data.MinCLIVersion
   370  	})
   371  	if minCLIVersion == "" {
   372  		return true
   373  	}
   374  
   375  	actualVersion, err := semver.Make(checkVersion)
   376  	if err != nil {
   377  		return false
   378  	}
   379  	requiredVersion, err := semver.Make(minCLIVersion)
   380  	if err != nil {
   381  		return false
   382  	}
   383  	return actualVersion.GTE(requiredVersion)
   384  }
   385  
   386  func (c *ConfigRepository) MinCLIVersion() (minCLIVersion string) {
   387  	c.read(func() {
   388  		minCLIVersion = c.data.MinCLIVersion
   389  	})
   390  	return
   391  }
   392  
   393  func (c *ConfigRepository) MinRecommendedCLIVersion() (minRecommendedCLIVersion string) {
   394  	c.read(func() {
   395  		minRecommendedCLIVersion = c.data.MinRecommendedCLIVersion
   396  	})
   397  	return
   398  }
   399  
   400  func (c *ConfigRepository) AsyncTimeout() (timeout uint) {
   401  	c.read(func() {
   402  		timeout = c.data.AsyncTimeout
   403  	})
   404  	return
   405  }
   406  
   407  func (c *ConfigRepository) Trace() (trace string) {
   408  	c.read(func() {
   409  		trace = c.data.Trace
   410  	})
   411  	return
   412  }
   413  
   414  func (c *ConfigRepository) ColorEnabled() (enabled string) {
   415  	c.read(func() {
   416  		enabled = c.data.ColorEnabled
   417  	})
   418  	return
   419  }
   420  
   421  func (c *ConfigRepository) Locale() (locale string) {
   422  	c.read(func() {
   423  		locale = c.data.Locale
   424  	})
   425  	return
   426  }
   427  
   428  func (c *ConfigRepository) PluginRepos() (repos []models.PluginRepo) {
   429  	c.read(func() {
   430  		repos = c.data.PluginRepos
   431  	})
   432  	return
   433  }
   434  
   435  // SETTERS
   436  
   437  func (c *ConfigRepository) ClearSession() {
   438  	c.write(func() {
   439  		c.data.AccessToken = ""
   440  		c.data.RefreshToken = ""
   441  		c.data.OrganizationFields = models.OrganizationFields{}
   442  		c.data.SpaceFields = models.SpaceFields{}
   443  	})
   444  }
   445  
   446  func (c *ConfigRepository) SetAPIEndpoint(endpoint string) {
   447  	c.write(func() {
   448  		c.data.Target = endpoint
   449  	})
   450  }
   451  
   452  func (c *ConfigRepository) SetAPIVersion(version string) {
   453  	c.write(func() {
   454  		c.data.APIVersion = version
   455  	})
   456  }
   457  
   458  func (c *ConfigRepository) SetMinCLIVersion(version string) {
   459  	c.write(func() {
   460  		c.data.MinCLIVersion = version
   461  	})
   462  }
   463  
   464  func (c *ConfigRepository) SetMinRecommendedCLIVersion(version string) {
   465  	c.write(func() {
   466  		c.data.MinRecommendedCLIVersion = version
   467  	})
   468  }
   469  
   470  func (c *ConfigRepository) SetAuthenticationEndpoint(endpoint string) {
   471  	c.write(func() {
   472  		c.data.AuthorizationEndpoint = endpoint
   473  	})
   474  }
   475  
   476  func (c *ConfigRepository) SetDopplerEndpoint(endpoint string) {
   477  	c.write(func() {
   478  		c.data.DopplerEndPoint = endpoint
   479  	})
   480  }
   481  
   482  func (c *ConfigRepository) SetUaaEndpoint(uaaEndpoint string) {
   483  	c.write(func() {
   484  		c.data.UaaEndpoint = uaaEndpoint
   485  	})
   486  }
   487  
   488  func (c *ConfigRepository) SetRoutingAPIEndpoint(routingAPIEndpoint string) {
   489  	c.write(func() {
   490  		c.data.RoutingAPIEndpoint = routingAPIEndpoint
   491  	})
   492  }
   493  
   494  func (c *ConfigRepository) SetAccessToken(token string) {
   495  	c.write(func() {
   496  		c.data.AccessToken = token
   497  	})
   498  }
   499  
   500  func (c *ConfigRepository) SetUAAOAuthClient(clientID string) {
   501  	c.write(func() {
   502  		c.data.UAAOAuthClient = clientID
   503  	})
   504  }
   505  
   506  func (c *ConfigRepository) SetUAAOAuthClientSecret(clientID string) {
   507  	c.write(func() {
   508  		c.data.UAAOAuthClientSecret = clientID
   509  	})
   510  }
   511  
   512  func (c *ConfigRepository) SetSSHOAuthClient(clientID string) {
   513  	c.write(func() {
   514  		c.data.SSHOAuthClient = clientID
   515  	})
   516  }
   517  
   518  func (c *ConfigRepository) SetRefreshToken(token string) {
   519  	c.write(func() {
   520  		c.data.RefreshToken = token
   521  	})
   522  }
   523  
   524  func (c *ConfigRepository) SetOrganizationFields(org models.OrganizationFields) {
   525  	c.write(func() {
   526  		c.data.OrganizationFields = org
   527  	})
   528  }
   529  
   530  func (c *ConfigRepository) SetSpaceFields(space models.SpaceFields) {
   531  	c.write(func() {
   532  		c.data.SpaceFields = space
   533  	})
   534  }
   535  
   536  func (c *ConfigRepository) SetSSLDisabled(disabled bool) {
   537  	c.write(func() {
   538  		c.data.SSLDisabled = disabled
   539  	})
   540  }
   541  
   542  func (c *ConfigRepository) SetAsyncTimeout(timeout uint) {
   543  	c.write(func() {
   544  		c.data.AsyncTimeout = timeout
   545  	})
   546  }
   547  
   548  func (c *ConfigRepository) SetTrace(value string) {
   549  	c.write(func() {
   550  		c.data.Trace = value
   551  	})
   552  }
   553  
   554  func (c *ConfigRepository) SetColorEnabled(enabled string) {
   555  	c.write(func() {
   556  		c.data.ColorEnabled = enabled
   557  	})
   558  }
   559  
   560  func (c *ConfigRepository) SetLocale(locale string) {
   561  	c.write(func() {
   562  		c.data.Locale = locale
   563  	})
   564  }
   565  
   566  func (c *ConfigRepository) SetPluginRepo(repo models.PluginRepo) {
   567  	c.write(func() {
   568  		c.data.PluginRepos = append(c.data.PluginRepos, repo)
   569  	})
   570  }
   571  
   572  func (c *ConfigRepository) UnSetPluginRepo(index int) {
   573  	c.write(func() {
   574  		c.data.PluginRepos = append(c.data.PluginRepos[:index], c.data.PluginRepos[index+1:]...)
   575  	})
   576  }
   577  
   578  func (c *ConfigRepository) UAAGrantType() string {
   579  	grantType := ""
   580  	c.read(func() {
   581  		grantType = c.data.UAAGrantType
   582  	})
   583  	return grantType
   584  }
   585  
   586  func (c *ConfigRepository) SetUAAGrantType(grantType string) {
   587  	c.write(func() {
   588  		c.data.UAAGrantType = grantType
   589  	})
   590  }