Skip to content

Commit

Permalink
OCM-5759 | feat: Add Device Code Flow (#591)
Browse files Browse the repository at this point in the history
  • Loading branch information
tylercreller authored Jan 29, 2024
1 parent ea1c988 commit 98944f7
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 20 deletions.
82 changes: 65 additions & 17 deletions cmd/ocm/login/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ limitations under the License.
package login

import (
"context"
"fmt"
"net/url"
"os"
"time"

"github.com/openshift-online/ocm-cli/pkg/config"
"github.com/openshift-online/ocm-cli/pkg/urls"
Expand Down Expand Up @@ -48,17 +51,18 @@ var urlAliases = map[string]string{
}

var args struct {
tokenURL string
clientID string
clientSecret string
scopes []string
url string
token string
user string
password string
insecure bool
persistent bool
useAuthCode bool
tokenURL string
clientID string
clientSecret string
scopes []string
url string
token string
user string
password string
insecure bool
persistent bool
useAuthCode bool
useDeviceCode bool
}

var Cmd = &cobra.Command{
Expand Down Expand Up @@ -149,14 +153,24 @@ func init() {
&args.useAuthCode,
"use-auth-code",
false,
"Enables OAuth Authorization Code login using PKCE. If this option is provided, "+
"the user will be taken to Red Hat SSO for authentication. In order to use a different account, "+
"log out from sso.redhat.com after using the 'ocm logout' command.",
"Login using OAuth Authorization Code. This should be used for most cases where a "+
"browser is available.",
)
flags.MarkHidden("use-auth-code")
flags.BoolVar(
&args.useDeviceCode,
"use-device-code",
false,
"Login using OAuth Device Code. "+
"This should only be used for remote hosts and containers where browsers are "+
"not available. Use auth code for all other scenarios.",
)
flags.MarkHidden("use-device-code")
}

func run(cmd *cobra.Command, argv []string) error {
ctx := context.Background()

var err error

// Check mandatory options:
Expand All @@ -166,12 +180,34 @@ func run(cmd *cobra.Command, argv []string) error {

if args.useAuthCode {
fmt.Println("You will now be redirected to Red Hat SSO login")
token, err := authentication.VerifyLogin(oauthClientID)
// Short wait for a less jarring experience
time.Sleep(2 * time.Second)
token, err := authentication.InitiateAuthCode(oauthClientID)
if err != nil {
return fmt.Errorf("an error occurred while retrieving the token : %v", err)
}
args.token = token
args.clientID = oauthClientID
}

if args.useDeviceCode {
deviceAuthConfig := &authentication.DeviceAuthConfig{
ClientID: oauthClientID,
}
_, err = deviceAuthConfig.InitiateDeviceAuth(ctx)
if err != nil || deviceAuthConfig == nil {
return fmt.Errorf("an error occurred while initiating device auth: %v", err)
}
deviceAuthResp := deviceAuthConfig.DeviceAuthResponse
fmt.Printf("To login, navigate to %v on another device and enter code %v\n",
deviceAuthResp.VerificationURI, deviceAuthResp.UserCode)
fmt.Printf("Checking status every %v seconds...\n", deviceAuthResp.Interval)
token, err := deviceAuthConfig.PollForTokenExchange(ctx)
if err != nil {
return fmt.Errorf("An error occurred while retrieving the token : %v", err)
return fmt.Errorf("an error occurred while polling for token exchange: %v", err)
}
args.token = token
fmt.Println("Token received successfully")
args.clientID = oauthClientID
}

// Check that we have some kind of credentials:
Expand Down Expand Up @@ -291,5 +327,17 @@ func run(cmd *cobra.Command, argv []string) error {
return fmt.Errorf("Can't save config file: %v", err)
}

if args.useAuthCode || args.useDeviceCode {
ssoURL, err := url.Parse(cfg.TokenURL)
if err != nil {
return fmt.Errorf("can't parse token url '%s': %v", args.tokenURL, err)
}
ssoHost := ssoURL.Scheme + "://" + ssoURL.Hostname()

fmt.Println("Login successful")
fmt.Printf("To switch accounts, logout from %s and run `ocm logout` "+
"before attempting to login again", ssoHost)
}

return nil
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ require (
github.com/nwidger/jsoncolor v0.3.2
github.com/onsi/ginkgo/v2 v2.11.0
github.com/onsi/gomega v1.27.8
github.com/openshift-online/ocm-sdk-go v0.1.393
github.com/openshift-online/ocm-sdk-go v0.1.395
github.com/openshift/rosa v1.2.24
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8
github.com/spf13/cobra v1.7.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,8 @@ github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc=
github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ=
github.com/openshift-online/ocm-sdk-go v0.1.393 h1:GjjgK70yTV5hBOgdH4x+2PoXn4W+5x+o7xCwm7fOGHw=
github.com/openshift-online/ocm-sdk-go v0.1.393/go.mod h1:tke8vKcE7eHKyRbkJv6qo4ljo919zhx04uyQTcgF5cQ=
github.com/openshift-online/ocm-sdk-go v0.1.395 h1:Lt4IJLHy+ArpCprZQqh2G8ifQr3wOP1l7yziU/5l7+Q=
github.com/openshift-online/ocm-sdk-go v0.1.395/go.mod h1:tke8vKcE7eHKyRbkJv6qo4ljo919zhx04uyQTcgF5cQ=
github.com/openshift/rosa v1.2.24 h1:vv0yYnWHx6CCPEAau/0rS54P2ksaf+uWXb1TQPWxiYE=
github.com/openshift/rosa v1.2.24/go.mod h1:MVXB27O3PF8WoOic23I03mmq6/9kVxpFx6FKyLMCyrQ=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
Expand Down

0 comments on commit 98944f7

Please sign in to comment.