github.com/jfrog/jfrog-cli-core/v2@v2.51.0/utils/config/config.go (about) 1 package config 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "errors" 7 "github.com/buger/jsonparser" 8 biutils "github.com/jfrog/build-info-go/utils" 9 "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" 10 cliLog "github.com/jfrog/jfrog-cli-core/v2/utils/log" 11 accessAuth "github.com/jfrog/jfrog-client-go/access/auth" 12 artifactoryAuth "github.com/jfrog/jfrog-client-go/artifactory/auth" 13 "github.com/jfrog/jfrog-client-go/auth" 14 distributionAuth "github.com/jfrog/jfrog-client-go/distribution/auth" 15 lifecycleAuth "github.com/jfrog/jfrog-client-go/lifecycle/auth" 16 pipelinesAuth "github.com/jfrog/jfrog-client-go/pipelines/auth" 17 "github.com/jfrog/jfrog-client-go/utils" 18 "github.com/jfrog/jfrog-client-go/utils/errorutils" 19 "github.com/jfrog/jfrog-client-go/utils/io/fileutils" 20 "github.com/jfrog/jfrog-client-go/utils/log" 21 xrayAuth "github.com/jfrog/jfrog-client-go/xray/auth" 22 xscAuth "github.com/jfrog/jfrog-client-go/xsc/auth" 23 "os" 24 "path/filepath" 25 "strconv" 26 "strings" 27 "time" 28 ) 29 30 func init() { 31 cliLog.SetDefaultLogger() 32 } 33 34 // This is the default server id. It is used when adding a server config without providing a server ID 35 const DefaultServerId = "Default-Server" 36 37 func IsServerConfExists() (bool, error) { 38 conf, err := readConf() 39 if err != nil { 40 return false, err 41 } 42 return conf.Servers != nil && len(conf.Servers) > 0, nil 43 } 44 45 // Returns the configured server or error if the server id was not found. 46 // If defaultOrEmpty: return empty details if no configurations found, or default conf for empty serverId. 47 // Exclude refreshable tokens when working with external tools (build tools, curl, etc.) or when sending requests not via ArtifactoryHttpClient. 48 func GetSpecificConfig(serverId string, defaultOrEmpty bool, excludeRefreshableTokens bool) (*ServerDetails, error) { 49 configs, err := GetAllServersConfigs() 50 if err != nil { 51 return nil, err 52 } 53 54 if defaultOrEmpty { 55 if len(configs) == 0 { 56 return new(ServerDetails), nil 57 } 58 if len(serverId) == 0 { 59 details, err := GetDefaultConfiguredConf(configs) 60 if excludeRefreshableTokens { 61 excludeRefreshableTokensFromDetails(details) 62 } 63 return details, errorutils.CheckError(err) 64 } 65 } 66 67 details, err := getServerConfByServerId(serverId, configs) 68 if err != nil { 69 return nil, err 70 } 71 if excludeRefreshableTokens { 72 excludeRefreshableTokensFromDetails(details) 73 } 74 return details, nil 75 } 76 77 // Disables the refreshable tokens mechanism if set in details. 78 // We identify the refreshable tokens mechanism by having both conditions: 79 // 1. Non-empty username and password 80 // 2. Non-empty access and refresh token OR token refresh interval enabled 81 func excludeRefreshableTokensFromDetails(details *ServerDetails) { 82 if details.WebLogin || details.User == "" || details.Password == "" { 83 return 84 } 85 if details.AccessToken != "" && details.ArtifactoryRefreshToken != "" || 86 details.AccessToken != "" && details.RefreshToken != "" { 87 details.AccessToken = "" 88 details.ArtifactoryRefreshToken = "" 89 details.RefreshToken = "" 90 } 91 details.ArtifactoryTokenRefreshInterval = coreutils.TokenRefreshDisabled 92 } 93 94 // Returns the default server configuration or error if not found. 95 // Caller should perform the check error if required. 96 func GetDefaultConfiguredConf(configs []*ServerDetails) (*ServerDetails, error) { 97 if len(configs) == 0 { 98 details := new(ServerDetails) 99 details.IsDefault = true 100 return details, nil 101 } 102 for _, conf := range configs { 103 if conf.IsDefault { 104 return conf, nil 105 } 106 } 107 return nil, errors.New("couldn't find default server") 108 } 109 110 // Returns default artifactory conf. Returns nil if default server doesn't exists. 111 func GetDefaultServerConf() (*ServerDetails, error) { 112 configurations, err := GetAllServersConfigs() 113 if err != nil { 114 return nil, err 115 } 116 117 if len(configurations) == 0 { 118 log.Debug("No servers were configured.") 119 return nil, err 120 } 121 122 return GetDefaultConfiguredConf(configurations) 123 } 124 125 // Returns the configured server or error if the server id not found 126 func getServerConfByServerId(serverId string, configs []*ServerDetails) (*ServerDetails, error) { 127 for _, conf := range configs { 128 if conf.ServerId == serverId { 129 return conf, nil 130 } 131 } 132 return nil, errorutils.CheckErrorf("Server ID '%s' does not exist.", serverId) 133 } 134 135 func GetAndRemoveConfiguration(serverName string, configs []*ServerDetails) (*ServerDetails, []*ServerDetails) { 136 for i, conf := range configs { 137 if conf.ServerId == serverName { 138 configs = append(configs[:i], configs[i+1:]...) 139 return conf, configs 140 } 141 } 142 return nil, configs 143 } 144 145 func GetAllServersConfigs() ([]*ServerDetails, error) { 146 conf, err := readConf() 147 if err != nil { 148 return nil, err 149 } 150 details := conf.Servers 151 if details == nil { 152 return make([]*ServerDetails, 0), nil 153 } 154 return details, nil 155 } 156 157 func SaveServersConf(details []*ServerDetails) error { 158 conf, err := readConf() 159 if err != nil { 160 return err 161 } 162 conf.Servers = details 163 conf.Version = strconv.Itoa(coreutils.GetCliConfigVersion()) 164 return saveConfig(conf) 165 } 166 167 func saveConfig(config *Config) error { 168 cloneConfig, err := config.Clone() 169 if err != nil { 170 return err 171 } 172 err = cloneConfig.encrypt() 173 if err != nil { 174 return err 175 } 176 177 content, err := cloneConfig.getContent() 178 if err != nil { 179 return err 180 } 181 182 path, err := getConfFilePath() 183 if err != nil { 184 return err 185 } 186 187 err = os.WriteFile(path, content, 0600) 188 if err != nil { 189 return errorutils.CheckError(err) 190 } 191 return nil 192 } 193 194 func readConf() (*Config, error) { 195 config := new(Config) 196 content, err := getConfigFile() 197 if err != nil { 198 return nil, err 199 } 200 if len(content) == 0 { 201 // No config file was found, returns a new empty config. 202 return config, nil 203 } 204 content, err = convertIfNeeded(content) 205 if err != nil { 206 return nil, err 207 } 208 209 err = json.Unmarshal(content, &config) 210 if err != nil { 211 return nil, errorutils.CheckError(err) 212 } 213 214 err = config.decrypt() 215 return config, err 216 } 217 218 func getConfigFile() (content []byte, err error) { 219 confFilePath, err := getConfFilePath() 220 if err != nil { 221 return 222 } 223 exists, err := fileutils.IsFileExists(confFilePath, false) 224 if err != nil { 225 return 226 } 227 if exists { 228 content, err = fileutils.ReadFile(confFilePath) 229 return 230 } 231 // Try to look for older config files 232 for i := coreutils.GetCliConfigVersion() - 1; i >= 3; i-- { 233 var versionedConfigPath string 234 versionedConfigPath, err = getLegacyConfigFilePath(i) 235 if err != nil { 236 return 237 } 238 exists, err = fileutils.IsFileExists(versionedConfigPath, false) 239 if err != nil { 240 return 241 } 242 if exists { 243 // If an old config file was found returns its content or an error. 244 content, err = fileutils.ReadFile(versionedConfigPath) 245 return 246 } 247 } 248 249 return 250 } 251 252 func (config *Config) Clone() (*Config, error) { 253 bytes, err := json.Marshal(config) 254 if err != nil { 255 return nil, errorutils.CheckError(err) 256 } 257 clone := &Config{} 258 if err = json.Unmarshal(bytes, clone); err != nil { 259 return nil, errorutils.CheckError(err) 260 } 261 return clone, nil 262 } 263 264 func (config *Config) getContent() ([]byte, error) { 265 b, err := json.Marshal(&config) 266 if err != nil { 267 return []byte{}, errorutils.CheckError(err) 268 } 269 var content bytes.Buffer 270 err = json.Indent(&content, b, "", " ") 271 if err != nil { 272 return []byte{}, errorutils.CheckError(err) 273 } 274 return content.Bytes(), nil 275 } 276 277 // Move SSL certificates from the old location in security dir to certs dir. 278 func convertCertsDir() error { 279 securityDir, err := coreutils.GetJfrogSecurityDir() 280 if err != nil { 281 return err 282 } 283 exists, err := fileutils.IsDirExists(securityDir, false) 284 // Security dir doesn't exist, no conversion needed. 285 if err != nil || !exists { 286 return err 287 } 288 289 certsDir, err := coreutils.GetJfrogCertsDir() 290 if err != nil { 291 return err 292 } 293 exists, err = fileutils.IsDirExists(certsDir, false) 294 // Certs dir already exists, no conversion needed. 295 if err != nil || exists { 296 return err 297 } 298 299 // Move certs to the new location. 300 files, err := os.ReadDir(securityDir) 301 if err != nil { 302 return errorutils.CheckError(err) 303 } 304 305 log.Debug("Migrating SSL certificates to the new location at: " + certsDir) 306 for _, f := range files { 307 // Skip directories and the security configuration file 308 if !f.IsDir() && f.Name() != coreutils.JfrogSecurityConfFile { 309 err = fileutils.CreateDirIfNotExist(certsDir) 310 if err != nil { 311 return err 312 } 313 err = os.Rename(filepath.Join(securityDir, f.Name()), filepath.Join(certsDir, f.Name())) 314 if err != nil { 315 return errorutils.CheckError(err) 316 } 317 } 318 } 319 return nil 320 } 321 322 // The configuration schema can change between versions, therefore we need to convert old versions to the new schema. 323 func convertIfNeeded(content []byte) ([]byte, error) { 324 version, err := getVersion(content) 325 if err != nil { 326 return nil, err 327 } 328 329 // Switch contains FALLTHROUGH to convert from a certain version to the latest. 330 switch version { 331 case strconv.Itoa(coreutils.GetCliConfigVersion()): 332 return content, nil 333 case "0": 334 content, err = convertConfigV0toV1(content) 335 if err != nil { 336 return nil, err 337 } 338 fallthrough 339 case "1": 340 err = createHomeDirBackup() 341 if err != nil { 342 return nil, err 343 } 344 err = convertCertsDir() 345 if err != nil { 346 return nil, err 347 } 348 fallthrough 349 case "2": 350 content, err = convertConfigV2toV3(content) 351 if err != nil { 352 return nil, err 353 } 354 fallthrough 355 case "3", "4": 356 content, err = convertConfigV4toV5(content) 357 if err != nil { 358 return nil, err 359 } 360 fallthrough 361 case "5": 362 content, err = convertConfigV5toV6(content) 363 } 364 if err != nil { 365 return nil, err 366 } 367 368 // Save config after all conversions (also updates version). 369 result := new(Config) 370 err = json.Unmarshal(content, &result) 371 if errorutils.CheckError(err) != nil { 372 return nil, err 373 } 374 result.Version = strconv.Itoa(coreutils.GetCliConfigVersion()) 375 err = saveConfig(result) 376 if err != nil { 377 return nil, err 378 } 379 content, err = json.Marshal(&result) 380 if err != nil { 381 return nil, errorutils.CheckError(err) 382 } 383 return content, err 384 } 385 386 // Creating a homedir backup prior to converting. 387 func createHomeDirBackup() error { 388 homeDir, err := coreutils.GetJfrogHomeDir() 389 if err != nil { 390 return err 391 } 392 backupDir, err := coreutils.GetJfrogBackupDir() 393 if err != nil { 394 return err 395 } 396 397 // Copy homedir contents to back up dir, excluding redundant dirs and the backup dir itself. 398 backupName := ".jfrog-" + strconv.FormatInt(time.Now().Unix(), 10) 399 curBackupPath := filepath.Join(backupDir, backupName) 400 log.Debug("Creating a homedir backup at: " + curBackupPath) 401 exclude := []string{coreutils.JfrogBackupDirName, coreutils.JfrogDependenciesDirName, coreutils.JfrogLocksDirName, coreutils.JfrogLogsDirName} 402 return biutils.CopyDir(homeDir, curBackupPath, true, exclude) 403 } 404 405 // Version key doesn't exist in version 0 406 // Version key is "Version" in version 1 407 // Version key is "version" in version 2 and above 408 func getVersion(content []byte) (value string, err error) { 409 value, err = jsonparser.GetString(bytes.ToLower(content), "version") 410 if err != nil && err.Error() == "Key path not found" { 411 return "0", nil 412 } 413 return value, errorutils.CheckError(err) 414 } 415 416 func convertConfigV0toV1(content []byte) ([]byte, error) { 417 result := new(ConfigV4) 418 configV0 := new(ConfigV0) 419 err := json.Unmarshal(content, &configV0) 420 if errorutils.CheckError(err) != nil { 421 return nil, err 422 } 423 result = configV0.Convert() 424 result.Version = "1" 425 content, err = json.Marshal(&result) 426 return content, errorutils.CheckError(err) 427 } 428 429 func convertConfigV2toV3(content []byte) ([]byte, error) { 430 config := new(ConfigV4) 431 err := json.Unmarshal(content, &config) 432 if errorutils.CheckError(err) != nil { 433 return nil, err 434 } 435 for _, rtConfig := range config.Artifactory { 436 rtConfig.User = strings.ToLower(rtConfig.User) 437 } 438 content, err = json.Marshal(&config) 439 return content, errorutils.CheckError(err) 440 } 441 442 func convertConfigV4toV5(content []byte) ([]byte, error) { 443 config := new(ConfigV4) 444 err := json.Unmarshal(content, &config) 445 if errorutils.CheckError(err) != nil { 446 return nil, err 447 } 448 449 result := config.Convert() 450 content, err = json.Marshal(&result) 451 return content, errorutils.CheckError(err) 452 } 453 454 func convertConfigV5toV6(content []byte) ([]byte, error) { 455 config := new(ConfigV5) 456 err := json.Unmarshal(content, &config) 457 if errorutils.CheckError(err) != nil { 458 return nil, err 459 } 460 461 result := config.Convert() 462 content, err = json.Marshal(&result) 463 return content, errorutils.CheckError(err) 464 } 465 466 func GetJfrogDependenciesPath() (string, error) { 467 dependenciesDir := os.Getenv(coreutils.DependenciesDir) 468 if dependenciesDir != "" { 469 return utils.AddTrailingSlashIfNeeded(dependenciesDir), nil 470 } 471 jfrogHome, err := coreutils.GetJfrogHomeDir() 472 if err != nil { 473 return "", err 474 } 475 return filepath.Join(jfrogHome, coreutils.JfrogDependenciesDirName), nil 476 } 477 478 func getConfFilePath() (string, error) { 479 confPath, err := coreutils.GetJfrogHomeDir() 480 if err != nil { 481 return "", err 482 } 483 err = os.MkdirAll(confPath, 0777) 484 if err != nil { 485 return "", err 486 } 487 488 versionString := ".v" + strconv.Itoa(coreutils.GetCliConfigVersion()) 489 confPath = filepath.Join(confPath, coreutils.JfrogConfigFile+versionString) 490 return confPath, nil 491 } 492 493 func getLegacyConfigFilePath(version int) (string, error) { 494 confPath, err := coreutils.GetJfrogHomeDir() 495 if err != nil { 496 return "", err 497 } 498 confPath = filepath.Join(confPath, coreutils.JfrogConfigFile) 499 // Before version 4 all the config files were saved with the same name. 500 if version < 4 { 501 return confPath, nil 502 } 503 return confPath + ".v" + strconv.Itoa(version), nil 504 505 } 506 507 // Config represents the CLI latest config version. 508 type Config struct { 509 ConfigV6 510 } 511 512 type ConfigV6 struct { 513 ConfigV5 514 } 515 516 type ConfigV5 struct { 517 Servers []*ServerDetails `json:"servers"` 518 Version string `json:"version,omitempty"` 519 Enc bool `json:"enc,omitempty"` 520 } 521 522 // This struct is suitable for versions 1, 2, 3 and 4. 523 type ConfigV4 struct { 524 Artifactory []*ServerDetails `json:"artifactory"` 525 MissionControl *MissionControlDetails `json:"missionControl,omitempty"` 526 Version string `json:"version,omitempty"` 527 Enc bool `json:"enc,omitempty"` 528 } 529 530 func (o *ConfigV5) Convert() *ConfigV6 { 531 config := new(ConfigV6) 532 config.Servers = o.Servers 533 for _, server := range config.Servers { 534 server.ArtifactoryRefreshToken = server.RefreshToken 535 server.RefreshToken = "" 536 } 537 return config 538 } 539 540 func (o *ConfigV4) Convert() *ConfigV5 { 541 config := new(ConfigV5) 542 config.Servers = o.Artifactory 543 for _, server := range config.Servers { 544 server.ArtifactoryUrl = server.Url 545 server.Url = "" 546 if server.IsDefault && o.MissionControl != nil { 547 server.MissionControlUrl = o.MissionControl.Url 548 } 549 } 550 return config 551 } 552 553 // This struct was created before the version property was added to the config. 554 type ConfigV0 struct { 555 Artifactory *ServerDetails `json:"artifactory,omitempty"` 556 MissionControl *MissionControlDetails `json:"MissionControl,omitempty"` 557 } 558 559 func (o *ConfigV0) Convert() *ConfigV4 { 560 config := new(ConfigV4) 561 config.MissionControl = o.MissionControl 562 if o.Artifactory != nil { 563 o.Artifactory.IsDefault = true 564 o.Artifactory.ServerId = DefaultServerId 565 config.Artifactory = []*ServerDetails{o.Artifactory} 566 } 567 return config 568 } 569 570 type ServerDetails struct { 571 Url string `json:"url,omitempty"` 572 SshUrl string `json:"-"` 573 ArtifactoryUrl string `json:"artifactoryUrl,omitempty"` 574 DistributionUrl string `json:"distributionUrl,omitempty"` 575 XrayUrl string `json:"xrayUrl,omitempty"` 576 XscUrl string `json:"xscUrl,omitempty"` 577 MissionControlUrl string `json:"missionControlUrl,omitempty"` 578 PipelinesUrl string `json:"pipelinesUrl,omitempty"` 579 AccessUrl string `json:"accessUrl,omitempty"` 580 LifecycleUrl string `json:"-"` 581 User string `json:"user,omitempty"` 582 Password string `json:"password,omitempty"` 583 SshKeyPath string `json:"sshKeyPath,omitempty"` 584 SshPassphrase string `json:"sshPassphrase,omitempty"` 585 AccessToken string `json:"accessToken,omitempty"` 586 RefreshToken string `json:"refreshToken,omitempty"` 587 ArtifactoryRefreshToken string `json:"artifactoryRefreshToken,omitempty"` 588 ArtifactoryTokenRefreshInterval int `json:"tokenRefreshInterval,omitempty"` 589 ClientCertPath string `json:"clientCertPath,omitempty"` 590 ClientCertKeyPath string `json:"clientCertKeyPath,omitempty"` 591 ServerId string `json:"serverId,omitempty"` 592 IsDefault bool `json:"isDefault,omitempty"` 593 InsecureTls bool `json:"-"` 594 WebLogin bool `json:"webLogin,omitempty"` 595 } 596 597 // Deprecated 598 type MissionControlDetails struct { 599 Url string `json:"url,omitempty"` 600 AccessToken string `json:"accessToken,omitempty"` 601 } 602 603 func (serverDetails *ServerDetails) IsEmpty() bool { 604 return len(serverDetails.ServerId) == 0 && serverDetails.Url == "" 605 } 606 607 func (serverDetails *ServerDetails) SetUser(username string) { 608 serverDetails.User = username 609 } 610 611 func (serverDetails *ServerDetails) SetPassword(password string) { 612 serverDetails.Password = password 613 } 614 615 func (serverDetails *ServerDetails) SetAccessToken(accessToken string) { 616 serverDetails.AccessToken = accessToken 617 } 618 619 func (serverDetails *ServerDetails) SetArtifactoryRefreshToken(refreshToken string) { 620 serverDetails.ArtifactoryRefreshToken = refreshToken 621 } 622 623 func (serverDetails *ServerDetails) SetRefreshToken(refreshToken string) { 624 serverDetails.RefreshToken = refreshToken 625 } 626 627 func (serverDetails *ServerDetails) SetSshPassphrase(sshPassphrase string) { 628 serverDetails.SshPassphrase = sshPassphrase 629 } 630 631 func (serverDetails *ServerDetails) SetClientCertPath(certificatePath string) { 632 serverDetails.ClientCertPath = certificatePath 633 } 634 635 func (serverDetails *ServerDetails) SetClientCertKeyPath(certificatePath string) { 636 serverDetails.ClientCertKeyPath = certificatePath 637 } 638 639 func (serverDetails *ServerDetails) GetUrl() string { 640 return serverDetails.Url 641 } 642 643 func (serverDetails *ServerDetails) GetArtifactoryUrl() string { 644 return serverDetails.ArtifactoryUrl 645 } 646 647 func (serverDetails *ServerDetails) GetDistributionUrl() string { 648 return serverDetails.DistributionUrl 649 } 650 651 func (serverDetails *ServerDetails) GetXrayUrl() string { 652 return serverDetails.XrayUrl 653 } 654 655 func (serverDetails *ServerDetails) GetMissionControlUrl() string { 656 return serverDetails.MissionControlUrl 657 } 658 659 func (serverDetails *ServerDetails) GetPipelinesUrl() string { 660 return serverDetails.PipelinesUrl 661 } 662 663 func (serverDetails *ServerDetails) GetAccessUrl() string { 664 return serverDetails.AccessUrl 665 } 666 667 func (serverDetails *ServerDetails) GetLifecycleUrl() string { 668 return serverDetails.LifecycleUrl 669 } 670 671 func (serverDetails *ServerDetails) GetUser() string { 672 return serverDetails.User 673 } 674 675 func (serverDetails *ServerDetails) GetPassword() string { 676 return serverDetails.Password 677 } 678 679 func (serverDetails *ServerDetails) GetAccessToken() string { 680 return serverDetails.AccessToken 681 } 682 683 func (serverDetails *ServerDetails) GetRefreshToken() string { 684 return serverDetails.RefreshToken 685 } 686 687 func (serverDetails *ServerDetails) GetClientCertPath() string { 688 return serverDetails.ClientCertPath 689 } 690 691 func (serverDetails *ServerDetails) GetClientCertKeyPath() string { 692 return serverDetails.ClientCertKeyPath 693 } 694 695 func (serverDetails *ServerDetails) CreateArtAuthConfig() (auth.ServiceDetails, error) { 696 artAuth := artifactoryAuth.NewArtifactoryDetails() 697 artAuth.SetUrl(serverDetails.ArtifactoryUrl) 698 return serverDetails.createAuthConfig(artAuth) 699 } 700 701 func (serverDetails *ServerDetails) CreateDistAuthConfig() (auth.ServiceDetails, error) { 702 artAuth := distributionAuth.NewDistributionDetails() 703 artAuth.SetUrl(serverDetails.DistributionUrl) 704 return serverDetails.createAuthConfig(artAuth) 705 } 706 707 func (serverDetails *ServerDetails) CreateXrayAuthConfig() (auth.ServiceDetails, error) { 708 artAuth := xrayAuth.NewXrayDetails() 709 artAuth.SetUrl(serverDetails.XrayUrl) 710 return serverDetails.createAuthConfig(artAuth) 711 } 712 713 func (serverDetails *ServerDetails) CreateXscAuthConfig() (auth.ServiceDetails, error) { 714 ascAuth := xscAuth.NewXscDetails() 715 ascAuth.SetUrl(serverDetails.convertXrayUrlToXscUrl()) 716 return serverDetails.createAuthConfig(ascAuth) 717 } 718 719 // Xray and Xsc will always have the same platform url. 720 func (serverDetails *ServerDetails) convertXrayUrlToXscUrl() string { 721 xscUrl := strings.TrimSuffix(serverDetails.XrayUrl, "/") 722 xscUrl = strings.TrimSuffix(xscUrl, "/xray") 723 return xscUrl + "/xsc/" 724 } 725 726 func (serverDetails *ServerDetails) CreatePipelinesAuthConfig() (auth.ServiceDetails, error) { 727 pAuth := pipelinesAuth.NewPipelinesDetails() 728 pAuth.SetUrl(serverDetails.PipelinesUrl) 729 return serverDetails.createAuthConfig(pAuth) 730 } 731 732 func (serverDetails *ServerDetails) CreateAccessAuthConfig() (auth.ServiceDetails, error) { 733 pAuth := accessAuth.NewAccessDetails() 734 pAuth.SetUrl(utils.AddTrailingSlashIfNeeded(serverDetails.Url) + "access/") 735 return serverDetails.createAuthConfig(pAuth) 736 } 737 738 func (serverDetails *ServerDetails) CreateLifecycleAuthConfig() (auth.ServiceDetails, error) { 739 lcAuth := lifecycleAuth.NewLifecycleDetails() 740 lcAuth.SetUrl(serverDetails.LifecycleUrl) 741 return serverDetails.createAuthConfig(lcAuth) 742 } 743 744 func (serverDetails *ServerDetails) createAuthConfig(details auth.ServiceDetails) (auth.ServiceDetails, error) { 745 details.SetSshUrl(serverDetails.SshUrl) 746 details.SetAccessToken(serverDetails.AccessToken) 747 // If refresh token is not empty, set a refresh handler and skip other credentials. 748 // First we check access's token, if empty we check artifactory's token. 749 switch { 750 case serverDetails.RefreshToken != "": 751 // Save serverId for refreshing if needed. If empty serverId is saved, default will be used. 752 tokenRefreshServerId = serverDetails.ServerId 753 details.AppendPreRequestFunction(AccessTokenRefreshPreRequestInterceptor) 754 case serverDetails.ArtifactoryRefreshToken != "": 755 // Save serverId for refreshing if needed. If empty serverId is saved, default will be used. 756 tokenRefreshServerId = serverDetails.ServerId 757 details.AppendPreRequestFunction(ArtifactoryTokenRefreshPreRequestInterceptor) 758 default: 759 details.SetUser(serverDetails.User) 760 details.SetPassword(serverDetails.Password) 761 } 762 details.SetClientCertPath(serverDetails.ClientCertPath) 763 details.SetClientCertKeyPath(serverDetails.ClientCertKeyPath) 764 details.SetSshKeyPath(serverDetails.SshKeyPath) 765 details.SetSshPassphrase(serverDetails.SshPassphrase) 766 return details, nil 767 } 768 769 // GetAuthenticationCredentials retrieves authentication credentials for the serverDetails instance. 770 // If both a username and password are provided, they are returned. 771 // If only an access token is provided, the function extracts the username from the access token, 772 // and both the username and access token are returned. 773 // 774 // Returns: 775 // - Username and password if both are provided. 776 // - Username extracted from the access token, along with the access token, if the access token is provided. 777 // - An error if neither username/password nor access token is provided, with details about the missing credentials. 778 func (serverDetails *ServerDetails) GetAuthenticationCredentials() (string, string, error) { 779 // Username and password are set 780 if serverDetails.Password != "" && serverDetails.User != "" { 781 return serverDetails.User, serverDetails.Password, nil 782 } 783 784 // Access token is set, extract the username from the access token if needed 785 if serverDetails.AccessToken != "" { 786 if serverDetails.User == "" { 787 serverDetails.User = auth.ExtractUsernameFromAccessToken(serverDetails.AccessToken) 788 } 789 return serverDetails.User, serverDetails.AccessToken, nil 790 } 791 792 // Username/Password or Access token isn't set 793 errMissingCredsMsg := "either username/password or access token must be set for " 794 if serverDetails.Url != "" { 795 errMissingCredsMsg += serverDetails.Url 796 } else if serverDetails.ArtifactoryUrl != "" { 797 errMissingCredsMsg += serverDetails.ArtifactoryUrl 798 } 799 return "", "", errorutils.CheckErrorf(errMissingCredsMsg) 800 } 801 802 func (missionControlDetails *MissionControlDetails) GetAccessToken() string { 803 return missionControlDetails.AccessToken 804 } 805 806 func (missionControlDetails *MissionControlDetails) SetAccessToken(accessToken string) { 807 missionControlDetails.AccessToken = accessToken 808 }