github.com/LukasHeimann/cloudfoundrycli/v8@v8.4.4/command/v7/auth_command.go (about)

     1  package v7
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/LukasHeimann/cloudfoundrycli/v8/api/uaa/constant"
     8  	"github.com/LukasHeimann/cloudfoundrycli/v8/api/uaa/uaaversion"
     9  	"github.com/LukasHeimann/cloudfoundrycli/v8/command"
    10  	"github.com/LukasHeimann/cloudfoundrycli/v8/command/flag"
    11  	"github.com/LukasHeimann/cloudfoundrycli/v8/command/translatableerror"
    12  	"github.com/LukasHeimann/cloudfoundrycli/v8/command/v7/shared"
    13  )
    14  
    15  type AuthCommand struct {
    16  	BaseCommand
    17  
    18  	RequiredArgs      flag.Authentication `positional-args:"yes"`
    19  	ClientCredentials bool                `long:"client-credentials" description:"Use (non-user) service account (also called client credentials)"`
    20  	Origin            string              `long:"origin" description:"Indicates the identity provider to be used for authentication"`
    21  	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)"`
    22  	relatedCommands   interface{}         `related_commands:"api, login, target"`
    23  }
    24  
    25  func (cmd AuthCommand) Execute(args []string) error {
    26  	if len(cmd.Origin) > 0 {
    27  		uaaVersion, err := cmd.Actor.GetUAAAPIVersion()
    28  		if err != nil {
    29  			return err
    30  		}
    31  
    32  		err = command.MinimumUAAAPIVersionCheck(uaaVersion, uaaversion.MinUAAClientVersion, "Option '--origin'")
    33  		if err != nil {
    34  			return err
    35  		}
    36  	}
    37  
    38  	if cmd.ClientCredentials && cmd.Origin != "" {
    39  		return translatableerror.ArgumentCombinationError{
    40  			Args: []string{"--client-credentials", "--origin"},
    41  		}
    42  	}
    43  
    44  	username, password, err := cmd.getUsernamePassword()
    45  	if err != nil {
    46  		return err
    47  	}
    48  
    49  	cmd.UI.DisplayTextWithFlavor(
    50  		"API endpoint: {{.Endpoint}}",
    51  		map[string]interface{}{
    52  			"Endpoint": cmd.Config.Target(),
    53  		})
    54  
    55  	versionWarning, err := shared.CheckCCAPIVersion(cmd.Config.APIVersion())
    56  	if err != nil {
    57  		cmd.UI.DisplayWarning("Warning: unable to determine whether targeted API's version meets minimum supported.")
    58  	}
    59  	if versionWarning != "" {
    60  		cmd.UI.DisplayWarning(versionWarning)
    61  	}
    62  
    63  	if !cmd.ClientCredentials {
    64  		if cmd.Config.UAAGrantType() == string(constant.GrantTypeClientCredentials) {
    65  			return translatableerror.PasswordGrantTypeLogoutRequiredError{}
    66  		} else if cmd.Config.UAAOAuthClient() != "cf" || cmd.Config.UAAOAuthClientSecret() != "" {
    67  			return translatableerror.ManualClientCredentialsError{}
    68  		}
    69  	}
    70  
    71  	cmd.UI.DisplayNewline()
    72  
    73  	cmd.UI.DisplayText("Authenticating...")
    74  
    75  	credentials := make(map[string]string)
    76  	grantType := constant.GrantTypePassword
    77  	if cmd.ClientCredentials {
    78  		grantType = constant.GrantTypeClientCredentials
    79  		credentials["client_id"] = username
    80  		credentials["client_secret"] = password
    81  	} else if cmd.Config.IsCFOnK8s() {
    82  		prompts, err := cmd.Actor.GetLoginPrompts()
    83  		if err != nil {
    84  			return err
    85  		}
    86  		prompt, ok := prompts["k8s-auth-info"]
    87  		if !ok {
    88  			return errors.New("kubernetes login context is missing")
    89  		}
    90  
    91  		userFound := false
    92  		for _, val := range prompt.Entries {
    93  			if val == username {
    94  				userFound = true
    95  				break
    96  			}
    97  		}
    98  		if !userFound {
    99  			return errors.New("kubernetes user not found in configuration: " + username)
   100  		}
   101  		credentials = map[string]string{
   102  			"k8s-auth-info": username,
   103  		}
   104  	} else {
   105  		credentials = map[string]string{
   106  			"username": username,
   107  			"password": password,
   108  		}
   109  	}
   110  
   111  	err = cmd.Actor.Authenticate(credentials, cmd.Origin, grantType)
   112  	if err != nil {
   113  		return err
   114  	}
   115  
   116  	cmd.UI.DisplayOK()
   117  	cmd.UI.DisplayTextWithFlavor(
   118  		"Use '{{.Command}}' to view or set your target org and space.",
   119  		map[string]interface{}{
   120  			"Command": fmt.Sprintf("%s target", cmd.Config.BinaryName()),
   121  		})
   122  
   123  	return nil
   124  }
   125  
   126  func (cmd AuthCommand) getUsernamePassword() (string, string, error) {
   127  	var (
   128  		userMissing     bool
   129  		passwordMissing bool
   130  	)
   131  
   132  	username := cmd.RequiredArgs.Username
   133  	if username == "" {
   134  		if envUser := cmd.Config.CFUsername(); envUser != "" {
   135  			username = envUser
   136  		} else {
   137  			userMissing = true
   138  		}
   139  	}
   140  
   141  	password := cmd.RequiredArgs.Password
   142  	if password == "" {
   143  		if envPassword := cmd.Config.CFPassword(); envPassword != "" {
   144  			password = envPassword
   145  		} else if !cmd.Config.IsCFOnK8s() {
   146  			passwordMissing = true
   147  		}
   148  	}
   149  
   150  	if userMissing || passwordMissing {
   151  		return "", "", translatableerror.MissingCredentialsError{
   152  			MissingUsername: userMissing,
   153  			MissingPassword: passwordMissing,
   154  		}
   155  	}
   156  
   157  	return username, password, nil
   158  }