Skip to content

Commit

Permalink
Merge pull request #31 from leungkimming/michael3
Browse files Browse the repository at this point in the history
Add Telerik Documents and fix Antiforgrey
  • Loading branch information
leungkimming authored May 20, 2022
2 parents 3456027 + bf2782c commit 5792769
Show file tree
Hide file tree
Showing 29 changed files with 1,257 additions and 40 deletions.
595 changes: 595 additions & 0 deletions API/Controllers/DocumentProcessingController.cs

Large diffs are not rendered by default.

30 changes: 19 additions & 11 deletions API/Controllers/LoginController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,36 @@ public LoginController(IConfiguration config,
public async Task<IActionResult> Get() {
JwtSecurityToken jwtToken;
string token;
AuthResult authResult;

if (HttpContext.User.Identity.Name == "" || HttpContext.User.Identity.Name == null) {
if (HttpContext.User.Identity!.Name == "" || HttpContext.User.Identity.Name == null) {
throw new InvalidUserException();
}

if (jwtUtil.ValidateToken(HttpContext.Request, out jwtToken, out token)) {
return Ok(new AuthResult() {
if (HttpContext.User.Identity.Name == jwtToken.Claims
.Where(c => c.Type == ClaimTypes.Name)
.Select(c => c.Value).SingleOrDefault()) {
Array.ForEach(jwtToken.Claims.Where(c => c.Type == ClaimTypes.Role)
.ToArray(), c => ((ClaimsIdentity)HttpContext.User.Identity).AddClaim(c));
}
authResult = new AuthResult() {
Token = token,
Success = true,
RefreshToken = ""
});
};
} else {
List<Claim>? claims = _service.GetUserClaims(HttpContext.User.Identity.Name);

ClaimsIdentity claimsIdentity = (ClaimsIdentity)HttpContext.User.Identity;
Array.ForEach(claims.Where(c => c.Type == ClaimTypes.Role).ToArray(),
c => claimsIdentity.AddClaim(c));
authResult = jwtUtil.GenerateJwtToken(HttpContext.User.Identity.Name, claims);
}

List<Claim>? claims = _service.GetUserClaims(HttpContext.User.Identity.Name);

ClaimsIdentity claimsIdentity = (ClaimsIdentity)HttpContext.User.Identity;
Array.ForEach(claims.Where(c => c.Type == ClaimTypes.Role).ToArray(),
c => claimsIdentity.AddClaim(c));

AntiforgeryTokenSet? tokens = antiforgery.GetAndStoreTokens(HttpContext);
HttpContext.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false });
HttpContext.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken!, new CookieOptions() { HttpOnly = false });

return Ok(jwtUtil.GenerateJwtToken(HttpContext.User.Identity.Name, claims));
return Ok(authResult);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
namespace API {
[ApiController]
[Route("systemparameters")]
[AutoValidateAntiforgeryToken]
public class SystemParametersController : ControllerBase {
private readonly SystemParametersService _service;
private readonly ILogger<UserController> _logger;
Expand All @@ -27,7 +28,6 @@ public async Task<IActionResult> SearchAll([FromBody]SystemParametersSearchReque
[HttpPost]
[Route("addsystemparameter")]
[AccessCodeAuthorize("SP02")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddSystemParameter([FromBody]AddSystemParameterRequest request) {
AddDataResponse response;
request.Refresh(HttpContext.User.Identity.Name,DateTime.Now);
Expand All @@ -37,7 +37,6 @@ public async Task<IActionResult> AddSystemParameter([FromBody]AddSystemParameter
[HttpPost]
[Route("editsystemparameter")]
[AccessCodeAuthorize("SP03")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> EditSystemParameter([FromBody] EditSystemParameterRequest request) {
EditDataResponse response;
request.Refresh(HttpContext.User.Identity.Name, DateTime.Now);
Expand All @@ -47,7 +46,6 @@ public async Task<IActionResult> EditSystemParameter([FromBody] EditSystemParame
[HttpGet]
[Route("deletesystemparameter")]
[AccessCodeAuthorize("SP04")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteSystemParameter([FromQuery] DeleteSystemParameterRequest request) {
EditDataResponse response;
response = await _service.DeleteSystemParameterAsync(request);
Expand Down
3 changes: 1 addition & 2 deletions API/Controllers/UserController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace API {
[ApiController]
[Route("users")]
[AutoValidateAntiforgeryToken]
public class UserController : ControllerBase {
private readonly UserService _service;
private readonly ILogger<UserController> _logger;
Expand Down Expand Up @@ -40,7 +41,6 @@ public async Task<IActionResult> Get([FromBody] GetUserRequest request) {

[HttpPost(Name = "AddNewUser")]
[AccessCodeAuthorize("AB01")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Add([FromBody] AddUserRequest request) {
AddUserResponse response;
request.Refresh(HttpContext.User.Identity.Name, DateTime.Now);
Expand All @@ -50,7 +50,6 @@ public async Task<IActionResult> Add([FromBody] AddUserRequest request) {

[HttpPost("Addpayslip")]
[AccessCodeAuthorize("AC01")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddPayslip([FromBody] AddPayslipRequest request) {
AddPayslipResponse _response;
request.Refresh(HttpContext.User.Identity.Name, DateTime.Now);
Expand Down
5 changes: 5 additions & 0 deletions API/P1.API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,17 @@
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
<PackageReference Include="Telerik.Documents.Core" Version="2022.1.217" />
<PackageReference Include="Telerik.Documents.Fixed" Version="2022.1.217" />
<PackageReference Include="Telerik.Documents.Flow" Version="2022.1.217" />
<PackageReference Include="Telerik.Documents.Spreadsheet" Version="2022.1.217" />
<PackageReference Include="Telerik.Reporting.Services.AspNetCore" Version="16.0.22.225" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Client\Client.csproj" />
<ProjectReference Include="..\Data\P3.Data.csproj" />
<ProjectReference Include="..\DocumentProcessing\P8.DocumentProcessing.csproj" />
<ProjectReference Include="..\Migrator\P7.Migrator.csproj" />
<ProjectReference Include="..\Service\P2.Service.csproj" />
</ItemGroup>
Expand Down
6 changes: 3 additions & 3 deletions API/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@
} else {
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
builder.Services.AddMvc(options => {
options.Filters.Add<ValidateAntiForgeryTokenAttribute>();
});
}
builder.Services.AddMvc(options => {
options.Filters.Add<ValidateAntiForgeryTokenAttribute>();
});
builder.Services.AddAuthorization(options => {
options.FallbackPolicy = options.DefaultPolicy;
});
Expand Down
5 changes: 5 additions & 0 deletions API/RegisterModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Service;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using DocumentProcessing;

namespace API {
public class RegisterModule : Module {
Expand Down Expand Up @@ -50,6 +51,10 @@ protected override void Load(ContainerBuilder builder) {
builder.RegisterType<AuthorizationResultTransformer>().As<IAuthorizationMiddlewareResultHandler>()
.SingleInstance();
//builder.RegisterType<JWTUtil>().As<IJWTUtil>().SingleInstance();
builder.RegisterType<PdfProcessing>().As<IPdfProcessing>();
builder.RegisterType<WordProcessing>().As<IWordProcessing>();
builder.RegisterType<SpreadProcessing>().As<ISpreadProcessing>();
builder.RegisterType<ZipProcessing>().As<IZipProcessing>();
}
}

Expand Down
1 change: 1 addition & 0 deletions Client/Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<PackageReference Include="Blazored.LocalStorage" Version="4.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.3" PrivateAssets="all" />
<PackageReference Include="Microsoft.Authentication.WebAssembly.Msal" Version="6.0.5" />
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
<PackageReference Include="Telerik.ReportViewer.Blazor" Version="16.0.22.225" />
<PackageReference Include="Telerik.UI.for.Blazor" Version="3.1.0" />
Expand Down
89 changes: 89 additions & 0 deletions Client/Pages/DocumentProcessing.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
@page "/documentprocessing"
@using System.Diagnostics
@inject HttpUtil _httpUtil
@inject IJSRuntime JsRuntime

<h3>Document Processing</h3>

<TelerikButton OnClick="@ExportPDF" Icon="file-pdf" Title="Export PDF"></TelerikButton>
<TelerikButton OnClick="@MergePDF" Icon="file-ascx" Title="Merge PDF"></TelerikButton>
<TelerikButton OnClick="@ExportDocx" Icon="file-word" Title="Export Docx"></TelerikButton>
<TelerikButton OnClick="@ExportXlsx" Icon="file-excel" Title="Export Xlsx"></TelerikButton>
<div class="k-form k-form-horizontal div-container">
<label>Zip Files Demo</label>
<div class="k-form-field-wrap">
<TelerikUpload SaveUrl="@SaveUrl"
AllowedExtensions="@AllowedExtensions"
AutoUpload="false"
MinFileSize="@MinFileSize"
MaxFileSize="@MaxFileSize"
Multiple="true"
OnUpload="@UploadHandler">
</TelerikUpload>
<div class="k-form-hint">Accepted files: <strong>DOCX, PDF, JPG and PNG</strong></div>
<div calss="div-container">
<TelerikTextBox Width="200px" Value="@Password" Title="Password" ValueChanged="@PasswordChanged" PlaceHolder="Password for protect."></TelerikTextBox>
<TelerikButton OnClick="@ZipFiles" Icon="file-zip" Title="Zip all uploaded files."></TelerikButton>
</div>

</div>
</div>
<div class="loader-container">
<TelerikLoader Class="loader-indicator" Type="@LoaderType.InfiniteSpinner" Size="@(ThemeConstants.Loader.Size.Large)" Visible="@IsLoad"></TelerikLoader>
</div>

@code {
public bool IsLoad { get; set; } = false;
public string Password { get; set; }
public async Task PasswordChanged(string value) {
Password = value;
}
public async Task ExportPDF() {
IsLoad = true;
var response = await _httpUtil.GetAsync("documentprocessing/exporttopdf");
var fileData = await response.Content.ReadAsByteArrayAsync();
Save(fileData, "application/pdf", "Sample Document.pdf");
}

public async Task MergePDF() {
IsLoad = true;
var response = await _httpUtil.GetAsync("documentprocessing/mergepdf");
var fileData = await response.Content.ReadAsByteArrayAsync();
Save(fileData, "application/pdf", "Merge Sample Document.pdf");
}
public async Task ExportDocx() {
IsLoad = true;
var response = await _httpUtil.GetAsync("documentprocessing/exporttodocx");
var fileData = await response.Content.ReadAsByteArrayAsync();
Save(fileData, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "Sample Document.docx");
}
public async Task ExportXlsx() {
IsLoad = true;
var response = await _httpUtil.GetAsync("documentprocessing/exporttoxlsx");
var fileData = await response.Content.ReadAsByteArrayAsync();
Save(fileData, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "Sample Document.xlsx");

}
public string SaveUrl => "documentprocessing/uploadfiles";
public List<string> AllowedExtensions { get; set; } = new List<string>() { ".docx", ".pdf", ".jpg", ".png" };
public int MinFileSize { get; set; } = 1024;
public int MaxFileSize { get; set; } = 4 * 1024 * 1024;
public async Task UploadHandler(UploadEventArgs e) {
e.RequestHeaders = new Dictionary<string, object>();
await _httpUtil.RefreshToken(e.RequestHeaders);
}
public async Task ZipFiles() {
IsLoad = true;
var response = await _httpUtil.GetAsync($"documentprocessing/zipfiles?password={Password}");
var fileData = await response.Content.ReadAsByteArrayAsync();
Save(fileData, "application/x-zip-compressed", "ZipDemo.zip");
}
public void Save(byte[] byteData, string mimeType, string fileName) {
if (byteData == null) {
return;
}
var fileBase64=Convert.ToBase64String(byteData);
JsRuntime.InvokeVoidAsync("saveFile", fileBase64, mimeType, fileName);
IsLoad = false;
}
}
1 change: 1 addition & 0 deletions Client/Shared/NavMenu/DrawerMenu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public static class DrawerMenu {
new DrawerItem{ Text = "Search User", Icon = "dollar", Url="/dotnet6EAA/searchuser", Group = "app"},
new DrawerItem{ Text = "Report", Icon = "dollar", Url="/dotnet6EAA/Report", Group = "app"},
new DrawerItem{ Text = "System Parameters", Icon = "tell-a-friend", Url="/dotnet6EAA/systemparameters/searchdatas", Group = "app"},
new DrawerItem{ Text = "Document Processing", Icon = "tell-a-friend", Url="/dotnet6EAA/documentprocessing", Group = "app"},
new DrawerItem{ Text = "Swagger UI", Icon="gear", Url="/dotnet6EAA/swagger/index.html",Group="settings",Target= MenuTarget.Blank.Code},
};
}
Expand Down
2 changes: 2 additions & 0 deletions Client/Util/GeneralSearchUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ private async Task PostData(HttpContent jsonContent, string apiUrl) {
Notspinning = true;
if (response == null) {
Message = "Response data is null";
return;
}
var content = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode) {
Expand All @@ -85,6 +86,7 @@ public async Task DeleteAsync(string apiUrl) {
Notspinning = true;
if (response == null) {
Message = "Response data is null";
return;
}
var content = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode) {
Expand Down
20 changes: 14 additions & 6 deletions Client/Util/HttpUtil.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
using Common;
using System.Net.Http.Json;
using Microsoft.JSInterop;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

namespace Client {
public class HttpUtil {
private readonly HttpClient _http;
private IJSRuntime _jSRuntime;
public HttpUtil(HttpClient http, IJSRuntime jsRuntime) {
private readonly IJSRuntime _jSRuntime;
public HttpUtil(HttpClient http, IJSRuntime jsRuntime, IServiceProvider serviceProvider) {
_http = http;
_jSRuntime = jsRuntime;
}
public async Task<HttpResponseMessage> PostAsync(string? requestUri, HttpContent? content) {
await RefreshToken();
return await _http.PostAsync($"{requestUri}", content);
return await _http.PostAsync($"{requestUri}", content);
}
public async Task<HttpResponseMessage> GetAsync(string? requestUri) {
await RefreshToken();
return await _http.GetAsync($"{requestUri}");
}
public async Task<HttpResponseMessage> PostAsJsonAsync(string? requestUri, object? content) {
Expand All @@ -25,9 +27,9 @@ public async Task<T> GetFromJsonAsync<T>(string? requestUri) {
await RefreshToken();
return await _http.GetFromJsonAsync<T>($"{requestUri}");
}
private async Task RefreshToken() {
public async Task RefreshToken() {
AuthResult authResult;
authResult = await _http.GetFromJsonAsync<AuthResult>("Login");
authResult = await _http.GetFromJsonAsync<AuthResult>("Login") ?? new AuthResult();

_http.DefaultRequestHeaders.Remove("X-UserRoles");
_http.DefaultRequestHeaders.Add("X-UserRoles", authResult.Token);
Expand All @@ -36,6 +38,12 @@ private async Task RefreshToken() {
_http.DefaultRequestHeaders.Remove("X-CSRF-TOKEN-HEADER");
_http.DefaultRequestHeaders.Add("X-CSRF-TOKEN-HEADER", token);
}

public async Task RefreshToken(Dictionary<string, object> requestHeaders) {
AuthResult authResult;
authResult = await _http.GetFromJsonAsync<AuthResult>("Login") ?? new AuthResult();
requestHeaders.Add("X-UserRoles", authResult.Token);
var token = await _jSRuntime.InvokeAsync<string>("getCookie", "XSRF-TOKEN");
requestHeaders.Add("X-CSRF-TOKEN-HEADER", token);
}
}
}
11 changes: 11 additions & 0 deletions Client/wwwroot/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -455,3 +455,14 @@ a {
.k-notification-group {
width: fit-content;
}
.loader-size-title {
display: block;
margin-bottom: 10px;
}

.loader-container {
text-align: center;
width: 100%;
display: inline-table;
padding-top: 10px;
}
19 changes: 11 additions & 8 deletions Client/wwwroot/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<link href="Client.styles.css" rel="stylesheet" />
<link rel="stylesheet" href="_content/Telerik.UI.for.Blazor/css/kendo-theme-default/all.css" />
<script src="_content/Telerik.UI.for.Blazor/js/telerik-blazor.js" defer></script>
<script src="js/download-upload-files.js"></script>
</head>

<body>
Expand All @@ -25,15 +26,17 @@
</div>
<script src="_framework/blazor.webassembly.js"></script>
<script>
function getCookie(cname) {
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for (var i = 0; i < ca.length; i++) {
var arr = ca[i].split('=');
if (arr[0] == cname)
return arr[1]
function getCookie(name) {
if (!document.cookie) {
return null;
}
return "";
const xsrfCookies = document.cookie.split(';')
.map(c => c.trim())
.filter(c => c.startsWith(name + '='));
if (xsrfCookies.length === 0) {
return null;
}
return decodeURIComponent(xsrfCookies[0].split('=')[1]);
}
</script>
<script src="_content/telerik.reportviewer.blazor/interop.js" defer></script>
Expand Down
Loading

0 comments on commit 5792769

Please sign in to comment.