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));
            }
        }
Exemple #2
0
        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);
        }
Exemple #4
0
        /// <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);
            }
        }
Exemple #5
0
        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);
            }
        }
Exemple #6
0
        /// <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);
            }
        }
Exemple #7
0
        /// <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));
            }
        }