github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/command/v6/auth_command.go (about)

     1  package v6
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"code.cloudfoundry.org/cli/actor/v2action"
     7  	"code.cloudfoundry.org/cli/api/uaa/constant"
     8  	"code.cloudfoundry.org/cli/api/uaa/uaaversion"
     9  	"code.cloudfoundry.org/cli/command"
    10  	"code.cloudfoundry.org/cli/command/flag"
    11  	"code.cloudfoundry.org/cli/command/translatableerror"
    12  	"code.cloudfoundry.org/cli/command/v6/shared"
    13  )
    14  
    15  //go:generate counterfeiter . AuthActor
    16  
    17  type AuthActor interface {
    18  	Authenticate(ID string, secret string, origin string, grantType constant.GrantType) error
    19  	CloudControllerAPIVersion() string
    20  	UAAAPIVersion() string
    21  }
    22  
    23  type AuthCommand struct {
    24  	RequiredArgs      flag.Authentication `positional-args:"yes"`
    25  	ClientCredentials bool                `long:"client-credentials" description:"Use (non-user) service account (also called client credentials)"`
    26  	Origin            string              `long:"origin" description:"Indicates the identity provider to be used for authentication"`
    27  	usage             interface{}         `usage:"CF_NAME auth USERNAME PASSWORD\n   CF_NAME auth USERNAME PASSWORD --origin ORIGIN\n   CF_NAME auth CLIENT_ID CLIENT_SECRET --client-credentials\n\nENVIRONMENT VARIABLES:\n   CF_USERNAME=user          Authenticating user. Overridden if USERNAME argument is provided.\n   CF_PASSWORD=password      Password associated with user. Overriden if PASSWORD argument is provided.\n\nWARNING:\n   Providing your password as a command line option is highly discouraged\n   Your password may be visible to others and may be recorded in your shell history\n   Consider using the CF_PASSWORD environment variable instead\n\nEXAMPLES:\n   CF_NAME auth name@example.com \"my password\" (use quotes for passwords with a space)\n   CF_NAME auth name@example.com \"\\\"password\\\"\" (escape quotes if used in password)"`
    28  	relatedCommands   interface{}         `related_commands:"api, login, target"`
    29  
    30  	UI     command.UI
    31  	Config command.Config
    32  	Actor  AuthActor
    33  }
    34  
    35  func (cmd *AuthCommand) Setup(config command.Config, ui command.UI) error {
    36  	cmd.UI = ui
    37  	cmd.Config = config
    38  
    39  	ccClient, uaaClient, err := shared.GetNewClientsAndConnectToCF(config, ui)
    40  	if err != nil {
    41  		return err
    42  	}
    43  	cmd.Actor = v2action.NewActor(ccClient, uaaClient, config)
    44  
    45  	return nil
    46  }
    47  
    48  func (cmd AuthCommand) Execute(args []string) error {
    49  	if len(cmd.Origin) > 0 {
    50  		err := command.MinimumUAAAPIVersionCheck(cmd.Actor.UAAAPIVersion(), uaaversion.MinVersionOrigin, "Option '--origin'")
    51  		if err != nil {
    52  			return err
    53  		}
    54  	}
    55  
    56  	if cmd.ClientCredentials && cmd.Origin != "" {
    57  		return translatableerror.ArgumentCombinationError{
    58  			Args: []string{"--client-credentials", "--origin"},
    59  		}
    60  	}
    61  
    62  	username, password, err := cmd.getUsernamePassword()
    63  	if err != nil {
    64  		return err
    65  	}
    66  
    67  	if !cmd.ClientCredentials {
    68  		if cmd.Config.UAAGrantType() == string(constant.GrantTypeClientCredentials) {
    69  			return translatableerror.PasswordGrantTypeLogoutRequiredError{}
    70  		} else if cmd.Config.UAAOAuthClient() != "cf" || cmd.Config.UAAOAuthClientSecret() != "" {
    71  			cmd.UI.DisplayWarning("Deprecation warning: Manually writing your client credentials to the config.json is deprecated and will be removed in the future. For similar functionality, please use the `cf auth --client-credentials` command instead.")
    72  		}
    73  	}
    74  
    75  	err = command.WarnIfCLIVersionBelowAPIDefinedMinimum(cmd.Config, cmd.Actor.CloudControllerAPIVersion(), cmd.UI)
    76  	if err != nil {
    77  		return err
    78  	}
    79  
    80  	cmd.UI.DisplayTextWithFlavor(
    81  		"API endpoint: {{.Endpoint}}",
    82  		map[string]interface{}{
    83  			"Endpoint": cmd.Config.Target(),
    84  		})
    85  	cmd.UI.DisplayText("Authenticating...")
    86  
    87  	grantType := constant.GrantTypePassword
    88  	if cmd.ClientCredentials {
    89  		grantType = constant.GrantTypeClientCredentials
    90  	}
    91  
    92  	err = cmd.Actor.Authenticate(username, password, cmd.Origin, grantType)
    93  	if err != nil {
    94  		return err
    95  	}
    96  
    97  	cmd.UI.DisplayOK()
    98  	cmd.UI.DisplayTextWithFlavor(
    99  		"Use '{{.Command}}' to view or set your target org and space.",
   100  		map[string]interface{}{
   101  			"Command": fmt.Sprintf("%s target", cmd.Config.BinaryName()),
   102  		})
   103  
   104  	return nil
   105  }
   106  
   107  func (cmd AuthCommand) getUsernamePassword() (string, string, error) {
   108  	var (
   109  		userMissing     bool
   110  		passwordMissing bool
   111  	)
   112  
   113  	username := cmd.RequiredArgs.Username
   114  	if username == "" {
   115  		if envUser := cmd.Config.CFUsername(); envUser != "" {
   116  			username = envUser
   117  		} else {
   118  			userMissing = true
   119  		}
   120  	}
   121  
   122  	password := cmd.RequiredArgs.Password
   123  	if password == "" {
   124  		if envPassword := cmd.Config.CFPassword(); envPassword != "" {
   125  			password = envPassword
   126  		} else {
   127  			passwordMissing = true
   128  		}
   129  	}
   130  
   131  	if userMissing || passwordMissing {
   132  		return "", "", translatableerror.MissingCredentialsError{
   133  			MissingUsername: userMissing,
   134  			MissingPassword: passwordMissing,
   135  		}
   136  	}
   137  
   138  	return username, password, nil
   139  }