// Populates index.html template and serves it private static async Task <ContentResult> ReturnIndexHtml(ExecutionContext context, ILogger log, string root, string connAndHubName) { string indexHtmlPath = Path.Join(root, "index.html"); string html = await File.ReadAllTextAsync(indexHtmlPath); // Replacing our custom meta tag with customized code from Storage or with default Content Security Policy string customMetaTagCode = (await CustomTemplates.GetCustomMetaTagCodeAsync()) ?? DefaultContentSecurityPolicyMeta; html = html.Replace("<meta name=\"durable-functions-monitor-meta\">", customMetaTagCode); // Calculating routePrefix string routePrefix = GetRoutePrefixFromHostJson(context, log); string dfmRoutePrefix = GetDfmRoutePrefixFromFunctionJson(context, log); if (!string.IsNullOrEmpty(dfmRoutePrefix)) { routePrefix = string.IsNullOrEmpty(routePrefix) ? dfmRoutePrefix : routePrefix + "/" + dfmRoutePrefix; } // Applying routePrefix, if it is set to something other than empty string if (!string.IsNullOrEmpty(routePrefix)) { html = html.Replace("<script>var DfmRoutePrefix=\"\"</script>", $"<script>var DfmRoutePrefix=\"{routePrefix}\"</script>"); html = html.Replace("href=\"/", $"href=\"/{routePrefix}/"); html = html.Replace("src=\"/", $"src=\"/{routePrefix}/"); } // Applying client config, if any string clientConfigString = Environment.GetEnvironmentVariable(EnvVariableNames.DFM_CLIENT_CONFIG); if (!string.IsNullOrEmpty(clientConfigString)) { dynamic clientConfig = JObject.Parse(clientConfigString); html = html.Replace("<script>var DfmClientConfig={}</script>", "<script>var DfmClientConfig=" + clientConfig.ToString() + "</script>"); } // Mentioning whether Function Map is available for this Task Hub. if (!string.IsNullOrEmpty(connAndHubName)) { // Two bugs away. Validating that the incoming Task Hub name looks like a Task Hub name Auth.ThrowIfTaskHubNameHasInvalidSymbols(connAndHubName); Globals.SplitConnNameAndHubName(connAndHubName, out var connName, out var hubName); string functionMap = (await CustomTemplates.GetFunctionMapsAsync()).GetFunctionMap(hubName); if (!string.IsNullOrEmpty(functionMap)) { html = html.Replace("<script>var IsFunctionGraphAvailable=0</script>", "<script>var IsFunctionGraphAvailable=1</script>"); } } return(new ContentResult() { Content = html, ContentType = "text/html; charset=UTF-8" }); }
public static async Task <IActionResult> DfmGetOrchestrationTabMarkupFunction( [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = Globals.ApiRoutePrefix + "/orchestrations('{instanceId}')/custom-tab-markup('{templateName}')")] HttpRequest req, string instanceId, string templateName, [DurableClient(TaskHub = Globals.TaskHubRouteParamName)] IDurableClient durableClient, ILogger log) { // Checking that the call is authenticated properly try { await Auth.ValidateIdentityAsync(req.HttpContext.User, req.Headers, durableClient.TaskHubName); } catch (Exception ex) { log.LogError(ex, "Failed to authenticate request"); return(new UnauthorizedResult()); } var status = await GetInstanceStatus(instanceId, durableClient, log); if (status == null) { return(new NotFoundObjectResult($"Instance {instanceId} doesn't exist")); } // The underlying Task never throws, so it's OK. var templatesMap = await CustomTemplates.GetTabTemplatesAsync(); string templateCode = templatesMap.GetTemplate(status.GetEntityTypeName(), templateName); if (templateCode == null) { return(new NotFoundObjectResult("The specified template doesn't exist")); } try { var fluidTemplate = FluidTemplate.Parse(templateCode); var fluidContext = new TemplateContext(status); return(new ContentResult() { Content = fluidTemplate.Render(fluidContext), ContentType = "text/html; charset=UTF-8" }); } catch (Exception ex) { return(new BadRequestObjectResult(ex.Message)); } }
public Task <IActionResult> DfmGetOrchestrationTabMarkupFunction( [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = Globals.ApiRoutePrefix + "/orchestrations('{instanceId}')/custom-tab-markup('{templateName}')")] HttpRequest req, [DurableClient(TaskHub = Globals.HubNameRouteParamName)] IDurableClient defaultDurableClient, string connName, string hubName, string instanceId, string templateName, ILogger log) { return(this.HandleAuthAndErrors(defaultDurableClient, req, connName, hubName, log, async(durableClient) => { var status = await GetInstanceStatusWithHistory(connName, instanceId, durableClient, log); if (status == null) { return new NotFoundObjectResult($"Instance {instanceId} doesn't exist"); } // The underlying Task never throws, so it's OK. var templatesMap = await CustomTemplates.GetTabTemplatesAsync(); string templateCode = templatesMap.GetTemplate(status.GetEntityTypeName(), templateName); if (templateCode == null) { return new NotFoundObjectResult("The specified template doesn't exist"); } try { var fluidTemplate = new FluidParser().Parse(templateCode); var options = new TemplateOptions(); options.MemberAccessStrategy.Register <JObject, object>((obj, fieldName) => obj[fieldName]); options.ValueConverters.Add(x => x is JObject obj ? new ObjectValue(obj) : null); options.ValueConverters.Add(x => x is JValue val ? val.Value : null); string fluidResult = fluidTemplate.Render(new TemplateContext(status, options)); return new ContentResult() { Content = fluidResult, ContentType = "text/html; charset=UTF-8" }; } catch (Exception ex) { return new BadRequestObjectResult(ex.Message); } })); }
public static Task <IActionResult> DfmGetFunctionMap( [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = Globals.ApiRoutePrefix + "/function-map")] HttpRequest req, string connName, string hubName, ILogger log ) { return(req.HandleAuthAndErrors(connName, hubName, log, async() => { // The underlying Task never throws, so it's OK. var functionMapsMap = await CustomTemplates.GetFunctionMapsAsync(); var functionMapJson = functionMapsMap.GetFunctionMap(hubName); if (string.IsNullOrEmpty(functionMapJson)) { return new NotFoundObjectResult("No Function Map provided"); } return new ContentResult() { Content = functionMapJson, ContentType = "application/json; charset=UTF-8" }; })); }
public static async Task <IActionResult> DfmServeStaticsFunction( [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = StaticsRoute)] HttpRequest req, ExecutionContext context, ILogger log ) { string root = context.FunctionAppDirectory + "/DfmStatics"; string path = req.Path.Value; string routePrefix = GetRoutePrefixFromHostJson(context, log); string dfmRoutePrefix = GetDfmRoutePrefixFromFunctionJson(context, log); if (!string.IsNullOrEmpty(dfmRoutePrefix)) { routePrefix = string.IsNullOrEmpty(routePrefix) ? dfmRoutePrefix : routePrefix + "/" + dfmRoutePrefix; } // Applying routePrefix, if it is set to something other than empty string if (!string.IsNullOrEmpty(routePrefix) && path.StartsWith("/" + routePrefix)) { path = path.Substring(routePrefix.Length + 1); } var contentType = FileMap.FirstOrDefault((kv => path.StartsWith(kv[0]))); if (contentType != null) { return(File.Exists(root + path) ? (IActionResult) new FileStreamResult(File.OpenRead(root + path), contentType[1]) : new NotFoundResult()); } // Returning index.html by default, to support client routing string html = await File.ReadAllTextAsync($"{root}/index.html"); // Replacing our custom meta tag with customized code from Storage or with default Content Security Policy string customMetaTagCode = (await CustomTemplates.GetCustomMetaTagCodeAsync()) ?? DefaultContentSecurityPolicyMeta; html = html.Replace(Globals.CustomMetaTag, customMetaTagCode); // Applying routePrefix, if it is set to something other than empty string if (!string.IsNullOrEmpty(routePrefix)) { html = html.Replace("<script>var DfmRoutePrefix=\"\"</script>", $"<script>var DfmRoutePrefix=\"{routePrefix}\"</script>"); html = html.Replace("href=\"/", $"href=\"/{routePrefix}/"); html = html.Replace("src=\"/", $"src=\"/{routePrefix}/"); } // Applying client config, if any string clientConfigString = Environment.GetEnvironmentVariable(EnvVariableNames.DFM_CLIENT_CONFIG); if (!string.IsNullOrEmpty(clientConfigString)) { dynamic clientConfig = JObject.Parse(clientConfigString); html = html.Replace("<script>var DfmClientConfig={}</script>", "<script>var DfmClientConfig=" + clientConfig.ToString() + "</script>"); } return(new ContentResult() { Content = html, ContentType = "text/html; charset=UTF-8" }); }