public async Task <Exercise> CloneAsync(Guid idToBeCloned, CancellationToken ct) { if (!(await _authorizationService.AuthorizeAsync(_user, null, new ExerciseCreationRequirement())).Succeeded) { throw new ForbiddenException(); } var exercise = await _context.Exercises .Include(o => o.Teams) .ThenInclude(o => o.Applications) .Include(o => o.Teams) .ThenInclude(o => o.Permissions) .Include(o => o.Applications) .SingleOrDefaultAsync(o => o.Id == idToBeCloned, ct); var newExercise = exercise.Clone(); newExercise.Name = $"Clone of {newExercise.Name}"; //copy exercise applications foreach (var application in exercise.Applications) { var newApplication = application.Clone(); newExercise.Applications.Add(newApplication); } //copy teams foreach (var team in exercise.Teams) { var newTeam = team.Clone(); //copy team applications foreach (var applicationInstance in team.Applications) { var newApplicationInstance = applicationInstance.Clone(); var application = exercise.Applications.FirstOrDefault(o => o.Id == applicationInstance.ApplicationId); var newApplication = newExercise.Applications.FirstOrDefault(o => application != null && o.Name == application.Name); newApplicationInstance.Application = newApplication; newTeam.Applications.Add(newApplicationInstance); } //copy team permissions foreach (var permission in team.Permissions) { var newPermission = new TeamPermissionEntity(newTeam.Id, permission.PermissionId); newTeam.Permissions.Add(newPermission); } newExercise.Teams.Add(newTeam); } _context.Add(newExercise); await _context.SaveChangesAsync(ct); return(_mapper.Map <Exercise>(newExercise)); }
public async Task <View> CloneAsync(Guid idToBeCloned, CancellationToken ct) { if (!(await _authorizationService.AuthorizeAsync(_user, null, new ViewCreationRequirement())).Succeeded) { throw new ForbiddenException(); } var view = await _context.Views .Include(o => o.Teams) .ThenInclude(o => o.Applications) .Include(o => o.Teams) .ThenInclude(o => o.Permissions) .Include(o => o.Applications) .ThenInclude(o => o.Template) .Include(o => o.Files) .SingleOrDefaultAsync(o => o.Id == idToBeCloned, ct); var newView = view.Clone(); newView.Name = $"Clone of {newView.Name}"; newView.Status = ViewStatus.Active; //copy view applications foreach (var application in view.Applications) { var newApplication = application.Clone(); newView.Applications.Add(newApplication); } //copy teams foreach (var team in view.Teams) { var newTeam = team.Clone(); //copy team applications foreach (var applicationInstance in team.Applications) { var newApplicationInstance = applicationInstance.Clone(); var application = view.Applications.FirstOrDefault(o => o.Id == applicationInstance.ApplicationId); var newApplication = newView.Applications.FirstOrDefault(o => application != null && o.GetName() == application.GetName()); newApplicationInstance.Application = newApplication; newTeam.Applications.Add(newApplicationInstance); } //copy team permissions foreach (var permission in team.Permissions) { var newPermission = new TeamPermissionEntity(newTeam.Id, permission.PermissionId); newTeam.Permissions.Add(newPermission); } newView.Teams.Add(newTeam); } // Copy files - note that the files themselves are not being copied, just the pointers foreach (var file in view.Files) { var cloned = file.Clone(); cloned.View = newView; newView.Files.Add(cloned); } _context.Add(newView); await _context.SaveChangesAsync(ct); // SaveChanges is called twice because we need the new IDs for each time. // Should figure out a better way to do it. foreach (var file in newView.Files) { List <Guid> newTeamIds = new List <Guid>(); foreach (var team in file.TeamIds) { var teamName = view.Teams.FirstOrDefault(t => t.Id == team).Name; var newId = file.View.Teams.FirstOrDefault(t => t.Name == teamName).Id; newTeamIds.Add(newId); } file.TeamIds = newTeamIds; } await _context.SaveChangesAsync(ct); return(_mapper.Map <View>(newView)); }