Add oauth2 command
authorMikael Berthe <mikael@lilotux.net>
Wed, 10 May 2017 14:11:13 +0200
changeset 113 2e411da68fd3
parent 112 58d30ab47543
child 114 590c9dd7328e
Add oauth2 command Allows OAuth 2.0 authentication interactively or non-interactively. % madonctl oauth2 or % madonctl oauth2 > conffile.yaml Non-interactively: % madonctl oauth2 get-url % madonctl oauth2 code OAUTHCODE (--output/--template can be used as well to customize the output.)
cmd/accounts.go
cmd/config.go
cmd/oauth2.go
cmd/status.go
--- a/cmd/accounts.go	Tue May 09 20:14:28 2017 +0200
+++ b/cmd/accounts.go	Wed May 10 14:11:13 2017 +0200
@@ -86,7 +86,6 @@
 	Aliases: []string{"account"},
 	Short:   "Account-related functions",
 	//Long:    `TBW...`, // TODO
-	//PersistentPreRunE: func(cmd *cobra.Command, args []string) error {},
 }
 
 // Note: Some account subcommands are not defined in this file.
--- a/cmd/config.go	Tue May 09 20:14:28 2017 +0200
+++ b/cmd/config.go	Wed May 10 14:11:13 2017 +0200
@@ -90,7 +90,8 @@
 			cfile = defaultConfigFile
 		}
 		errPrint("You can copy the following lines into a configuration file.")
-		errPrint("E.g. %s -i INSTANCE -L USERNAME -P PASS config dump > %s\n", AppName, cfile)
+		errPrint("E.g. %s -i INSTANCE -L USERNAME -P PASS config dump > %s", AppName, cfile)
+		errPrint(" or  %s -i INSTANCE oauth2 > %s\n", AppName, cfile)
 		pOptions := printer.Options{"template": configurationTemplate}
 		p, err = printer.NewPrinterTemplate(pOptions)
 	} else {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmd/oauth2.go	Wed May 10 14:11:13 2017 +0200
@@ -0,0 +1,116 @@
+// Copyright © 2017 Mikael Berthe <mikael@lilotux.net>
+//
+// Licensed under the MIT license.
+// Please see the LICENSE file is this directory.
+
+package cmd
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/pkg/errors"
+	"github.com/spf13/cobra"
+	//"github.com/McKael/madonctl/printer"
+)
+
+var oauth2Cmd = &cobra.Command{
+	Use:   "oauth2",
+	Short: "OAuth2 authentication/authorization",
+	Example: `  madonctl oauth2           # Interactive OAuth2 login
+  madonctl oauth2 get-url   # Display OAuth2 auhtorization URL
+  madonctl oauth2 code CODE # Enter OAuth2 code`,
+	RunE: func(cmd *cobra.Command, args []string) error {
+		return oAuth2Interactive(args)
+	},
+	PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
+		// Initialize application; do not log in yet
+		return madonInit(false)
+	},
+}
+
+func init() {
+	RootCmd.AddCommand(oauth2Cmd)
+
+	// Subcommands
+	oauth2Cmd.AddCommand(oauth2Subcommands...)
+}
+
+var oauth2Subcommands = []*cobra.Command{
+	&cobra.Command{
+		Use:   "get-url",
+		Short: "Get OAuth2 URL",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return oAuth2GetURL()
+		},
+	},
+	&cobra.Command{
+		Use:   "code",
+		Short: "Log in with OAuth2 code",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return oAuth2ExchangeCode(args)
+		},
+	},
+}
+
+func oAuth2GetURL() error {
+	// (gClient != nil thanks to PreRun)
+
+	url, err := gClient.LoginOAuth2("", scopes)
+	if err != nil {
+		return errors.Wrap(err, "OAuth2 authentication failed")
+	}
+
+	fmt.Printf("%s\n", url)
+	return nil
+}
+
+func oAuth2ExchangeCode(args []string) error {
+	// (gClient != nil thanks to PreRun)
+
+	if len(args) != 1 {
+		return errors.New("wrong usage: code needs 1 argument")
+	}
+
+	code := args[0]
+
+	if code == "" {
+		return errors.New("no code entered")
+	}
+
+	// The code has been set; proceed with token exchange
+	_, err := gClient.LoginOAuth2(code, scopes)
+	if err != nil {
+		return err
+	}
+
+	if gClient.UserToken != nil {
+		errPrint("Login successful.\n")
+		configDump()
+	}
+	return nil
+}
+
+// oAuth2Interactive is the default behaviour
+func oAuth2Interactive(args []string) error {
+	// (gClient != nil thanks to PreRun)
+
+	url, err := gClient.LoginOAuth2("", scopes)
+	if err != nil {
+		return errors.Wrap(err, "OAuth2 authentication failed")
+	}
+
+	fmt.Fprintf(os.Stderr, "Visit the URL for the auth dialog:\n%s\n", url)
+	fmt.Fprintf(os.Stderr, "Enter code: ")
+	var code string
+	if _, err := fmt.Scan(&code); err != nil {
+		return err
+	}
+
+	if code == "" {
+		return errors.New("no code entered")
+	}
+
+	// The code has been set; proceed with token exchange
+	return oAuth2ExchangeCode([]string{code})
+}
--- a/cmd/status.go	Tue May 09 20:14:28 2017 +0200
+++ b/cmd/status.go	Wed May 10 14:11:13 2017 +0200
@@ -82,10 +82,7 @@
 		if statusOpts.statusID < 1 && cmd.Name() != "post" {
 			return errors.New("missing status ID")
 		}
-		if err := madonInit(true); err != nil {
-			return err
-		}
-		return nil
+		return madonInit(true)
 	},
 }