Skip to content

Commit

Permalink
attempting to implement browser auth for ocm
Browse files Browse the repository at this point in the history
Adds the workflow to prompt for browser-based auth when launching
ocm-container, if the user is not logged in.

Signed-off-by: Chris Collins <[email protected]>
  • Loading branch information
clcollins committed Aug 13, 2024
1 parent 03a6286 commit c74e5e7
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 35 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.22.1
require (
github.com/charmbracelet/bubbletea v0.25.0
github.com/charmbracelet/huh v0.3.1-0.20240306161957-71f31c155b08
github.com/openshift-online/ocm-cli v0.1.66
github.com/openshift-online/ocm-sdk-go v0.1.405
github.com/openshift/osdctl v0.28.0
github.com/sirupsen/logrus v1.9.3
Expand Down Expand Up @@ -69,6 +70,7 @@ require (
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/microcosm-cc/bluemonday v1.0.23 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
Expand All @@ -80,7 +82,6 @@ require (
github.com/muesli/termenv v0.15.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nwidger/jsoncolor v0.3.2 // indirect
github.com/openshift-online/ocm-cli v0.1.66 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/microcosm-cc/bluemonday v1.0.23 h1:SMZe2IGa0NuHvnVNAZ+6B38gsTbi5e4sViiWJyDDqFY=
github.com/microcosm-cc/bluemonday v1.0.23/go.mod h1:mN70sk7UkkF8TUr2IGBpNN0jAgStuPzlK76QuruE/z4=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA=
Expand Down
134 changes: 100 additions & 34 deletions pkg/ocm/ocm.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ package ocm
// creating the container

import (
"fmt"
"os"
"path/filepath"

"github.com/openshift-online/ocm-cli/pkg/config"
sdk "github.com/openshift-online/ocm-sdk-go"
auth "github.com/openshift-online/ocm-sdk-go/authentication"
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
"github.com/openshift/ocm-container/pkg/engine"
"github.com/openshift/osdctl/pkg/utils"
log "github.com/sirupsen/logrus"
)

const (
Expand All @@ -21,12 +24,16 @@ const (
productionGovURL = "https://api.openshiftusgov.com"

ocmConfigDest = "/root/.config/ocm/ocm.json"
ocmConfigMountOpts = "rw"
ocmConfigMountOpts = "ro" // This should stay read-only, to keep the container from impacting the external environment

ocmContainerClientId = "ocm-cli"
)

// supprotedUrls is a shortened list of the urlAliases, for the help message
// SupportedUrls is a shortened list of the urlAliases, for the help message
// We actually support all the urlAliases, but that's too many for the help
var (
defaultOcmScopes = []string{"openid"}

SupportedUrls = []string{
"prod",
"stage",
Expand Down Expand Up @@ -77,11 +84,100 @@ func New(ocmUrl string) (*Config, error) {
return c, errInvalidOcmUrl
}

ocmConfigLocation, err := getOCMConfigLocation()
// ocmConfigLocation, err := getOCMConfigLocation()
// if err != nil {
// return c, err
// }

ocmConfig, err := config.Load()
if err != nil {
return c, err
}

if ocmConfig == nil {
ocmConfig = new(config.Config)
}

armed, reason, err := ocmConfig.Armed()
if err != nil {
log.Errorf("error checking OCM config arming: %s", err)
return c, err
}

var token string

if !armed {
log.Infof("not logged into OCM: %s", reason)
token, err = auth.InitiateAuthCode(ocmContainerClientId)
if err != nil {
log.Errorf("error initiating auth code: %s", err)
return c, err
}
} else {
log.Info("already logged into OCM")
token = ocmConfig.AccessToken
}

if config.IsEncryptedToken(token) {
log.Debug("OCM token is encrypted; assuming it is a RefreshToken")
ocmConfig.AccessToken = ""
ocmConfig.RefreshToken = token
} else {
log.Debug("OCM token is not encrypted; assuming it is an AccessToken")

parsedToken, err := config.ParseToken(token)
if err != nil {
return c, fmt.Errorf("error parsing token: %s", err)
}

typ, err := config.TokenType(parsedToken)
if err != nil {
return c, fmt.Errorf("error determining token type: %s", err)
}

switch typ {
case "Bearer", "":
ocmConfig.AccessToken = token
ocmConfig.RefreshToken = ""
case "Refresh":
ocmConfig.AccessToken = ""
ocmConfig.RefreshToken = token
default:
return c, fmt.Errorf("unknown token type: %s", typ)
}

}

ocmConfig.ClientID = ocmContainerClientId
ocmConfig.TokenURL = sdk.DefaultTokenURL
ocmConfig.Scopes = defaultOcmScopes
ocmConfig.URL = c.Env["OCMC_OCM_URL"]

connection, err := ocmConfig.Connection()
if err != nil {
log.Errorf("error creating OCM connection: %s", err)
return c, err
}

accessToken, refreshToken, err := connection.Tokens()
if err != nil {
log.Errorf("error getting OCM tokens: %s", err)
// return c, err
}

ocmConfig.AccessToken = accessToken
ocmConfig.RefreshToken = refreshToken

err = config.Save(ocmConfig)
if err != nil {
log.Errorf("error saving OCM config: %s", err)
}

ocmConfigLocation, err := config.Location()
if err != nil {
return c, fmt.Errorf("unable to identify OCM config location: %s", err)
}

ocmVolume := engine.VolumeMount{
Source: ocmConfigLocation,
Destination: ocmConfigDest,
Expand Down Expand Up @@ -132,33 +228,3 @@ func GetClusterId(ocmClient *sdk.Connection, key string) (string, error) {

return cluster.ID(), err
}

// Finds the OCM Configuration file and returns the path to it
// Taken wholesale from openshift-online/ocm-cli
func getOCMConfigLocation() (string, error) {
if ocmconfig := os.Getenv("OCM_CONFIG"); ocmconfig != "" {
return ocmconfig, nil
}

// Determine home directory to use for the legacy file path
home, err := os.UserHomeDir()
if err != nil {
return "", err
}

path := filepath.Join(home, ".ocm.json")

_, err = os.Stat(path)
if os.IsNotExist(err) {
// Determine standard config directory
configDir, err := os.UserConfigDir()
if err != nil {
return path, err
}

// Use standard config directory
path = filepath.Join(configDir, "/ocm/ocm.json")
}

return path, nil
}

0 comments on commit c74e5e7

Please sign in to comment.