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 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);
        }
Example #3
0
        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);
        }
Example #5
0
        public async Task IncrementsLoginCount()
        {
            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(CreateOctokitUser("baymax")));
            var hostCache    = new InMemoryBlobCache();
            var modelService = Substitute.For <IModelService>();
            var loginManager = Substitute.For <ILoginManager>();

            loginManager.Login(HostAddress.GitHubDotComHostAddress, Arg.Any <IGitHubClient>(), "baymax", "aPassword").Returns(CreateOctokitUser("baymax"));
            var loginCache = new TestLoginCache();
            var usage      = Substitute.For <IUsageTracker>();
            var host       = new RepositoryHost(apiClient, modelService, loginManager, loginCache, usage);

            var result = await host.LogIn("baymax", "aPassword");

            var model = new UsageModel();

            await usage.Received().IncrementCounter(
                Arg.Is <Expression <Func <UsageModel, int> > >(x =>
                                                               ((MemberExpression)x.Body).Member.Name == nameof(model.NumberOfLogins)));
        }
Example #6
0
        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);
        }
        public async Task SupportsGistIsFalseWhenGistScopeIsNotPresent()
        {
            var apiClient = Substitute.For <IApiClient>();

            apiClient.HostAddress.Returns(HostAddress.GitHubDotComHostAddress);
            apiClient.GetUser().Returns(Observable.Return(CreateUserAndScopes("baymax", new[] { "foo" })));
            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);
            Assert.False(host.SupportsGist);
        }
        public async Task IncrementsLoginCount()
        {
            var apiClient = Substitute.For <IApiClient>();

            apiClient.HostAddress.Returns(HostAddress.GitHubDotComHostAddress);
            var hostCache    = new InMemoryBlobCache();
            var modelService = Substitute.For <IModelService>();
            var loginManager = Substitute.For <ILoginManager>();

            loginManager.LoginFromCache(HostAddress.GitHubDotComHostAddress, Arg.Any <IGitHubClient>()).Returns(CreateOctokitUser("baymax"));
            var loginCache = new TestLoginCache();
            var usage      = Substitute.For <IUsageTracker>();
            var host       = new RepositoryHost(apiClient, modelService, loginManager, loginCache, usage);

            var result = await host.LogInFromCache();

            await usage.Received().IncrementLoginCount();
        }
        public async Task SupportsGistIsTrueWhenScopesAreNull()
        {
            // TODO: Check assumptions here. From my conversation with @shana it seems that the first login
            // will be done with basic auth and from then on a token will be used. So if it's the first login,
            // it's from this version and so gists will be supported. However I've been unable to repro this
            // behavior.
            var apiClient = Substitute.For <IApiClient>();

            apiClient.HostAddress.Returns(HostAddress.GitHubDotComHostAddress);
            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);
            Assert.True(host.SupportsGist);
        }
        public async Task DoesNotLogInWhenRetrievingOauthTokenFails()
        {
            var apiClient = Substitute.For <IApiClient>();

            apiClient.HostAddress.Returns(HostAddress.GitHubDotComHostAddress);
            var hostCache    = new InMemoryBlobCache();
            var modelService = new ModelService(apiClient, hostCache, Substitute.For <IAvatarProvider>());
            var loginManager = Substitute.For <ILoginManager>();

            loginManager.Login(HostAddress.GitHubDotComHostAddress, Arg.Any <IGitHubClient>(), "jiminy", "cricket")
            .Returns <User>(_ => { throw new NotFoundException("", HttpStatusCode.BadGateway); });
            var loginCache = new TestLoginCache();
            var usage      = Substitute.For <IUsageTracker>();
            var host       = new RepositoryHost(apiClient, modelService, loginManager, loginCache, usage);

            await Assert.ThrowsAsync <NotFoundException>(async() => await host.LogIn("jiminy", "cricket"));

            await Assert.ThrowsAsync <KeyNotFoundException>(
                async() => await hostCache.GetObject <AccountCacheItem>("user"));
        }
        public async Task LogsTheUserInSuccessfullyAndCachesRelevantInfo()
        {
            var apiClient = Substitute.For <IApiClient>();

            apiClient.HostAddress.Returns(HostAddress.GitHubDotComHostAddress);
            var hostCache    = new InMemoryBlobCache();
            var modelService = new ModelService(apiClient, hostCache, Substitute.For <IAvatarProvider>());
            var loginManager = Substitute.For <ILoginManager>();

            loginManager.LoginFromCache(HostAddress.GitHubDotComHostAddress, Arg.Any <IGitHubClient>()).Returns(CreateOctokitUser("baymax"));
            var loginCache = new TestLoginCache();
            var usage      = Substitute.For <IUsageTracker>();
            var host       = new RepositoryHost(apiClient, modelService, loginManager, loginCache, usage);

            var result = await host.LogInFromCache();

            Assert.Equal(AuthenticationResult.Success, result);
            var user = await hostCache.GetObject <AccountCacheItem>("user");

            Assert.NotNull(user);
            Assert.Equal("baymax", user.Login);
        }
Example #12
0
        public async Task IncrementsLoginCount()
        {
            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 = Substitute.For <IModelService>();
            var loginManager = Substitute.For <ILoginManager>();

            loginManager.Login(HostAddress.GitHubDotComHostAddress, Arg.Any <IGitHubClient>(), "baymax", "aPassword").Returns(CreateUserAndScopes("baymax").User);
            var loginCache = new TestLoginCache();
            var usage      = Substitute.For <IUsageTracker>();
            var host       = new RepositoryHost(apiClient, modelService, loginManager, loginCache, usage);

            var result = await host.LogIn("baymax", "aPassword");

            await usage.Received().IncrementLoginCount();
        }
Example #13
0
        public async Task IncrementsLoginCount()
        {
            var apiClient = Substitute.For <IApiClient>();

            apiClient.HostAddress.Returns(HostAddress.GitHubDotComHostAddress);
            var hostCache    = new InMemoryBlobCache();
            var modelService = Substitute.For <IModelService>();
            var loginManager = Substitute.For <ILoginManager>();

            loginManager.LoginFromCache(HostAddress.GitHubDotComHostAddress, Arg.Any <IGitHubClient>()).Returns(CreateOctokitUser("baymax"));
            var loginCache = new TestLoginCache();
            var usage      = Substitute.For <IUsageTracker>();
            var host       = new RepositoryHost(apiClient, modelService, loginManager, loginCache, usage);

            var result = await host.LogInFromCache();

            var model = new UsageModel();

            await usage.Received().IncrementCounter(
                Arg.Is <Expression <Func <UsageModel, int> > >(x =>
                                                               ((MemberExpression)x.Body).Member.Name == nameof(model.NumberOfLogins)));
        }