public async Task <IActionResult> Invoke([FromBody] JToken body) { var invokeHeaders = ProcessInvokeHeaders(); if (string.IsNullOrWhiteSpace(invokeHeaders.Path)) { return(BadRequest($"Missing {PathQueryHeader} header")); } var detectorId = body?["id"] != null ? body["id"].ToString() : string.Empty; string applensLink = "https://applens.azurewebsites.net/" + invokeHeaders.Path.Replace("resourcegroup", "resourceGroup").Replace("diagnostics/publish", string.Empty) + "detectors/" + detectorId; var detectorAuthorEmails = new List <EmailAddress>(); if (invokeHeaders.DetectorAuthors.Any()) { detectorAuthorEmails = invokeHeaders.DetectorAuthors .Select(x => x.EndsWith("@microsoft.com") ? x : $"{x}@microsoft.com") .Distinct(StringComparer.OrdinalIgnoreCase) .Select(x => new EmailAddress(x)).ToList(); } HttpRequestHeaders headers = new HttpRequestMessage().Headers; foreach (var header in Request.Headers) { if ((header.Key.StartsWith("x-ms-") || header.Key.StartsWith("diag-")) && !headers.Contains(header.Key)) { headers.Add(header.Key, header.Value.ToString()); } } var response = await DiagnosticClient.Execute(invokeHeaders.Method, invokeHeaders.Path, body?.ToString(), invokeHeaders.InternalClient, invokeHeaders.InternalView, headers); if (response == null) { return(StatusCode(500, "Null response from DiagnosticClient")); } var responseTask = response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode) { return(StatusCode((int)response.StatusCode, await responseTask)); } if (response.Headers.Contains(ScriptEtagHeader)) { Request.HttpContext.Response.Headers.Add(ScriptEtagHeader, response.Headers.GetValues(ScriptEtagHeader).First()); } if (invokeHeaders.Path.EndsWith("/diagnostics/publish", StringComparison.OrdinalIgnoreCase) && detectorAuthorEmails.Count > 0 && Env.IsProduction()) { EmailNotificationService.SendPublishingAlert(invokeHeaders.DetectorAuthors.Last(), detectorId, applensLink, detectorAuthorEmails); } return(Ok(JsonConvert.DeserializeObject(await responseTask))); }
public async Task <IActionResult> Invoke([FromBody] JToken body) { if (!Request.Headers.ContainsKey("x-ms-path-query")) { return(BadRequest("Missing x-ms-path-query header")); } string path = Request.Headers["x-ms-path-query"]; string method = HttpMethod.Get.Method; if (Request.Headers.ContainsKey("x-ms-method")) { method = Request.Headers["x-ms-method"]; } bool internalClient = true; if (Request.Headers.ContainsKey("x-ms-internal-client")) { bool.TryParse(Request.Headers["x-ms-internal-client"], out internalClient); } bool internalView = true; if (Request.Headers.ContainsKey("x-ms-internal-view")) { bool.TryParse(Request.Headers["x-ms-internal-view"], out internalView); } string alias = string.Empty; string detectorId = string.Empty; string detectorAuthor = string.Empty; List <EmailAddress> tos = new List <EmailAddress>(); List <string> distinctEmailRecipientsList = new List <string>(); if (body != null && body["id"] != null) { detectorId = body["id"].ToString(); } string applensLink = "https://applens.azurewebsites.net/" + path.Replace("resourcegroup", "resourceGroup").Replace("diagnostics/publish", "") + "detectors/" + detectorId; if (!string.IsNullOrWhiteSpace(Request.Headers["x-ms-emailRecipients"])) { detectorAuthor = Request.Headers["x-ms-emailRecipients"]; char[] separators = { ' ', ',', ';', ':' }; // Currently there's a bug in sendgrid v3, email will not be sent if there are duplicates in the recipient list // Remove duplicates before adding to the recipient list string[] authors = detectorAuthor.Split(separators, StringSplitOptions.RemoveEmptyEntries).Distinct(StringComparer.OrdinalIgnoreCase).ToArray(); foreach (var author in authors) { if (string.IsNullOrWhiteSpace(alias)) { alias = author; } string baseEmailAddressString = author.EndsWith("@microsoft.com", StringComparison.OrdinalIgnoreCase) ? author : author + "@microsoft.com"; if (!distinctEmailRecipientsList.Contains(baseEmailAddressString)) { EmailAddress emailAddress = new EmailAddress(baseEmailAddressString); tos.Add(emailAddress); distinctEmailRecipientsList.Add(baseEmailAddressString); } } } var scriptETag = string.Empty; if (Request.Headers.ContainsKey("diag-script-etag")) { scriptETag = Request.Headers["diag-script-etag"]; } var assemblyName = string.Empty; if (Request.Headers.ContainsKey("diag-assembly-name")) { assemblyName = Request.Headers["diag-assembly-name"]; } HttpRequestHeaders headers = new HttpRequestMessage().Headers; if (!string.IsNullOrWhiteSpace(scriptETag)) { headers.Add("diag-script-etag", scriptETag); } if (!string.IsNullOrWhiteSpace(assemblyName)) { headers.Add("diag-assembly-name", assemblyName); } var response = await DiagnosticClient.Execute(method, path, body?.ToString(), internalClient, internalView, headers); if (response != null) { var responseString = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { var responseObject = JsonConvert.DeserializeObject(responseString); if (response.Headers.Contains("diag-script-etag")) { Request.HttpContext.Response.Headers.Add("diag-script-etag", response.Headers.GetValues("diag-script-etag").First()); } if (path.EndsWith("/diagnostics/publish", StringComparison.OrdinalIgnoreCase) && tos.Count > 0 && Env.IsProduction()) { EmailNotificationService.SendPublishingAlert(alias, detectorId, applensLink, tos); } return(Ok(responseObject)); } else if (response.StatusCode == HttpStatusCode.BadRequest) { return(BadRequest(responseString)); } } return(StatusCode((int)response.StatusCode)); }
public async Task <IActionResult> Invoke([FromBody] JToken body) { var invokeHeaders = ProcessInvokeHeaders(); if (string.IsNullOrWhiteSpace(invokeHeaders.Path)) { return(BadRequest($"Missing {PathQueryHeader} header")); } string detectorId = null; if (body?.GetType() != typeof(JArray)) { detectorId = body?["id"] != null ? body["id"].ToString() : string.Empty; } string applensLink = "https://applens.azurewebsites.net/" + invokeHeaders.Path.Replace("resourcegroup", "resourceGroup").Replace("diagnostics/publish", string.Empty) + "detectors/" + detectorId; var detectorAuthorEmails = new List <EmailAddress>(); if (invokeHeaders.DetectorAuthors.Any()) { detectorAuthorEmails = invokeHeaders.DetectorAuthors .Select(x => x.EndsWith("@microsoft.com") ? x : $"{x}@microsoft.com") .Distinct(StringComparer.OrdinalIgnoreCase) .Select(x => new EmailAddress(x)).ToList(); } HttpRequestHeaders headers = new HttpRequestMessage().Headers; var locationPlacementId = await GetLocationPlacementId(invokeHeaders); if (!string.IsNullOrWhiteSpace(locationPlacementId)) { headers.Add("x-ms-subscription-location-placementid", locationPlacementId); } foreach (var header in Request.Headers) { if ((header.Key.StartsWith("x-ms-") || header.Key.StartsWith("diag-")) && !headers.Contains(header.Key)) { headers.Add(header.Key, header.Value.ToString()); } } // For Publishing Detector Calls, validate if user has access to publish the detector if (invokeHeaders.Path.EndsWith("/diagnostics/publish", StringComparison.OrdinalIgnoreCase)) { if (!TryFetchPublishAcessParametersFromRequestBody(body, out string resourceType, out string detectorCode, out bool isOriginalCodeMarkedPublic, out string errMsg)) { return(BadRequest(errMsg)); } string userAlias = Utilities.GetUserIdFromToken(Request.Headers["Authorization"].ToString()); var resourceConfig = await this.resourceConfigService.GetResourceConfig(resourceType); bool hasAccess = await Utilities.IsUserAllowedToPublishDetector(userAlias, resourceConfig, detectorCode, isOriginalCodeMarkedPublic); if (!hasAccess) { return(Unauthorized()); } } var response = await DiagnosticClient.Execute(invokeHeaders.Method, invokeHeaders.Path, body?.ToString(), invokeHeaders.InternalClient, invokeHeaders.InternalView, headers); if (response == null) { return(StatusCode(500, "Null response from DiagnosticClient")); } var responseTask = response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode) { return(StatusCode((int)response.StatusCode, await responseTask)); } if (response.Headers.Contains(ScriptEtagHeader)) { Request.HttpContext.Response.Headers.Add(ScriptEtagHeader, response.Headers.GetValues(ScriptEtagHeader).First()); } if (invokeHeaders.Path.EndsWith("/diagnostics/publish", StringComparison.OrdinalIgnoreCase) && detectorAuthorEmails.Count > 0 && Env.IsProduction()) { EmailNotificationService.SendPublishingAlert(invokeHeaders.ModifiedBy, detectorId, applensLink, detectorAuthorEmails); } return(Ok(JsonConvert.DeserializeObject(await responseTask))); }