brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sjcorb...@apache.org
Subject [10/18] brooklyn-client git commit: base64 encode passwords and simplify .brooklyn_cli structure
Date Mon, 17 Jul 2017 12:06:17 GMT
base64 encode passwords and simplify .brooklyn_cli structure

Includes support for old style .brooklyn_cli format such that it will
read credentials from the old style and use them, but overwrite with
the new style on next login.

New style looks like:
{
  "credentials": {
    "password": "cGFzc3dvcmQ=",
    "username": "geoff"
  },
  "skipSslChecks": false,
  "target": "http://geoffs-macbook-pro.local:8081"
}


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-client/commit/2ec78dd0
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-client/tree/2ec78dd0
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-client/diff/2ec78dd0

Branch: refs/heads/master
Commit: 2ec78dd09b5b342a219bc085028ae78c5bcfc73c
Parents: 6b7970e
Author: Geoff Macartney <geoff.macartney@cloudsoftcorp.com>
Authored: Wed May 24 12:49:56 2017 +0100
Committer: Geoff Macartney <geoff.macartney@cloudsoftcorp.com>
Committed: Tue Jul 4 11:06:00 2017 +0100

----------------------------------------------------------------------
 cli/br/brooklyn.go    |  25 +++------
 cli/commands/login.go |  59 ++++++++++-----------
 cli/io/config.go      | 124 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 158 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/2ec78dd0/cli/br/brooklyn.go
----------------------------------------------------------------------
diff --git a/cli/br/brooklyn.go b/cli/br/brooklyn.go
index 1ffb765..3250a8f 100644
--- a/cli/br/brooklyn.go
+++ b/cli/br/brooklyn.go
@@ -30,27 +30,14 @@ import (
 	"path/filepath"
 )
 
-func getNetworkCredentialsFromConfig(yamlMap map[string]interface{}) (string, string, string,
bool) {
-	var target, username, password string
-	var skipSslChecks bool
-	target, found := yamlMap["target"].(string)
-	if found {
-		auth, found := yamlMap["auth"].(map[string]interface{})
-		if found {
-			creds := auth[target].(map[string]interface{})
-			username, found = creds["username"].(string)
-			if found {
-				password, found = creds["password"].(string)
-			}
-		}
-		skipSslChecks, _ = yamlMap["skipSslChecks"].(bool)
-	}
-	return target, username, password, skipSslChecks
-}
-
 func main() {
 	config := io.GetConfig()
-	target, username, password, skipSslChecks := getNetworkCredentialsFromConfig(config.Map)
+	skipSslChecks := config.GetSkipSslChecks()
+	target, username, password, err := config.GetNetworkCredentials()
+	if err != nil {
+		error_handler.ErrorExit(err)
+	}
+
 	//target, username, password := "http://192.168.50.101:8081", "brooklyn", "Sns4Hh9j7l"
 	network := net.NewNetwork(target, username, password, skipSslChecks)
 	cmdFactory := command_factory.NewFactory(network, config)

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/2ec78dd0/cli/commands/login.go
----------------------------------------------------------------------
diff --git a/cli/commands/login.go b/cli/commands/login.go
index d7ddb7e..a0459ca 100644
--- a/cli/commands/login.go
+++ b/cli/commands/login.go
@@ -58,6 +58,30 @@ func (cmd *Login) Metadata() command_metadata.CommandMetadata {
 	}
 }
 
+
+func (cmd *Login) promptAndReadUsername() (username string) {
+	for username == "" {
+		reader := bufio.NewReader(os.Stdin)
+		fmt.Print("Enter Username: ")
+		user, err := reader.ReadString('\n')
+		if err != nil {
+			error_handler.ErrorExit(err)
+		}
+		username = strings.TrimSpace(user)
+	}
+	return username
+}
+
+func (cmd *Login) promptAndReadPassword() (password string) {
+	fmt.Print("Enter Password: ")
+	bytePassword, err := terminal.ReadPassword(int(syscall.Stdin))
+	if err != nil {
+		error_handler.ErrorExit(err)
+	}
+	fmt.Printf("\n")
+	return string(bytePassword)
+}
+
 func (cmd *Login) Run(scope scope.Scope, c *cli.Context) {
 	if !c.Args().Present() {
 		error_handler.ErrorExit("A URL must be provided as the first argument", error_handler.CLIUsageErrorExitCode)
@@ -83,44 +107,17 @@ func (cmd *Login) Run(scope scope.Scope, c *cli.Context) {
 
 	// Prompt for username if not supplied
 	if cmd.network.BrooklynUser == "" {
-		var userName string
-		for userName == "" {
-			reader := bufio.NewReader(os.Stdin)
-			fmt.Print("Enter Username: ")
-			user, err := reader.ReadString('\n')
-			if err != nil {
-				error_handler.ErrorExit(err)
-			}
-			userName = strings.TrimSpace(user)
-		}
-		cmd.network.BrooklynUser = userName
+		cmd.network.BrooklynUser = cmd.promptAndReadUsername()
 	}
 
 	// Prompt for password if not supplied (password is not echoed to screen
 	if cmd.network.BrooklynUser != "" && cmd.network.BrooklynPass == "" {
-		fmt.Print("Enter Password: ")
-		bytePassword, err := terminal.ReadPassword(int(syscall.Stdin))
-		if err != nil {
-			error_handler.ErrorExit(err)
-		}
-		fmt.Printf("\n")
-		cmd.network.BrooklynPass = string(bytePassword)
+		cmd.network.BrooklynPass = cmd.promptAndReadPassword()
 	}
 
-	if cmd.config.Map == nil {
-		cmd.config.Map = make(map[string]interface{})
-	}
 	// now persist these credentials to the yaml file
-	auth := make(map[string]interface{})
-	cmd.config.Map["auth"] = auth
-
-	auth[cmd.network.BrooklynUrl] = map[string]string{
-		"username": cmd.network.BrooklynUser,
-		"password": cmd.network.BrooklynPass,
-	}
-
-	cmd.config.Map["target"] = cmd.network.BrooklynUrl
-	cmd.config.Map["skipSslChecks"] = cmd.network.SkipSslChecks
+	cmd.config.SetNetworkCredentials(cmd.network.BrooklynUrl, cmd.network.BrooklynUser, cmd.network.BrooklynPass)
+	cmd.config.SetSkipSslChecks(cmd.network.SkipSslChecks)
 	cmd.config.Write()
 
 	loginVersion, code, err := version.Version(cmd.network)

http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/2ec78dd0/cli/io/config.go
----------------------------------------------------------------------
diff --git a/cli/io/config.go b/cli/io/config.go
index 662ae24..372c59c 100644
--- a/cli/io/config.go
+++ b/cli/io/config.go
@@ -24,8 +24,19 @@ import (
 	"path/filepath"
 
 	"github.com/apache/brooklyn-client/cli/error_handler"
+	"encoding/base64"
+	"errors"
 )
 
+// Deprecated: support old style of .brooklyn_cli format for version <= 0.11.0
+const authKey = "auth"
+
+const credentialsKey = "credentials"
+const usernameKey = "username"
+const secretKey = "password"
+const targetKey = "target"
+const skipSslChecksKey = "skipSslChecks"
+
 type Config struct {
 	FilePath string
 	Map      map[string]interface{}
@@ -78,3 +89,116 @@ func (config *Config) Read() {
 	dec := json.NewDecoder(fileToRead)
 	dec.Decode(&config.Map)
 }
+
+
+// getCredentials reads credentials from .brooklyn_cli data formatted for versions > 0.11.0
+// Note that the password is base64 encoded to avoid json formatting problems
+//{
+//  "credentials": {
+//      "password": "cGFzc3dvcmQ=",
+//      "username": "geoff"
+//  },
+//  "skipSslChecks": false,
+//  "target": "http://geoffs-macbook-pro.local:8081"
+//}
+func (config *Config) getCredentials(target string) (username string, password string, err
error) {
+	credentials, found := config.Map[credentialsKey].(map[string]interface{})
+	if !found {
+		err = errors.New("No credentials found for " + target)
+		return
+	}
+
+	if username, found = credentials["username"].(string); !found {
+		err = errors.New("No credentials for " + target)
+		return
+	}
+
+	if password, found = credentials["password"].(string); !found {
+		err = errors.New("No credentials for " + target)
+		return
+	}
+
+	if decodedPassword, err := base64.StdEncoding.DecodeString(password); err != nil {
+		err = errors.New("Could not decode password for " + username)
+	} else {
+		password = string(decodedPassword)
+	}
+	return username, password, err
+}
+
+// Deprecated:
+// getCredentialsOldStyle provides backward support for .brooklyn_cli format for version
<= 0.11.0:
+// {
+//  "auth": {
+//    "http://geoffs-macbook-pro.local:8081": {
+//      "password": "password",
+//      "username": "geoff"
+//    }
+//  },
+//  "skipSslChecks": false,
+//  "target": "http://geoffs-macbook-pro.local:8081"
+//}
+func (config *Config) getCredentialsOldStyle(target string) (username string, password string,
err error) {
+	auth, found := config.Map[authKey].(map[string]interface{})
+	if !found {
+		err = errors.New("No credentials for " + target)
+		return
+	}
+
+	creds, found := auth[target].(map[string]interface{})
+	if !found {
+		err = errors.New("No credentials found for " + target)
+		return
+	}
+
+	if username, found = creds[usernameKey].(string); !found {
+		err = errors.New("No credentials for " + username)
+		return
+	}
+
+	if password, found = creds[secretKey].(string); !found {
+		err = errors.New("No credentials for " + username)
+		return
+	}
+
+	return username, password, err
+}
+
+func (config *Config) SetNetworkCredentials(target string, username string, password string)
{
+	if config.Map == nil {
+		config.Map = make(map[string]interface{})
+	}
+	encodedPassword := base64.StdEncoding.EncodeToString([]byte(password))
+	config.Map[credentialsKey] = map[string]interface{}{
+		usernameKey: username,
+		secretKey: encodedPassword,
+	}
+	config.Map[targetKey] = target
+
+	// Overwrite old style format from version <= 0.11.0
+	delete(config.Map, authKey)
+}
+
+func (config *Config) GetNetworkCredentials() (target string, username string, password string,
err error) {
+	target, found := config.Map[targetKey].(string)
+	if found {
+		if username, password, err = config.getCredentials(target); nil != err {
+			username, password, err = config.getCredentialsOldStyle(target)
+		}
+	} else {
+		err = errors.New("No target defined in config file")
+	}
+	return target, username, password, err
+}
+
+func (config *Config) GetSkipSslChecks() bool {
+	if config.Map == nil {
+		config.Map = make(map[string]interface{})
+	}
+	skipSslChecks, _ := config.Map[skipSslChecksKey].(bool)
+	return skipSslChecks
+}
+
+func (config *Config) SetSkipSslChecks(skipSslChecks bool) {
+	config.Map["skipSslChecks"] = skipSslChecks
+}
\ No newline at end of file


Mime
View raw message