Skip to content

Commit

Permalink
Update the UAA-based login flow to discover org id
Browse files Browse the repository at this point in the history
best case effort to retrieve org name/id from the metadata file from a
predetermined URL.

Env vars to support setting of these values are still supported as a
fallback.
  • Loading branch information
vuil committed Sep 24, 2024
1 parent 505ad76 commit 50b6a0d
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 10 deletions.
16 changes: 10 additions & 6 deletions pkg/auth/common/login_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,24 +432,28 @@ func (h *TanzuLoginHandler) promptAndLoginWithAuthCode(ctx context.Context, auth
// of if persisted cert information associated with the issuer endpoint is found,
// with the provided information taking precedence over persisted information.
func (h *TanzuLoginHandler) getTLSConfig() *tls.Config {
return GetTLSConfig(h.issuer, h.caCertData, h.tlsSkipVerify)
}

func GetTLSConfig(endpoint, certData string, skipVerify bool) *tls.Config {
var savedCertData string
var savedSkipVerify bool

c, _ := config.GetCert(h.issuer)
c, _ := config.GetCert(endpoint)

if c != nil {
savedCertData = c.CACertData
savedSkipVerify, _ = strconv.ParseBool(c.SkipCertVerify)
}

if savedSkipVerify || h.tlsSkipVerify {
if savedSkipVerify || skipVerify {
//nolint:gosec // skipTLSVerify: true is only possible if the user has explicitly enabled it
return &tls.Config{InsecureSkipVerify: true, MinVersion: tls.VersionTLS12}
}

caCertData := savedCertData
if h.caCertData != "" {
caCertData = h.caCertData
if certData != "" {
caCertData = certData
}

if caCertData != "" {
Expand All @@ -458,7 +462,7 @@ func (h *TanzuLoginHandler) getTLSConfig() *tls.Config {

decodedCACertData, err := base64.StdEncoding.DecodeString(caCertData)
if err != nil {
log.Infof("unable to use custom cert for '%s' endpoint. Error: %s", h.issuer, err.Error())
log.Infof("unable to use custom cert for '%s' endpoint. Error: %s", endpoint, err.Error())
return nil
}

Expand All @@ -468,7 +472,7 @@ func (h *TanzuLoginHandler) getTLSConfig() *tls.Config {
}

if ok := pool.AppendCertsFromPEM(decodedCACertData); !ok {
log.Infof("unable to use custom cert for %s endpoint", h.issuer)
log.Infof("unable to use custom cert for %s endpoint", endpoint)
return nil
}
return &tls.Config{RootCAs: pool, MinVersion: tls.VersionTLS12}
Expand Down
72 changes: 68 additions & 4 deletions pkg/command/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,59 @@ func globalTanzuLogin(c *configtypes.Context, generateContextNameFunc func(orgNa
return errors.New(invalidIdpType)
}

type DeploymentMetadata struct {
APIEndpoint string `json:"apiEndpoint"`
Organization DeploymentMetadataOrganization `json:"organization"`
}

type DeploymentMetadataOrganization struct {
DisplayName string `json:"displayName"`
ID string `json:"id"`
Name string `json:"name"`
}

func getOrgFromSelfManaged(c *configtypes.Context) (string, string, error) {
hubEndpoint := c.AdditionalMetadata[config.TanzuHubEndpointKey].(string)
hubEndpoint = strings.TrimRight(hubEndpoint, " /")
metadataURL := hubEndpoint + "/assets/env-config/env-config.json"
req, _ := http.NewRequest("GET", metadataURL, http.NoBody) //nolint:noctx

tlsConfig := commonauth.GetTLSConfig(hubEndpoint, "", false)
if tlsConfig == nil {
return "", "", errors.New("Unable to build TLS configuration")
}
client := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: tlsConfig,
},
Timeout: time.Second * 10,
}

response, err := client.Do(req)
if err != nil {
return "", "", errors.Wrap(err, "failed to get tanzu platform deployment metadata")
}
defer response.Body.Close()

if response.StatusCode != http.StatusOK {
return "", "", errors.New("failed to get tanzu platform deployment metadata")
}

responseBody, err := io.ReadAll(response.Body)
if err != nil {
return "", "", errors.Wrap(err, "failed to read the response body")
}

var dm DeploymentMetadata
err = json.Unmarshal(responseBody, &dm)
if err != nil {
return "", "", errors.Wrap(err, "error parsing http response body ")
}

return dm.Organization.ID, dm.Organization.Name, nil
}

func globalTanzuLoginUAA(c *configtypes.Context, generateContextNameFunc func(orgName, endpoint string, isStaging bool) string) error {
uaaEndpoint := c.AdditionalMetadata[config.TanzuAuthEndpointKey].(string)
log.V(7).Infof("Login to UAA endpoint: %s", uaaEndpoint)
Expand All @@ -658,20 +711,31 @@ func globalTanzuLoginUAA(c *configtypes.Context, generateContextNameFunc func(or
return err
}

// UAA-based authentication does not provide org id or name yet.
// Note: org id/name may be discoverable in UAA-based auth in the future.
// UAA-based authentication itself not provide org id or name.
// Instead they are retrievable via a predefined location
var orgID string
orgName := "self-managed"

retrievedOrgID, retrievedOrgName, err := getOrgFromSelfManaged(c)
if err == nil && retrievedOrgID != "" {
orgID = retrievedOrgID
if retrievedOrgName != "" {
orgName = retrievedOrgName
}
}

uaaOrgIDValue, ok := os.LookupEnv(constants.UAALoginOrgID)
if ok {
if retrievedOrgID != "" && retrievedOrgID != uaaOrgIDValue {
log.Infof("Organization ID %s retrieved from endpoint is being overridden by environment variable value %s\n",
retrievedOrgID, uaaOrgIDValue)
}
orgID = uaaOrgIDValue
}
claims.OrgID = orgID
uaaOrgNameValue, ok := os.LookupEnv(constants.UAALoginOrgName)
if ok {
orgName = uaaOrgNameValue
} else if orgID != "" {
orgName = orgID
}

if err := updateContextOnTanzuLogin(c, generateContextNameFunc, claims, orgName); err != nil {
Expand Down

0 comments on commit 50b6a0d

Please sign in to comment.