public async Task RespectsTaskHubNameFromHostJson()
        {
            // Arrange

            var hubName = $"HubName{DateTime.Now.Ticks}";

            var request = new DefaultHttpContext().Request;

            var logMoq = new Mock <ILogger>();

            logMoq.Setup(log => log.Log(It.IsAny <LogLevel>(), It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), It.IsAny <Func <It.IsAnyType, Exception, string> >()))
            .Callback((LogLevel l, EventId i, object s, Exception ex, object o) =>
            {
                // Ensuring the correct type of exception was raised internally
                Assert.IsInstanceOfType(ex, typeof(UnauthorizedAccessException));
                Assert.AreEqual("XSRF token is missing.", ex.Message);
            });

            Environment.SetEnvironmentVariable(EnvVariableNames.DFM_HUB_NAME, string.Empty);

            await File.WriteAllTextAsync("../host.json", $"{{\"extensions\":{{\"durableTask\": {{\"hubName\": \"{hubName}\"}}}}}}");

            // Act
            var result = await About.DfmAboutFunction(request, "-", hubName, logMoq.Object);

            // Assert
            File.Delete("../host.json");

            Assert.IsInstanceOfType(result, typeof(UnauthorizedResult));
        }
Esempio n. 2
0
        public async Task ReturnsUnauthorizedResultIfUserIsNotInRole()
        {
            // Arrange
            var request = new DefaultHttpContext().Request;

            var logMoq = new Mock <ILogger>();

            string userName = "******";

            logMoq.Setup(log => log.Log(It.IsAny <LogLevel>(), It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), It.IsAny <Func <It.IsAnyType, Exception, string> >()))
            .Callback((LogLevel l, EventId i, object s, Exception ex, object o) =>
            {
                // Ensuring the correct type of exception was raised internally
                Assert.IsInstanceOfType(ex, typeof(UnauthorizedAccessException));
                Assert.AreEqual($"User {userName} doesn't have any of roles mentioned in {EnvVariableNames.DFM_ALLOWED_APP_ROLES} config setting. Call is rejected", ex.Message);
            });

            Environment.SetEnvironmentVariable(EnvVariableNames.DFM_HUB_NAME, string.Empty);
            Environment.SetEnvironmentVariable(EnvVariableNames.DFM_ALLOWED_USER_NAMES, "");
            Environment.SetEnvironmentVariable(EnvVariableNames.DFM_ALLOWED_APP_ROLES, "role1,role2");

            // Need to reset DfmEndpoint.Settings
            DfmEndpoint.Setup();

            request.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity[] { new ClaimsIdentity(new Claim[] {
                    new Claim("preferred_username", userName)
                }) });

            // Act
            var result = await About.DfmAboutFunction(request, "TestHub", logMoq.Object);

            // Assert
            Assert.IsInstanceOfType(result, typeof(UnauthorizedResult));
        }
Esempio n. 3
0
        public async Task ValidatesTokenWithoutEasyAuthsHelp()
        {
            // Arrange
            var request = new DefaultHttpContext().Request;

            var logMoq = new Mock <ILogger>();

            string userName = "******";
            string roleName = "my-app-role";
            string audience = "my-audience";
            string issuer   = "my-issuer";
            string token    = "blah-blah";

            var principal = new ClaimsPrincipal(new ClaimsIdentity[] { new ClaimsIdentity(new Claim[] {
                    new Claim("preferred_username", userName),
                    new Claim("roles", roleName)
                }) });

            ICollection <SecurityKey> securityKeys = new SecurityKey[0];

            ValidateTokenDelegate validateTokenDelegate = (string t, TokenValidationParameters p, out SecurityToken st) =>
            {
                st = null;

                Assert.AreEqual(token, t);
                Assert.AreEqual(audience, p.ValidAudiences.Single());
                Assert.AreEqual(issuer, p.ValidIssuers.Single());
                Assert.AreEqual(securityKeys, p.IssuerSigningKeys);
            };

            SecurityToken st            = null;
            var           jwtHandlerMoq = new Mock <JwtSecurityTokenHandler>();

            jwtHandlerMoq.Setup(h => h.ValidateToken(It.IsAny <string>(), It.IsAny <TokenValidationParameters>(), out st))
            .Callback(validateTokenDelegate)
            .Returns(principal);

            Auth.MockedJwtSecurityTokenHandler = jwtHandlerMoq.Object;
            Auth.GetSigningKeysTask            = Task.FromResult(securityKeys);

            Environment.SetEnvironmentVariable(EnvVariableNames.DFM_HUB_NAME, string.Empty);
            Environment.SetEnvironmentVariable(EnvVariableNames.WEBSITE_AUTH_CLIENT_ID, audience);
            Environment.SetEnvironmentVariable(EnvVariableNames.WEBSITE_AUTH_OPENID_ISSUER, issuer);

            Environment.SetEnvironmentVariable(EnvVariableNames.DFM_ALLOWED_USER_NAMES, "[email protected],[email protected]," + userName);
            Environment.SetEnvironmentVariable(EnvVariableNames.DFM_ALLOWED_APP_ROLES, roleName);
            Environment.SetEnvironmentVariable(EnvVariableNames.AzureWebJobsStorage, token);

            // Need to reset DfmEndpoint.Settings
            DfmEndpoint.Setup();

            request.Headers.Add("Authorization", "Bearer " + token);

            // Act
            var result = await About.DfmAboutFunction(request, "TestHub", logMoq.Object);

            // Assert
            Assert.IsInstanceOfType(result, typeof(ContentResult));
        }
        public async Task LoadsListOfTablesFromTableStorage()
        {
            // Arrange
            var request = new DefaultHttpContext().Request;

            string xsrfToken = $"xsrf-token-{DateTime.Now.Ticks}";

            request.Headers.Add("Cookie", new CookieHeaderValue(Globals.XsrfTokenCookieAndHeaderName, xsrfToken).ToString());
            request.Headers.Add(Globals.XsrfTokenCookieAndHeaderName, xsrfToken);

            var logMoq = new Mock <ILogger>();

            bool   tableClientInitialized = false;
            string hubName = "InvalidHubName";

            logMoq.Setup(log => log.Log(It.IsAny <LogLevel>(), It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), It.IsAny <Func <It.IsAnyType, Exception, string> >()))
            .Callback((LogLevel l, EventId i, object s, Exception ex, object o) =>
            {
                // Ensuring the correct type of exception was raised internally
                Assert.IsInstanceOfType(ex, typeof(UnauthorizedAccessException));

                // If TableClient throws, task hub validation should be skipped, and we should get 'No access token provided'.
                // Next time, when MockedTableClient is set, we should get 'Task Hub is not allowed'.
                // This also validates that queries against table storage are properly retried.
                Assert.AreEqual(
                    tableClientInitialized ?
                    $"Task Hub '{hubName}' is not allowed." :
                    "No access token provided. Call is rejected.",
                    ex.Message);
            });

            Environment.SetEnvironmentVariable(EnvVariableNames.DFM_HUB_NAME, string.Empty);

            var tableClientMoq = new Mock <ITableClient>();

            tableClientMoq.Setup(c => c.ListTableNamesAsync())
            .Returns(Task.FromResult <IEnumerable <string> >(new string[] {
                "Hub1Instances", "Hub1History",
                "Hub2Instances", "Hub2History"
            }));

            // Act
            var result = await About.DfmAboutFunction(request, "-", hubName, logMoq.Object);

            TableClient.MockedTableClient = tableClientMoq.Object;
            tableClientInitialized        = true;

            result = await About.DfmAboutFunction(request, "-", hubName, logMoq.Object);

            result = await About.DfmAboutFunction(request, "-", hubName, logMoq.Object);

            // Assert
            Assert.IsInstanceOfType(result, typeof(UnauthorizedResult));
        }
        public async Task LoadsListOfTablesFromAlternativeStorage()
        {
            // Arrange
            var request = new DefaultHttpContext().Request;

            string xsrfToken = $"xsrf-token-{DateTime.Now.Ticks}";

            request.Headers.Add(Globals.XsrfTokenCookieAndHeaderName, xsrfToken);

            var logMoq = new Mock <ILogger>();

            string connName = "MyConnStringName";
            string hubName  = "Hub2";

            Auth.AlternativeConnectionStringNames = new[] { connName };

            logMoq.Setup(log => log.Log(It.IsAny <LogLevel>(), It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), It.IsAny <Func <It.IsAnyType, Exception, string> >()))
            .Callback((LogLevel l, EventId i, object s, Exception ex, object o) =>
            {
                // Ensuring the correct type of exception was raised internally
                Assert.IsInstanceOfType(ex, typeof(UnauthorizedAccessException));
                Assert.AreEqual("XSRF tokens do not match.", ex.Message);
            });

            Environment.SetEnvironmentVariable(EnvVariableNames.DFM_HUB_NAME, string.Empty);

            var tableClientMoq = new Mock <ITableClient>();

            tableClientMoq.Setup(c => c.ListTableNamesAsync())
            .Returns(Task.FromResult <IEnumerable <string> >(new string[] {
                "Hub1Instances", "Hub1History",
                "Hub2Instances", "Hub2History"
            }));

            TableClient.MockedTableClient = tableClientMoq.Object;

            // Act

            var result = await About.DfmAboutFunction(request, connName, hubName, logMoq.Object);

            // Assert
            Assert.IsInstanceOfType(result, typeof(UnauthorizedResult));
        }
        public async Task ReturnsBadRequestResultIfTaskHubNameIsInvalid()
        {
            // Arrange
            var request = new DefaultHttpContext().Request;

            var logMoq = new Mock <ILogger>();

            logMoq.Setup(log => log.Log(It.IsAny <LogLevel>(), It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), It.IsAny <Func <It.IsAnyType, Exception, string> >()))
            .Callback((LogLevel l, EventId i, object s, Exception ex, object o) =>
            {
                // Ensuring the correct type of exception was raised internally
                Assert.IsInstanceOfType(ex, typeof(ArgumentException));
                Assert.AreEqual("Task Hub name is invalid.", ex.Message);
            });

            // Act
            var result = await About.DfmAboutFunction(request, "-", "bad//hub\\name", logMoq.Object);

            // Assert
            Assert.IsInstanceOfType(result, typeof(BadRequestObjectResult));
        }
        public async Task RespectsTaskHubNameEnvVariableFromHostJson()
        {
            // Arrange

            var hubName         = $"HubName-{DateTime.Now.Ticks}";
            var hubNameVariable = $"HubNameEnvVariable{DateTime.Now.Ticks}";

            var request = new DefaultHttpContext().Request;

            request.Headers.Add("Authorization", "Bearer blah-blah");

            string xsrfToken = $"xsrf-token-{DateTime.Now.Ticks}";

            request.Headers.Add("Cookie", new CookieHeaderValue(Globals.XsrfTokenCookieAndHeaderName, xsrfToken).ToString());
            request.Headers.Add(Globals.XsrfTokenCookieAndHeaderName, xsrfToken);

            var logMoq = new Mock <ILogger>();

            logMoq.Setup(log => log.Log(It.IsAny <LogLevel>(), It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), It.IsAny <Func <It.IsAnyType, Exception, string> >()))
            .Callback((LogLevel l, EventId i, object s, Exception ex, object o) =>
            {
                // Ensuring the correct type of exception was raised internally
                Assert.IsInstanceOfType(ex, typeof(UnauthorizedAccessException));
                Assert.AreEqual("Specify the Valid Issuer value via 'WEBSITE_AUTH_OPENID_ISSUER' config setting. Typically it looks like 'https://login.microsoftonline.com/<your-aad-tenant-id>/v2.0'.", ex.Message);
            });

            await File.WriteAllTextAsync("../host.json", $"{{\"extensions\":{{\"durableTask\": {{\"hubName\": \"%{hubNameVariable}%\"}}}}}}");

            Environment.SetEnvironmentVariable(hubNameVariable, hubName);

            Environment.SetEnvironmentVariable(EnvVariableNames.WEBSITE_AUTH_CLIENT_ID, $"SomeClientId{DateTime.Now}");

            // Act
            var result = await About.DfmAboutFunction(request, "-", hubName, logMoq.Object);

            // Assert
            File.Delete("../host.json");

            Assert.IsInstanceOfType(result, typeof(UnauthorizedResult));
        }
Esempio n. 8
0
        public async Task DfmAboutFunctionSucceeds()
        {
            // Arrange
            var request = new DefaultHttpContext().Request;

            request.Headers["x-dfm-nonce"] = Shared.Nonce;

            var logMoq = new Mock <ILogger>();

            Environment.SetEnvironmentVariable(EnvVariableNames.DFM_NONCE, Shared.Nonce);
            Environment.SetEnvironmentVariable(EnvVariableNames.AzureWebJobsStorage, "blah-blah AccountName=Tino; blah-blah");
            Environment.SetEnvironmentVariable(EnvVariableNames.DFM_HUB_NAME, "Hub1,Hub2,Hub3");

            // Act
            var result = (ContentResult)await About.DfmAboutFunction(request, "Hub1", logMoq.Object);

            // Assert
            dynamic resultJson = JsonConvert.DeserializeObject(result.Content);

            Assert.AreEqual("Tino", resultJson.accountName.ToString());
            Assert.AreEqual("Hub1", resultJson.hubName.ToString());
        }
        public async Task ReturnsUnauthorizedResultIfUserNotWhitelisted()
        {
            // Arrange
            var request = new DefaultHttpContext().Request;

            string xsrfToken = $"xsrf-token-{DateTime.Now.Ticks}";

            request.Headers.Add("Cookie", new CookieHeaderValue(Globals.XsrfTokenCookieAndHeaderName, xsrfToken).ToString());
            request.Headers.Add(Globals.XsrfTokenCookieAndHeaderName, xsrfToken);

            var logMoq = new Mock <ILogger>();

            string userName = "******";

            logMoq.Setup(log => log.Log(It.IsAny <LogLevel>(), It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), It.IsAny <Func <It.IsAnyType, Exception, string> >()))
            .Callback((LogLevel l, EventId i, object s, Exception ex, object o) =>
            {
                // Ensuring the correct type of exception was raised internally
                Assert.IsInstanceOfType(ex, typeof(UnauthorizedAccessException));
                Assert.AreEqual($"User {userName} is not mentioned in {EnvVariableNames.DFM_ALLOWED_USER_NAMES} config setting. Call is rejected", ex.Message);
            });

            Environment.SetEnvironmentVariable(EnvVariableNames.DFM_HUB_NAME, string.Empty);
            Environment.SetEnvironmentVariable(EnvVariableNames.DFM_ALLOWED_USER_NAMES, "[email protected],[email protected]");

            // Need to reset DfmEndpoint.Settings
            DfmEndpoint.Setup();

            request.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity[] { new ClaimsIdentity(new Claim[] {
                    new Claim("preferred_username", userName)
                }) });

            // Act
            var result = await About.DfmAboutFunction(request, "-", "TestHub", logMoq.Object);

            // Assert
            Assert.IsInstanceOfType(result, typeof(UnauthorizedResult));
        }
Esempio n. 10
0
        public async Task ReturnsUnauthorizedResultIfTaskHubNotAllowed()
        {
            // Arrange
            var request = new DefaultHttpContext().Request;

            var logMoq = new Mock <ILogger>();

            logMoq.Setup(log => log.Log(It.IsAny <LogLevel>(), It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), It.IsAny <Func <It.IsAnyType, Exception, string> >()))
            .Callback((LogLevel l, EventId i, object s, Exception ex, object o) =>
            {
                // Ensuring the correct type of exception was raised internally
                Assert.IsInstanceOfType(ex, typeof(UnauthorizedAccessException));
                Assert.AreEqual("Task Hub 'InvalidHubName' is not allowed.", ex.Message);
            });

            Environment.SetEnvironmentVariable(EnvVariableNames.DFM_HUB_NAME, "Hub1,Hub2,Hub3");

            // Act
            var result = await About.DfmAboutFunction(request, "InvalidHubName", logMoq.Object);

            // Assert
            Assert.IsInstanceOfType(result, typeof(UnauthorizedResult));
        }
Esempio n. 11
0
        public async Task ReturnsUnauthorizedResultIfNotAuthenticated()
        {
            // Arrange
            var request = new DefaultHttpContext().Request;

            var durableClientMoq = new Mock <IDurableClient>();
            var logMoq           = new Mock <ILogger>();

            // Getting the list of all functions to be validated
            var functionsToBeCalled = typeof(DfmEndpoint).Assembly.DefinedTypes
                                      .Where(t => t.IsClass)
                                      .SelectMany(t => t.GetMethods(BindingFlags.Static | BindingFlags.Public))
                                      .Where(m => m.CustomAttributes.Any(a => a.AttributeType == typeof(FunctionNameAttribute)))
                                      .Select(m => m.Name)
                                      .ToHashSet();

            // Only these two methods should be publicly accessible as of today
            functionsToBeCalled.Remove(nameof(ServeStatics.DfmServeStaticsFunction));
            functionsToBeCalled.Remove(nameof(EasyAuthConfig.DfmGetEasyAuthConfigFunction));

            // Collecting the list of functions that were actually called by this test
            var functionsThatWereCalled = new HashSet <string>();
            var methodExtractionRegex   = new Regex(@"\.(\w+)\(HttpRequest req,");

            logMoq.Setup(log => log.Log(It.IsAny <LogLevel>(), It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), It.IsAny <Func <It.IsAnyType, Exception, string> >()))
            .Callback((LogLevel l, EventId i, object s, Exception ex, object o) =>
            {
                // Ensuring the correct type of exception was raised internally
                Assert.IsInstanceOfType(ex, typeof(UnauthorizedAccessException));
                Assert.AreEqual("No access token provided. Call is rejected.", ex.Message);

                // Also extracting the function name that was called
                functionsThatWereCalled.Add(methodExtractionRegex.Match(ex.StackTrace).Groups[1].Value);
            });

            Environment.SetEnvironmentVariable(EnvVariableNames.DFM_HUB_NAME, string.Empty);

            // Act
            var results = new List <IActionResult>()
            {
                await About.DfmAboutFunction(request, "TestHub", logMoq.Object),

                await CleanEntityStorage.DfmCleanEntityStorageFunction(request, durableClientMoq.Object, logMoq.Object),

                await DeleteTaskHub.DfmDeleteTaskHubFunction(request, "TestHub", logMoq.Object),

                await IdSuggestions.DfmGetIdSuggestionsFunction(request, durableClientMoq.Object, "abc", logMoq.Object),

                await ManageConnection.DfmManageConnectionFunction(request, "TestHub", new Microsoft.Azure.WebJobs.ExecutionContext(), logMoq.Object),

                await IdSuggestions.DfmGetIdSuggestionsFunction(request, durableClientMoq.Object, "abc", logMoq.Object),

                await Orchestration.DfmGetOrchestrationFunction(request, "abc", durableClientMoq.Object, logMoq.Object),

                await Orchestration.DfmGetOrchestrationHistoryFunction(request, "abc", durableClientMoq.Object, logMoq.Object),

                await Orchestration.DfmPostOrchestrationFunction(request, "abc", "todo", durableClientMoq.Object, logMoq.Object),

                await Orchestration.DfmGetOrchestrationTabMarkupFunction(request, "abc", "todo", durableClientMoq.Object, logMoq.Object),

                await Orchestrations.DfmGetOrchestrationsFunction(request, durableClientMoq.Object, logMoq.Object),

                await PurgeHistory.DfmPurgeHistoryFunction(request, durableClientMoq.Object, logMoq.Object),

                await TaskHubNames.DfmGetTaskHubNamesFunction(request, logMoq.Object),
            };

            // Assert
            results.ForEach(r => Assert.IsInstanceOfType(r, typeof(UnauthorizedResult)));

            functionsToBeCalled.ExceptWith(functionsThatWereCalled);
            Assert.IsTrue(functionsToBeCalled.Count == 0, "You forgot to test " + string.Join(", ", functionsToBeCalled));
        }