Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
"program": "${workspaceFolder}/cmd/rhoas",
"env": {},
"args": [
"login",
"--url=localhost:8000"
"login"
]
},
{
Expand Down
3 changes: 2 additions & 1 deletion docs/commands/rhoas_login.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ rhoas login [flags]
--client-id string OpenID client identifier. (default "rhoas-cli-prod")
-h, --help help for login
--insecure Enables insecure communication with the server. This disables verification of TLS certificates and host names.
--print-sso-url Prints the login URL to the console so you can control which browser to open it in. Useful if you need to log in with a user that is different to the one logged in on your default web browser.
--url string URL of the API gateway. The value can be the complete URL or an alias. The valid aliases are 'production', 'staging', 'integration', 'development' and their shorthands. (default "https://api.stage.openshift.com")
....

=== SEE ALSO

* link:rhoas.adoc[rhoas] - rhoas cli

==== Auto generated by spf13/cobra on 10-Dec-2020
==== Auto generated by spf13/cobra on 14-Dec-2020
27 changes: 18 additions & 9 deletions pkg/auth/token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ func (c *Token) IsValid() (tokenIsValid bool, err error) {
var expires bool
var left time.Duration
var accessToken *jwt.Token
accessToken, err = parseToken(c.AccessToken)
accessToken, err = Parse(c.AccessToken)
if err != nil {
return
}
expires, left, err = getTokenExpiry(accessToken, now)
expires, left, err = GetExpiry(accessToken, now)
if err != nil {
return
}
Expand All @@ -36,11 +36,11 @@ func (c *Token) IsValid() (tokenIsValid bool, err error) {
var expires bool
var left time.Duration
var refreshToken *jwt.Token
refreshToken, err = parseToken(c.RefreshToken)
refreshToken, err = Parse(c.RefreshToken)
if err != nil {
return
}
expires, left, err = getTokenExpiry(refreshToken, now)
expires, left, err = GetExpiry(refreshToken, now)
if err != nil {
return
}
Expand All @@ -52,7 +52,7 @@ func (c *Token) IsValid() (tokenIsValid bool, err error) {
return
}

func parseToken(textToken string) (token *jwt.Token, err error) {
func Parse(textToken string) (token *jwt.Token, err error) {
parser := new(jwt.Parser)
token, _, err = parser.ParseUnverified(textToken, jwt.MapClaims{})
if err != nil {
Expand All @@ -62,12 +62,21 @@ func parseToken(textToken string) (token *jwt.Token, err error) {
return token, nil
}

func getTokenExpiry(token *jwt.Token, now time.Time) (expires bool,
left time.Duration, err error) {
func MapClaims(token *jwt.Token) (jwt.MapClaims, error) {
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
err = fmt.Errorf("expected map claims bug got %T", claims)
return
err := fmt.Errorf("expected map claims bug got %T", claims)
return nil, err
}

return claims, nil
}

func GetExpiry(token *jwt.Token, now time.Time) (expires bool,
left time.Duration, err error) {
claims, err := MapClaims(token)
if err != nil {
return false, 0, err
}
var exp float64
claim, ok := claims["exp"]
Expand Down
35 changes: 29 additions & 6 deletions pkg/cmd/login/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import (
"net/url"
"os"

"github.com/bf2fc6cc711aee1a0c2a/cli/pkg/auth/token"

"github.com/MakeNowJust/heredoc"

"github.com/bf2fc6cc711aee1a0c2a/cli/pkg/browser"
"github.com/bf2fc6cc711aee1a0c2a/cli/pkg/connection"

Expand All @@ -26,7 +30,7 @@ import (
"github.com/spf13/cobra"
)

var (
const (
devURL = "http://localhost:8000"
productionURL = "https://api.openshift.com"
stagingURL = "https://api.stage.openshift.com"
Expand Down Expand Up @@ -73,6 +77,7 @@ var args struct {
authURL string
clientID string
insecureSkipTLSVerify bool
printURL bool
}

// NewLoginCmd gets the command that's log the user in
Expand All @@ -88,6 +93,7 @@ func NewLoginCmd() *cobra.Command {
cmd.Flags().BoolVar(&args.insecureSkipTLSVerify, "insecure", false, "Enables insecure communication with the server. This disables verification of TLS certificates and host names.")
cmd.Flags().StringVar(&args.clientID, "client-id", defaultClientID, "OpenID client identifier.")
cmd.Flags().StringVar(&args.authURL, "auth-url", connection.DefaultAuthURL, "SSO Authentication server")
cmd.Flags().BoolVar(&args.printURL, "print-sso-url", false, "Prints the login URL to the console so you can control which browser to open it in. Useful if you need to log in with a user that is different to the one logged in on your default web browser.")

return cmd
}
Expand Down Expand Up @@ -162,8 +168,6 @@ func runLogin(cmd *cobra.Command, _ []string) error {
Addr: redirectURL.Host,
}

fmt.Fprintln(os.Stderr, "Logging in...")

sm.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, authCodeURL, http.StatusFound)
})
Expand Down Expand Up @@ -219,12 +223,31 @@ func runLogin(cmd *cobra.Command, _ []string) error {

w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprintln(w, PostLoginPage)
fmt.Fprintln(os.Stderr, "Successfully logged in to RHOAS")

accessTkn, _ := token.Parse(resp.OAuth2Token.AccessToken)
tknClaims, _ := token.MapClaims(accessTkn)
userName, ok := tknClaims["preferred_username"]
if !ok {
fmt.Fprintln(os.Stderr, "\nYou are now logged in")
} else {
fmt.Fprintf(os.Stderr, "\nYou are now logged in as %v\n", userName)
}
cancel()
return
})

openBrowserExec, _ := browser.GetOpenBrowserCommand(authCodeURL)
_ = openBrowserExec.Run()
if args.printURL {
fmt.Println(heredoc.Docf(`
Login URL:

%v`, authCodeURL))
} else {
openBrowserExec, _ := browser.GetOpenBrowserCommand(authCodeURL)
err = openBrowserExec.Run()
if err != nil {
return err
}
}

go func() {
if err := server.ListenAndServe(); err != nil {
Expand Down