github.com/loafoe/cli@v7.1.0+incompatible/command/v7/auth_command_test.go (about) 1 package v7_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/v7" 12 "code.cloudfoundry.org/cli/command/v7/v7fakes" 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 *v7fakes.FakeActor 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(v7fakes.FakeActor) 32 fakeConfig = new(commandfakes.FakeConfig) 33 34 cmd = AuthCommand{ 35 BaseCommand: BaseCommand{ 36 UI: testUI, 37 Config: fakeConfig, 38 Actor: fakeActor, 39 }, 40 } 41 42 binaryName = "faceman" 43 fakeConfig.BinaryNameReturns(binaryName) 44 fakeConfig.UAAOAuthClientReturns("cf") 45 fakeConfig.APIVersionReturns("3.85.0") 46 }) 47 48 JustBeforeEach(func() { 49 err = cmd.Execute(nil) 50 }) 51 52 When("--origin are set", func() { 53 BeforeEach(func() { 54 cmd.Origin = "some-origin" 55 }) 56 57 When("the UAA is below the minimum API version", func() { 58 BeforeEach(func() { 59 fakeActor.UAAAPIVersionReturns(uaaversion.InvalidUAAClientVersion) 60 }) 61 62 It("returns an API version error", func() { 63 Expect(err).To(MatchError(translatableerror.MinimumUAAAPIVersionNotMetError{ 64 Command: "Option '--origin'", 65 MinimumVersion: uaaversion.MinUAAClientVersion, 66 })) 67 }) 68 }) 69 70 When("--client-credentials set", func() { 71 BeforeEach(func() { 72 cmd.ClientCredentials = true 73 fakeActor.UAAAPIVersionReturns(uaaversion.MinUAAClientVersion) 74 }) 75 76 It("returns an ArgumentCombinationError", func() { 77 Expect(err).To(MatchError(translatableerror.ArgumentCombinationError{ 78 Args: []string{"--client-credentials", "--origin"}, 79 })) 80 }) 81 }) 82 }) 83 84 When("credentials are missing", func() { 85 When("username and password are both missing", func() { 86 It("raises an error", func() { 87 Expect(err).To(MatchError(translatableerror.MissingCredentialsError{ 88 MissingUsername: true, 89 MissingPassword: true, 90 })) 91 }) 92 }) 93 94 When("username is missing", func() { 95 BeforeEach(func() { 96 cmd.RequiredArgs.Password = "mypassword" 97 }) 98 99 It("raises an error", func() { 100 Expect(err).To(MatchError(translatableerror.MissingCredentialsError{ 101 MissingUsername: true, 102 })) 103 }) 104 }) 105 106 When("password is missing", func() { 107 BeforeEach(func() { 108 cmd.RequiredArgs.Username = "myuser" 109 }) 110 111 It("raises an error", func() { 112 Expect(err).To(MatchError(translatableerror.MissingCredentialsError{ 113 MissingPassword: true, 114 })) 115 }) 116 }) 117 }) 118 119 When("there is an auth error", func() { 120 BeforeEach(func() { 121 cmd.RequiredArgs.Username = "foo" 122 cmd.RequiredArgs.Password = "bar" 123 124 fakeConfig.TargetReturns("some-api-target") 125 fakeActor.AuthenticateReturns(uaa.UnauthorizedError{Message: "some message"}) 126 }) 127 128 It("returns a BadCredentialsError", func() { 129 Expect(err).To(MatchError(uaa.UnauthorizedError{Message: "some message"})) 130 }) 131 }) 132 133 When("there is an account locked error", func() { 134 BeforeEach(func() { 135 cmd.RequiredArgs.Username = "foo" 136 cmd.RequiredArgs.Password = "bar" 137 138 fakeConfig.TargetReturns("some-api-target") 139 fakeActor.AuthenticateReturns(uaa.AccountLockedError{Message: "some message"}) 140 }) 141 142 It("returns a BadCredentialsError", func() { 143 Expect(err).To(MatchError(uaa.AccountLockedError{Message: "some message"})) 144 }) 145 }) 146 147 When("there is a non-auth error", func() { 148 var expectedError error 149 150 BeforeEach(func() { 151 cmd.RequiredArgs.Username = "foo" 152 cmd.RequiredArgs.Password = "bar" 153 154 fakeConfig.TargetReturns("some-api-target") 155 expectedError = errors.New("my humps") 156 157 fakeActor.AuthenticateReturns(expectedError) 158 }) 159 160 It("returns the error", func() { 161 Expect(err).To(MatchError(expectedError)) 162 }) 163 }) 164 165 When("there are no input errors", func() { 166 var ( 167 testID string 168 testSecret string 169 ) 170 171 BeforeEach(func() { 172 testID = "hello" 173 testSecret = "goodbye" 174 175 fakeConfig.TargetReturns("some-api-target") 176 }) 177 178 When("--client-credentials is set", func() { 179 BeforeEach(func() { 180 cmd.ClientCredentials = true 181 cmd.RequiredArgs.Username = testID 182 cmd.RequiredArgs.Password = testSecret 183 }) 184 185 It("outputs API target information and clears the targeted org and space", func() { 186 Expect(err).ToNot(HaveOccurred()) 187 188 Expect(testUI.Out).To(Say("API endpoint: %s", fakeConfig.Target())) 189 Expect(testUI.Out).To(Say(`Authenticating\.\.\.`)) 190 Expect(testUI.Out).To(Say("OK")) 191 Expect(testUI.Out).To(Say("Use '%s target' to view or set your target org and space", binaryName)) 192 193 Expect(fakeActor.AuthenticateCallCount()).To(Equal(1)) 194 credentials, origin, grantType := fakeActor.AuthenticateArgsForCall(0) 195 ID := credentials["client_id"] 196 secret := credentials["client_secret"] 197 Expect(ID).To(Equal(testID)) 198 Expect(secret).To(Equal(testSecret)) 199 Expect(origin).To(BeEmpty()) 200 Expect(grantType).To(Equal(constant.GrantTypeClientCredentials)) 201 }) 202 }) 203 204 When("--client-credentials is not set", func() { 205 When("username and password are only provided as arguments", func() { 206 BeforeEach(func() { 207 cmd.RequiredArgs.Username = testID 208 cmd.RequiredArgs.Password = testSecret 209 }) 210 211 When("the API version is older than the minimum supported API version for the v7 CLI", func() { 212 BeforeEach(func() { 213 fakeConfig.APIVersionReturns("3.83.0") 214 }) 215 It("warns that the user is targeting an unsupported API version and that things may not work correctly", func() { 216 Expect(err).ToNot(HaveOccurred()) 217 Expect(testUI.Out).To(Say("API endpoint: %s", fakeConfig.Target())) 218 Expect(testUI.Err).To(Say("Warning: Your targeted API's version \\(3.83.0\\) is less than the minimum supported API version \\(3.85.0\\). Some commands may not function correctly.")) 219 }) 220 }) 221 222 When("the API version is empty", func() { 223 BeforeEach(func() { 224 fakeConfig.APIVersionReturns("") 225 }) 226 It("prints a warning message", func() { 227 Expect(err).ToNot(HaveOccurred()) 228 Expect(testUI.Err).To(Say("Warning: unable to determine whether targeted API's version meets minimum supported.")) 229 }) 230 }) 231 232 It("should NOT warn that the user is targeting an unsupported API version", func() { 233 Expect(testUI.Err).ToNot(Say("is less than the minimum supported API version")) 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 credentials, origin, grantType := fakeActor.AuthenticateArgsForCall(0) 246 username := credentials["username"] 247 password := credentials["password"] 248 Expect(username).To(Equal(testID)) 249 Expect(password).To(Equal(testSecret)) 250 Expect(origin).To(BeEmpty()) 251 Expect(grantType).To(Equal(constant.GrantTypePassword)) 252 }) 253 }) 254 255 When("the username and password are provided in env variables", func() { 256 var ( 257 envUsername string 258 envPassword string 259 ) 260 261 BeforeEach(func() { 262 envUsername = "banana" 263 envPassword = "potato" 264 fakeConfig.CFUsernameReturns(envUsername) 265 fakeConfig.CFPasswordReturns(envPassword) 266 }) 267 268 When("username and password are not also provided as arguments", func() { 269 It("authenticates with the values in the env variables", func() { 270 Expect(err).ToNot(HaveOccurred()) 271 272 Expect(fakeActor.AuthenticateCallCount()).To(Equal(1)) 273 credentials, origin, _ := fakeActor.AuthenticateArgsForCall(0) 274 username := credentials["username"] 275 password := credentials["password"] 276 Expect(username).To(Equal(envUsername)) 277 Expect(password).To(Equal(envPassword)) 278 Expect(origin).To(BeEmpty()) 279 }) 280 }) 281 282 When("username and password are also provided as arguments", func() { 283 BeforeEach(func() { 284 cmd.RequiredArgs.Username = testID 285 cmd.RequiredArgs.Password = testSecret 286 }) 287 288 It("authenticates with the values from the command line args", func() { 289 Expect(err).ToNot(HaveOccurred()) 290 291 Expect(fakeActor.AuthenticateCallCount()).To(Equal(1)) 292 credentials, origin, _ := fakeActor.AuthenticateArgsForCall(0) 293 username := credentials["username"] 294 password := credentials["password"] 295 Expect(username).To(Equal(testID)) 296 Expect(password).To(Equal(testSecret)) 297 Expect(origin).To(BeEmpty()) 298 }) 299 }) 300 }) 301 }) 302 303 When("a user has manually added their client credentials to the config file", func() { 304 BeforeEach(func() { 305 fakeConfig.UAAOAuthClientReturns("AClientsId") 306 }) 307 308 When("the --client-credentials flag is not set", func() { 309 BeforeEach(func() { 310 cmd.ClientCredentials = false 311 cmd.RequiredArgs.Username = "some-username" 312 cmd.RequiredArgs.Password = "some-password" 313 }) 314 315 It("fails with an error indicating manual client credentials are no longer supported in the config file", func() { 316 Expect(err).To(MatchError(translatableerror.ManualClientCredentialsError{})) 317 }) 318 }) 319 }) 320 }) 321 322 When("already logged in via client credentials", func() { 323 BeforeEach(func() { 324 fakeConfig.UAAGrantTypeReturns("client_credentials") 325 }) 326 327 When("authenticating as a user", func() { 328 BeforeEach(func() { 329 cmd.ClientCredentials = false 330 cmd.RequiredArgs.Username = "some-username" 331 cmd.RequiredArgs.Password = "some-password" 332 }) 333 334 It("returns an already logged in error", func() { 335 Expect(err).To(MatchError("Service account currently logged in. Use 'cf logout' to log out service account and try again.")) 336 Expect(fakeConfig.UAAGrantTypeCallCount()).To(Equal(1)) 337 }) 338 339 It("the returned error is translatable", func() { 340 Expect(err).To(MatchError(translatableerror.PasswordGrantTypeLogoutRequiredError{})) 341 }) 342 }) 343 344 When("authenticating as a client", func() { 345 BeforeEach(func() { 346 cmd.ClientCredentials = true 347 cmd.RequiredArgs.Username = "some-client-id" 348 cmd.RequiredArgs.Password = "some-client-secret" 349 }) 350 It("does not error", func() { 351 Expect(err).ToNot(HaveOccurred()) 352 Expect(fakeConfig.UAAGrantTypeCallCount()).To(Equal(0)) 353 }) 354 }) 355 }) 356 })