package config import ( "os" "github.com/alcionai/clues" "github.com/spf13/viper" "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/internal/common/str" "github.com/alcionai/corso/src/pkg/account" "github.com/alcionai/corso/src/pkg/credentials" ) // prerequisite: readRepoConfig must have been run prior to this to populate the global viper values. func m365ConfigsFromViper(vpr *viper.Viper) (account.M365Config, error) { var m365 account.M365Config m365.AzureClientID = vpr.GetString(account.AzureClientID) m365.AzureClientSecret = vpr.GetString(account.AzureSecret) m365.AzureTenantID = vpr.GetString(account.AzureTenantIDKey) return m365, nil } func m365Overrides(in map[string]string) map[string]string { return map[string]string{ account.AzureTenantID: in[account.AzureTenantID], account.AccountProviderTypeKey: in[account.AccountProviderTypeKey], } } // configureAccount builds a complete account configuration from a mix of // viper properties and manual overrides. func configureAccount( vpr *viper.Viper, readConfigFromViper bool, matchFromConfig bool, overrides map[string]string, ) (account.Account, error) { var ( m365Cfg account.M365Config m365 credentials.M365 acct account.Account err error ) if readConfigFromViper { m365Cfg, err = m365ConfigsFromViper(vpr) if err != nil { return acct, clues.Wrap(err, "reading m365 configs from corso config file") } if matchFromConfig { providerType := vpr.GetString(account.AccountProviderTypeKey) if providerType != account.ProviderM365.String() { return acct, clues.New("unsupported account provider: [" + providerType + "]") } if err := mustMatchConfig(vpr, m365Overrides(overrides)); err != nil { return acct, clues.Wrap(err, "verifying m365 configs in corso config file") } } } // compose the m365 config and credentials m365 = GetM365(m365Cfg) if err := m365.Validate(); err != nil { return acct, clues.Wrap(err, "validating m365 credentials") } m365Cfg = account.M365Config{ M365: m365, AzureTenantID: str.First( overrides[account.AzureTenantID], flags.AzureClientTenantFV, os.Getenv(account.AzureTenantID), m365Cfg.AzureTenantID), } // ensure required properties are present if err := requireProps(map[string]string{ credentials.AzureClientID: m365Cfg.M365.AzureClientID, credentials.AzureClientSecret: m365Cfg.M365.AzureClientSecret, account.AzureTenantID: m365Cfg.AzureTenantID, }); err != nil { return acct, err } // build the account acct, err = account.NewAccount(account.ProviderM365, m365Cfg) if err != nil { return acct, clues.Wrap(err, "retrieving m365 account configuration") } return acct, nil } // M365 is a helper for aggregating m365 secrets and credentials. func GetM365(m365Cfg account.M365Config) credentials.M365 { AzureClientID := str.First( flags.AzureClientIDFV, os.Getenv(credentials.AzureClientID), m365Cfg.AzureClientID) AzureClientSecret := str.First( flags.AzureClientSecretFV, os.Getenv(credentials.AzureClientSecret), m365Cfg.AzureClientSecret) return credentials.M365{ AzureClientID: AzureClientID, AzureClientSecret: AzureClientSecret, } }