add lastmodified and lastmodifiedid to table also add code for modified and create

This commit is contained in:
Kham
2021-09-01 16:03:05 +10:00
parent c5ab17115d
commit cc276d4a17
25 changed files with 255 additions and 115 deletions
@@ -21,13 +21,13 @@ namespace CarParkValidationAPI.Authorization
public async Task Invoke(HttpContext context, IUserService userService, IJwtUtils jwtUtils)
{
var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
var userId = jwtUtils.ValidateJwtToken(token);
if (userId != null)
var user = jwtUtils.ValidateJwtToken(token);
if (user != null)
{
// attach user to context on successful jwt validation
//here to put in the real user
//TODO if you want to add information for User
// context.Items["User"] = userService.GetById(userId.Value);
context.Items["User"] = user;
}
await _next(context);
+31 -5
View File
@@ -30,7 +30,9 @@ namespace CarParkValidationAPI.Authorization
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[] {
new Claim("id", user.Id.ToString())
new Claim("id", user.Id.ToString()),
new Claim("subject", user.Username)
//add more if we need it
}
),
@@ -40,8 +42,8 @@ namespace CarParkValidationAPI.Authorization
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
public int? ValidateJwtToken(string token)
// get back id and username. in subject
public User? ValidateJwtToken(string token)
{
if (token == null)
return null;
@@ -61,10 +63,34 @@ namespace CarParkValidationAPI.Authorization
}, out SecurityToken validatedToken);
var jwtToken = (JwtSecurityToken)validatedToken;
var userId = int.Parse(jwtToken.Claims.First(x => x.Type == "id").Value);
// var userId = int.Parse(jwtToken.Claims.First(x => x.Type == "id").Value); //old
int userId = 0;
string username = "";
Claim claim;
for (int i = 0; i< jwtToken.Claims.Count(); i++)
{
claim = jwtToken.Claims.ElementAt(i);
if (claim.Type == "id")
{
userId = int.Parse(claim.Value);
}
else if (claim.Type == "subject")
{
username = claim.Value;
}
if (!string.IsNullOrEmpty(username) && userId > 0)
{
break;
}
}
User user = new User();
user.Id = userId;
user.Username = username;
// return user id from JWT token if validation successful
return userId;
return user;
}
catch
{
@@ -21,6 +21,10 @@ namespace CarParkValidationAPI.Controllers
[HttpPost]
public async Task<IActionResult> AdminUser([FromBody] AdminUserDto model)
{
var currentUser = (User)HttpContext.Items["User"];
if (null == currentUser)
return Unauthorized(new { message = "Unauthorized" });
_adminUser.SetCurrentUser(currentUser.Username);
var response = await _adminUser.SaveAdminUserAsync(model);
return Ok(response);
}
@@ -47,12 +51,10 @@ namespace CarParkValidationAPI.Controllers
[HttpDelete("{id:int}")]
public async Task<IActionResult> DeleteAdminUser(int id)
{
/*
// only admins can access other user records
var currentUser = (User)HttpContext.Items["User"];
if (id != currentUser.Id && currentUser.Role != Role.Admin)
if (null == currentUser)
return Unauthorized(new { message = "Unauthorized" });
*/
_adminUser.SetCurrentUser(currentUser.Username);
var retval = await _adminUser.DeleteAdminUserAsync(id);
return Ok(retval);
}
@@ -22,6 +22,10 @@ namespace CarParkValidationAPI.Controllers
[HttpPost]
public async Task<IActionResult> ConcessionType([FromBody] ConcessionTypeDto model)
{
var currentUser = (User)HttpContext.Items["User"];
if (null == currentUser)
return Unauthorized(new { message = "Unauthorized" });
_concessionType.SetCurrentUser(currentUser.Username);
var response = await _concessionType.SaveConcessionTypeAsync(model);
return Ok(response);
}
@@ -23,6 +23,7 @@ namespace CarParkValidationAPI.Controllers
public ConcessionValidationController(IConcessionValidation concessionValidation,
ConcessionValidationReportRepository concesionReportReport)
{
_concessionValidationReport = concesionReportReport;
_concessionValidation = concessionValidation;
}
@@ -31,6 +32,10 @@ namespace CarParkValidationAPI.Controllers
[HttpPost]
public async Task<IActionResult> ConcessionValidation([FromBody] ConcessionValidationDto model)
{
var currentUser = (User)HttpContext.Items["User"];
if (null == currentUser)
return Unauthorized(new { message = "Unauthorized" });
_concessionValidation.SetCurrentUser(currentUser.Username);
var response = await _concessionValidation.SaveConcessionValidationAsync(model);
return Ok(response);
}
@@ -72,12 +77,12 @@ namespace CarParkValidationAPI.Controllers
[HttpDelete("{id:int}")]
public async Task<IActionResult> DeleteConcessionValidation(int id)
{
/*
// only admins can access other user records
var currentUser = (User)HttpContext.Items["User"];
if (id != currentUser.Id && currentUser.Role != Role.Admin)
//if (id != currentUser.Id && currentUser.Role != Role.Admin)
return Unauthorized(new { message = "Unauthorized" });
*/
//
var retval = await _concessionValidation.DeleteConcessionValidationAsync(id);
return Ok(retval);
}
@@ -23,11 +23,14 @@ namespace CarParkValidationAPI.Controllers
[HttpPost]
public async Task<IActionResult> ValidationPoint([FromBody] ValidationPointDto model)
{
var currentUser = (User)HttpContext.Items["User"];
if (null == currentUser)
return Unauthorized(new { message = "Unauthorized" });
_validationPoint.SetCurrentUser(currentUser.Username);
var response = await _validationPoint.SaveValidationPointAsync(model);
return Ok(response);
}
[HttpGet]
public async Task<IActionResult> ValidationPoint(bool onlyActive=true)
{
@@ -50,12 +53,11 @@ namespace CarParkValidationAPI.Controllers
[HttpDelete("{id:int}")]
public async Task<IActionResult> DeleteConcessionType(int id)
{
/*
// only admins can access other user records
var currentUser = (User)HttpContext.Items["User"];
if (id != currentUser.Id && currentUser.Role != Role.Admin)
if (null == currentUser)
return Unauthorized(new { message = "Unauthorized" });
*/
_validationPoint.SetCurrentUser(currentUser.Username);
var retval = await _validationPoint.DeleteValidationPointAsync(id);
return Ok(retval);
}
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace CarParkValidationAPI.Entities
{
public class ApiException
{
public ApiException(int statusCode, string message = null, string details = null)
{
StatusCode = statusCode;
Message = message;
Details = details;
}
public int StatusCode { get; set; }
public string Message { get; set; }
public string Details { get; set; }
}
}
@@ -1,4 +1,7 @@
using CarParkValidationAPI.Entities;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Net;
@@ -10,30 +13,35 @@ namespace CarParkValidationAPI.Helpers
public class ErrorHandlerMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<ErrorHandlerMiddleware> _logger;
private readonly IHostEnvironment _env;
public ErrorHandlerMiddleware(RequestDelegate next)
public ErrorHandlerMiddleware(RequestDelegate next,
ILogger<ErrorHandlerMiddleware> logger, IHostEnvironment env)
{
_next = next;
_logger = logger;
_env = env;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception error)
catch (Exception ex)
{
var response = context.Response;
response.ContentType = "application/json";
switch(error)
_logger.LogError(ex, ex.Message);
/*
switch (ex)
{
// case Exception e:
// // custom application error
// response.StatusCode = (int)HttpStatusCode.BadRequest;
// break;
case KeyNotFoundException e:
case KeyNotFoundException:
// not found error
response.StatusCode = (int)HttpStatusCode.NotFound;
break;
@@ -41,10 +49,24 @@ namespace CarParkValidationAPI.Helpers
// unhandled error
response.StatusCode = (int)HttpStatusCode.InternalServerError;
break;
}
} */
response.StatusCode = ex switch
{
// case Exception e:
// // custom application error
// response.StatusCode = (int)HttpStatusCode.BadRequest;
// break;
KeyNotFoundException => (int)HttpStatusCode.NotFound,// not found error
_ => (int)HttpStatusCode.InternalServerError,// unhandled error
};
//response.StatusCode = (int)HttpStatusCode.InternalServerError;
var res = _env.IsDevelopment() ?
new ApiException(response.StatusCode, ex.Message, ex.StackTrace?.ToString())
: new ApiException(response.StatusCode, "Internal Server Error");
var result = JsonSerializer.Serialize(new { message = error?.Message });
await response.WriteAsync(result);
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
var json = JsonSerializer.Serialize(res, options);
await response.WriteAsync(json);
}
}
}
@@ -14,5 +14,6 @@ namespace CarParkValidationAPI.Interface
Task<ResultModel<int>> SaveAdminUserAsync(AdminUserDto item);
Task<ResultModel<AdminUserDto>> LoadAdminUserByIdAsync(int id);
Task<ResultModel<bool>> DeleteAdminUserAsync(int id);
void SetCurrentUser(string username);
}
}
@@ -14,5 +14,6 @@ namespace CarParkValidationAPI.Interface
Task<ResultModel<int>> SaveConcessionTypeAsync(ConcessionTypeDto item);
Task<ResultModel<ConcessionTypeDto>> LoadConcessionTypeByIdAsync(int id);
Task<ResultModel<bool>> DeleteConcessionTypeAsync(int id);
void SetCurrentUser(string username);
}
}
@@ -17,5 +17,6 @@ namespace CarParkValidationAPI.Interface
Task<ResultModel<ConcessionValidationDto>> LoadConcessionValidationByIdAsync(int id);
Task<ResultModel<bool>> DeleteConcessionValidationAsync(int id);
Task<ResultModel<FileContent>> GetReport(DateTime fromDate, DateTime toDate);
void SetCurrentUser(string username);
}
}
+1 -1
View File
@@ -11,6 +11,6 @@ namespace CarParkValidationAPI.Interface
public interface IJwtUtils
{
public string GenerateJwtToken(User user);
public int? ValidateJwtToken(string token);
public User? ValidateJwtToken(string token);
}
}
@@ -14,5 +14,6 @@ namespace CarParkValidationAPI.Interface
Task<ResultModel<int>> SaveValidationPointAsync(ValidationPointDto item);
Task<ResultModel<ValidationPointDto>> LoadValidationPointByIdAsync(int id);
Task<ResultModel<bool>> DeleteValidationPointAsync(int id);
void SetCurrentUser(string username);
}
}
+2
View File
@@ -56,6 +56,8 @@ namespace CarParkValidationAPI.Models
public bool Active { get; set; }
public AdminRole RoleType { get; set; }
public DateTime? LastModified { get; set; }
public string? LastModifiedId { get; set; }
#endregion
}
}
@@ -21,6 +21,8 @@ namespace CarParkValidationAPI.Models
public string ConcessionDisplay { get; set; }
public bool Active { get; set; }
public DateTime? LastModified { get; set; }
public string? LastModifiedId { get; set; }
#endregion
}
}
@@ -45,6 +45,11 @@ namespace CarParkValidationAPI.Models
public string StaffFirstName { get; set; }
public string StaffLastName { get; set; }
public string StaffEmail { get; set; }
public DateTime? CreatedDate { get; set; }
public string? CreatedId { get; set; }
public DateTime? LastModified { get; set; }
public string? LastModifiedId{ get; set; }
#endregion
}
}
@@ -20,6 +20,7 @@ namespace CarParkValidationAPI.Models
public bool Active { get; set; }
public DateTime? LastModified { get; set; }
public string? LastModifiedId { get; set; }
}
}
@@ -18,6 +18,7 @@ namespace CarParkValidationAPI.Repository
public class AdminUserFakeRepository : IAdminUser
{
private DataContext _context;
private string _currentUser = "";
List<AdminUserDto> _resultList = new List<AdminUserDto>();
private readonly AppSettings _appSettings;
@@ -31,6 +32,10 @@ namespace CarParkValidationAPI.Repository
_appSettings = appSettings.Value;
}
public void SetCurrentUser(string username)
{
_currentUser = username;
}
private AdminUserDto FillAdminUserDto(AdminUser model)
{
AdminUserDto dto = new AdminUserDto();
@@ -46,7 +51,6 @@ namespace CarParkValidationAPI.Repository
private AdminUser FillAdminUser(AdminUserDto dto, AdminUser model)
{
model.UserID = dto.Id;
model.Name = dto.Name;
model.RoleType = dto.RoleType;
@@ -18,7 +18,7 @@ namespace CarParkValidationAPI.Repository
public class AdminUserRepository : IAdminUser
{
private DataContext _context;
private string _currentUser = "";
private readonly AppSettings _appSettings;
@@ -30,7 +30,10 @@ namespace CarParkValidationAPI.Repository
_context = context;
_appSettings = appSettings.Value;
}
public void SetCurrentUser(string username)
{
_currentUser = username;
}
private AdminUserDto FillAdminUserDto(AdminUser model)
{
AdminUserDto dto = new AdminUserDto();
@@ -132,6 +135,8 @@ namespace CarParkValidationAPI.Repository
{
model = await _context.AdminUsers.FindAsync(item.Id);
model = FillAdminUser(item, model);
model.LastModified = DateTime.Now;
model.LastModifiedId = _currentUser;
await _context.SaveChangesAsync();
}
else
@@ -171,6 +176,8 @@ namespace CarParkValidationAPI.Repository
{
AdminUser model = await _context.AdminUsers.FindAsync(id);
model.Active = false;
model.LastModified = DateTime.Now;
model.LastModifiedId = _currentUser;
await _context.SaveChangesAsync();
statuscode = 1;
}
@@ -18,7 +18,7 @@ namespace CarParkValidationAPI.Repository
public class ConcessionTypeRepository : IConcessionType
{
private DataContext _context;
private string _currentUser = "";
private readonly AppSettings _appSettings;
public ConcessionTypeRepository(
@@ -29,7 +29,10 @@ namespace CarParkValidationAPI.Repository
_context = context;
_appSettings = appSettings.Value;
}
public void SetCurrentUser(string username)
{
_currentUser = username;
}
private ConcessionTypeDto FillConcessionTypeDto(ConcessionType model)
{
ConcessionTypeDto dto = new ConcessionTypeDto();
@@ -63,6 +66,7 @@ namespace CarParkValidationAPI.Repository
Active = x.Active
}).ToListAsync();
statuscode = 1;
result.Sort((x, y) => x.Description.CompareTo(y.Description));
}
catch (Exception ex)
{
@@ -118,6 +122,8 @@ namespace CarParkValidationAPI.Repository
{
model = await _context.ConcessionTypes.FindAsync(item.Id);
model = FillConcessionType(item, model);
model.LastModified = DateTime.Now;
model.LastModifiedId = _currentUser;
await _context.SaveChangesAsync();
result = item.Id;
}
@@ -125,6 +131,8 @@ namespace CarParkValidationAPI.Repository
{
model = new ConcessionType();
model = FillConcessionType(item, model);
model.LastModified = DateTime.Now;
model.LastModifiedId = _currentUser;
_context.ConcessionTypes.Add(model);
var id = await _context.SaveChangesAsync();
result = id;
@@ -18,7 +18,7 @@ namespace CarParkValidationAPI.Repository
public class ConcessionValidationRepository : IConcessionValidation
{
private DataContext _context;
private string _currentUser = "";
private readonly AppSettings _appSettings;
public ConcessionValidationRepository(
@@ -29,6 +29,10 @@ namespace CarParkValidationAPI.Repository
_appSettings = appSettings.Value;
}
public void SetCurrentUser(string username)
{
_currentUser = username;
}
private ConcessionValidationDto FillConcessionValidationDto(ConcessionValidation model)
{
ConcessionValidationDto dto = new ConcessionValidationDto();
@@ -167,7 +171,7 @@ namespace CarParkValidationAPI.Repository
{
var anyRecord = await _context.SelectCheckConcessionValidationAsync(currentDate.ToLocalTime().Date, concessionCard, staffLinkNo);
if (anyRecord.Count > 0)
if (anyRecord.Count > 1)
{
result = -1;
}
@@ -267,6 +271,7 @@ namespace CarParkValidationAPI.Repository
int result = default(int);
int statuscode = 0;
string error = "";
//_currentUser = item.StafflinkNo;
try
{
ConcessionValidation model;
@@ -274,12 +279,18 @@ namespace CarParkValidationAPI.Repository
{
model = await _context.ConcessionValidations.FindAsync(item.Id);
model = FillConcessionValidation(item, model);
model.LastModified = DateTime.Now;
model.LastModifiedId = _currentUser;
result = await _context.SaveChangesAsync();
}
else
{
model = new ConcessionValidation();
model = FillConcessionValidation(item, model);
model.LastModified = DateTime.Now;
model.LastModifiedId = _currentUser;
model.CreatedDate = DateTime.Now;
model.CreatedId = _currentUser;
_context.ConcessionValidations.Add(model);
result = await _context.SaveChangesAsync();
}
@@ -312,8 +323,10 @@ namespace CarParkValidationAPI.Repository
if (id > 0)
{
ConcessionValidation model = await _context.ConcessionValidations.FindAsync(id);
// model.Active = false;
_context.ConcessionValidations.Remove(model);
model.Active = false;
model.LastModified = DateTime.Now;
model.LastModifiedId = _currentUser;
//_context.ConcessionValidations.Remove(model);
await _context.SaveChangesAsync();
statuscode = 1;
}
@@ -45,6 +45,7 @@ namespace CarParkValidationAPI.Repository
}).ToListAsync();
statuscode = 1;
result.Sort((x,y) => x.Description.CompareTo(y.Description));
}
catch (Exception ex)
{
@@ -72,6 +73,7 @@ namespace CarParkValidationAPI.Repository
Id = x.ValidationPointID,
Description = x.Description
}).ToListAsync();
result.Sort((x, y) => x.Description.CompareTo(y.Description));
statuscode = 1;
}
catch (Exception ex)
@@ -16,7 +16,7 @@ namespace CarParkValidationAPI.Repository
private DataContext _context;
private readonly AppSettings _appSettings;
private string _currentUser = "";
private List<ValidationPointDto> _list = new List<ValidationPointDto>();
public ValidationPointFakeRepository(
@@ -27,7 +27,10 @@ namespace CarParkValidationAPI.Repository
_context = context;
_appSettings = appSettings.Value;
}
public void SetCurrentUser(string username)
{
_currentUser = username;
}
private ValidationPointDto FillValidationDto(ValidationPoint item)
{
ValidationPointDto dto = new ValidationPointDto();
@@ -16,7 +16,7 @@ namespace CarParkValidationAPI.Repository
private DataContext _context;
private readonly AppSettings _appSettings;
private string _currentUser = "";
private List<ValidationPointDto> _list = new List<ValidationPointDto>();
public ValidationPointRepository(
@@ -27,7 +27,10 @@ namespace CarParkValidationAPI.Repository
_context = context;
_appSettings = appSettings.Value;
}
public void SetCurrentUser(string username)
{
_currentUser = username;
}
private ValidationPointDto FillValidationDto(ValidationPoint item)
{
ValidationPointDto dto = new ValidationPointDto();
@@ -61,7 +64,7 @@ namespace CarParkValidationAPI.Repository
dto = FillValidationDto(it[i]);
_list.Add(dto);
}
_list.Sort((x, y) => x.Description.CompareTo(y.Description));
statuscode = 1;
}
@@ -116,12 +119,16 @@ namespace CarParkValidationAPI.Repository
{
model = await _context.Validations.FindAsync(item.Id);
model = FillValidationModel(item, model);
model.LastModified = DateTime.Now;
model.LastModifiedId = _currentUser;
await _context.SaveChangesAsync();
result = item.Id;
}
else //new record
{
model = new ValidationPoint();
model.LastModified = DateTime.Now;
model.LastModifiedId = _currentUser;
model = FillValidationModel(item, model);
_context.Validations.Add(model);
var id = await _context.SaveChangesAsync();
+4 -4
View File
@@ -1,6 +1,7 @@
using CarParkValidationAPI.Authorization;
using CarParkValidationAPI.Datas;
using CarParkValidationAPI.Entities;
using CarParkValidationAPI.Helpers;
using CarParkValidationAPI.Interface;
using CarParkValidationAPI.Models;
using CarParkValidationAPI.Repository;
@@ -97,15 +98,15 @@ namespace CarParkValidationAPI
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DataContext context)
{
/*
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
*/
app.UseMiddleware<ErrorHandlerMiddleware>(); // use this exception
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.DocExpansion(Swashbuckle.AspNetCore.SwaggerUI.DocExpansion.None);
@@ -135,7 +136,6 @@ namespace CarParkValidationAPI
/***************************/
// app.UseDefaultFiles(); //it will use index.html <------------------
// app.UseStaticFiles(); //it for angular <-------------------------
/***************************/
app.UseEndpoints(endpoints =>