github.com/jenspinney/cli@v6.42.1-0.20190207184520-7450c600020e+incompatible/command/v6/auth_command_test.go (about)

     1  package v6_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	"code.cloudfoundry.org/cli/api/uaa"
     7  	"code.cloudfoundry.org/cli/api/uaa/constant"
     8  	"code.cloudfoundry.org/cli/api/uaa/uaaversion"
     9  	"code.cloudfoundry.org/cli/command/commandfakes"
    10  	"code.cloudfoundry.org/cli/command/translatableerror"
    11  	. "code.cloudfoundry.org/cli/command/v6"
    12  	"code.cloudfoundry.org/cli/command/v6/v6fakes"
    13  	"code.cloudfoundry.org/cli/util/ui"
    14  	. "github.com/onsi/ginkgo"
    15  	. "github.com/onsi/gomega"
    16  	. "github.com/onsi/gomega/gbytes"
    17  )
    18  
    19  var _ = Describe("auth Command", func() {
    20  	var (
    21  		cmd        AuthCommand
    22  		testUI     *ui.UI
    23  		fakeActor  *v6fakes.FakeAuthActor
    24  		fakeConfig *commandfakes.FakeConfig
    25  		binaryName string
    26  		err        error
    27  	)
    28  
    29  	BeforeEach(func() {
    30  		testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer())
    31  		fakeActor = new(v6fakes.FakeAuthActor)
    32  		fakeConfig = new(commandfakes.FakeConfig)
    33  
    34  		cmd = AuthCommand{
    35  			UI:     testUI,
    36  			Config: fakeConfig,
    37  			Actor:  fakeActor,
    38  		}
    39  
    40  		binaryName = "faceman"
    41  		fakeConfig.BinaryNameReturns(binaryName)
    42  	})
    43  
    44  	JustBeforeEach(func() {
    45  		err = cmd.Execute(nil)
    46  	})
    47  
    48  	When("--origin are set", func() {
    49  		BeforeEach(func() {
    50  			cmd.Origin = "some-origin"
    51  		})
    52  
    53  		When("the UAA is below the minimum API version", func() {
    54  			BeforeEach(func() {
    55  				fakeActor.UAAAPIVersionReturns(uaaversion.MinUAAClientVersion)
    56  			})
    57  
    58  			It("returns an API version error", func() {
    59  				Expect(err).To(MatchError(translatableerror.MinimumUAAAPIVersionNotMetError{
    60  					Command:        "Option '--origin'",
    61  					MinimumVersion: uaaversion.MinVersionOrigin,
    62  				}))
    63  			})
    64  		})
    65  
    66  		When("--client-credentials set", func() {
    67  			BeforeEach(func() {
    68  				cmd.ClientCredentials = true
    69  				fakeActor.UAAAPIVersionReturns(uaaversion.MinVersionOrigin)
    70  			})
    71  
    72  			It("returns an ArgumentCombinationError", func() {
    73  				Expect(err).To(MatchError(translatableerror.ArgumentCombinationError{
    74  					Args: []string{"--client-credentials", "--origin"},
    75  				}))
    76  			})
    77  		})
    78  
    79  		When("when the UAA is above the minimum API version", func() {
    80  			BeforeEach(func() {
    81  				cmd.RequiredArgs.Username = "doesn't matter"
    82  				cmd.RequiredArgs.Password = "doesn't matter"
    83  				fakeActor.UAAAPIVersionReturns(uaaversion.MinVersionOrigin)
    84  			})
    85  
    86  			It("authenticates with the values from the command line args", func() {
    87  				Expect(err).ToNot(HaveOccurred())
    88  
    89  				Expect(fakeActor.AuthenticateCallCount()).To(Equal(1))
    90  				_, _, origin, _ := fakeActor.AuthenticateArgsForCall(0)
    91  				Expect(origin).To(Equal("some-origin"))
    92  			})
    93  		})
    94  	})
    95  
    96  	When("credentials are missing", func() {
    97  		When("username and password are both missing", func() {
    98  			It("raises an error", func() {
    99  				Expect(err).To(MatchError(translatableerror.MissingCredentialsError{
   100  					MissingUsername: true,
   101  					MissingPassword: true,
   102  				}))
   103  			})
   104  		})
   105  
   106  		When("username is missing", func() {
   107  			BeforeEach(func() {
   108  				cmd.RequiredArgs.Password = "mypassword"
   109  			})
   110  
   111  			It("raises an error", func() {
   112  				Expect(err).To(MatchError(translatableerror.MissingCredentialsError{
   113  					MissingUsername: true,
   114  				}))
   115  			})
   116  		})
   117  
   118  		When("password is missing", func() {
   119  			BeforeEach(func() {
   120  				cmd.RequiredArgs.Username = "myuser"
   121  			})
   122  
   123  			It("raises an error", func() {
   124  				Expect(err).To(MatchError(translatableerror.MissingCredentialsError{
   125  					MissingPassword: true,
   126  				}))
   127  			})
   128  		})
   129  	})
   130  
   131  	When("there is an auth error", func() {
   132  		BeforeEach(func() {
   133  			cmd.RequiredArgs.Username = "foo"
   134  			cmd.RequiredArgs.Password = "bar"
   135  
   136  			fakeConfig.TargetReturns("some-api-target")
   137  			fakeActor.AuthenticateReturns(uaa.UnauthorizedError{Message: "some message"})
   138  		})
   139  
   140  		It("returns a BadCredentialsError", func() {
   141  			Expect(err).To(MatchError(uaa.UnauthorizedError{Message: "some message"}))
   142  		})
   143  	})
   144  
   145  	When("there is a non-auth error", func() {
   146  		var expectedError error
   147  
   148  		BeforeEach(func() {
   149  			cmd.RequiredArgs.Username = "foo"
   150  			cmd.RequiredArgs.Password = "bar"
   151  
   152  			fakeConfig.TargetReturns("some-api-target")
   153  			expectedError = errors.New("my humps")
   154  
   155  			fakeActor.AuthenticateReturns(expectedError)
   156  		})
   157  
   158  		It("returns the error", func() {
   159  			Expect(err).To(MatchError(expectedError))
   160  		})
   161  	})
   162  
   163  	Describe("it checks the CLI version", func() {
   164  		var (
   165  			apiVersion    string
   166  			minCLIVersion string
   167  			binaryVersion string
   168  		)
   169  
   170  		BeforeEach(func() {
   171  			apiVersion = "1.2.3"
   172  			fakeActor.CloudControllerAPIVersionReturns(apiVersion)
   173  			minCLIVersion = "1.0.0"
   174  			fakeConfig.MinCLIVersionReturns(minCLIVersion)
   175  
   176  			cmd.RequiredArgs.Username = "user"
   177  			cmd.RequiredArgs.Password = "password"
   178  		})
   179  
   180  		Context("the CLI version is older than the minimum version required by the API", func() {
   181  			BeforeEach(func() {
   182  				binaryVersion = "0.0.0"
   183  				fakeConfig.BinaryVersionReturns(binaryVersion)
   184  			})
   185  
   186  			It("displays a recommendation to update the CLI version", func() {
   187  				Expect(err).ToNot(HaveOccurred())
   188  				Expect(testUI.Err).To(Say("Cloud Foundry API version %s requires CLI version %s. You are currently on version %s. To upgrade your CLI, please visit: https://github.com/cloudfoundry/cli#downloads", apiVersion, minCLIVersion, binaryVersion))
   189  			})
   190  		})
   191  
   192  		Context("the CLI version satisfies the API's minimum version requirements", func() {
   193  			BeforeEach(func() {
   194  				binaryVersion = "1.0.0"
   195  				fakeConfig.BinaryVersionReturns(binaryVersion)
   196  			})
   197  
   198  			It("does not display a recommendation to update the CLI version", func() {
   199  				Expect(err).ToNot(HaveOccurred())
   200  				Expect(testUI.Err).ToNot(Say("Cloud Foundry API version %s requires CLI version %s. You are currently on version %s. To upgrade your CLI, please visit: https://github.com/cloudfoundry/cli#downloads", apiVersion, minCLIVersion, binaryVersion))
   201  			})
   202  		})
   203  
   204  		When("the CLI version is invalid", func() {
   205  			BeforeEach(func() {
   206  				fakeConfig.BinaryVersionReturns("&#%")
   207  			})
   208  
   209  			It("returns an error", func() {
   210  				Expect(err).To(HaveOccurred())
   211  				Expect(err.Error()).To(Equal("No Major.Minor.Patch elements found"))
   212  			})
   213  		})
   214  	})
   215  
   216  	When("there are no input errors", func() {
   217  		var (
   218  			testID     string
   219  			testSecret string
   220  		)
   221  
   222  		BeforeEach(func() {
   223  			testID = "hello"
   224  			testSecret = "goodbye"
   225  
   226  			fakeConfig.TargetReturns("some-api-target")
   227  		})
   228  
   229  		When("--client-credentials is set", func() {
   230  			BeforeEach(func() {
   231  				cmd.ClientCredentials = true
   232  				cmd.RequiredArgs.Username = testID
   233  				cmd.RequiredArgs.Password = testSecret
   234  			})
   235  
   236  			It("outputs API target information and clears the targeted org and space", func() {
   237  				Expect(err).ToNot(HaveOccurred())
   238  
   239  				Expect(testUI.Out).To(Say("API endpoint: %s", fakeConfig.Target()))
   240  				Expect(testUI.Out).To(Say(`Authenticating\.\.\.`))
   241  				Expect(testUI.Out).To(Say("OK"))
   242  				Expect(testUI.Out).To(Say("Use '%s target' to view or set your target org and space", binaryName))
   243  
   244  				Expect(fakeActor.AuthenticateCallCount()).To(Equal(1))
   245  				ID, secret, origin, grantType := fakeActor.AuthenticateArgsForCall(0)
   246  				Expect(ID).To(Equal(testID))
   247  				Expect(secret).To(Equal(testSecret))
   248  				Expect(origin).To(BeEmpty())
   249  				Expect(grantType).To(Equal(constant.GrantTypeClientCredentials))
   250  			})
   251  		})
   252  
   253  		When("--client-credentials is not set", func() {
   254  			When("username and password are only provided as arguments", func() {
   255  				BeforeEach(func() {
   256  					cmd.RequiredArgs.Username = testID
   257  					cmd.RequiredArgs.Password = testSecret
   258  				})
   259  
   260  				It("outputs API target information and clears the targeted org and space", func() {
   261  					Expect(err).ToNot(HaveOccurred())
   262  
   263  					Expect(testUI.Out).To(Say("API endpoint: %s", fakeConfig.Target()))
   264  					Expect(testUI.Out).To(Say(`Authenticating\.\.\.`))
   265  					Expect(testUI.Out).To(Say("OK"))
   266  					Expect(testUI.Out).To(Say("Use '%s target' to view or set your target org and space", binaryName))
   267  
   268  					Expect(fakeActor.AuthenticateCallCount()).To(Equal(1))
   269  					username, password, origin, grantType := fakeActor.AuthenticateArgsForCall(0)
   270  					Expect(username).To(Equal(testID))
   271  					Expect(password).To(Equal(testSecret))
   272  					Expect(origin).To(BeEmpty())
   273  					Expect(grantType).To(Equal(constant.GrantTypePassword))
   274  				})
   275  			})
   276  
   277  			When("the username and password are provided in env variables", func() {
   278  				var (
   279  					envUsername string
   280  					envPassword string
   281  				)
   282  
   283  				BeforeEach(func() {
   284  					envUsername = "banana"
   285  					envPassword = "potato"
   286  					fakeConfig.CFUsernameReturns(envUsername)
   287  					fakeConfig.CFPasswordReturns(envPassword)
   288  				})
   289  
   290  				When("username and password are not also provided as arguments", func() {
   291  					It("authenticates with the values in the env variables", func() {
   292  						Expect(err).ToNot(HaveOccurred())
   293  
   294  						Expect(fakeActor.AuthenticateCallCount()).To(Equal(1))
   295  						username, password, origin, _ := fakeActor.AuthenticateArgsForCall(0)
   296  						Expect(username).To(Equal(envUsername))
   297  						Expect(password).To(Equal(envPassword))
   298  						Expect(origin).To(BeEmpty())
   299  					})
   300  				})
   301  
   302  				When("username and password are also provided as arguments", func() {
   303  					BeforeEach(func() {
   304  						cmd.RequiredArgs.Username = testID
   305  						cmd.RequiredArgs.Password = testSecret
   306  					})
   307  
   308  					It("authenticates with the values from the command line args", func() {
   309  						Expect(err).ToNot(HaveOccurred())
   310  
   311  						Expect(fakeActor.AuthenticateCallCount()).To(Equal(1))
   312  						username, password, origin, _ := fakeActor.AuthenticateArgsForCall(0)
   313  						Expect(username).To(Equal(testID))
   314  						Expect(password).To(Equal(testSecret))
   315  						Expect(origin).To(BeEmpty())
   316  					})
   317  				})
   318  			})
   319  		})
   320  	})
   321  })