public async Task UsesUsernameAndPasswordInsteadOfAuthorizationTokenWhenEnterpriseAndAPIReturns404() { var enterpriseHostAddress = HostAddress.Create("https://enterprise.example.com/"); var apiClient = Substitute.For <IApiClient>(); apiClient.HostAddress.Returns(enterpriseHostAddress); // Throw a 404 on the first try with the new scopes apiClient.GetOrCreateApplicationAuthenticationCode(Args.TwoFactorChallengCallback, null, false, true) .Returns(Observable.Throw <ApplicationAuthorization>(new NotFoundException("Not there", HttpStatusCode.NotFound))); // Throw a 404 on the retry with the old scopes: apiClient.GetOrCreateApplicationAuthenticationCode(Args.TwoFactorChallengCallback, null, true, false) .Returns(Observable.Throw <ApplicationAuthorization>(new NotFoundException("Also not there", HttpStatusCode.NotFound))); apiClient.GetUser().Returns(Observable.Return(CreateUserAndScopes("Cthulu"))); var hostCache = new InMemoryBlobCache(); var modelService = new ModelService(apiClient, hostCache, Substitute.For <IAvatarProvider>()); var loginCache = new TestLoginCache(); var host = new RepositoryHost(apiClient, modelService, loginCache, Substitute.For <ITwoFactorChallengeHandler>()); var result = await host.LogIn("Cthulu", "aPassword"); Assert.Equal(AuthenticationResult.Success, result); // Only username and password were saved, never an authorization token: var loginInfo = await loginCache.GetLoginAsync(enterpriseHostAddress); Assert.Equal("Cthulu", loginInfo.UserName); Assert.Equal("aPassword", loginInfo.Password); Assert.True(host.IsLoggedIn); }
public async Task DoesNotLogInWhenRetrievingOauthTokenFails() { var apiClient = Substitute.For <IApiClient>(); apiClient.HostAddress.Returns(HostAddress.GitHubDotComHostAddress); apiClient.GetOrCreateApplicationAuthenticationCode( Args.TwoFactorChallengCallback, Args.String, Args.Boolean) .Returns(Observable.Throw <ApplicationAuthorization>(new NotFoundException("", HttpStatusCode.BadGateway))); apiClient.GetUser().Returns(Observable.Return(CreateUserAndScopes("jiminy"))); var hostCache = new InMemoryBlobCache(); var modelService = new ModelService(apiClient, hostCache, Substitute.For <IAvatarProvider>()); var loginCache = new TestLoginCache(); var host = new RepositoryHost(apiClient, modelService, loginCache, Substitute.For <ITwoFactorChallengeHandler>()); await Assert.ThrowsAsync <NotFoundException>(async() => await host.LogIn("jiminy", "cricket")); await Assert.ThrowsAsync <KeyNotFoundException>( async() => await hostCache.GetObject <AccountCacheItem>("user")); var loginInfo = await loginCache.GetLoginAsync(HostAddress.GitHubDotComHostAddress); Assert.Equal("jiminy", loginInfo.UserName); Assert.Equal("cricket", loginInfo.Password); Assert.False(host.IsLoggedIn); }
public async Task DoesNotFallBackToOldScopesWhenGitHubAndTwoFactorAuthFailsAndErasesLogin() { var apiClient = Substitute.For <IApiClient>(); apiClient.HostAddress.Returns(HostAddress.GitHubDotComHostAddress); apiClient.GetOrCreateApplicationAuthenticationCode(Args.TwoFactorChallengCallback, null, false, true) .Returns(Observable.Throw <ApplicationAuthorization>(new TwoFactorChallengeFailedException())); apiClient.GetUser().Returns(Observable.Return(CreateOctokitUser("jiminy"))); var hostCache = new InMemoryBlobCache(); var modelService = new ModelService(apiClient, hostCache, Substitute.For <IAvatarProvider>()); var loginCache = new TestLoginCache(); var host = new RepositoryHost(apiClient, modelService, loginCache, Substitute.For <ITwoFactorChallengeHandler>()); await host.LogIn("aUsername", "aPassowrd"); apiClient.Received() .GetOrCreateApplicationAuthenticationCode(Args.TwoFactorChallengCallback, null, false, true); apiClient.DidNotReceive().GetOrCreateApplicationAuthenticationCode( Args.TwoFactorChallengCallback, Args.String, true, Args.Boolean); Assert.False(host.IsLoggedIn); var loginInfo = await loginCache.GetLoginAsync(HostAddress.GitHubDotComHostAddress); Assert.Equal("", loginInfo.UserName); Assert.Equal("", loginInfo.Password); }
public async Task LogsTheUserInSuccessfullyAndCachesRelevantInfo() { var apiClient = Substitute.For <IApiClient>(); apiClient.HostAddress.Returns(HostAddress.GitHubDotComHostAddress); apiClient.GetOrCreateApplicationAuthenticationCode( Args.TwoFactorChallengCallback, Args.String, Args.Boolean) .Returns(Observable.Return(new ApplicationAuthorization("S3CR3TS"))); apiClient.GetUser().Returns(Observable.Return(CreateUserAndScopes("baymax"))); var hostCache = new InMemoryBlobCache(); var modelService = new ModelService(apiClient, hostCache, Substitute.For <IAvatarProvider>()); var loginCache = new TestLoginCache(); var host = new RepositoryHost(apiClient, modelService, loginCache, Substitute.For <ITwoFactorChallengeHandler>()); var result = await host.LogIn("baymax", "aPassword"); Assert.Equal(AuthenticationResult.Success, result); var user = await hostCache.GetObject <AccountCacheItem>("user"); Assert.NotNull(user); Assert.Equal("baymax", user.Login); var loginInfo = await loginCache.GetLoginAsync(HostAddress.GitHubDotComHostAddress); Assert.Equal("baymax", loginInfo.UserName); Assert.Equal("S3CR3TS", loginInfo.Password); Assert.True(host.IsLoggedIn); }
public async Task RetriesUsingOldScopeWhenAuthenticationFailsAndIsEnterprise() { var enterpriseHostAddress = HostAddress.Create("https://enterprise.example.com/"); var apiClient = Substitute.For <IApiClient>(); apiClient.HostAddress.Returns(enterpriseHostAddress); apiClient.GetOrCreateApplicationAuthenticationCode(Args.TwoFactorChallengCallback, null, false, true) .Returns(Observable.Throw <ApplicationAuthorization>(new ApiException("Bad scopes", (HttpStatusCode)422))); apiClient.GetOrCreateApplicationAuthenticationCode(Args.TwoFactorChallengCallback, null, true, false) .Returns(Observable.Return(new ApplicationAuthorization("T0k3n"))); apiClient.GetUser().Returns(Observable.Return(CreateUserAndScopes("jiminy"))); var hostCache = new InMemoryBlobCache(); var modelService = new ModelService(apiClient, hostCache, Substitute.For <IAvatarProvider>()); var loginCache = new TestLoginCache(); var usage = Substitute.For <IUsageTracker>(); var host = new RepositoryHost(apiClient, modelService, loginCache, Substitute.For <ITwoFactorChallengeHandler>(), usage); await host.LogIn("jiminy", "aPassowrd"); Assert.True(host.IsLoggedIn); var loginInfo = await loginCache.GetLoginAsync(enterpriseHostAddress); Assert.Equal("jiminy", loginInfo.UserName); Assert.Equal("T0k3n", loginInfo.Password); }