/// <summary>
        /// Creates the items in the database.
        /// </summary>
        /// <param name="serviceProvider">The application service provider.</param>
        /// <param name="token">The cancellation token for the task.</param>
        public async Task CreateAsync(IServiceProvider serviceProvider, CancellationToken token)
        {
            // Check if there weren't any valid items found.
            if (Items == null)
            {
                // Throw an exception.
                throw new TaskException("No valid items could be found with the provided data.");
            }
            // Check if the exception item should be shown.
            var showExceptionItem = Items.Count() > 1;
            // Get the total number of batches.
            var count = Math.Ceiling((double)Items.Count() / ApplicationDbContext.BatchSize);

            // Go over each batch.
            for (var index = 0; index < count; index++)
            {
                // Check if the cancellation was requested.
                if (token.IsCancellationRequested)
                {
                    // Break.
                    break;
                }
                // Get the items in the current batch.
                var batchItems = Items
                                 .Skip(index * ApplicationDbContext.BatchSize)
                                 .Take(ApplicationDbContext.BatchSize);
                // Get the IDs of the related entities that appear in the current batch.
                var batchAnalysisIds = batchItems
                                       .Where(item => item.Analysis != null)
                                       .Select(item => item.Analysis)
                                       .Where(item => !string.IsNullOrEmpty(item.Id))
                                       .Select(item => item.Id)
                                       .Distinct();
                var batchUserIds = batchItems
                                   .Where(item => item.User != null)
                                   .Select(item => item.User)
                                   .Where(item => !string.IsNullOrEmpty(item.Id))
                                   .Select(item => item.Id)
                                   .Distinct();
                // Define the list of items to get.
                var analyses = new List <Analysis>();
                var users    = new List <User>();
                // Create a new scope.
                using (var scope = serviceProvider.CreateScope())
                {
                    // Use a new context instance.
                    using var context = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>();
                    // Get the related entities that appear in the current batch.
                    analyses = context.Analyses
                               .Where(item => batchAnalysisIds.Contains(item.Id))
                               .ToList();
                    users = context.Users
                            .Where(item => batchUserIds.Contains(item.Id))
                            .ToList();
                }
                // Save the items to add.
                var analysisUsersToAdd = new List <AnalysisUser>();
                // Go over each item in the current batch.
                foreach (var batchItem in batchItems)
                {
                    // Check if there was no analysis provided.
                    if (batchItem.Analysis == null || string.IsNullOrEmpty(batchItem.Analysis.Id))
                    {
                        // Throw an exception.
                        throw new TaskException("There was no analysis provided.", showExceptionItem, batchItem);
                    }
                    // Get the analysis.
                    var analysis = analyses
                                   .FirstOrDefault(item => item.Id == batchItem.Analysis.Id);
                    // Check if there was no analysis found.
                    if (analysis == null)
                    {
                        // Throw an exception.
                        throw new TaskException($"There was no analysis found.", showExceptionItem, batchItem);
                    }
                    // Check if there was no user provided.
                    if (batchItem.User == null || string.IsNullOrEmpty(batchItem.User.Id))
                    {
                        // Throw an exception.
                        throw new TaskException("There was no user provided.", showExceptionItem, batchItem);
                    }
                    // Get the user.
                    var user = users
                               .FirstOrDefault(item => item.Id == batchItem.User.Id);
                    // Check if there was no user found.
                    if (user == null)
                    {
                        // Throw an exception.
                        throw new TaskException($"There was no user found.", showExceptionItem, batchItem);
                    }
                    // Define the new item.
                    var analysisUser = new AnalysisUser
                    {
                        DateTimeCreated = DateTime.UtcNow,
                        AnalysisId      = analysis.Id,
                        UserId          = user.Id
                    };
                    // Add the item to the list.
                    analysisUsersToAdd.Add(analysisUser);
                }
                // Create the items.
                await IEnumerableExtensions.CreateAsync(analysisUsersToAdd, serviceProvider, token);
            }
        }
Exemplo n.º 2
0
        public async Task <IActionResult> OnPostAsync(string id)
        {
            // Get the current user.
            var user = await _userManager.GetUserAsync(User);

            // Check if the user does not exist.
            if (user == null)
            {
                // Display a message.
                TempData["StatusMessage"] = "Error: An error occured while trying to load the user data. If you are already logged in, please log out and try again.";
                // Redirect to the home page.
                return(RedirectToPage("/Index"));
            }
            // Check if there isn't any ID provided.
            if (string.IsNullOrEmpty(id))
            {
                // Display a message.
                TempData["StatusMessage"] = "Error: No ID has been provided.";
                // Redirect to the index page.
                return(RedirectToPage("/Content/Created/Analyses/Index"));
            }
            // Get the items with the provided ID.
            var items = _context.Analyses
                        .Where(item => item.AnalysisUsers.Any(item1 => item1.User == user))
                        .Where(item => item.Id == id);

            // Check if there were no items found.
            if (items == null || !items.Any())
            {
                // Display a message.
                TempData["StatusMessage"] = "Error: No item has been found with the provided ID, or you don't have access to it.";
                // Redirect to the index page.
                return(RedirectToPage("/Content/Created/Analyses/Index"));
            }
            // Define the view.
            View = new ViewModel
            {
                Analysis = items
                           .Include(item => item.AnalysisUsers)
                           .ThenInclude(item => item.User)
                           .Include(item => item.AnalysisUserInvitations)
                           .First()
            };
            // Check if the reCaptcha is valid.
            if (!await _reCaptchaChecker.IsValid(Input.ReCaptchaToken))
            {
                // Add an error to the model.
                ModelState.AddModelError(string.Empty, "The reCaptcha verification failed.");
                // Return the page.
                return(Page());
            }
            // Check if the provided model is not valid.
            if (!ModelState.IsValid)
            {
                // Add an error to the model.
                ModelState.AddModelError(string.Empty, "An error was encountered. Please check again the input fields.");
                // Return the page.
                return(Page());
            }
            // Check if the provided e-mail address already has access to the network.
            if (View.Analysis.AnalysisUsers.Any(item => item.User.Email == Input.Email) || View.Analysis.AnalysisUserInvitations.Any(item => item.Email == Input.Email))
            {
                // Add an error to the model.
                ModelState.AddModelError(string.Empty, "The user with the provided e-mail already has access to the network.");
                // Return the page.
                return(Page());
            }
            // Try to get the user with the provided e-mail address.
            var userToAdd = _context.Users
                            .FirstOrDefault(item => item.Email == Input.Email);

            // Check if any user has been found.
            if (userToAdd != null)
            {
                // Create the user permission.
                var networkUser = new AnalysisUser
                {
                    UserId          = userToAdd.Id,
                    User            = userToAdd,
                    AnalysisId      = View.Analysis.Id,
                    Analysis        = View.Analysis,
                    DateTimeCreated = DateTime.Now
                };
                // Mark it for addition to the database.
                _context.AnalysisUsers.Add(networkUser);
                // Save the changes to the database.
                await _context.SaveChangesAsync();
            }
            else
            {
                // Create the user permission.
                var networkUserInvitation = new AnalysisUserInvitation
                {
                    Email           = Input.Email,
                    AnalysisId      = View.Analysis.Id,
                    Analysis        = View.Analysis,
                    DateTimeCreated = DateTime.Now
                };
                // Mark it for addition to the database.
                _context.AnalysisUserInvitations.Add(networkUserInvitation);
                // Save the changes to the database.
                await _context.SaveChangesAsync();
            }
            // Define the view model for the e-mails.
            var emailAddedToAnalysisViewModel = new EmailAddedToAnalysisViewModel
            {
                Email          = user.Email,
                Name           = View.Analysis.Name,
                Url            = _linkGenerator.GetUriByPage(HttpContext, "/Content/Created/Analyses/Details/Index", handler: null, values: new { id = View.Analysis.Id }),
                AddedEmail     = Input.Email,
                ApplicationUrl = _linkGenerator.GetUriByPage(HttpContext, "/Index", handler: null, values: null)
            };
            var emailWasAddedToAnalysisViewModel = new EmailWasAddedToAnalysisViewModel
            {
                Email          = Input.Email,
                Name           = View.Analysis.Name,
                Url            = _linkGenerator.GetUriByPage(HttpContext, "/Content/Created/Analyses/Details/Index", handler: null, values: new { id = View.Analysis.Id }),
                AddedByEmail   = user.Email,
                ApplicationUrl = _linkGenerator.GetUriByPage(HttpContext, "/Index", handler: null, values: null)
            };
            // Send the defined e-mails.
            await _emailSender.SendAddedToAnalysisEmailAsync(emailAddedToAnalysisViewModel);

            await _emailSender.SendWasAddedToAnalysisEmailAsync(emailWasAddedToAnalysisViewModel);

            // Display a message to the user.
            TempData["StatusMessage"] = "Success: 1 user added successfully to the network.";
            // Redirect to the users page.
            return(RedirectToPage("/Content/Created/Analyses/Details/Accounts/Users/Index", new { id = View.Analysis.Id }));
        }