// TODO Need to figure out how we rollback if cancellation is requested or prevent it? public async Task UpdateGroupMultipartDocument(Guid userId, string slug, byte[] rowVersion, Stream requestBody, string?contentType, CancellationToken cancellationToken) { var userCanPerformAction = await _permissionsService.UserCanPerformActionAsync(userId, slug, GroupEditRole, cancellationToken); if (userCanPerformAction is false) { _logger.LogError($"Error: CreateFileAsync - User:{0} does not have access to group:{1}", userId, slug); throw new SecurityException($"Error: User does not have access"); } var groupDto = await _groupCommand.GetGroupAsync(slug, cancellationToken); if (!groupDto.RowVersion.SequenceEqual(rowVersion)) { _logger.LogError($"Precondition Failed: UpdateGroupAsync - Group:{0} has changed prior to submission ", slug); throw new PreconditionFailedExeption("Precondition Failed: Group has changed prior to submission"); } var(group, image) = await UploadGroupImageMultipartContent(groupDto, userId, slug, requestBody, rowVersion, contentType, cancellationToken); var groupValidator = new GroupValidator(); var groupValidationResult = await groupValidator.ValidateAsync(group, cancellationToken); if (groupValidationResult.Errors.Count > 0) { throw new ValidationException(groupValidationResult); } try { if (image is not null) { var imageId = await _imageService.CreateImageAsync(image); group = group with { ImageId = imageId }; } } catch (DBConcurrencyException ex) { _logger.LogError(ex, $"Error: CreateImageAsync - Error adding image to group {0}", slug); if (image is not null) { await _blobStorageProvider.DeleteFileAsync(image.FileName); await _imageService.DeleteImageAsync(image.Id); } } try { await UpdateGroupAsync(userId, slug, group, cancellationToken); } catch (DBConcurrencyException ex) { _logger.LogError(ex, $"Error: UpdateGroupAsync - Error updating group {0}", slug); if (image is not null) { await _blobStorageProvider.DeleteFileAsync(image.FileName); await _imageService.DeleteImageAsync(image.Id); } } //TODO - Delete old image of everything succeeds and the image has been removed or replaced }
public async Task CreateGroupAsync(Guid userId, Stream requestBody, string?contentType, CancellationToken cancellationToken) { var now = _systemClock.UtcNow.UtcDateTime; var userCanPerformAction = await _permissionsService.UserCanPerformActionAsync(userId, AddGroupRole, cancellationToken); if (userCanPerformAction is not true) { _logger.LogError($"Error: CreateGroupAsync - User:{0} does not have access to add group:{1}", userId); throw new SecurityException($"Error: User does not have access"); } var(group, image) = await AdminUploadGroupImageMultipartContent(userId, requestBody, contentType, cancellationToken); if (image is not null) { try { var imageId = await _imageService.CreateImageAsync(image); group = group with { ImageId = imageId }; } catch (DBConcurrencyException ex) { _logger.LogError(ex, $"Error: CreateImageAsync - Error creating image {0}", null); if (image is not null) { await _blobStorageProvider.DeleteFileAsync(image.FileName); await _imageService.DeleteImageAsync(image.Id); } throw new DBConcurrencyException("Error: User request to create an image was not successful"); } } var groupValidator = new GroupValidator(); var groupValidationResult = await groupValidator.ValidateAsync(group, cancellationToken); if (groupValidationResult.Errors.Count > 0) { throw new ValidationException(groupValidationResult); } var groupSiteDto = new GroupSiteDto() { CreatedAtUTC = now, CreatedBy = userId, }; try { groupSiteDto.GroupId = await _groupCommand.CreateGroupAsync(userId, group, cancellationToken); } catch (DBConcurrencyException ex) { if (image is not null) { await _blobStorageProvider.DeleteFileAsync(image.FileName); await _imageService.DeleteImageAsync(image.Id); } _logger.LogError(ex, $"Error: CreateGroupAsync - Error creating group {0}", null); throw new DBConcurrencyException("Error: User request to create a group was not successful"); } // Create the group homepage content in Umbraco var createContentResponse = await _contentService.CreatePageAsync(userId, groupSiteDto.GroupId, null, cancellationToken); // If the create content request fails, delete the associated group if (createContentResponse is null || !createContentResponse.Succeeded) { //TODO: rollback/delete group (feature: 75323) _logger.LogError($"Error: CreatePageAsync - Error creating group homepage content {groupSiteDto.GroupId}"); throw new HttpRequestException($"Error: CreatePageAsync - Error creating group homepage content {groupSiteDto.GroupId}"); } try { groupSiteDto.ContentRootId = Guid.Parse(createContentResponse.Data); await _groupCommand.CreateGroupSiteAsync(groupSiteDto, cancellationToken); } catch (DBConcurrencyException ex) { _logger.LogError(ex, $"Error: CreateGroupSiteAsync - Error creating group site {0}"); throw new DBConcurrencyException("Error: User request to create a group site was not successful"); } }