Skip to content
Permalink
Browse files
This closes #42
Improve login handling.
  • Loading branch information
sjcorbett committed Jul 17, 2017
2 parents 052d3bd + 6abe8d1 commit be8051602b7bc2ad7bf0c1975aad55d7f354048a
Show file tree
Hide file tree
Showing 12 changed files with 482 additions and 55 deletions.
@@ -24,13 +24,14 @@ import (
"github.com/apache/brooklyn-client/cli/net"
)

func Version(network *net.Network) (models.VersionSummary, error) {
func Version(network *net.Network) (models.VersionSummary, int, error) {
url := "/v1/server/version"
var versionSummary models.VersionSummary
body, err := network.SendGetRequest(url)
req := network.NewGetRequest(url)
body, code, err := network.SendRequestGetStatusCode(req)
if err != nil {
return versionSummary, err
return versionSummary, code, err
}
err = json.Unmarshal(body, &versionSummary)
return versionSummary, err
return versionSummary, code, err
}
@@ -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 && requiresLogin(os.Args) {
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)
@@ -63,3 +50,33 @@ func main() {
error_handler.ErrorExit(err)
}
}

func requiresLogin(args []string) bool {
// global help or version commands
if (contains(args, "-h") ||
contains(args, "--help") ||
contains(args, "-v") ||
contains(args, "--version")) {
return false
}
// br on its own
if (len(args) == 1) {
return false
}
//
if (len(args) > 1) {
if (args[1] == "login" || args[1] == "help") {
return false
}
}
return true
}

func contains(slice []string, val string) bool {
for _, a := range slice {
if a == val {
return true
}
}
return false
}
@@ -70,9 +70,11 @@ func NewFactory(network *net.Network, config *io.Config) (factory concreteFactor
// factory.superCommand(commands.NewList(network))
factory.simpleCommand(commands.NewLocations(network))
factory.simpleCommand(commands.NewLogin(network, config))
factory.simpleCommand(commands.NewLogout(network, config))
factory.simpleCommand(commands.NewPolicy(network))
factory.simpleCommand(commands.NewRename(network))
factory.simpleCommand(commands.NewSensor(network))
factory.simpleCommand(commands.NewServer(network))
factory.simpleCommand(commands.NewSetConfig(network))
factory.simpleCommand(commands.NewSpec(network))
factory.simpleCommand(commands.NewStartPolicy(network))
@@ -21,6 +21,11 @@ package commands
import (
"fmt"
"syscall"
"bufio"
"os"
"strings"
"net/http"
"errors"

"github.com/apache/brooklyn-client/cli/api/version"
"github.com/apache/brooklyn-client/cli/command_metadata"
@@ -53,6 +58,42 @@ 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) getCredentialsFromCommandLineIfNeeded() {
// Prompt for username if not supplied
if cmd.network.BrooklynUser == "" {
cmd.network.BrooklynUser = cmd.promptAndReadUsername()
}

// Prompt for password if not supplied (password is not echoed to screen
if cmd.network.BrooklynUser != "" && cmd.network.BrooklynPass == "" {
cmd.network.BrooklynPass = cmd.promptAndReadPassword()
}
}

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)
@@ -64,6 +105,8 @@ func (cmd *Login) Run(scope scope.Scope, c *cli.Context) {
cmd.network.BrooklynPass = c.Args().Get(2)
cmd.network.SkipSslChecks = c.Bool("skipSslChecks")

config := io.GetConfig()

if err := net.VerifyLoginURL(cmd.network); err != nil {
error_handler.ErrorExit(err)
}
@@ -76,38 +119,25 @@ func (cmd *Login) Run(scope scope.Scope, c *cli.Context) {
cmd.network.BrooklynUrl = cmd.network.BrooklynUrl[0 : len(cmd.network.BrooklynUrl)-1]
}

// 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)
if cmd.network.BrooklynUrl != "" && cmd.network.BrooklynUser == "" {
// if only target supplied at command line see if it already exists in the config file
if username, password, err := config.GetNetworkCredentialsForTarget(cmd.network.BrooklynUrl); err == nil {
cmd.network.BrooklynUser = username
cmd.network.BrooklynPass = password
}
fmt.Printf("\n")
cmd.network.BrooklynPass = string(bytePassword)
}
cmd.getCredentialsFromCommandLineIfNeeded()

if cmd.config.Map == nil {
cmd.config.Map = make(map[string]interface{})
}
// now persist these credentials to the yaml file
auth, ok := cmd.config.Map["auth"].(map[string]interface{})
if !ok {
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, err := version.Version(cmd.network)
loginVersion, code, err := version.Version(cmd.network)
if nil != err {
if code == http.StatusUnauthorized {
err = errors.New("Unauthorized")
}
error_handler.ErrorExit(err)
}
fmt.Printf("Connected to Brooklyn version %s at %s\n", loginVersion.Version, cmd.network.BrooklynUrl)
@@ -0,0 +1,57 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package commands

import (
"github.com/apache/brooklyn-client/cli/command_metadata"
"github.com/apache/brooklyn-client/cli/error_handler"
"github.com/apache/brooklyn-client/cli/io"
"github.com/apache/brooklyn-client/cli/net"
"github.com/apache/brooklyn-client/cli/scope"
"github.com/urfave/cli"
)

type Logout struct {
network *net.Network
config *io.Config
}

func NewLogout(network *net.Network, config *io.Config) (cmd *Logout) {
cmd = new(Logout)
cmd.network = network
cmd.config = config
return
}

func (cmd *Logout) Metadata() command_metadata.CommandMetadata {
return command_metadata.CommandMetadata{
Name: "logout",
Description: "Logout of brooklyn",
Usage: "BROOKLYN_NAME logout",
Flags: []cli.Flag{},
}
}

func (cmd *Logout) Run(scope scope.Scope, c *cli.Context) {
config := io.GetConfig()
err := config.Delete()
if err != nil {
error_handler.ErrorExit(err)
}
}
@@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Server 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package commands

import (
"github.com/apache/brooklyn-client/cli/command_metadata"
"github.com/apache/brooklyn-client/cli/net"
"github.com/apache/brooklyn-client/cli/scope"
"github.com/urfave/cli"
"fmt"
)

type Server struct {
network *net.Network
}

func NewServer(network *net.Network) (cmd *Server) {
cmd = new(Server)
cmd.network = network
return
}

func (cmd *Server) Metadata() command_metadata.CommandMetadata {
return command_metadata.CommandMetadata{
Name: "server",
Description: "Display the URL of the connected Brooklyn",
Usage: "BROOKLYN_NAME server",
Flags: []cli.Flag{},
}
}

func (cmd *Server) Run(scope scope.Scope, c *cli.Context) {
fmt.Println(cmd.network.BrooklynUrl)
}
@@ -51,7 +51,7 @@ func (cmd *Version) Run(scope scope.Scope, c *cli.Context) {
if err := net.VerifyLoginURL(cmd.network); err != nil {
error_handler.ErrorExit(err)
}
version, err := version.Version(cmd.network)
version, _, err := version.Version(cmd.network)
if nil != err {
error_handler.ErrorExit(err)
}

0 comments on commit be80516

Please sign in to comment.