Browse Source
* Image added * ImageMaximumBytes * FileController remove Authorized * ApplicationCore.Constants.AuthorizationConstants.AUTH_KEY * SavePicture in the interface. * IFileSystem in Core * WebFileSystem in Infrastructure * PictureUri removed from UpdateCatalogItemRequest * Modal scroll fixmain
committed by
GitHub
29 changed files with 654 additions and 196 deletions
@ -0,0 +1,9 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Microsoft.eShopWeb.ApplicationCore.Interfaces |
|||
{ |
|||
public interface IFileSystem |
|||
{ |
|||
Task<bool> SavePicture(string pictureName, string pictureBase64); |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.JSInterop; |
|||
|
|||
namespace BlazorAdmin.JavaScript |
|||
{ |
|||
public class Css |
|||
{ |
|||
private readonly IJSRuntime _jsRuntime; |
|||
|
|||
public Css(IJSRuntime jsRuntime) |
|||
{ |
|||
_jsRuntime = jsRuntime; |
|||
} |
|||
|
|||
public async Task ShowBodyOverflow() |
|||
{ |
|||
await _jsRuntime.InvokeAsync<string>(JSInteropConstants.ShowBodyOverflow); |
|||
} |
|||
|
|||
public async Task<string> HideBodyOverflow() |
|||
{ |
|||
return await _jsRuntime.InvokeAsync<string>(JSInteropConstants.HideBodyOverflow); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
namespace Microsoft.eShopWeb.Infrastructure.Data |
|||
{ |
|||
public class FileItem |
|||
{ |
|||
public string FileName { get; set; } |
|||
public string Url { get; set; } |
|||
public long Size { get; set; } |
|||
public string Ext { get; set; } |
|||
public string Type { get; set; } |
|||
public string DataBase64 { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,83 @@ |
|||
using System; |
|||
using System.IO; |
|||
using System.Net.Http; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.eShopWeb.ApplicationCore.Interfaces; |
|||
using Microsoft.eShopWeb.Infrastructure.Data; |
|||
using Newtonsoft.Json; |
|||
|
|||
namespace Microsoft.eShopWeb.Infrastructure.Services |
|||
{ |
|||
public class WebFileSystem: IFileSystem |
|||
{ |
|||
private readonly HttpClient _httpClient; |
|||
private readonly string _url; |
|||
public const string AUTH_KEY = "AuthKeyOfDoomThatMustBeAMinimumNumberOfBytes"; |
|||
|
|||
public WebFileSystem(string url) |
|||
{ |
|||
_url = url; |
|||
_httpClient = new HttpClient(); |
|||
_httpClient.DefaultRequestHeaders.Add("auth-key", AUTH_KEY); |
|||
} |
|||
|
|||
public async Task<bool> SavePicture(string pictureName, string pictureBase64) |
|||
{ |
|||
if (!await UploadFile(pictureName, Convert.FromBase64String(pictureBase64))) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
private async Task<bool> UploadFile(string fileName, byte[] fileData) |
|||
{ |
|||
if (!fileData.IsValidImage(fileName)) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
return await UploadToWeb(fileName, fileData); |
|||
} |
|||
|
|||
private async Task<bool> UploadToWeb(string fileName, byte[] fileData) |
|||
{ |
|||
var request = new FileItem |
|||
{ |
|||
DataBase64 = Convert.ToBase64String(fileData), |
|||
FileName = fileName |
|||
}; |
|||
var content = new StringContent(JsonConvert.SerializeObject(request), Encoding.UTF8, "application/json"); |
|||
|
|||
using var message = await _httpClient.PostAsync(_url, content); |
|||
if (!message.IsSuccessStatusCode) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
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); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using System; |
|||
using System.IO; |
|||
|
|||
namespace Microsoft.eShopWeb.PublicApi |
|||
{ |
|||
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); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
using System; |
|||
using System.IO; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.eShopWeb.Web.ViewModels.File; |
|||
|
|||
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(); |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Microsoft.eShopWeb.Web.ViewModels.File |
|||
{ |
|||
public class FileViewModel |
|||
{ |
|||
public string FileName { get; set; } |
|||
public string Url { get; set; } |
|||
public string DataBase64 { get; set; } |
|||
} |
|||
} |
|||
Loading…
Reference in new issue