public async Task <ActionResult> Subscribe(AlertFilterViewModel actViewAlertFilter) { try { var startDateTime = DateTime.Now; var token = string.Empty; if (Request.Headers.ContainsKey("Authorization")) { token = Request.Headers["Authorization"].ToString()?.Split(" ")?[1]; } _graphService = _graphServiceProvider.GetService(token); if (actViewAlertFilter != null && actViewAlertFilter.Filters.GetFilterValue("alert:category").Equals("Any") && actViewAlertFilter.Filters.GetFilterValue("vendor:provider").Equals("Any") && actViewAlertFilter.Filters.GetFilterValue("alert:severity").Equals("Any")) { return(BadRequest("Please select at least one property/criterion for subscribing to alert notifications")); } else { var filter = new AlertFilterModel(actViewAlertFilter); var createSubscriptionResult = await _graphService.SubscribeAsync(filter); var subscription = createSubscriptionResult.Item1; Debug.WriteLine($"SubscriptionController Subscribe execution time: {DateTime.Now - startDateTime}"); return(Ok(subscription)); } } catch (Exception exception) { return(BadRequest(exception.Message)); } }
public static string GetQueryByAlertFilter(AlertFilterModel filter) { var filteredQuery = string.Empty; foreach (KeyValuePair <string, List <AlertFilterProperty> > property in filter) { var filtersForKey = string.Empty; if (property.Key.Equals("createdDateTime")) { filtersForKey = $"({string.Join($" {AlertFilterOperator.And} ", property.Key.Trim().EndsWith(")") ? property.Value.Select(item => $"{property.Key.Substring(0, property.Key.Length - 1)} {item.PropertyDescription.Operator} {item.Value})") : property.Value.Select(item => $"{property.Key} {item.PropertyDescription.Operator} {item.Value}"))})"; }
public static string GetQueryByAlertFilter(AlertFilterModel filter) { var filteredQuery = string.Empty; foreach (KeyValuePair <string, List <AlertFilterProperty> > property in filter) { var filtersForKey = string.Join($" {AlertFilterOperator.And} ", property.Key.Trim().EndsWith(")") ? property.Value.Select(item => $"{property.Key.Substring(0, property.Key.Length - 1)} {item.PropertyDescription.Operator} {item.Value})") : property.Value.Select(item => $"{property.Key} {item.PropertyDescription.Operator} {item.Value}")); filteredQuery += $"{(filteredQuery.Length != 0 ? $" {AlertFilterOperator.And} " : string.Empty)}{filtersForKey}"; } return(filteredQuery); }
/// <summary> /// Create web hook subscriptions in order to receive the notifications /// </summary> /// <param name="filters"></param> /// <returns>The subscription object</returns> public async Task <Tuple <Subscription, string> > SubscribeAsync(AlertFilterModel filters) { var startDateTime = DateTime.Now; try { var changeType = "updated"; var expirationDate = DateTime.UtcNow.AddHours(3); var randno = new Random().Next(1, 100).ToString(); var clientState = "IsgSdkSubscription" + randno; var filteredQuery = GraphQueryProvider.GetQueryByAlertFilter(filters); var resource = filters.ContainsKey("AlertId") && filters.HasPropertyFilter("AlertId") ? $"/security/alerts/{filters.GetFirstPropertyFilter("AlertId").Value}" : $"/security/alerts{(!String.IsNullOrWhiteSpace(filteredQuery) ? $"?$filter={filteredQuery}" : string.Empty)}"; Subscription subscription = new Subscription() { ChangeType = changeType, NotificationUrl = NotificationUri, Resource = resource, ExpirationDateTime = expirationDate, ClientState = clientState }; var result = await _graphClient.Subscriptions.Request().AddAsync(subscription); Debug.WriteLine($"GraphService/SubscribeAsync execution time: {DateTime.Now - startDateTime}"); return(new Tuple <Subscription, string>(result, filteredQuery)); } catch (Exception exception) { Trace.WriteLine(exception.Message); return(null); } }
public ValueProviderResult GetValue(string key) { if (this.ContainsPrefix(key)) { var filters = new AlertFilterCollection(); var formData = HttpContext.Current.Request.Form; foreach (var formKey in formData.AllKeys) { var valuesByKey = formData.GetValues(formKey); if (AlertFilterModel.HasPropertyDescription(formKey) && valuesByKey != null && valuesByKey.Length > 0) { filters.Add(formKey, valuesByKey[0]); } } return(new ValueProviderResult(filters, null, CultureInfo.InvariantCulture)); } else { return(null); } }
/// <summary> /// Get information about alert statistics /// </summary> /// <returns>Statistics Data</returns> public async Task <AlertStatisticModel> GetStatisticAsync(int topAlertAmount) { try { var startDateTime = DateTime.Now; // Select all unresolved alerts var allAlertsFilter = new AlertFilterModel { Top = topAlertAmount }; var allAlerts = await GetAlertsAsync(allAlertsFilter); var unresolvedAlerts = allAlerts?.Item1?.Where(alert => alert.Status != AlertStatus.Resolved); var newAlerts = allAlerts?.Item1?.Where(alert => alert.Status == AlertStatus.NewAlert); var inProgressAlerts = allAlerts?.Item1?.Where(alert => alert.Status == AlertStatus.InProgress); var resolvedAlerts = allAlerts?.Item1?.Where(alert => alert.Status == AlertStatus.Resolved); //// Get top secure score var secureScores = await GetSecureScoresAsync($"?$top={topAlertAmount}"); var latestSecureScore = secureScores.OrderByDescending(rec => rec.CreatedDateTime).FirstOrDefault(); Dictionary <string, int> res = new Dictionary <string, int>(); foreach (var comparativeScore in latestSecureScore?.AverageComparativeScores) { res.Add(comparativeScore.Basis, (int)comparativeScore.AverageScore); } var secureScoreModel = latestSecureScore != null ? new SecureScoreStatisticModel { Current = latestSecureScore.CurrentScore ?? 0, Max = latestSecureScore.MaxScore ?? 0, ComparativeScores = res, } : null; var activeAlerts = new Dictionary <string, int>(); var newAlertsD = new Dictionary <string, int>(); var inProgressAlertsD = new Dictionary <string, int>(); var resolcedAlertsD = new Dictionary <string, int>(); var usersAlerts = new StatisticCollectionModel <SeveritySortOrder>(); var hostsAlerts = new StatisticCollectionModel <SeveritySortOrder>(); var providersAlerts = new StatisticCollectionModel <SeveritySortOrder>(); var ipAlerts = new StatisticCollectionModel <SeveritySortOrder>(); var domainAlerts = new StatisticCollectionModel <SeveritySortOrder>(); if (unresolvedAlerts != null) { foreach (var alert in unresolvedAlerts) { // Calculate users with the most alerts var userPrincipalName = alert.UserStates?.FirstOrDefault()?.UserPrincipalName; if (!string.IsNullOrWhiteSpace(userPrincipalName)) { usersAlerts.Add(userPrincipalName, alert.Severity.ToString()); } // Calculate destination ip address with the most alerts var ipAddress = alert.NetworkConnections?.FirstOrDefault()?.DestinationAddress; if (!string.IsNullOrWhiteSpace(ipAddress)) { ipAlerts.Add(ipAddress, alert.Severity.ToString()); } // Calculate hosts with the most alerts var hostName = alert.HostStates?.FirstOrDefault()?.Fqdn; if (!string.IsNullOrWhiteSpace(hostName)) { hostsAlerts.Add(hostName, alert.Severity.ToString()); } // Calculate providers with the most alerts var provider = alert.VendorInformation.Provider; if (!string.IsNullOrWhiteSpace(provider)) { providersAlerts.Add(provider, alert.Severity.ToString()); } // Calculate domain with the most alerts var domainName = alert.NetworkConnections?.FirstOrDefault()?.DestinationDomain; if (!string.IsNullOrWhiteSpace(domainName)) { domainAlerts.Add(domainName, alert.Severity.ToString()); } } } if (newAlerts != null) { foreach (var alert in newAlerts) { // Calculate active alerts if (!newAlertsD.ContainsKey(alert.Severity.ToString())) { newAlertsD.Add(alert.Severity.ToString(), 1); } else { ++newAlertsD[alert.Severity.ToString()]; } } } if (inProgressAlerts != null) { foreach (var alert in inProgressAlerts) { // Calculate active alerts if (!inProgressAlertsD.ContainsKey(alert.Severity.ToString())) { inProgressAlertsD.Add(alert.Severity.ToString(), 1); } else { ++inProgressAlertsD[alert.Severity.ToString()]; } } } if (resolvedAlerts != null) { foreach (var alert in resolvedAlerts) { // Calculate active alerts if (!resolcedAlertsD.ContainsKey(alert.Severity.ToString())) { resolcedAlertsD.Add(alert.Severity.ToString(), 1); } else { ++resolcedAlertsD[alert.Severity.ToString()]; } } } // Get top of the sorted users with the most alerts var sortedTopUserAlertsWithPrincipalNames = usersAlerts.GetSortedTopValues(4); var sortedTopUserAlert = new Dictionary <KeyValuePair <string, string>, Dictionary <SeveritySortOrder, int> >(); var usersList = sortedTopUserAlertsWithPrincipalNames.Select(rec => rec.Key); // Get additional information about each user from top list var users = await GetUserDisplayNamesAsync(usersList); //// Replaced UserPrincipalName to DisplayName if it is possible if (users != null) { foreach (var rec in sortedTopUserAlertsWithPrincipalNames) { var newKey = users.ContainsKey(rec.Key) && !users[rec.Key].Equals(rec.Key, StringComparison.CurrentCultureIgnoreCase) ? users[rec.Key] : rec.Key; sortedTopUserAlert.Add(new KeyValuePair <string, string>(newKey, rec.Key), rec.Value); } } Debug.WriteLine($"GraphService/GetStatisticAsync topAlertAmount: {topAlertAmount}, execution time: {DateTime.Now - startDateTime}"); return(new AlertStatisticModel { NewAlerts = newAlertsD, InProgressAlerts = inProgressAlertsD, ResolvedAlerts = resolcedAlertsD, SecureScore = secureScoreModel, UsersWithTheMostAlerts = sortedTopUserAlert, HostsWithTheMostAlerts = hostsAlerts.GetSortedTopValues(4) .Select(rec => new KeyValuePair <KeyValuePair <string, string>, Dictionary <SeveritySortOrder, int> >( new KeyValuePair <string, string>( rec.Key.Split('.').FirstOrDefault() ?? rec.Key, rec.Key), rec.Value)).ToDictionary(rec => rec.Key, rec => rec.Value), ProvidersWithTheMostAlerts = providersAlerts.GetSortedTopValues(topAlertAmount).Select(rec => new KeyValuePair <KeyValuePair <string, string>, Dictionary <SeveritySortOrder, int> >( new KeyValuePair <string, string>( rec.Key, rec.Key), rec.Value)).ToDictionary(rec => rec.Key, rec => rec.Value), IPWithTheMostAlerts = ipAlerts.GetSortedTopValues(4) .Select(rec => new KeyValuePair <KeyValuePair <string, string>, Dictionary <SeveritySortOrder, int> >( new KeyValuePair <string, string>( rec.Key.Split('.').FirstOrDefault() ?? rec.Key, rec.Key), rec.Value)).ToDictionary(rec => rec.Key, rec => rec.Value), DomainsWithTheMostAlerts = domainAlerts.GetSortedTopValues(4) .Select(rec => new KeyValuePair <KeyValuePair <string, string>, Dictionary <SeveritySortOrder, int> >( new KeyValuePair <string, string>( rec.Key.Split('.').FirstOrDefault() ?? rec.Key, rec.Key), rec.Value)).ToDictionary(rec => rec.Key, rec => rec.Value), }); } catch (Exception exception) { Trace.WriteLine(exception.Message); return(null); } }
/// <summary> /// Get alerts based on the alert filters /// </summary> /// <param name="filters"></param> /// <returns>alerts matching the filtering criteria</returns> public async Task <Tuple <IEnumerable <Alert>, string> > GetAlertsAsync(AlertFilterModel filters, Dictionary <string, string> odredByParams = null) { try { var startDateTime = DateTime.Now; if (filters == null) { var result = await _graphClient.Security.Alerts.Request().GetAsync(); Debug.WriteLine($"GraphService/GetAlertsAsync execution time: {DateTime.Now - startDateTime}"); return(new Tuple <IEnumerable <Alert>, string>(result, string.Empty)); } else if (filters != null && filters.Count == 0) { var result = await _graphClient.Security.Alerts.Request().Top(filters.Top).GetAsync(); Debug.WriteLine($"GraphService/GetAlertsAsync execution time: {DateTime.Now - startDateTime}"); return(new Tuple <IEnumerable <Alert>, string>(result, string.Empty)); } else { // var s = _graphClient.Security.Alerts.Request() // Create filter query var filterQuery = GraphQueryProvider.GetQueryByAlertFilter(filters); var customOrderByParams = new Dictionary <string, string>(); //// If there are no filters and there are no custom odredByParams (if specified only top X) if ((odredByParams == null || odredByParams.Count() < 1) && filters.Count < 1) { //// Order by 1. Provider 2. CreatedDateTime (desc) customOrderByParams.Add("vendorInformation/provider", "asc"); customOrderByParams.Add("createdDateTime", "desc"); } else if (filters.Count >= 1 && filters.ContainsKey("createdDateTime")) { customOrderByParams.Add("createdDateTime", "desc"); } // Create request with filter and top X var request = _graphClient.Security.Alerts.Request().Filter(filterQuery).Top(filters.Top); // Add order py params if (customOrderByParams.Count > 0) { request = request.OrderBy(string.Join(", ", customOrderByParams.Select(param => $"{param.Key} {param.Value}"))); } else if (odredByParams != null && odredByParams.Count() > 0) { request = request.OrderBy(string.Join(", ", odredByParams.Select(param => $"{param.Key} {param.Value}"))); } // Get alerts var result = await request.GetAsync(); Debug.WriteLine($"GraphService/GetAlertsAsync execution time: {DateTime.Now - startDateTime}"); return(new Tuple <IEnumerable <Alert>, string>(result, filterQuery)); } } catch (Exception exception) { Trace.WriteLine(exception.Message); return(null); } }
public async Task <ActionResult> GetAlertsByFilter([FromQuery] string key, [FromQuery] string value) { try { var token = string.Empty; if (Request.Headers.ContainsKey("Authorization")) { token = Request.Headers["Authorization"].ToString()?.Split(" ")?[1]; } _graphService = _graphServiceProvider.GetService(token); if (string.IsNullOrWhiteSpace(key) || string.IsNullOrWhiteSpace(value)) { return(BadRequest(new ArgumentNullException(value, "value and key can't be null"))); } var viewAlertFilter = new AlertFilterViewModel { Top = 50, Filters = new AlertFilterCollection() }; viewAlertFilter.Filters.Add(key, (new List <string>() { value })); var orderByOarams = new Dictionary <string, string>(); switch (key) { case "alert:severity": { orderByOarams.Add("createdDateTime", "desc"); } break; default: { orderByOarams.Add("severity", "desc"); orderByOarams.Add("createdDateTime", "desc"); } break; } var filter = new AlertFilterModel(viewAlertFilter); var securityAlertsResult = await _graphService.GetAlertsAsync(filter, orderByOarams); var filterQuery = securityAlertsResult?.Item2 ?? string.Empty; // Generate queries var sdkQueryBuilder = new StringBuilder(); var restQueryBuilder = new StringBuilder(); sdkQueryBuilder.Append("await graphClient.Security.Alerts.Request()"); if (!string.IsNullOrEmpty(filterQuery)) { sdkQueryBuilder.Append($".Filter(\"{filterQuery}\")"); } sdkQueryBuilder.Append($".Top({filter.Top}).GetAsync()"); if (!string.IsNullOrEmpty(filterQuery)) { restQueryBuilder.Append( $"<a href=\"https://developer.microsoft.com/en-us/graph/graph-explorer?request=security/alerts?$filter={HttpUtility.UrlEncode(filterQuery)}%26$top={filter.Top}&&method=GET&version={_graphService.GraphUrlVersion}&GraphUrl=https://graph.microsoft.com\" target=\"_blank\">https://graph.microsoft.com/{_graphService.GraphUrlVersion}/security/alerts?"); restQueryBuilder.Append($"$filter={HttpUtility.UrlEncode(filterQuery)}&"); restQueryBuilder.Append($"$top={filter.Top}</a>"); } else { restQueryBuilder.Append( $"<a href=\"https://developer.microsoft.com/en-us/graph/graph-explorer?request=security/alerts?$top={filter.Top}&&method=GET&version={_graphService.GraphUrlVersion}&GraphUrl=https://graph.microsoft.com\" target=\"_blank\">https://graph.microsoft.com/{_graphService.GraphUrlVersion}/security/alerts?"); restQueryBuilder.Append($"$top={filter.Top}</a>"); } var alerts = securityAlertsResult?.Item1?.Select(sa => new AlertResultItemModel { Id = sa.Id, Title = sa.Title, Status = sa.Status, Provider = sa.VendorInformation?.Provider, CreatedDateTime = sa.CreatedDateTime, Severity = sa.Severity.ToString(), Category = sa.Category }) ?? Enumerable.Empty <AlertResultItemModel>(); // Save queries to session var queries = new ResultQueriesViewModel(sdkQueryBuilder.ToString(), restQueryBuilder.ToString()); var alertsResponse = new AlertsResponse(alerts, queries); return(Ok(alertsResponse)); } catch (Exception exception) { return(BadRequest(exception.Message)); } }
public async Task <ActionResult> GetAlerts([FromBody] AlertFilterViewModel viewAlertFilter) { try { var startGetAlerts = DateTime.Now; var token = string.Empty; if (Request.Headers.ContainsKey("Authorization")) { token = Request.Headers["Authorization"].ToString()?.Split(" ")?[1]; } _graphService = _graphServiceProvider.GetService(token); AlertFilterModel filter = new AlertFilterModel(viewAlertFilter); var startGetAlertsfromGraph = DateTime.Now; var securityAlertsResult = await _graphService.GetAlertsAsync(filter); var filterQuery = securityAlertsResult?.Item2 ?? string.Empty; Debug.WriteLine($"Get Alerts from Graph: {DateTime.Now - startGetAlertsfromGraph}"); // Generate queries var sdkQueryBuilder = new StringBuilder(); var restQueryBuilder = new StringBuilder(); sdkQueryBuilder.Append("await graphClient.Security.Alerts.Request()"); if (!string.IsNullOrEmpty(filterQuery)) { sdkQueryBuilder.Append($".Filter(\"{filterQuery}\")"); } sdkQueryBuilder.Append($".Top({viewAlertFilter.Top}).GetAsync()"); if (!string.IsNullOrEmpty(filterQuery)) { restQueryBuilder.Append($"<a href=\"https://developer.microsoft.com/en-us/graph/graph-explorer?request=security/alerts?$filter={HttpUtility.UrlEncode(filterQuery)}%26$top={viewAlertFilter.Top}&&method=GET&version={_graphService.GraphUrlVersion}&GraphUrl=https://graph.microsoft.com\" target=\"_blank\">https://graph.microsoft.com/{_graphService.GraphUrlVersion}/security/alerts?"); restQueryBuilder.Append($"$filter={HttpUtility.UrlEncode(filterQuery)}&"); restQueryBuilder.Append($"$top={viewAlertFilter.Top}</a>"); } else { restQueryBuilder.Append($"<a href=\"https://developer.microsoft.com/en-us/graph/graph-explorer?request=security/alerts?$top={viewAlertFilter.Top}&&method=GET&version={_graphService.GraphUrlVersion}&GraphUrl=https://graph.microsoft.com\" target=\"_blank\">https://graph.microsoft.com/{_graphService.GraphUrlVersion}/security/alerts?"); restQueryBuilder.Append($"$top={viewAlertFilter.Top}</a>"); } ResultQueriesViewModel resultQueriesViewModel = new ResultQueriesViewModel(sdkQueryBuilder.ToString(), restQueryBuilder.ToString()); var alertSearchResult = securityAlertsResult?.Item1?.Select(sa => new AlertResultItemModel { Id = sa.Id, Title = sa.Title, Status = sa.Status, Provider = sa.VendorInformation?.Provider, CreatedDateTime = sa.CreatedDateTime, AssignedTo = sa.AssignedTo, Severity = sa.Severity.ToString(), Category = sa.Category }) ?? Enumerable.Empty <AlertResultItemModel>(); var alertsResponse = new AlertsResponse(alertSearchResult, resultQueriesViewModel); Debug.WriteLine($"Executionf time AlertController GetAlerts: {DateTime.Now - startGetAlerts}"); return(Ok(alertsResponse)); } catch (Exception exception) { return(BadRequest(exception.Message)); } }