public async Task NoMatchingAccountsUsernameOnly()
        {
            string         expToken           = Guid.NewGuid().ToString();
            DateTimeOffset expExpiresOn       = DateTimeOffset.UtcNow.AddMinutes(5);
            string         fakeuserTenantId   = Guid.NewGuid().ToString();
            string         madeupuserTenantId = Guid.NewGuid().ToString();

            var mockMsalClient = new MockMsalPublicClient
            {
                Accounts          = new IAccount[] { new MockAccount("*****@*****.**", fakeuserTenantId), new MockAccount("*****@*****.**", madeupuserTenantId) },
                SilentAuthFactory = (_) => { return(AuthenticationResultFactory.Create(accessToken: expToken, expiresOn: expExpiresOn)); }
            };

            // with username
            var credential = InstrumentClient(new SharedTokenCacheCredential(null, "*****@*****.**", CredentialPipeline.GetInstance(null), mockMsalClient));

            var ex = Assert.ThrowsAsync <CredentialUnavailableException>(async() => await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default)));

            Assert.AreEqual(ex.Message, "SharedTokenCacheCredential authentication unavailable. No account matching the specified username: [email protected] was found in the cache.");

            await Task.CompletedTask;
        }
        public async Task UiRequiredException()
        {
            string         expToken     = Guid.NewGuid().ToString();
            DateTimeOffset expExpiresOn = DateTimeOffset.UtcNow.AddMinutes(5);

            var mockMsalClient = new MockMsalPublicClient
            {
                Accounts          = new IAccount[] { new MockAccount("*****@*****.**") },
                SilentAuthFactory = (_) => { throw new MsalUiRequiredException("code", "message"); }
            };

            // with username
            var credential = InstrumentClient(new SharedTokenCacheCredential(null, "*****@*****.**", CredentialPipeline.GetInstance(null), mockMsalClient));

            var ex = Assert.ThrowsAsync <CredentialUnavailableException>(async() => await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default)));

            var expErrorMessage = "Token acquisition failed for user [email protected]. To fix, re-authenticate through developer tooling supporting Azure single sign on.";

            Assert.AreEqual(expErrorMessage, ex.Message);

            await Task.CompletedTask;
        }
        public async Task VerifyAuthenticationRecordOption()
        {
            var expectedHomeId = $"{Guid.NewGuid()}.{Guid.NewGuid()}";

            var expectedEnvironment = AzureAuthorityHosts.AzurePublicCloud.ToString();

            var acquireTokenSilentCalled = false;

            var options = new SharedTokenCacheCredentialOptions
            {
                AuthenticationRecord = new AuthenticationRecord(expectedUsername, expectedEnvironment, expectedHomeId, Guid.NewGuid().ToString(), Guid.NewGuid().ToString())
            };

            var mockMsalClient = new MockMsalPublicClient
            {
                Accounts = new List <IAccount> {
                    new MockAccount("*****@*****.**")
                },
                ExtendedSilentAuthFactory = (_, account, __, ___) =>
                {
                    Assert.AreEqual(expectedUsername, account.Username);

                    Assert.AreEqual(expectedEnvironment, account.Environment);

                    Assert.AreEqual(expectedHomeId, account.HomeAccountId.Identifier);

                    acquireTokenSilentCalled = true;

                    return(AuthenticationResultFactory.Create());
                }
            };

            var credential = InstrumentClient(new SharedTokenCacheCredential(null, null, options, null, mockMsalClient));

            AccessToken token = await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default));

            Assert.IsTrue(acquireTokenSilentCalled);
        }
        public async Task MatchAnyTenantIdWithEnableGuestTenantAuthenticationAndUsername()
        {
            string         expToken       = Guid.NewGuid().ToString();
            DateTimeOffset expExpiresOn   = DateTimeOffset.UtcNow.AddMinutes(5);
            string         tenantId       = Guid.NewGuid().ToString();
            var            mockMsalClient = new MockMsalPublicClient
            {
                Accounts = new List <IAccount> {
                    new MockAccount("*****@*****.**", Guid.NewGuid().ToString()), new MockAccount("*****@*****.**", Guid.NewGuid().ToString())
                },
                SilentAuthFactory = (_) => { return(AuthenticationResultFactory.Create(accessToken: expToken, expiresOn: expExpiresOn)); }
            };

            var credential = InstrumentClient(new SharedTokenCacheCredential(tenantId, "*****@*****.**", new SharedTokenCacheCredentialOptions {
                EnableGuestTenantAuthentication = true
            }, null, mockMsalClient));

            AccessToken token = await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default));

            Assert.AreEqual(expToken, token.Token);

            Assert.AreEqual(expExpiresOn, token.ExpiresOn);
        }
        public async Task MultipleAccountsNoTenantIdOrUsername()
        {
            string         expToken           = Guid.NewGuid().ToString();
            DateTimeOffset expExpiresOn       = DateTimeOffset.UtcNow.AddMinutes(5);
            string         fakeuserTenantId   = Guid.NewGuid().ToString();
            string         madeupuserTenantId = Guid.NewGuid().ToString();

            var mockMsalClient = new MockMsalPublicClient
            {
                Accounts = new List <IAccount> {
                    new MockAccount("*****@*****.**", fakeuserTenantId), new MockAccount("*****@*****.**", madeupuserTenantId)
                },
                SilentAuthFactory = (_) => { return(AuthenticationResultFactory.Create(accessToken: expToken, expiresOn: expExpiresOn)); }
            };

            var credential = InstrumentClient(new SharedTokenCacheCredential(null, null, null, null, mockMsalClient));

            var ex = Assert.ThrowsAsync <CredentialUnavailableException>(async() => await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default)));

            Assert.AreEqual(ex.Message, "SharedTokenCacheCredential authentication unavailable. Multiple accounts were found in the cache. Use username and tenant id to disambiguate.");

            await Task.CompletedTask;
        }
        public async Task VerifyMsalClientExceptionAsync()
        {
            string expInnerExMessage = Guid.NewGuid().ToString();

            var mockMsalClient = new MockMsalPublicClient()
            {
                UserPassAuthFactory = (_) => { throw new MockClientException(expInnerExMessage); }
            };

            var username = Guid.NewGuid().ToString();
            var password = Guid.NewGuid().ToString();

            var credential = InstrumentClient(new UsernamePasswordCredential(username, password, CredentialPipeline.GetInstance(null), mockMsalClient));

            var ex = Assert.ThrowsAsync <AuthenticationFailedException>(async() => await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default)));

            Assert.IsNotNull(ex.InnerException);

            Assert.IsInstanceOf(typeof(MockClientException), ex.InnerException);

            Assert.AreEqual(expInnerExMessage, ex.InnerException.Message);

            await Task.CompletedTask;
        }
        public async Task UiRequiredException()
        {
            string         expToken     = Guid.NewGuid().ToString();
            DateTimeOffset expExpiresOn = DateTimeOffset.UtcNow.AddMinutes(5);

            var mockMsalClient = new MockMsalPublicClient
            {
                Accounts = new List <IAccount> {
                    new MockAccount(expectedUsername)
                },
                SilentAuthFactory = (_) => { throw new MsalUiRequiredException("code", "message"); }
            };

            // with username
            var credential = InstrumentClient(new SharedTokenCacheCredential(null, expectedUsername, null, null, mockMsalClient));

            var ex = Assert.ThrowsAsync <CredentialUnavailableException>(async() => await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default)));

            var expErrorMessage = $"SharedTokenCacheCredential authentication unavailable. Token acquisition failed for user {expectedUsername}. Ensure that you have authenticated with a developer tool that supports Azure single sign on.";

            Assert.AreEqual(expErrorMessage, ex.Message);

            await Task.CompletedTask;
        }
        public async Task MultipleMatchingAccountsUsernameAndTenantId()
        {
            string         expToken              = Guid.NewGuid().ToString();
            DateTimeOffset expExpiresOn          = DateTimeOffset.UtcNow.AddMinutes(5);
            string         fakeuserTenantId      = Guid.NewGuid().ToString();
            string         mockuserTenantId      = Guid.NewGuid().ToString();
            string         mockuserGuestTenantId = fakeuserTenantId;

            var mockMsalClient = new MockMsalPublicClient
            {
                Accounts = new List <IAccount> {
                    new MockAccount("*****@*****.**", fakeuserTenantId), new MockAccount(expectedUsername, mockuserTenantId), new MockAccount(expectedUsername, mockuserTenantId)
                },
                SilentAuthFactory = (_) => { return(AuthenticationResultFactory.Create(accessToken: expToken, expiresOn: expExpiresOn)); }
            };

            var credential = InstrumentClient(new SharedTokenCacheCredential(mockuserTenantId, expectedUsername, null, null, mockMsalClient));

            var ex = Assert.ThrowsAsync <CredentialUnavailableException>(async() => await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default)));

            Assert.AreEqual(ex.Message, $"SharedTokenCacheCredential authentication unavailable. Multiple accounts matching the specified username: {expectedUsername} tenantId: {mockuserTenantId} were found in the cache.");

            await Task.CompletedTask;
        }
        public void TestSetup()
        {
            expectedTenantId      = null;
            expectedReplyUri      = null;
            authCode              = Guid.NewGuid().ToString();
            options               = new TokenCredentialOptions();
            expectedToken         = Guid.NewGuid().ToString();
            expectedUserAssertion = Guid.NewGuid().ToString();
            expiresOn             = DateTimeOffset.Now.AddHours(1);
            result = new AuthenticationResult(
                expectedToken,
                false,
                null,
                expiresOn,
                expiresOn,
                TenantId,
                new MockAccount("username"),
                null,
                new[] { Scope },
                Guid.NewGuid(),
                null,
                "Bearer");

            mockConfidentialMsalClient = new MockMsalConfidentialClient()
                                         .WithSilentFactory(
                (_, _tenantId, _replyUri, _) =>
            {
                Assert.AreEqual(expectedTenantId, _tenantId);
                Assert.AreEqual(expectedReplyUri, _replyUri);
                return(new ValueTask <AuthenticationResult>(result));
            })
                                         .WithAuthCodeFactory(
                (_, _tenantId, _replyUri, _) =>
            {
                Assert.AreEqual(expectedTenantId, _tenantId);
                Assert.AreEqual(expectedReplyUri, _replyUri);
                return(result);
            })
                                         .WithOnBehalfOfFactory(
                (_, _, userAssertion, _, _) =>
            {
                Assert.AreEqual(expectedUserAssertion, userAssertion.Assertion);
                return(new ValueTask <AuthenticationResult>(result));
            })
                                         .WithClientFactory(
                (_, _tenantId) =>
            {
                Assert.AreEqual(expectedTenantId, _tenantId);
                return(result);
            });

            expectedCode         = Guid.NewGuid().ToString();
            mockPublicMsalClient = new MockMsalPublicClient();
            deviceCodeResult     = MockMsalPublicClient.GetDeviceCodeResult(deviceCode: expectedCode);
            mockPublicMsalClient.DeviceCodeResult = deviceCodeResult;
            var publicResult = new AuthenticationResult(
                expectedToken,
                false,
                null,
                expiresOn,
                expiresOn,
                TenantId,
                new MockAccount("username"),
                null,
                new[] { Scope },
                Guid.NewGuid(),
                null,
                "Bearer");

            mockPublicMsalClient.SilentAuthFactory = (_, tId) =>
            {
                Assert.AreEqual(expectedTenantId, tId);
                return(publicResult);
            };
            mockPublicMsalClient.DeviceCodeAuthFactory = (_, _) =>
            {
                // Assert.AreEqual(tenantId, tId);
                return(publicResult);
            };
            mockPublicMsalClient.InteractiveAuthFactory = (_, _, _, _, tenant, _, _) =>
            {
                Assert.AreEqual(expectedTenantId, tenant, "TenantId passed to msal should match");
                return(result);
            };
            mockPublicMsalClient.SilentAuthFactory = (_, tenant) =>
            {
                Assert.AreEqual(expectedTenantId, tenant, "TenantId passed to msal should match");
                return(result);
            };
            mockPublicMsalClient.ExtendedSilentAuthFactory = (_, _, _, tenant, _, _) =>
            {
                Assert.AreEqual(expectedTenantId, tenant, "TenantId passed to msal should match");
                return(result);
            };
            mockPublicMsalClient.UserPassAuthFactory = (_, tenant) =>
            {
                Assert.AreEqual(expectedTenantId, tenant, "TenantId passed to msal should match");
                return(result);
            };
            mockPublicMsalClient.RefreshTokenFactory = (_, _, _, _, tenant, _, _) =>
            {
                Assert.AreEqual(expectedTenantId, tenant, "TenantId passed to msal should match");
                return(result);
            };
        }