From c6bd0543e2f08c8cc90e8912197a4d301a43a0e4 Mon Sep 17 00:00:00 2001 From: Sumit Ghosh <13281246+sughosneo@users.noreply.github.com> Date: Thu, 24 Jun 2021 15:01:51 +0530 Subject: [PATCH 1/4] Removed image upload functionality --- .../Pages/CatalogItemPage/Create.razor | 4 +- .../Pages/CatalogItemPage/Edit.razor | 4 +- src/Infrastructure/Services/WebFileSystem.cs | 12 +++--- src/PublicApi/CatalogItemEndpoints/Create.cs | 19 ++++----- src/PublicApi/CatalogItemEndpoints/Update.cs | 24 ++--------- src/PublicApi/Startup.cs | 3 +- src/Web/Controllers/FileController.cs | 38 ------------------ .../images/products/eCatalog-item-default.png | Bin 0 -> 4093 bytes 8 files changed, 25 insertions(+), 79 deletions(-) delete mode 100644 src/Web/Controllers/FileController.cs create mode 100644 src/Web/wwwroot/images/products/eCatalog-item-default.png diff --git a/src/BlazorAdmin/Pages/CatalogItemPage/Create.razor b/src/BlazorAdmin/Pages/CatalogItemPage/Create.razor index 07f2b71..995fe49 100644 --- a/src/BlazorAdmin/Pages/CatalogItemPage/Create.razor +++ b/src/BlazorAdmin/Pages/CatalogItemPage/Create.razor @@ -82,7 +82,7 @@ -
+ @*
@@ -96,7 +96,7 @@
@_badFileMessage
-
+
*@ diff --git a/src/BlazorAdmin/Pages/CatalogItemPage/Edit.razor b/src/BlazorAdmin/Pages/CatalogItemPage/Edit.razor index 415765f..cce6a52 100644 --- a/src/BlazorAdmin/Pages/CatalogItemPage/Edit.razor +++ b/src/BlazorAdmin/Pages/CatalogItemPage/Edit.razor @@ -85,7 +85,7 @@ -
+ @*
@@ -99,7 +99,7 @@
@_badFileMessage
-
+
*@ diff --git a/src/Infrastructure/Services/WebFileSystem.cs b/src/Infrastructure/Services/WebFileSystem.cs index b51ba54..f670079 100644 --- a/src/Infrastructure/Services/WebFileSystem.cs +++ b/src/Infrastructure/Services/WebFileSystem.cs @@ -10,11 +10,13 @@ using System.Threading.Tasks; namespace Microsoft.eShopWeb.Infrastructure.Services { + // This class never gets called. Modify it based on your need. + public class WebFileSystem : IFileSystem { private readonly HttpClient _httpClient; private readonly string _url; - public const string AUTH_KEY = "AuthKeyOfDoomThatMustBeAMinimumNumberOfBytes"; + public const string AUTH_KEY = ""; public WebFileSystem(string url) { @@ -50,13 +52,11 @@ namespace Microsoft.eShopWeb.Infrastructure.Services DataBase64 = Convert.ToBase64String(fileData), FileName = fileName }; + var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); - using var message = await _httpClient.PostAsync(_url, content, cancellationToken); - if (!message.IsSuccessStatusCode) - { - return false; - } + // TODO: Write the actual File image upload logic to web. + // Post this image binary content to an Image Upload API. return true; } diff --git a/src/PublicApi/CatalogItemEndpoints/Create.cs b/src/PublicApi/CatalogItemEndpoints/Create.cs index ef35707..a4f018f 100644 --- a/src/PublicApi/CatalogItemEndpoints/Create.cs +++ b/src/PublicApi/CatalogItemEndpoints/Create.cs @@ -19,13 +19,11 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints { private readonly IAsyncRepository _itemRepository; private readonly IUriComposer _uriComposer; - private readonly IFileSystem _webFileSystem; - public Create(IAsyncRepository itemRepository, IUriComposer uriComposer, IFileSystem webFileSystem) + public Create(IAsyncRepository itemRepository, IUriComposer uriComposer) { _itemRepository = itemRepository; _uriComposer = uriComposer; - _webFileSystem = webFileSystem; } [HttpPost("api/catalog-items")] @@ -45,12 +43,15 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints if (newItem.Id != 0) { - var picName = $"{newItem.Id}{Path.GetExtension(request.PictureName)}"; - if (await _webFileSystem.SavePicture(picName, request.PictureBase64, cancellationToken)) - { - newItem.UpdatePictureUri(picName); - await _itemRepository.UpdateAsync(newItem, cancellationToken); - } + // At this point time, the Admin application uses the default catalog item image for any new product item. + // But in the actual production scenario, you'll implement the image file upload mechanism in your application and set the image + // file the Uri accordingly. You can refer to fewlines of the boilerplate code are commented out and kept it in the following files. + // - BlazorAdmin project -> Create.razor and Edit.razor. + // - Infrastructure project -> Services/WebFileSystem.cs + + var picName = "eCatalog-item-default.png"; + newItem.UpdatePictureUri(picName); + await _itemRepository.UpdateAsync(newItem, cancellationToken); } var dto = new CatalogItemDto diff --git a/src/PublicApi/CatalogItemEndpoints/Update.cs b/src/PublicApi/CatalogItemEndpoints/Update.cs index 991c72e..97b45a4 100644 --- a/src/PublicApi/CatalogItemEndpoints/Update.cs +++ b/src/PublicApi/CatalogItemEndpoints/Update.cs @@ -17,15 +17,12 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints .WithResponse { private readonly IAsyncRepository _itemRepository; - private readonly IUriComposer _uriComposer; - private readonly IFileSystem _webFileSystem; + private readonly IUriComposer _uriComposer; - public Update(IAsyncRepository itemRepository, IUriComposer uriComposer, IFileSystem webFileSystem) + public Update(IAsyncRepository itemRepository, IUriComposer uriComposer) { _itemRepository = itemRepository; - _uriComposer = uriComposer; - _webFileSystem = webFileSystem; - + _uriComposer = uriComposer; } [HttpPut("api/catalog-items")] @@ -43,20 +40,7 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints existingItem.UpdateDetails(request.Name, request.Description, request.Price); existingItem.UpdateBrand(request.CatalogBrandId); - existingItem.UpdateType(request.CatalogTypeId); - - if (string.IsNullOrEmpty(request.PictureBase64) && string.IsNullOrEmpty(request.PictureUri)) - { - existingItem.UpdatePictureUri(string.Empty); - } - else - { - var picName = $"{existingItem.Id}{Path.GetExtension(request.PictureName)}"; - if (await _webFileSystem.SavePicture($"{picName}", request.PictureBase64, cancellationToken)) - { - existingItem.UpdatePictureUri(picName); - } - } + existingItem.UpdateType(request.CatalogTypeId); await _itemRepository.UpdateAsync(existingItem, cancellationToken); diff --git a/src/PublicApi/Startup.cs b/src/PublicApi/Startup.cs index e2d4e19..0747537 100644 --- a/src/PublicApi/Startup.cs +++ b/src/PublicApi/Startup.cs @@ -95,8 +95,7 @@ namespace Microsoft.eShopWeb.PublicApi services.AddScoped(); var baseUrlConfig = new BaseUrlConfiguration(); - Configuration.Bind(BaseUrlConfiguration.CONFIG_NAME, baseUrlConfig); - services.AddScoped(x => new WebFileSystem($"{baseUrlConfig.WebBase}File")); + Configuration.Bind(BaseUrlConfiguration.CONFIG_NAME, baseUrlConfig); services.AddMemoryCache(); diff --git a/src/Web/Controllers/FileController.cs b/src/Web/Controllers/FileController.cs deleted file mode 100644 index 1e3b9c3..0000000 --- a/src/Web/Controllers/FileController.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.eShopWeb.Web.ViewModels.File; -using System; -using System.IO; - -namespace Microsoft.eShopWeb.Web.Controllers -{ - [Route("[controller]")] - [ApiController] - public class FileController : ControllerBase - { - [HttpPost] - [AllowAnonymous] - public IActionResult Upload(FileViewModel fileViewModel) - { - if (!Request.Headers.ContainsKey("auth-key") || Request.Headers["auth-key"].ToString() != ApplicationCore.Constants.AuthorizationConstants.AUTH_KEY) - { - return Unauthorized(); - } - - if(fileViewModel == null || string.IsNullOrEmpty(fileViewModel.DataBase64)) return BadRequest(); - - var fileData = Convert.FromBase64String(fileViewModel.DataBase64); - if (fileData.Length <= 0) return BadRequest(); - - var fullPath = Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot/images/products", fileViewModel.FileName); - if (System.IO.File.Exists(fullPath)) - { - System.IO.File.Delete(fullPath); - } - System.IO.File.WriteAllBytes(fullPath, fileData); - - return Ok(); - } - - } -} \ No newline at end of file diff --git a/src/Web/wwwroot/images/products/eCatalog-item-default.png b/src/Web/wwwroot/images/products/eCatalog-item-default.png new file mode 100644 index 0000000000000000000000000000000000000000..5079b8b3d6f8c20ed2d8b68f3ef1d40a93e9af03 GIT binary patch literal 4093 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 literal 0 HcmV?d00001 From 1f1882e320fd6e3bca3f4c05ff42e9b24abf5a31 Mon Sep 17 00:00:00 2001 From: Sumit Ghosh <13281246+sughosneo@users.noreply.github.com> Date: Thu, 24 Jun 2021 15:27:01 +0530 Subject: [PATCH 2/4] Fixed integration test cases --- .../PublicApi/CatalogItemEndpoints/CreateEndpoint.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/FunctionalTests/PublicApi/CatalogItemEndpoints/CreateEndpoint.cs b/tests/FunctionalTests/PublicApi/CatalogItemEndpoints/CreateEndpoint.cs index 55d33d4..aff2473 100644 --- a/tests/FunctionalTests/PublicApi/CatalogItemEndpoints/CreateEndpoint.cs +++ b/tests/FunctionalTests/PublicApi/CatalogItemEndpoints/CreateEndpoint.cs @@ -18,8 +18,7 @@ namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers private int _testBrandId = 1; private int _testTypeId = 2; private string _testDescription = "test description"; - private string _testName = "test name"; - private string _testUri = "test uri"; + private string _testName = "test name"; private decimal _testPrice = 1.23m; public CreateEndpoint(ApiTestFixture factory) @@ -54,8 +53,7 @@ namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers Assert.Equal(_testBrandId, model.CatalogItem.CatalogBrandId); Assert.Equal(_testTypeId, model.CatalogItem.CatalogTypeId); Assert.Equal(_testDescription, model.CatalogItem.Description); - Assert.Equal(_testName, model.CatalogItem.Name); - Assert.Equal(_testUri, model.CatalogItem.PictureUri); + Assert.Equal(_testName, model.CatalogItem.Name); Assert.Equal(_testPrice, model.CatalogItem.Price); } @@ -66,8 +64,7 @@ namespace Microsoft.eShopWeb.FunctionalTests.Web.Controllers CatalogBrandId = _testBrandId, CatalogTypeId = _testTypeId, Description = _testDescription, - Name = _testName, - PictureUri = _testUri, + Name = _testName, Price = _testPrice }; var jsonContent = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); From c29001aae33c30b553823fbc042cdd2dffbd48c6 Mon Sep 17 00:00:00 2001 From: Sumit Ghosh Date: Mon, 28 Jun 2021 20:12:48 +0530 Subject: [PATCH 3/4] Update src/PublicApi/CatalogItemEndpoints/Create.cs Co-authored-by: David Pine --- src/PublicApi/CatalogItemEndpoints/Create.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/PublicApi/CatalogItemEndpoints/Create.cs b/src/PublicApi/CatalogItemEndpoints/Create.cs index a4f018f..e69e717 100644 --- a/src/PublicApi/CatalogItemEndpoints/Create.cs +++ b/src/PublicApi/CatalogItemEndpoints/Create.cs @@ -49,8 +49,7 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints // - BlazorAdmin project -> Create.razor and Edit.razor. // - Infrastructure project -> Services/WebFileSystem.cs - var picName = "eCatalog-item-default.png"; - newItem.UpdatePictureUri(picName); + newItem.UpdatePictureUri("eCatalog-item-default.png"); await _itemRepository.UpdateAsync(newItem, cancellationToken); } From 1c9c491c515825bb4a9fd08165b18d097bb644ad Mon Sep 17 00:00:00 2001 From: Sumit Ghosh <13281246+sughosneo@users.noreply.github.com> Date: Tue, 29 Jun 2021 11:53:43 +0530 Subject: [PATCH 4/4] Included feedback --- src/ApplicationCore/Interfaces/IFileSystem.cs | 10 --- .../CatalogFilterPaginatedSpecification.cs | 4 +- .../Pages/CatalogItemPage/Create.razor | 40 +-------- .../Pages/CatalogItemPage/Edit.razor | 41 +-------- src/Infrastructure/Services/WebFileSystem.cs | 84 ------------------- src/PublicApi/CatalogItemEndpoints/Create.cs | 8 +- 6 files changed, 7 insertions(+), 180 deletions(-) delete mode 100644 src/ApplicationCore/Interfaces/IFileSystem.cs delete mode 100644 src/Infrastructure/Services/WebFileSystem.cs diff --git a/src/ApplicationCore/Interfaces/IFileSystem.cs b/src/ApplicationCore/Interfaces/IFileSystem.cs deleted file mode 100644 index 29d9f04..0000000 --- a/src/ApplicationCore/Interfaces/IFileSystem.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.eShopWeb.ApplicationCore.Interfaces -{ - public interface IFileSystem - { - Task SavePicture(string pictureName, string pictureBase64, CancellationToken cancellationToken); - } -} diff --git a/src/ApplicationCore/Specifications/CatalogFilterPaginatedSpecification.cs b/src/ApplicationCore/Specifications/CatalogFilterPaginatedSpecification.cs index f3d0954..d6d577a 100644 --- a/src/ApplicationCore/Specifications/CatalogFilterPaginatedSpecification.cs +++ b/src/ApplicationCore/Specifications/CatalogFilterPaginatedSpecification.cs @@ -7,11 +7,11 @@ namespace Microsoft.eShopWeb.ApplicationCore.Specifications { public CatalogFilterPaginatedSpecification(int skip, int take, int? brandId, int? typeId) : base() - { + { Query .Where(i => (!brandId.HasValue || i.CatalogBrandId == brandId) && (!typeId.HasValue || i.CatalogTypeId == typeId)) - .Paginate(skip, take); + .Skip(skip).Take(take); } } } diff --git a/src/BlazorAdmin/Pages/CatalogItemPage/Create.razor b/src/BlazorAdmin/Pages/CatalogItemPage/Create.razor index 995fe49..0101526 100644 --- a/src/BlazorAdmin/Pages/CatalogItemPage/Create.razor +++ b/src/BlazorAdmin/Pages/CatalogItemPage/Create.razor @@ -80,23 +80,7 @@ - - - @*
- -
-
- -
-
- @if (HasPicture) - { - - } -
- @_badFileMessage -
-
*@ + @@ -171,26 +155,4 @@ _modalClass = ""; _showCreateModal = false; } - - private async Task AddFile(IFileListEntry[] files) - { - _badFileMessage = string.Empty; - - var file = files.FirstOrDefault(); - _item.PictureName = file?.Name; - _item.PictureBase64 = await CatalogItem.DataToBase64(file); - - _badFileMessage = CatalogItem.IsValidImage(_item.PictureName, _item.PictureBase64); - if (!string.IsNullOrEmpty(_badFileMessage)) - { - _item.PictureName = null; - _item.PictureBase64 = null; - } - } - - private void RemoveImage() - { - _item.PictureName = null; - _item.PictureBase64 = null; - } } diff --git a/src/BlazorAdmin/Pages/CatalogItemPage/Edit.razor b/src/BlazorAdmin/Pages/CatalogItemPage/Edit.razor index cce6a52..9ae161c 100644 --- a/src/BlazorAdmin/Pages/CatalogItemPage/Edit.razor +++ b/src/BlazorAdmin/Pages/CatalogItemPage/Edit.razor @@ -83,23 +83,7 @@ - - - @*
- -
-
- -
-
- @if (HasPicture) - { - - } -
- @_badFileMessage -
-
*@ + @@ -170,27 +154,4 @@ _modalClass = ""; _showEditModal = false; } - - private async Task ChangeFile(IFileListEntry[] files) - { - _badFileMessage = string.Empty; - - var file = files.FirstOrDefault(); - _item.PictureName = file?.Name; - _item.PictureBase64 = await CatalogItem.DataToBase64(file); - - _badFileMessage = CatalogItem.IsValidImage(_item.PictureName, _item.PictureBase64); - if (!string.IsNullOrEmpty(_badFileMessage)) - { - _item.PictureName = null; - _item.PictureBase64 = null; - } - } - - private void RemoveImage() - { - _item.PictureName = null; - _item.PictureBase64 = null; - _item.PictureUri = null; - } } diff --git a/src/Infrastructure/Services/WebFileSystem.cs b/src/Infrastructure/Services/WebFileSystem.cs deleted file mode 100644 index f670079..0000000 --- a/src/Infrastructure/Services/WebFileSystem.cs +++ /dev/null @@ -1,84 +0,0 @@ -using Microsoft.eShopWeb.ApplicationCore.Interfaces; -using Microsoft.eShopWeb.Infrastructure.Data; -using System; -using System.IO; -using System.Net.Http; -using System.Text; -using System.Text.Json; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.eShopWeb.Infrastructure.Services -{ - // This class never gets called. Modify it based on your need. - - public class WebFileSystem : IFileSystem - { - private readonly HttpClient _httpClient; - private readonly string _url; - public const string AUTH_KEY = ""; - - public WebFileSystem(string url) - { - _url = url; - _httpClient = new HttpClient(); - _httpClient.DefaultRequestHeaders.Add("auth-key", AUTH_KEY); - } - - public async Task SavePicture(string pictureName, string pictureBase64, CancellationToken cancellationToken) - { - if (string.IsNullOrEmpty(pictureBase64) || !await UploadFile(pictureName, Convert.FromBase64String(pictureBase64), cancellationToken)) - { - return false; - } - - return true; - } - - private async Task UploadFile(string fileName, byte[] fileData, CancellationToken cancellationToken) - { - if (!fileData.IsValidImage(fileName)) - { - return false; - } - - return await UploadToWeb(fileName, fileData, cancellationToken); - } - - private async Task UploadToWeb(string fileName, byte[] fileData, CancellationToken cancellationToken) - { - var request = new FileItem - { - DataBase64 = Convert.ToBase64String(fileData), - FileName = fileName - }; - - var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); - - // TODO: Write the actual File image upload logic to web. - // Post this image binary content to an Image Upload API. - - return true; - } - } - - public static class ImageValidators - { - private const int ImageMaximumBytes = 512000; - - public static bool IsValidImage(this byte[] postedFile, string fileName) - { - return postedFile != null && postedFile.Length > 0 && postedFile.Length <= ImageMaximumBytes && IsExtensionValid(fileName); - } - - private static bool IsExtensionValid(string fileName) - { - var extension = Path.GetExtension(fileName); - - return string.Equals(extension, ".jpg", StringComparison.OrdinalIgnoreCase) || - string.Equals(extension, ".png", StringComparison.OrdinalIgnoreCase) || - string.Equals(extension, ".gif", StringComparison.OrdinalIgnoreCase) || - string.Equals(extension, ".jpeg", StringComparison.OrdinalIgnoreCase); - } - } -} diff --git a/src/PublicApi/CatalogItemEndpoints/Create.cs b/src/PublicApi/CatalogItemEndpoints/Create.cs index e69e717..1cb5eee 100644 --- a/src/PublicApi/CatalogItemEndpoints/Create.cs +++ b/src/PublicApi/CatalogItemEndpoints/Create.cs @@ -43,11 +43,9 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints if (newItem.Id != 0) { - // At this point time, the Admin application uses the default catalog item image for any new product item. - // But in the actual production scenario, you'll implement the image file upload mechanism in your application and set the image - // file the Uri accordingly. You can refer to fewlines of the boilerplate code are commented out and kept it in the following files. - // - BlazorAdmin project -> Create.razor and Edit.razor. - // - Infrastructure project -> Services/WebFileSystem.cs + //We disabled the upload functionality and added a default/placeholder image to this sample due to a potential security risk + // pointed out by the community. More info in this issue: https://github.com/dotnet-architecture/eShopOnWeb/issues/537 + // In production, we recommend uploading to a blob storage and deliver the image via CDN after a verification process. newItem.UpdatePictureUri("eCatalog-item-default.png"); await _itemRepository.UpdateAsync(newItem, cancellationToken);