From d90e73dfcc433046763b9d250e0aa0a2f0dd9d1e Mon Sep 17 00:00:00 2001 From: Kham Date: Mon, 23 Aug 2021 08:18:46 +1000 Subject: [PATCH] Add project files. --- CarParkValidationAPI.sln | 31 ++ .../.config/dotnet-tools.json | 12 + .../Authorization/AllowAnonymousAttribute.cs | 8 + .../Authorization/AuthorizeAttribute.cs | 38 ++ .../Authorization/JwtMiddleware.cs | 34 ++ .../Authorization/JwtUtils.cs | 76 ++++ .../CarParkValidationAPI.csproj | 22 ++ .../Controllers/AdminUserController.cs | 60 +++ .../Controllers/ConcessionTypeController.cs | 62 +++ .../ConcessionValidationController.cs | 91 +++++ .../Controllers/LookupCodeController.cs | 37 ++ .../Controllers/UsersController.cs | 82 ++++ .../Controllers/ValidationPointController.cs | 63 +++ CarParkValidationAPI/Datas/DataContext.cs | 179 +++++++++ CarParkValidationAPI/Entities/AdminUserDto.cs | 26 ++ .../Entities/ConcessionTypeDto.cs | 20 + .../Entities/ConcessionValidationDto.cs | 37 ++ CarParkValidationAPI/Entities/FileContent.cs | 13 + .../Entities/LookupCodeDto.cs | 20 + CarParkValidationAPI/Entities/Role.cs | 8 + .../Entities/ValidationPointDto.cs | 24 ++ .../Helpers/ErrorHandlerMiddleware.cs | 51 +++ CarParkValidationAPI/Interface/IAdminUser.cs | 18 + .../Interface/IConcessionType.cs | 18 + .../Interface/IConcessionValidation.cs | 20 + CarParkValidationAPI/Interface/IJwtUtils.cs | 16 + CarParkValidationAPI/Interface/ILookupCode.cs | 17 + CarParkValidationAPI/Interface/IUser.cs | 21 + .../Interface/IValidationPoint.cs | 18 + CarParkValidationAPI/Models/AdminUser.cs | 61 +++ CarParkValidationAPI/Models/AppSettings.cs | 28 ++ CarParkValidationAPI/Models/ConcessionType.cs | 26 ++ .../Models/ConcessionValidation.cs | 47 +++ CarParkValidationAPI/Models/ResultModel.cs | 14 + CarParkValidationAPI/Models/User.cs | 17 + .../Models/Users/AuthenticateRequest.cs | 13 + .../Models/Users/AuthenticateResponse.cs | 24 ++ .../Models/ValidationPoint.cs | 25 ++ CarParkValidationAPI/Program.cs | 26 ++ .../Properties/launchSettings.json | 35 ++ .../Repository/AdminUserFakeRepository.cs | 199 ++++++++++ .../Repository/AdminUserRepository.cs | 196 +++++++++ .../Repository/ConcessionTypeRepository.cs | 184 +++++++++ .../ConcessionValidationRepository.cs | 273 +++++++++++++ .../Repository/LookupCodeRepository.cs | 92 +++++ .../Repository/UserFakeRepository.cs | 251 ++++++++++++ .../Repository/UserRepository.cs | 223 +++++++++++ .../ValidationPointFackRepository.cs | 192 +++++++++ .../Repository/ValidationPointRepository.cs | 179 +++++++++ CarParkValidationAPI/Startup.cs | 137 +++++++ .../appsettings.Development.json | 23 ++ CarParkValidationAPI/appsettings.json | 23 ++ CarParkValidationAPI/web.config | 15 + CommonAD/ADConfig.cs | 44 +++ CommonAD/ADStaffLink.cs | 373 +++++++++++++++++ CommonAD/CommonAD.csproj | 12 + CommonAD/MyADObject.cs | 33 ++ CommonAD/WebAPIUtil.cs | 268 +++++++++++++ CommonAuth/ADConfig.cs | 44 +++ CommonAuth/ADStaffLink.cs | 374 ++++++++++++++++++ CommonAuth/CommonAuth.csproj | 13 + CommonAuth/MyADObject.cs | 33 ++ CommonAuth_old/ADConfig.cs | 44 +++ CommonAuth_old/ADStaffLink.cs | 374 ++++++++++++++++++ CommonAuth_old/CommonAuth.csproj | 11 + CommonAuth_old/MyADObject.cs | 33 ++ 66 files changed, 5081 insertions(+) create mode 100644 CarParkValidationAPI.sln create mode 100644 CarParkValidationAPI/.config/dotnet-tools.json create mode 100644 CarParkValidationAPI/Authorization/AllowAnonymousAttribute.cs create mode 100644 CarParkValidationAPI/Authorization/AuthorizeAttribute.cs create mode 100644 CarParkValidationAPI/Authorization/JwtMiddleware.cs create mode 100644 CarParkValidationAPI/Authorization/JwtUtils.cs create mode 100644 CarParkValidationAPI/CarParkValidationAPI.csproj create mode 100644 CarParkValidationAPI/Controllers/AdminUserController.cs create mode 100644 CarParkValidationAPI/Controllers/ConcessionTypeController.cs create mode 100644 CarParkValidationAPI/Controllers/ConcessionValidationController.cs create mode 100644 CarParkValidationAPI/Controllers/LookupCodeController.cs create mode 100644 CarParkValidationAPI/Controllers/UsersController.cs create mode 100644 CarParkValidationAPI/Controllers/ValidationPointController.cs create mode 100644 CarParkValidationAPI/Datas/DataContext.cs create mode 100644 CarParkValidationAPI/Entities/AdminUserDto.cs create mode 100644 CarParkValidationAPI/Entities/ConcessionTypeDto.cs create mode 100644 CarParkValidationAPI/Entities/ConcessionValidationDto.cs create mode 100644 CarParkValidationAPI/Entities/FileContent.cs create mode 100644 CarParkValidationAPI/Entities/LookupCodeDto.cs create mode 100644 CarParkValidationAPI/Entities/Role.cs create mode 100644 CarParkValidationAPI/Entities/ValidationPointDto.cs create mode 100644 CarParkValidationAPI/Helpers/ErrorHandlerMiddleware.cs create mode 100644 CarParkValidationAPI/Interface/IAdminUser.cs create mode 100644 CarParkValidationAPI/Interface/IConcessionType.cs create mode 100644 CarParkValidationAPI/Interface/IConcessionValidation.cs create mode 100644 CarParkValidationAPI/Interface/IJwtUtils.cs create mode 100644 CarParkValidationAPI/Interface/ILookupCode.cs create mode 100644 CarParkValidationAPI/Interface/IUser.cs create mode 100644 CarParkValidationAPI/Interface/IValidationPoint.cs create mode 100644 CarParkValidationAPI/Models/AdminUser.cs create mode 100644 CarParkValidationAPI/Models/AppSettings.cs create mode 100644 CarParkValidationAPI/Models/ConcessionType.cs create mode 100644 CarParkValidationAPI/Models/ConcessionValidation.cs create mode 100644 CarParkValidationAPI/Models/ResultModel.cs create mode 100644 CarParkValidationAPI/Models/User.cs create mode 100644 CarParkValidationAPI/Models/Users/AuthenticateRequest.cs create mode 100644 CarParkValidationAPI/Models/Users/AuthenticateResponse.cs create mode 100644 CarParkValidationAPI/Models/ValidationPoint.cs create mode 100644 CarParkValidationAPI/Program.cs create mode 100644 CarParkValidationAPI/Properties/launchSettings.json create mode 100644 CarParkValidationAPI/Repository/AdminUserFakeRepository.cs create mode 100644 CarParkValidationAPI/Repository/AdminUserRepository.cs create mode 100644 CarParkValidationAPI/Repository/ConcessionTypeRepository.cs create mode 100644 CarParkValidationAPI/Repository/ConcessionValidationRepository.cs create mode 100644 CarParkValidationAPI/Repository/LookupCodeRepository.cs create mode 100644 CarParkValidationAPI/Repository/UserFakeRepository.cs create mode 100644 CarParkValidationAPI/Repository/UserRepository.cs create mode 100644 CarParkValidationAPI/Repository/ValidationPointFackRepository.cs create mode 100644 CarParkValidationAPI/Repository/ValidationPointRepository.cs create mode 100644 CarParkValidationAPI/Startup.cs create mode 100644 CarParkValidationAPI/appsettings.Development.json create mode 100644 CarParkValidationAPI/appsettings.json create mode 100644 CarParkValidationAPI/web.config create mode 100644 CommonAD/ADConfig.cs create mode 100644 CommonAD/ADStaffLink.cs create mode 100644 CommonAD/CommonAD.csproj create mode 100644 CommonAD/MyADObject.cs create mode 100644 CommonAD/WebAPIUtil.cs create mode 100644 CommonAuth/ADConfig.cs create mode 100644 CommonAuth/ADStaffLink.cs create mode 100644 CommonAuth/CommonAuth.csproj create mode 100644 CommonAuth/MyADObject.cs create mode 100644 CommonAuth_old/ADConfig.cs create mode 100644 CommonAuth_old/ADStaffLink.cs create mode 100644 CommonAuth_old/CommonAuth.csproj create mode 100644 CommonAuth_old/MyADObject.cs diff --git a/CarParkValidationAPI.sln b/CarParkValidationAPI.sln new file mode 100644 index 0000000..b48e8db --- /dev/null +++ b/CarParkValidationAPI.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31515.178 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CarParkValidationAPI", "CarParkValidationAPI\CarParkValidationAPI.csproj", "{FCD8F53F-967F-4E66-B42C-DCD0C83B2670}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommonAD", "CommonAD\CommonAD.csproj", "{43FC73FD-1EE6-4B68-9299-E77049B5E490}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FCD8F53F-967F-4E66-B42C-DCD0C83B2670}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FCD8F53F-967F-4E66-B42C-DCD0C83B2670}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FCD8F53F-967F-4E66-B42C-DCD0C83B2670}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FCD8F53F-967F-4E66-B42C-DCD0C83B2670}.Release|Any CPU.Build.0 = Release|Any CPU + {43FC73FD-1EE6-4B68-9299-E77049B5E490}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {43FC73FD-1EE6-4B68-9299-E77049B5E490}.Debug|Any CPU.Build.0 = Debug|Any CPU + {43FC73FD-1EE6-4B68-9299-E77049B5E490}.Release|Any CPU.ActiveCfg = Release|Any CPU + {43FC73FD-1EE6-4B68-9299-E77049B5E490}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B6C27BFF-4D28-4CB3-954C-F3B6C100B5EC} + EndGlobalSection +EndGlobal diff --git a/CarParkValidationAPI/.config/dotnet-tools.json b/CarParkValidationAPI/.config/dotnet-tools.json new file mode 100644 index 0000000..06b8682 --- /dev/null +++ b/CarParkValidationAPI/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "5.0.9", + "commands": [ + "dotnet-ef" + ] + } + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Authorization/AllowAnonymousAttribute.cs b/CarParkValidationAPI/Authorization/AllowAnonymousAttribute.cs new file mode 100644 index 0000000..b2ab26c --- /dev/null +++ b/CarParkValidationAPI/Authorization/AllowAnonymousAttribute.cs @@ -0,0 +1,8 @@ +using System; + +namespace CarParkValidationAPI.Authorization +{ + [AttributeUsage(AttributeTargets.Method)] + public class AllowAnonymousAttribute : Attribute + { } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Authorization/AuthorizeAttribute.cs b/CarParkValidationAPI/Authorization/AuthorizeAttribute.cs new file mode 100644 index 0000000..d3ac7af --- /dev/null +++ b/CarParkValidationAPI/Authorization/AuthorizeAttribute.cs @@ -0,0 +1,38 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using System; +using System.Collections.Generic; +using System.Linq; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Models; + +namespace CarParkValidationAPI.Authorization +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] + public class AuthorizeAttribute : Attribute, IAuthorizationFilter + { + private readonly IList _roles; + + public AuthorizeAttribute(params AdminRole[] roles) + { + _roles = roles ?? new AdminRole[] { }; + } + + public void OnAuthorization(AuthorizationFilterContext context) + { + // skip authorization if action is decorated with [AllowAnonymous] attribute + var allowAnonymous = context.ActionDescriptor.EndpointMetadata.OfType().Any(); + if (allowAnonymous) + return; + + // authorization + var user = (User)context.HttpContext.Items["User"]; + if (user == null || (_roles.Any() && !_roles.Contains(user.Role))) + { + // not logged in or role not authorized + context.Result = new JsonResult(new { message = "Unauthorized" }) { StatusCode = StatusCodes.Status401Unauthorized }; + } + } + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Authorization/JwtMiddleware.cs b/CarParkValidationAPI/Authorization/JwtMiddleware.cs new file mode 100644 index 0000000..488eba5 --- /dev/null +++ b/CarParkValidationAPI/Authorization/JwtMiddleware.cs @@ -0,0 +1,34 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; +using System.Linq; +using System.Threading.Tasks; +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Repository; +using CarParkValidationAPI.Interface; +namespace CarParkValidationAPI.Authorization +{ + public class JwtMiddleware + { + private readonly RequestDelegate _next; + private readonly AppSettings _appSettings; + + public JwtMiddleware(RequestDelegate next, IOptions appSettings) + { + _next = next; + _appSettings = appSettings.Value; + } + + 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) + { + // attach user to context on successful jwt validation + context.Items["User"] = userService.GetById(userId.Value); + } + + await _next(context); + } + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Authorization/JwtUtils.cs b/CarParkValidationAPI/Authorization/JwtUtils.cs new file mode 100644 index 0000000..8850fc5 --- /dev/null +++ b/CarParkValidationAPI/Authorization/JwtUtils.cs @@ -0,0 +1,76 @@ +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; +using System; +using System.IdentityModel.Tokens.Jwt; +using System.Linq; +using System.Security.Claims; +using System.Text; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Interface; +using CarParkValidationAPI.Models; + +namespace CarParkValidationAPI.Authorization +{ + + + public class JwtUtils : IJwtUtils + { + private readonly AppSettings _appSettings; + + public JwtUtils(IOptions appSettings) + { + _appSettings = appSettings.Value; + } + + public string GenerateJwtToken(User user) + { + // generate token that is valid for 2 days + var tokenHandler = new JwtSecurityTokenHandler(); + var key = Encoding.ASCII.GetBytes(_appSettings.Secret); + var tokenDescriptor = new SecurityTokenDescriptor + { + Subject = new ClaimsIdentity(new[] { + new Claim("id", user.Id.ToString()) + //add more if we need it + } + ), + Expires = DateTime.UtcNow.AddDays(2), + SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) + }; + var token = tokenHandler.CreateToken(tokenDescriptor); + return tokenHandler.WriteToken(token); + } + + public int? ValidateJwtToken(string token) + { + if (token == null) + return null; + + var tokenHandler = new JwtSecurityTokenHandler(); + var key = Encoding.ASCII.GetBytes(_appSettings.Secret); + try + { + tokenHandler.ValidateToken(token, new TokenValidationParameters + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(key), + ValidateIssuer = false, + ValidateAudience = false, + // set clockskew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later) + ClockSkew = TimeSpan.Zero + }, out SecurityToken validatedToken); + + var jwtToken = (JwtSecurityToken)validatedToken; + var userId = int.Parse(jwtToken.Claims.First(x => x.Type == "id").Value); + + // return user id from JWT token if validation successful + return userId; + } + catch + { + // return null if validation fails + return null; + } + } + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/CarParkValidationAPI.csproj b/CarParkValidationAPI/CarParkValidationAPI.csproj new file mode 100644 index 0000000..a95f862 --- /dev/null +++ b/CarParkValidationAPI/CarParkValidationAPI.csproj @@ -0,0 +1,22 @@ + + + + net5.0 + + + + + + + + + + + + + + + + + + diff --git a/CarParkValidationAPI/Controllers/AdminUserController.cs b/CarParkValidationAPI/Controllers/AdminUserController.cs new file mode 100644 index 0000000..dc17d3d --- /dev/null +++ b/CarParkValidationAPI/Controllers/AdminUserController.cs @@ -0,0 +1,60 @@ +using Microsoft.AspNetCore.Mvc; +using CarParkValidationAPI.Authorization; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Interface; +using System.Threading.Tasks; + +namespace CarParkValidationAPI.Controllers +{ +// [Authorize] + [ApiController] + [Route("api/v1/[controller]")] + public class AdminUserController : ControllerBase + { + private IAdminUser _adminUser; + public AdminUserController(IAdminUser adminUser) + { + _adminUser = adminUser; + } + + [HttpPost] + public async Task AdminUser([FromBody] AdminUserDto model) + { + var response = await _adminUser.SaveAdminUserAsync(model); + return Ok(response); + } + + [HttpGet] + public async Task AdminUser(bool onlyActive=true) + { + var retval = await _adminUser.LoadAdminUserAsync(onlyActive); + return Ok(retval); + } + + [HttpGet("{id:int}")] + public async Task AdminUser(int id) + { + /* + // only admins can access other user records + var currentUser = (User)HttpContext.Items["User"]; + if (id != currentUser.Id && currentUser.Role != Role.Admin) + return Unauthorized(new { message = "Unauthorized" }); + */ + var retval = await _adminUser.LoadAdminUserByIdAsync(id); + return Ok(retval); + } + [HttpDelete("{id:int}")] + public async Task DeleteAdminUser(int id) + { + /* + // only admins can access other user records + var currentUser = (User)HttpContext.Items["User"]; + if (id != currentUser.Id && currentUser.Role != Role.Admin) + return Unauthorized(new { message = "Unauthorized" }); + */ + var retval = await _adminUser.DeleteAdminUserAsync(id); + return Ok(retval); + } + } +} diff --git a/CarParkValidationAPI/Controllers/ConcessionTypeController.cs b/CarParkValidationAPI/Controllers/ConcessionTypeController.cs new file mode 100644 index 0000000..efa567e --- /dev/null +++ b/CarParkValidationAPI/Controllers/ConcessionTypeController.cs @@ -0,0 +1,62 @@ +using Microsoft.AspNetCore.Mvc; +using CarParkValidationAPI.Authorization; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Interface; +using System.Threading.Tasks; + +namespace CarParkValidationAPI.Controllers +{ + //[Authorize] + [ApiController] + [Route("api/v1/[controller]")] + public class ConcessionTypeController : ControllerBase + { + private IConcessionType _concessionType; + + public ConcessionTypeController(IConcessionType concessionType) + { + _concessionType = concessionType; + } + + [HttpPost] + public async Task ConcessionType([FromBody] ConcessionTypeDto model) + { + var response = await _concessionType.SaveConcessionTypeAsync(model); + return Ok(response); + } + + + [HttpGet] + public async Task ConcessionType(bool onlyActive =true) + { + var retval = await _concessionType.LoadConcessionTypeAsync(onlyActive); + return Ok(retval); + } + + [HttpGet("{id:int}")] + public async Task ConcessionType(int id) + { + /* + // only admins can access other user records + var currentUser = (User)HttpContext.Items["User"]; + if (id != currentUser.Id && currentUser.Role != Role.Admin) + return Unauthorized(new { message = "Unauthorized" }); + */ + var retval = await _concessionType.LoadConcessionTypeByIdAsync(id); + return Ok(retval); + } + [HttpDelete("{id:int}")] + public async Task DeleteConcessionType(int id) + { + /* + // only admins can access other user records + var currentUser = (User)HttpContext.Items["User"]; + if (id != currentUser.Id && currentUser.Role != Role.Admin) + return Unauthorized(new { message = "Unauthorized" }); + */ + var retval = await _concessionType.DeleteConcessionTypeAsync(id); + return Ok(retval); + } + } +} diff --git a/CarParkValidationAPI/Controllers/ConcessionValidationController.cs b/CarParkValidationAPI/Controllers/ConcessionValidationController.cs new file mode 100644 index 0000000..e3751c9 --- /dev/null +++ b/CarParkValidationAPI/Controllers/ConcessionValidationController.cs @@ -0,0 +1,91 @@ +using Microsoft.AspNetCore.Mvc; +using CarParkValidationAPI.Authorization; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Interface; +using System.Threading.Tasks; +using System; +using Microsoft.AspNetCore.StaticFiles; + +namespace CarParkValidationAPI.Controllers +{ + // [Authorize] + [ApiController] + [Route("api/v1/[controller]")] + public class ConcessionValidationController : ControllerBase + { + private IConcessionValidation _concessionValidation; + private readonly FileExtensionContentTypeProvider _contentTypeProvider; + public ConcessionValidationController(IConcessionValidation concessionValidation) + { + _concessionValidation = concessionValidation; + } + + + [HttpPost] + public async Task ConcessionValidation([FromBody] ConcessionValidationDto model) + { + var response = await _concessionValidation.SaveConcessionValidationAsync(model); + return Ok(response); + } + + + [HttpGet] + public async Task ConcessionValidation(bool onlyActive=true) + { + var retval = await _concessionValidation.LoadConcessionValidationAsync(onlyActive); + return Ok(retval); + } + + [HttpGet("[action]")] + public async Task ConcessionValidationByStaff(string staffLinkNo, DateTime currentDate) + { + var retval = await _concessionValidation.LoadConcessionValidationStaffLinkNoAsync(staffLinkNo, currentDate); + return Ok(retval); + } + + [HttpGet("{id:int}")] + public async Task ConcessionValidation(int id) + { + /* + // only admins can access other user records + var currentUser = (User)HttpContext.Items["User"]; + if (id != currentUser.Id && currentUser.Role != Role.Admin) + return Unauthorized(new { message = "Unauthorized" }); + */ + var retval = await _concessionValidation.LoadConcessionValidationByIdAsync(id); + return Ok(retval); + } + [HttpDelete("{id:int}")] + public async Task DeleteConcessionValidation(int id) + { + /* + // only admins can access other user records + var currentUser = (User)HttpContext.Items["User"]; + if (id != currentUser.Id && currentUser.Role != Role.Admin) + return Unauthorized(new { message = "Unauthorized" }); + */ + var retval = await _concessionValidation.DeleteConcessionValidationAsync(id); + return Ok(retval); + } + /* download the excel file */ + [HttpGet("[action]")] + + public async Task GetReportFile(DateTime fromDate , DateTime toDate) + { + var result = await _concessionValidation.GetReport(fromDate, toDate); + string fileContentType = Map(result.Data.FileName); + return File(result.Data.Content, fileContentType, result.Data.FileName); + } + + [NonAction] + private string Map(string fileName) + { + if (!_contentTypeProvider.TryGetContentType(fileName, out string contentType)) + { + contentType = "application/octet-stream"; + } + return contentType; + } + } +} diff --git a/CarParkValidationAPI/Controllers/LookupCodeController.cs b/CarParkValidationAPI/Controllers/LookupCodeController.cs new file mode 100644 index 0000000..8463319 --- /dev/null +++ b/CarParkValidationAPI/Controllers/LookupCodeController.cs @@ -0,0 +1,37 @@ +using Microsoft.AspNetCore.Mvc; +using CarParkValidationAPI.Authorization; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Interface; +using System.Threading.Tasks; + +namespace CarParkValidationAPI.Controllers +{ + // [Authorize] + [ApiController] + [Route("api/v1/[controller]")] + public class LookupCodeController : ControllerBase + { + private readonly ILookupCode _lookupCodeService; + + public LookupCodeController(ILookupCode lookupCode) + { + _lookupCodeService = lookupCode; + } + + [HttpGet("[action]")] + public async Task ConcessionTypes(bool onlyActive=true) + { + var retval = await _lookupCodeService.LoadConcessionTypeAsync(onlyActive); + return Ok(retval); + } + [HttpGet("[action]")] + public async Task ValidationPoints(bool onlyActive= true) + { + var retval = await _lookupCodeService.LoadValidationPointAsync(onlyActive); + return Ok(retval); + } + + + } +} diff --git a/CarParkValidationAPI/Controllers/UsersController.cs b/CarParkValidationAPI/Controllers/UsersController.cs new file mode 100644 index 0000000..3f806c1 --- /dev/null +++ b/CarParkValidationAPI/Controllers/UsersController.cs @@ -0,0 +1,82 @@ +using Microsoft.AspNetCore.Mvc; +using CarParkValidationAPI.Authorization; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Models.Users; +using CarParkValidationAPI.Interface; +using System.Threading.Tasks; +using CarParkValidationAPI.Models; + +namespace CarParkValidationAPI.Controllers +{ + [Authorize] + [ApiController] + [Route("api/v1/[controller]")] + public class UsersController : ControllerBase + { + private IUserService _userService; + + public UsersController(IUserService userService) + { + _userService = userService; + } + + [AllowAnonymous] + [HttpPost("[action]")] + public IActionResult Authenticate(AuthenticateRequest model) + { + var response = _userService.Authenticate(model); + + + return Ok(response); + } + [AllowAnonymous] + [HttpPost("[action]")] + public async Task LoginAD(AuthenticateRequest model) + { + var response = await _userService.LoginAD(model); + return Ok(response); + } + [AllowAnonymous] + [HttpPost("[action]")] + public async Task LoginApiAD(AuthenticateRequest model) + { + var response = await _userService.LoginApiAD(model); + return Ok(response); + } + [AllowAnonymous] + [HttpGet("[action]")] + public async Task SearchApiStaff(string stafflinkNo) + { + var user = await _userService.SearchApiStaff(stafflinkNo); + return Ok(user); + } + + [AllowAnonymous] + [HttpGet("[action]")] + public async Task> SearchADStaff(string stafflinkNo) + { + var user = await _userService.SearchADStaff(stafflinkNo); + return user; + } + + [Authorize(AdminRole.Admin)] + [HttpGet] + public async Task GetAllUsers() + { + var users = await _userService.GetAllUsers(); + return Ok(users); + } + + [HttpGet("{id:int}")] + public async Task GetById(int id) + { + // only admins can access other user records + var currentUser = (User)HttpContext.Items["User"]; + if (id != currentUser.Id && currentUser.Role != AdminRole.Admin) + return Unauthorized(new { message = "Unauthorized" }); + + var user = await _userService.GetById(id); + return Ok(user); + } + } +} diff --git a/CarParkValidationAPI/Controllers/ValidationPointController.cs b/CarParkValidationAPI/Controllers/ValidationPointController.cs new file mode 100644 index 0000000..ff87217 --- /dev/null +++ b/CarParkValidationAPI/Controllers/ValidationPointController.cs @@ -0,0 +1,63 @@ +using Microsoft.AspNetCore.Mvc; +using CarParkValidationAPI.Authorization; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Interface; +using System.Threading.Tasks; + +namespace CarParkValidationAPI.Controllers +{ + /* [Authorize] */ + [ApiController] + [Route("api/v1/[controller]")] + public class ValidationPointController : ControllerBase + { + private IValidationPoint _validationPoint; + + public ValidationPointController(IValidationPoint validationPoint) + { + _validationPoint = validationPoint; + } + + + [HttpPost] + public async Task ValidationPoint([FromBody] ValidationPointDto model) + { + var response = await _validationPoint.SaveValidationPointAsync(model); + return Ok(response); + } + + + [HttpGet] + public async Task ValidationPoint(bool onlyActive=true) + { + var retval = await _validationPoint.LoadValidationPointAsync(onlyActive); + return Ok(retval); + } + + [HttpGet("{id:int}")] + public async Task ValidationPoint(int id) + { + /* + // only admins can access other user records + var currentUser = (User)HttpContext.Items["User"]; + if (id != currentUser.Id && currentUser.Role != Role.Admin) + return Unauthorized(new { message = "Unauthorized" }); + */ + var retval = await _validationPoint.LoadValidationPointByIdAsync(id); + return Ok(retval); + } + [HttpDelete("{id:int}")] + public async Task DeleteConcessionType(int id) + { + /* + // only admins can access other user records + var currentUser = (User)HttpContext.Items["User"]; + if (id != currentUser.Id && currentUser.Role != Role.Admin) + return Unauthorized(new { message = "Unauthorized" }); + */ + var retval = await _validationPoint.DeleteValidationPointAsync(id); + return Ok(retval); + } + } +} diff --git a/CarParkValidationAPI/Datas/DataContext.cs b/CarParkValidationAPI/Datas/DataContext.cs new file mode 100644 index 0000000..f32a82a --- /dev/null +++ b/CarParkValidationAPI/Datas/DataContext.cs @@ -0,0 +1,179 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Models; +using Microsoft.Extensions.Options; +using Microsoft.Data.SqlClient; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.Data; +using System.Data.Common; + +namespace CarParkValidationAPI.Datas +{ + public class DataContext : DbContext + { + public DbSet Users { get; set; } + public DbSet AdminUsers { get; set; } + public DbSet Validations { get; set; } + public DbSet ConcessionValidations { get; set; } + + public DbSet ConcessionTypes { get; set; } + private readonly IConfiguration Configuration; + private IOptions _appSettings; + public DataContext(IConfiguration configuration, IOptions appSettings) + { + Configuration = configuration; + _appSettings = appSettings; + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity().ToTable("ValidationPoint"); + modelBuilder.Entity().ToTable("ConcessionValidation"); + + modelBuilder.Entity().ToTable("ConcessionType"); + modelBuilder.Entity().ToTable("AdminUser"); + + } + + protected override void OnConfiguring(DbContextOptionsBuilder options) + { + // in memory database used for simplicity, change to a real db for production applications + // options.UseInMemoryDatabase("TestDb"); + + options.UseSqlServer(_appSettings.Value.SQLConnectionString); + } + + private ConcessionValidationExtDto PopulateItem(IDataReader reader) + { + ConcessionValidationExtDto item = new ConcessionValidationExtDto(); + object myobj; + myobj = reader["ValidationID"]; + if (myobj != System.DBNull.Value) + item.Id = (int)myobj; + + myobj = reader["ValidateDate"]; + if (myobj != System.DBNull.Value) + item.ValidateDate = (DateTime)myobj; + + myobj = reader["ConcessionCard"]; + if (myobj != System.DBNull.Value) + item.ConcessionCard = (string)myobj; + + myobj = reader["ConcessionHolder"]; + if (myobj != System.DBNull.Value) + item.ConcessionHolder = (string)myobj; + + myobj = reader["ConcessionExpiry"]; + if (myobj != System.DBNull.Value) + item.ConcessionExpiry = (bool)myobj; + /* + myobj = reader["ConcessionTypeID"]; + if (myobj != System.DBNull.Value) + item.ConcessionTypeId = (int)myobj; + */ + myobj = reader["StafflinkNo"]; + if (myobj != System.DBNull.Value) + item.StafflinkNo = (string) myobj; + + myobj = reader["ConcessionType"]; + if (myobj != System.DBNull.Value) + item.ConcessionType = (string)myobj; + + myobj = reader["ValidationPoint"]; + if (myobj != System.DBNull.Value) + item.ValidationPiont = (string)myobj; + /* + myobj = reader["ValidationPointID"]; + if (myobj != System.DBNull.Value) + item.ValidationPointId = (int)myobj; + */ + myobj = reader["Active"]; + if (myobj != System.DBNull.Value) + item.Active = (bool)myobj; + + return item; + } + public async Task> SelectConcessionValidationByStaffId(bool activeOnly, string stafflinkNo, DateTime fromDate, DateTime toDate) + { + var pfromDate = new SqlParameter + { + ParameterName = "fromDate", + Value = fromDate.Date + }; + var pStaffLink = new SqlParameter + { + ParameterName = "StafflinkNo", + Value = stafflinkNo + }; + + var pToDate = new SqlParameter + { + ParameterName = "toDate", + Value = toDate.Date + }; + ConcessionValidationExtDto item; + List result = new List(); + using (var command = this.Database.GetDbConnection().CreateCommand()) + { + command.CommandType = CommandType.StoredProcedure; + command.CommandText = ("capv_ConValidation_Sel"); + command.Parameters.Add(pfromDate); + command.Parameters.Add(pToDate); + command.Parameters.Add(pStaffLink); + this.Database.OpenConnection(); + using (DbDataReader reader = await command.ExecuteReaderAsync()) + { + while (await reader.ReadAsync()) + { + item = PopulateItem(reader); + result.Add(item); + } + } + } + + return result; + + } + + public async Task> SelectConcessionValidationByDate(bool activeOnly, DateTime fromDate, DateTime toDate) + { + var pfromDate = new SqlParameter + { + ParameterName = "fromDate", + Value = fromDate.Date + }; + + + var pToDate = new SqlParameter + { + ParameterName = "toDate", + Value = toDate.Date + }; + ConcessionValidationExtDto item; + List result = new List(); + using (var command = this.Database.GetDbConnection().CreateCommand()) + { + command.CommandType = CommandType.StoredProcedure; + command.CommandText = ("capv_ConValidationDate_Sel"); + command.Parameters.Add(pfromDate); + command.Parameters.Add(pToDate); + + this.Database.OpenConnection(); + using (DbDataReader reader = await command.ExecuteReaderAsync()) + { + while (await reader.ReadAsync()) + { + item = PopulateItem(reader); + result.Add(item); + } + } + } + + return result; + + } + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Entities/AdminUserDto.cs b/CarParkValidationAPI/Entities/AdminUserDto.cs new file mode 100644 index 0000000..571e076 --- /dev/null +++ b/CarParkValidationAPI/Entities/AdminUserDto.cs @@ -0,0 +1,26 @@ +using CarParkValidationAPI.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace CarParkValidationAPI.Entities +{ + public class AdminUserDto + { + #region public Member + public int Id { get; set; } + public string StafflinkNo { get; set; } + + public string Name { get; set; } + + public string AddedBy { get; set; } + + public DateTime AddedOn { get; set; } + + public bool Active { get; set; } + + public AdminRole RoleType { get; set; } + #endregion + } +} diff --git a/CarParkValidationAPI/Entities/ConcessionTypeDto.cs b/CarParkValidationAPI/Entities/ConcessionTypeDto.cs new file mode 100644 index 0000000..1751a7f --- /dev/null +++ b/CarParkValidationAPI/Entities/ConcessionTypeDto.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace CarParkValidationAPI.Entities +{ + public class ConcessionTypeDto + { + #region public Member + + public int Id { get; set; } + public string Description { get; set; } + + public string Display { get; set; } + + public bool Active { get; set; } + #endregion + } +} diff --git a/CarParkValidationAPI/Entities/ConcessionValidationDto.cs b/CarParkValidationAPI/Entities/ConcessionValidationDto.cs new file mode 100644 index 0000000..1229acc --- /dev/null +++ b/CarParkValidationAPI/Entities/ConcessionValidationDto.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace CarParkValidationAPI.Entities +{ + public class ConcessionValidationExtDto: ConcessionValidationDto + { + public string ConcessionType { get; set; } + public string ValidationPiont { get; set; } + + + } + public partial class ConcessionValidationDto + { + #region public Member + + public int Id { get; set; } + public DateTime ValidateDate { get; set; } + + public string ConcessionCard { get; set; } + + public string ConcessionHolder { get; set; } + + public bool ConcessionExpiry { get; set; } + + public int ConcessionTypeId { get; set; } + + public string StafflinkNo { get; set; } + + public int ValidationPointId { get; set; } + + public bool Active { get; set; } + #endregion + } +} diff --git a/CarParkValidationAPI/Entities/FileContent.cs b/CarParkValidationAPI/Entities/FileContent.cs new file mode 100644 index 0000000..9bc23d1 --- /dev/null +++ b/CarParkValidationAPI/Entities/FileContent.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace CarParkValidationAPI.Entities +{ + public class FileContent + { + public byte[] Content { get; set; } + public string FileName { get; set; } + } +} diff --git a/CarParkValidationAPI/Entities/LookupCodeDto.cs b/CarParkValidationAPI/Entities/LookupCodeDto.cs new file mode 100644 index 0000000..217644a --- /dev/null +++ b/CarParkValidationAPI/Entities/LookupCodeDto.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace CarParkValidationAPI.Entities +{ + public class LookupCodeDto + { + public int Id + { + get; set; + } + public string Description + { + get; set; + } + + } +} diff --git a/CarParkValidationAPI/Entities/Role.cs b/CarParkValidationAPI/Entities/Role.cs new file mode 100644 index 0000000..f000a23 --- /dev/null +++ b/CarParkValidationAPI/Entities/Role.cs @@ -0,0 +1,8 @@ +namespace CarParkValidationAPI.Entities +{ + public enum Role + { + Admin, + User + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Entities/ValidationPointDto.cs b/CarParkValidationAPI/Entities/ValidationPointDto.cs new file mode 100644 index 0000000..0a8c59e --- /dev/null +++ b/CarParkValidationAPI/Entities/ValidationPointDto.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace CarParkValidationAPI.Entities +{ + public class ValidationPointDto + { + + #region public Member + + public int Id { get; set; } + [Required] + public string Description { get; set; } + + public string Display { get; set; } + + public bool Active { get; set; } + #endregion + + } +} diff --git a/CarParkValidationAPI/Helpers/ErrorHandlerMiddleware.cs b/CarParkValidationAPI/Helpers/ErrorHandlerMiddleware.cs new file mode 100644 index 0000000..0dcdefb --- /dev/null +++ b/CarParkValidationAPI/Helpers/ErrorHandlerMiddleware.cs @@ -0,0 +1,51 @@ +using Microsoft.AspNetCore.Http; +using System; +using System.Collections.Generic; +using System.Net; +using System.Text.Json; +using System.Threading.Tasks; + +namespace CarParkValidationAPI.Helpers +{ + public class ErrorHandlerMiddleware + { + private readonly RequestDelegate _next; + + public ErrorHandlerMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task Invoke(HttpContext context) + { + try + { + await _next(context); + } + catch (Exception error) + { + var response = context.Response; + response.ContentType = "application/json"; + + switch(error) + { + // case Exception e: + // // custom application error + // response.StatusCode = (int)HttpStatusCode.BadRequest; + // break; + case KeyNotFoundException e: + // not found error + response.StatusCode = (int)HttpStatusCode.NotFound; + break; + default: + // unhandled error + response.StatusCode = (int)HttpStatusCode.InternalServerError; + break; + } + + var result = JsonSerializer.Serialize(new { message = error?.Message }); + await response.WriteAsync(result); + } + } + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Interface/IAdminUser.cs b/CarParkValidationAPI/Interface/IAdminUser.cs new file mode 100644 index 0000000..80a2ff0 --- /dev/null +++ b/CarParkValidationAPI/Interface/IAdminUser.cs @@ -0,0 +1,18 @@ +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + + +namespace CarParkValidationAPI.Interface +{ + public interface IAdminUser + { + Task>> LoadAdminUserAsync(bool OnlyActive); + Task> SaveAdminUserAsync(AdminUserDto item); + Task> LoadAdminUserByIdAsync(int id); + Task> DeleteAdminUserAsync(int id); + } +} diff --git a/CarParkValidationAPI/Interface/IConcessionType.cs b/CarParkValidationAPI/Interface/IConcessionType.cs new file mode 100644 index 0000000..557bd2a --- /dev/null +++ b/CarParkValidationAPI/Interface/IConcessionType.cs @@ -0,0 +1,18 @@ +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + + +namespace CarParkValidationAPI.Interface +{ + public interface IConcessionType + { + Task>> LoadConcessionTypeAsync(bool OnlyActive); + Task> SaveConcessionTypeAsync(ConcessionTypeDto item); + Task> LoadConcessionTypeByIdAsync(int id); + Task> DeleteConcessionTypeAsync(int id); + } +} diff --git a/CarParkValidationAPI/Interface/IConcessionValidation.cs b/CarParkValidationAPI/Interface/IConcessionValidation.cs new file mode 100644 index 0000000..b8ca175 --- /dev/null +++ b/CarParkValidationAPI/Interface/IConcessionValidation.cs @@ -0,0 +1,20 @@ +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + + +namespace CarParkValidationAPI.Interface +{ + public interface IConcessionValidation + { + Task>> LoadConcessionValidationAsync(bool OnlyActive); + Task>> LoadConcessionValidationStaffLinkNoAsync(string staffLinkNo, DateTime currentDate); + Task> SaveConcessionValidationAsync(ConcessionValidationDto item); + Task> LoadConcessionValidationByIdAsync(int id); + Task> DeleteConcessionValidationAsync(int id); + Task> GetReport(DateTime fromDate, DateTime toDate); + } +} diff --git a/CarParkValidationAPI/Interface/IJwtUtils.cs b/CarParkValidationAPI/Interface/IJwtUtils.cs new file mode 100644 index 0000000..c899db0 --- /dev/null +++ b/CarParkValidationAPI/Interface/IJwtUtils.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using CarParkValidationAPI.Interface; +using CarParkValidationAPI.Models; + + +namespace CarParkValidationAPI.Interface +{ + public interface IJwtUtils + { + public string GenerateJwtToken(User user); + public int? ValidateJwtToken(string token); + } +} diff --git a/CarParkValidationAPI/Interface/ILookupCode.cs b/CarParkValidationAPI/Interface/ILookupCode.cs new file mode 100644 index 0000000..642760a --- /dev/null +++ b/CarParkValidationAPI/Interface/ILookupCode.cs @@ -0,0 +1,17 @@ +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + + +namespace CarParkValidationAPI.Interface +{ + public interface ILookupCode + { + Task>> LoadConcessionTypeAsync(bool OnlyActive); + Task>> LoadValidationPointAsync(bool OnlyActive); + + } +} diff --git a/CarParkValidationAPI/Interface/IUser.cs b/CarParkValidationAPI/Interface/IUser.cs new file mode 100644 index 0000000..8a6b9fd --- /dev/null +++ b/CarParkValidationAPI/Interface/IUser.cs @@ -0,0 +1,21 @@ +using CarParkValidationAPI.Models.Users; +using CarParkValidationAPI.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using CarParkValidationAPI.Models; + +namespace CarParkValidationAPI.Interface +{ + public interface IUserService + { + AuthenticateResponse Authenticate(AuthenticateRequest model); + Task> LoginApiAD(AuthenticateRequest model); + Task> LoginAD(AuthenticateRequest model); + Task>> GetAllUsers(); + Task> GetById(int id); + Task> SearchApiStaff(string staffLinkNo); + Task> SearchADStaff(string staffLinkNo); + } +} diff --git a/CarParkValidationAPI/Interface/IValidationPoint.cs b/CarParkValidationAPI/Interface/IValidationPoint.cs new file mode 100644 index 0000000..594fb68 --- /dev/null +++ b/CarParkValidationAPI/Interface/IValidationPoint.cs @@ -0,0 +1,18 @@ +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + + +namespace CarParkValidationAPI.Interface +{ + public interface IValidationPoint + { + Task>> LoadValidationPointAsync(bool OnlyActive); + Task> SaveValidationPointAsync(ValidationPointDto item); + Task> LoadValidationPointByIdAsync(int id); + Task> DeleteValidationPointAsync(int id); + } +} diff --git a/CarParkValidationAPI/Models/AdminUser.cs b/CarParkValidationAPI/Models/AdminUser.cs new file mode 100644 index 0000000..2118aad --- /dev/null +++ b/CarParkValidationAPI/Models/AdminUser.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using System.Runtime.Serialization; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace CarParkValidationAPI.Models +{ + public enum AdminRole + { + Normal = 1, + Admin = 2 + } + public partial class AdminUserCriteria + { + public AdminUserCriteria() + { + } + #region public Member + + public int? UserID { get; set; } + + public int? StafflinkNo { get; set; } + + public string Name { get; set; } + + public string AddedBy { get; set; } + + public DateTime? AddedOn { get; set; } + + public bool? Active { get; set; } + + public int? RoleType { get; set; } + #endregion + } + [Table("AdminUser")] + public partial class AdminUser + { + public AdminUser() + { + } + #region public Member + [Key] + public int UserID { get; set; } + public string StafflinkNo { get; set; } + + public string Name { get; set; } + + public string AddedBy { get; set; } + + public DateTime AddedOn { get; set; } + + public bool Active { get; set; } + + public AdminRole RoleType { get; set; } + #endregion + } +} diff --git a/CarParkValidationAPI/Models/AppSettings.cs b/CarParkValidationAPI/Models/AppSettings.cs new file mode 100644 index 0000000..5b51adc --- /dev/null +++ b/CarParkValidationAPI/Models/AppSettings.cs @@ -0,0 +1,28 @@ +using System; + +namespace CarParkValidationAPI.Models +{ + public class AppSettings + { + public string Secret { get; set; } + public string SQLConnectionString { get; set; } + public string LDAPPath { get; set; } + public string LDAPUser { get; set; } + public string LDAPPassword { get; set; } + + public string LoginWebAPI { get; set; } + /// + /// for convert to time. use GetADTimeOut + /// TimeSpan.FromSeconds(Convert.ToDouble(ConfigurationManager.AppSettings["ADTimeOut"])); + public string ADTimeOut { get; set; } + + public TimeSpan GetADTimeOut() + { + if (!string.IsNullOrEmpty(ADTimeOut)) + return TimeSpan.FromSeconds(Convert.ToDouble(ADTimeOut)); + else + return TimeSpan.FromSeconds(0); + } + + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Models/ConcessionType.cs b/CarParkValidationAPI/Models/ConcessionType.cs new file mode 100644 index 0000000..29a1ccb --- /dev/null +++ b/CarParkValidationAPI/Models/ConcessionType.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using System.Runtime.Serialization; +using System.ComponentModel.DataAnnotations; + +namespace CarParkValidationAPI.Models +{ + public partial class ConcessionType + { + public ConcessionType() + { + } + #region public Member + [Key] + public int ConcessionTypeID { get; set; } + public string ConcessionDesc { get; set; } + + public string ConcessionDisplay { get; set; } + + public bool Active { get; set; } + #endregion + } +} diff --git a/CarParkValidationAPI/Models/ConcessionValidation.cs b/CarParkValidationAPI/Models/ConcessionValidation.cs new file mode 100644 index 0000000..7f2485e --- /dev/null +++ b/CarParkValidationAPI/Models/ConcessionValidation.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using System.Runtime.Serialization; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace CarParkValidationAPI.Models +{ + [NotMapped] + public class ConcessionValidationExt: ConcessionValidation + { + #region public Member + public string ConcessionType { get; set; } + public string ValidationPiont { get; set; } + + #endregion + } + public partial class ConcessionValidation + { + public ConcessionValidation() + { + } + + #region public Member + [Key] + public int ValidationID { get; set; } + public DateTime ValidateDate { get; set; } + + public string ConcessionCard { get; set; } + + public string ConcessionHolder { get; set; } + + public bool ConcessionExpiry { get; set; } + + public int ConcessionTypeID { get; set; } + + public string StafflinkNo { get; set; } + + public int ValidationPointID { get; set; } + + public bool Active { get; set; } + #endregion + } +} diff --git a/CarParkValidationAPI/Models/ResultModel.cs b/CarParkValidationAPI/Models/ResultModel.cs new file mode 100644 index 0000000..536c496 --- /dev/null +++ b/CarParkValidationAPI/Models/ResultModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace CarParkValidationAPI.Models +{ + public class ResultModel + { + public T Data { get; set; } + public int StatusCode { get; set; } + public string Message { get; set; } + } +} diff --git a/CarParkValidationAPI/Models/User.cs b/CarParkValidationAPI/Models/User.cs new file mode 100644 index 0000000..e567495 --- /dev/null +++ b/CarParkValidationAPI/Models/User.cs @@ -0,0 +1,17 @@ +using System.Text.Json.Serialization; + +namespace CarParkValidationAPI.Models +{ + public class User + { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Email { get; set; } + public string Username { get; set; } + public AdminRole Role { get; set; } + + [JsonIgnore] + public string PasswordHash { get; set; } + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Models/Users/AuthenticateRequest.cs b/CarParkValidationAPI/Models/Users/AuthenticateRequest.cs new file mode 100644 index 0000000..86410f2 --- /dev/null +++ b/CarParkValidationAPI/Models/Users/AuthenticateRequest.cs @@ -0,0 +1,13 @@ +using System.ComponentModel.DataAnnotations; + +namespace CarParkValidationAPI.Models.Users +{ + public class AuthenticateRequest + { + [Required] + public string Username { get; set; } + + [Required] + public string Password { get; set; } + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Models/Users/AuthenticateResponse.cs b/CarParkValidationAPI/Models/Users/AuthenticateResponse.cs new file mode 100644 index 0000000..9f166aa --- /dev/null +++ b/CarParkValidationAPI/Models/Users/AuthenticateResponse.cs @@ -0,0 +1,24 @@ +using CarParkValidationAPI.Entities; + +namespace CarParkValidationAPI.Models.Users +{ + public class AuthenticateResponse + { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Username { get; set; } + public AdminRole Role { get; set; } + public string Token { get; set; } + + public AuthenticateResponse(User user, string token) + { + Id = user.Id; + FirstName = user.FirstName; + LastName = user.LastName; + Username = user.Username; + Role = user.Role; + Token = token; + } + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Models/ValidationPoint.cs b/CarParkValidationAPI/Models/ValidationPoint.cs new file mode 100644 index 0000000..8e23cf6 --- /dev/null +++ b/CarParkValidationAPI/Models/ValidationPoint.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using System.Runtime.Serialization; +using System.ComponentModel.DataAnnotations; + +namespace CarParkValidationAPI.Models +{ + + + public class ValidationPoint + { + [Key] + public int ValidationPointID { get; set; } + public string Description { get; set; } + + public string DisplayName { get; set; } + + public bool Active { get; set; } + + + } +} diff --git a/CarParkValidationAPI/Program.cs b/CarParkValidationAPI/Program.cs new file mode 100644 index 0000000..c0619e1 --- /dev/null +++ b/CarParkValidationAPI/Program.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace CarParkValidationAPI +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } +} diff --git a/CarParkValidationAPI/Properties/launchSettings.json b/CarParkValidationAPI/Properties/launchSettings.json new file mode 100644 index 0000000..4afabc6 --- /dev/null +++ b/CarParkValidationAPI/Properties/launchSettings.json @@ -0,0 +1,35 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iis": { + "applicationUrl": "http://localhost/CarParkValidationAPI", + "sslPort": 0 + }, + "iisExpress": { + "applicationUrl": "http://localhost:61744", + "sslPort": 0 + } + }, + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "api/v1/LookupCode/ConcessionTypes", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "CarParkValidationAPI": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": "true", + "applicationUrl": "http://localhost:5100" + } + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Repository/AdminUserFakeRepository.cs b/CarParkValidationAPI/Repository/AdminUserFakeRepository.cs new file mode 100644 index 0000000..66c686d --- /dev/null +++ b/CarParkValidationAPI/Repository/AdminUserFakeRepository.cs @@ -0,0 +1,199 @@ +//using BCryptNet = BCrypt.Net.BCrypt; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using CarParkValidationAPI.Authorization; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Helpers; +using CarParkValidationAPI.Models.Users; +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Datas; +using CarParkValidationAPI.Interface; +using Microsoft.EntityFrameworkCore; +using System; + +namespace CarParkValidationAPI.Repository +{ + public class AdminUserFakeRepository : IAdminUser + { + private DataContext _context; + List _resultList = new List(); + private readonly AppSettings _appSettings; + + + public AdminUserFakeRepository( + DataContext context, + + IOptions appSettings) + { + _context = context; + _appSettings = appSettings.Value; + } + + private AdminUserDto FillAdminUserDto(AdminUser model) + { + AdminUserDto dto = new AdminUserDto(); + dto.Id = model.UserID; + dto.Name = model.Name; + dto.RoleType = model.RoleType; + dto.StafflinkNo = model.StafflinkNo; + dto.Active = model.Active; + dto.AddedBy = model.AddedBy; + dto.AddedOn = model.AddedOn; + return dto; + } + + private AdminUser FillAdminUser(AdminUserDto dto, AdminUser model) + { + + model.UserID = dto.Id; + model.Name = dto.Name; + model.RoleType = dto.RoleType; + model.StafflinkNo = dto.StafflinkNo; + model.Active = dto.Active; + model.AddedBy = dto.AddedBy; + model.AddedOn = dto.AddedOn; + return model; + } + + public async Task>> LoadAdminUserAsync(bool onlyActive) + { + /* + List resultList = new List(); + try + { + var it = await _context.AdminUsers.AsQueryable().ToListAsync(); + + AdminUserDto dto; + for (int i = 0; i < it.Count; i++) + { + dto = FillAdminUserDto(it[i]); + resultList.Add(dto); + } + //var it = await Task.Run(() => _list); + + return new ResultModel>() + { + Data = resultList, + StateCode = 1 + }; + + } + catch (Exception ex) + { + throw ex; + } + */ + for (int i =0; i < 10; i++) + { + AdminUserDto dto = new AdminUserDto(); + dto.Id = i; + dto.Name = $"Name {i}"; + dto.RoleType = AdminRole.Admin; + dto.StafflinkNo = $"{i+40000}"; + dto.Active = true; + dto.AddedOn = DateTime.Today.AddDays(i); + dto.AddedBy = "ddfed"; + _resultList.Add(dto); + } + return new ResultModel>() + { + Data = _resultList, + StatusCode = 1 + }; + } + public async Task> LoadAdminUserByIdAsync(int id) + { + AdminUserDto result = null; + /* + try + { + if (id > 0) + { + AdminUser model = await _context.AdminUsers.FindAsync(id); + result = FillAdminUserDto(model); + + } + } + catch (Exception ex) + { + throw ex; + } + */ + int idx = _resultList.FindIndex(x => x.Id == id); + if (idx > -1) + { + result = _resultList[idx]; + } + + return new ResultModel() + { + Data = result, + StatusCode = 1 + }; + } + public async Task> SaveAdminUserAsync(AdminUserDto item) + { + int result = default(int); + try + { + AdminUser model; + if (item.Id > 0) + { + model = await _context.AdminUsers.FindAsync(item.Id); + model = FillAdminUser(item, model); + await _context.SaveChangesAsync(); + } + else + { + model = new AdminUser(); + model = FillAdminUser(item, model); + _context.AdminUsers.Add(model); + await _context.SaveChangesAsync(); + } + result = 1; + } + catch (Exception ex) + { + result = -1; + throw ex; + } + + return new ResultModel() + { + Data = result, + StatusCode = 1 + }; + + } + + public async Task> DeleteAdminUserAsync(int id) + { + bool result = true; + + try + { + if (id > 0) + { + AdminUser model = await _context.AdminUsers.FindAsync(id); + model.Active = false; + await _context.SaveChangesAsync(); + } + } + catch (Exception ex) + { + result = false; + throw ex; + } + + return new ResultModel() + { + Data = result, + StatusCode = 1 + }; + } + + + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Repository/AdminUserRepository.cs b/CarParkValidationAPI/Repository/AdminUserRepository.cs new file mode 100644 index 0000000..94dcafa --- /dev/null +++ b/CarParkValidationAPI/Repository/AdminUserRepository.cs @@ -0,0 +1,196 @@ +//using BCryptNet = BCrypt.Net.BCrypt; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using CarParkValidationAPI.Authorization; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Helpers; +using CarParkValidationAPI.Models.Users; +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Datas; +using CarParkValidationAPI.Interface; +using Microsoft.EntityFrameworkCore; +using System; + +namespace CarParkValidationAPI.Repository +{ + public class AdminUserRepository : IAdminUser + { + private DataContext _context; + + private readonly AppSettings _appSettings; + + + public AdminUserRepository( + DataContext context, + + IOptions appSettings) + { + _context = context; + _appSettings = appSettings.Value; + } + + private AdminUserDto FillAdminUserDto(AdminUser model) + { + AdminUserDto dto = new AdminUserDto(); + dto.Id = model.UserID; + dto.Name = model.Name; + dto.RoleType = model.RoleType; + dto.StafflinkNo = model.StafflinkNo; + dto.Active = model.Active; + dto.AddedBy = model.AddedBy; + dto.AddedOn = model.AddedOn; + return dto; + } + + private AdminUser FillAdminUser(AdminUserDto dto, AdminUser model) + { + + model.UserID = dto.Id; + model.Name = dto.Name; + model.RoleType = dto.RoleType; + model.StafflinkNo = dto.StafflinkNo; + model.Active = dto.Active; + model.AddedBy = dto.AddedBy; + model.AddedOn = dto.AddedOn; + return model; + } + + public async Task>> LoadAdminUserAsync(bool onlyActive) + { + List resultList = new List(); + int statuscode = 0; + string error = ""; + try + { + //var list = await _context.AdminUsers.Where(x => x.Active == onlyActive).ToListAsync(); + var list = await _context.AdminUsers.AsQueryable().ToListAsync(); + + AdminUserDto dto; + AdminUser user; + for (int i = 0; i < list.Count; i++) + { + user = list[i]; + dto = FillAdminUserDto(user); + resultList.Add(dto); + + } + statuscode = 1; + } + catch (Exception ex) + { + error = ex.ToString(); + statuscode = 0; + throw ex; + } + + return new ResultModel>() + { + Data = resultList, + StatusCode = statuscode, + Message = error + }; + } + public async Task> LoadAdminUserByIdAsync(int id) + { + AdminUserDto result = null; + int statuscode = 0; + string error = ""; + try + { + if (id > 0) + { + AdminUser model = await _context.AdminUsers.FindAsync(id); + result = FillAdminUserDto(model); + statuscode = 1; + } + } + catch (Exception ex) + { + error = ex.ToString(); + statuscode = 0; + throw ex; + } + + return new ResultModel() + { + Data = result, + StatusCode = statuscode, + Message = error + }; + } + public async Task> SaveAdminUserAsync(AdminUserDto item) + { + int result = default(int); + int statuscode = 0; + string error = ""; + try + { + AdminUser model; + if (item.Id > 0) + { + model = await _context.AdminUsers.FindAsync(item.Id); + model = FillAdminUser(item, model); + await _context.SaveChangesAsync(); + } + else + { + model = new AdminUser(); + model = FillAdminUser(item, model); + _context.AdminUsers.Add(model); + await _context.SaveChangesAsync(); + } + result = 1; + statuscode = 1; + } + catch (Exception ex) + { + result = -1; + error = ex.ToString(); + statuscode = 0; + throw ex; + } + + return new ResultModel() + { + Data = result, + StatusCode = statuscode, + Message = error + }; + } + + public async Task> DeleteAdminUserAsync(int id) + { + bool result = true; + int statuscode = 0; + string error = ""; + try + { + if (id > 0) + { + AdminUser model = await _context.AdminUsers.FindAsync(id); + model.Active = false; + await _context.SaveChangesAsync(); + statuscode = 1; + } + } + catch (Exception ex) + { + error = ex.ToString(); + statuscode = 0; + result = false; + throw ex; + } + + return new ResultModel() + { + Data = result, + StatusCode = statuscode, + Message = error + }; + } + + + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Repository/ConcessionTypeRepository.cs b/CarParkValidationAPI/Repository/ConcessionTypeRepository.cs new file mode 100644 index 0000000..b046dae --- /dev/null +++ b/CarParkValidationAPI/Repository/ConcessionTypeRepository.cs @@ -0,0 +1,184 @@ +//using BCryptNet = BCrypt.Net.BCrypt; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using CarParkValidationAPI.Authorization; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Helpers; +using CarParkValidationAPI.Models.Users; +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Datas; +using CarParkValidationAPI.Interface; +using Microsoft.EntityFrameworkCore; +using System; + +namespace CarParkValidationAPI.Repository +{ + public class ConcessionTypeRepository : IConcessionType + { + private DataContext _context; + + private readonly AppSettings _appSettings; + + public ConcessionTypeRepository( + DataContext context, + + IOptions appSettings) + { + _context = context; + _appSettings = appSettings.Value; + } + + private ConcessionTypeDto FillConcessionTypeDto(ConcessionType model) + { + ConcessionTypeDto dto = new ConcessionTypeDto(); + dto.Active = model.Active; + dto.Description = model.ConcessionDesc; + dto.Display = model.ConcessionDisplay; + dto.Id = model.ConcessionTypeID; + return dto; + } + private ConcessionType FillConcessionType(ConcessionTypeDto dto, ConcessionType model) + { + model.Active = dto.Active; + model.ConcessionDesc = dto.Description; + model.ConcessionDisplay = dto.Display; + model.ConcessionTypeID = dto.Id; + return model; + } + public async Task>> LoadConcessionTypeAsync(bool onlyActive) + { + List result = null; + int statuscode = 0; + string error = ""; + try + { + result = await _context.ConcessionTypes.Select( + x => new ConcessionTypeDto() + { + Id = x.ConcessionTypeID, + Description = x.ConcessionDesc, + Display = x.ConcessionDisplay, + Active = x.Active + }).ToListAsync(); + statuscode = 1; + } + catch (Exception ex) + { + result = null; + error = ex.ToString(); + statuscode = 0; + throw ex; + } + + return new ResultModel>() + { + Data = result, + StatusCode = statuscode, + Message = error + }; + } + public async Task> LoadConcessionTypeByIdAsync(int id) + { + ConcessionType result = null; + int statuscode = 0; + string error = ""; + ConcessionTypeDto dto; + try + { + result = await _context.ConcessionTypes.FindAsync(id); + dto = FillConcessionTypeDto(result); + //result = _list.Find(x => x.Id == id); + //var dto = await Task.Run(() => result); + statuscode = 1; + } + catch (Exception ex) + { + error = ex.ToString(); + statuscode = 0; + throw ex; + } + return new ResultModel() + { + Data = dto, + StatusCode = statuscode, + Message = error + }; + } + public async Task> SaveConcessionTypeAsync(ConcessionTypeDto item) + { + int result = default(int); + int statuscode = 0; + string error = ""; + try + { + ConcessionType model; + if (item.Id > 0) + { + model = await _context.ConcessionTypes.FindAsync(item.Id); + model = FillConcessionType(item, model); + await _context.SaveChangesAsync(); + result = item.Id; + } + else //new record + { + model = new ConcessionType(); + model = FillConcessionType(item, model); + _context.ConcessionTypes.Add(model); + var id = await _context.SaveChangesAsync(); + result = id; + item.Id = id; + } + statuscode = 1; + } + catch (Exception ex) + { + error = ex.ToString(); + statuscode = 0; + throw ex; + } + //var dto = await Task.Run(() => result); + return new ResultModel() + { + Data = result, + StatusCode = statuscode, + Message = error + }; + } + + public async Task> DeleteConcessionTypeAsync(int id) + { + bool result = true; + int statuscode = 0; + string error = ""; + try + { + ConcessionType model; + if (id > 0) + { + model = await _context.ConcessionTypes.FindAsync(id); + model.Active = false; + //_context.ConcessionTypes.Remove(model); + await _context.SaveChangesAsync(); + statuscode = 1; + } + } + catch (Exception ex) + { + error = ex.ToString(); + statuscode = 0; + throw; + } + //var dto = await Task.Run(() => result); + return new ResultModel() + { + Data = result, + StatusCode = statuscode, + Message = error + }; + } + + + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Repository/ConcessionValidationRepository.cs b/CarParkValidationAPI/Repository/ConcessionValidationRepository.cs new file mode 100644 index 0000000..4cf3372 --- /dev/null +++ b/CarParkValidationAPI/Repository/ConcessionValidationRepository.cs @@ -0,0 +1,273 @@ +//using BCryptNet = BCrypt.Net.BCrypt; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using CarParkValidationAPI.Authorization; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Helpers; +using CarParkValidationAPI.Models.Users; +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Datas; +using CarParkValidationAPI.Interface; +using Microsoft.EntityFrameworkCore; +using System; + +namespace CarParkValidationAPI.Repository +{ + public class ConcessionValidationRepository : IConcessionValidation + { + private DataContext _context; + + private readonly AppSettings _appSettings; + + public ConcessionValidationRepository( + DataContext context, + + IOptions appSettings) + { + _context = context; + _appSettings = appSettings.Value; + } + + private ConcessionValidationDto FillConcessionValidationDto(ConcessionValidation model) + { + ConcessionValidationDto dto = new ConcessionValidationDto(); + dto.Active = model.Active; + dto.ConcessionCard = model.ConcessionCard; + dto.ConcessionExpiry = model.ConcessionExpiry; + dto.ConcessionHolder = model.ConcessionHolder; + dto.ConcessionTypeId = model.ConcessionTypeID; + dto.Id = model.ValidationID; + dto.StafflinkNo = model.StafflinkNo; + dto.ValidateDate = model.ValidateDate; + dto.ValidationPointId = model.ValidationPointID; + return dto; + } + + private ConcessionValidationExtDto FillConcessionValidationExtDto(ConcessionValidation model) + { + ConcessionValidationExtDto dto = new ConcessionValidationExtDto(); + dto.Active = model.Active; + dto.ConcessionCard = model.ConcessionCard; + dto.ConcessionExpiry = model.ConcessionExpiry; + dto.ConcessionHolder = model.ConcessionHolder; + dto.ConcessionTypeId = model.ConcessionTypeID; + dto.Id = model.ValidationID; + dto.StafflinkNo = model.StafflinkNo; + dto.ValidateDate = model.ValidateDate; + dto.ValidationPointId = model.ValidationPointID; + return dto; + } + + private ConcessionValidation FillConcessionValidation(ConcessionValidationDto dto, ConcessionValidation model) + { + + model.Active = dto.Active; + model.ConcessionCard = dto.ConcessionCard; + model.ConcessionExpiry = dto.ConcessionExpiry; + model.ConcessionHolder = dto.ConcessionHolder; + model.ConcessionTypeID = dto.ConcessionTypeId; + model.ValidationID = dto.Id; + model.StafflinkNo = dto.StafflinkNo; + model.ValidateDate = dto.ValidateDate; + model.ValidationPointID = dto.ValidationPointId; + return model; + } + public async Task>> LoadConcessionValidationAsync(bool onlyActive) + { + int statuscode = 0; + string error = ""; + List result = new List(); + + ConcessionValidationExtDto dto; + ConcessionValidation model; + try + { + List clist = await _context.ConcessionValidations.Where(x => x.Active == true).ToListAsync(); + for (int i = 0; i < clist.Count; i++) + { + model = clist[i]; + dto = FillConcessionValidationExtDto(model); + result.Add(dto); + } + statuscode = 1; + } + catch (Exception ex) + { + statuscode = 0; + error = ex.ToString(); + throw; + } + + return new ResultModel>() + { + Data = result, + StatusCode = statuscode, + Message = error + }; + } + + public async Task>> LoadConcessionValidationStaffLinkNoAsync(string staffLinkNo, DateTime currentDate) + { + List result = new List(); + // ConcessionValidationExtDto dto; + // ConcessionValidation model; + int statuscode = 0; + string error = ""; + try + { + + //List clist = await _context.ConcessionValidations.Where(x => + // x.Active == true + // && x.StafflinkNo == staffLinkNo + // && x.ValidateDate.Date == currentDate.Date + //).ToListAsync(); + result = await _context.SelectConcessionValidationByStaffId(true, staffLinkNo, currentDate, currentDate); + /* + //var clist = await _context.SPSelectValidation(true, staffLinkNo, currentDate); + for (int i = 0; i < clist.Count; i++) + { + model = clist[i]; + dto = FillConcessionValidationExtDto(model); + result.Add(dto); + + } + */ + statuscode = 1; + + } + catch (Exception ex) + { + statuscode = 0; + error = ex.ToString(); + throw; + } + + return new ResultModel>() + { + Data = result, + StatusCode = statuscode, + Message = error + }; + } + public async Task> LoadConcessionValidationByIdAsync(int id) + { + ConcessionValidationDto result = null; + int statuscode = 0; + string error = ""; + try + { + if (id > 0) + { + ConcessionValidation model = await _context.ConcessionValidations.FindAsync(id); + result = FillConcessionValidationDto(model); + statuscode = 1; + } + + } + catch (Exception ex) + { + statuscode = 0; + error = ex.ToString(); + throw; + } + + return new ResultModel() + { + Data = result, + StatusCode = statuscode, + Message = error + }; + } + public async Task> SaveConcessionValidationAsync(ConcessionValidationDto item) + { + int result = default(int); + int statuscode = 0; + string error = ""; + try + { + ConcessionValidation model; + if (item.Id > 0) + { + model = await _context.ConcessionValidations.FindAsync(item.Id); + model = FillConcessionValidation(item, model); + result = await _context.SaveChangesAsync(); + } + else + { + model = new ConcessionValidation(); + model = FillConcessionValidation(item, model); + _context.ConcessionValidations.Add(model); + result = await _context.SaveChangesAsync(); + } + statuscode = 1; + } + catch (Exception ex) + { + statuscode = 0; + error = ex.ToString(); + throw; + } + + + return new ResultModel() + { + Data = result, + StatusCode = statuscode, + Message = error + }; + + } + + public async Task> DeleteConcessionValidationAsync(int id) + { + bool result = true; + int statuscode = 0; + string error = ""; + try + { + if (id > 0) + { + ConcessionValidation model = await _context.ConcessionValidations.FindAsync(id); + model.Active = false; + await _context.SaveChangesAsync(); + statuscode = 1; + } + } + catch (Exception ex) + { + result = false; + statuscode = 0; + error = ex.ToString(); + throw; + } + + + return new ResultModel() + { + Data = result, + StatusCode = statuscode, + Message = error + }; + } + public async Task> GetReport(DateTime fromDate, DateTime toDate) + { + int statusCode = 1; + string fileContext = "filecontain as string this is file contain in string format"; + var result = new FileContent + { + Content = Convert.FromBase64String(fileContext), + FileName = "excel extension" + }; + var task = await Task.Run(() => 1); + return new ResultModel + { + Data = result, + StatusCode = statusCode + }; + } + + + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Repository/LookupCodeRepository.cs b/CarParkValidationAPI/Repository/LookupCodeRepository.cs new file mode 100644 index 0000000..cfaf303 --- /dev/null +++ b/CarParkValidationAPI/Repository/LookupCodeRepository.cs @@ -0,0 +1,92 @@ +//using BCryptNet = BCrypt.Net.BCrypt; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using CarParkValidationAPI.Authorization; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Helpers; +using CarParkValidationAPI.Models.Users; +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Datas; +using CarParkValidationAPI.Interface; +using Microsoft.EntityFrameworkCore; +using System; + +namespace CarParkValidationAPI.Repository +{ + + public class LookupCodeRepository: ILookupCode + { + private DataContext _context; + + private readonly AppSettings _appSettings; + + public LookupCodeRepository( + DataContext context, + + IOptions appSettings) + { + _context = context; + _appSettings = appSettings.Value; + } + public async Task>> LoadConcessionTypeAsync(bool onlyActive) + { + List result = null; + int statuscode = 0; + string error = ""; + try + { + result = await _context.ConcessionTypes.Where(x => x.Active == onlyActive).Select( + x => new LookupCodeDto() + { + Id = x.ConcessionTypeID, + Description = x.ConcessionDesc, + + }).ToListAsync(); + statuscode = 1; + } + catch (Exception ex) + { + statuscode = 0; + error = ex.ToString(); + throw; + } + return new ResultModel>() + { + Data = result, + StatusCode = statuscode, + Message = error + }; + } + public async Task>> LoadValidationPointAsync(bool onlyActive) + { + List result = null; + int statuscode = 0; + string error = ""; + try + { + result = await _context.Validations.Where(x => x.Active == onlyActive).Select( + x => new LookupCodeDto() + { + Id = x.ValidationPointID, + Description = x.Description + }).ToListAsync(); + statuscode = 1; + } + catch (Exception ex) + { + statuscode = 0; + error = ex.ToString(); + throw; + } + return new ResultModel>() + { + Data = result, + StatusCode = statuscode, + Message = error + }; + } + + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Repository/UserFakeRepository.cs b/CarParkValidationAPI/Repository/UserFakeRepository.cs new file mode 100644 index 0000000..6603854 --- /dev/null +++ b/CarParkValidationAPI/Repository/UserFakeRepository.cs @@ -0,0 +1,251 @@ +//using BCryptNet = BCrypt.Net.BCrypt; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using CarParkValidationAPI.Authorization; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Helpers; +using CarParkValidationAPI.Models.Users; +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Datas; +using CarParkValidationAPI.Interface; +using Microsoft.EntityFrameworkCore; +using CommonAD.Models; +using CommonAD; + +namespace CarParkValidationAPI.Repository +{ + public class UserFakeRepository : IUserService + { + private DataContext _context; + private IJwtUtils _jwtUtils; + private readonly AppSettings _appSettings; + + public UserFakeRepository( + DataContext context, + IJwtUtils jwtUtils, + IOptions appSettings) + { + _context = context; + _jwtUtils = jwtUtils; + _appSettings = appSettings.Value; + + } + public AuthenticateResponse Authenticate(AuthenticateRequest model) + { + var user = _context.Users.SingleOrDefault(x => x.Username == model.Username); + + // validate + // if (user == null || !BCryptNet.Verify(model.Password, user.PasswordHash)) + if (user == null || (model.Password != user.PasswordHash)) + throw new System.Exception("Username or password is incorrect"); + + // authentication successful so generate jwt token + var jwtToken = _jwtUtils.GenerateJwtToken(user); + + return new AuthenticateResponse(user, jwtToken); + } + public async Task> LoginApiAD(AuthenticateRequest model) + { + User user = new User(); + int statusCode = 1; + if (model.Username.ToLower() == "admin") + { + user.FirstName = model.Username; + user.LastName = "LS Test"; + user.Role = AdminRole.Admin; + user.Username = model.Username; + } + else + { + user.Username = model.Username; + user.FirstName = model.Username; + user.LastName = " LS Normal"; + user.Role = AdminRole.Normal; + } + + // authentication successful so generate jwt token + var jwtToken = _jwtUtils.GenerateJwtToken(user); + + var retval = await Task.Run(() => new AuthenticateResponse(user, jwtToken)); + return new ResultModel() + { + Data = retval, + StatusCode = statusCode + }; + } + + public async Task> NLoginApiAD(AuthenticateRequest model) + { + User myUser = null; + AuthenticateResponse retval = null; + int statuscode = 0; + string webAPIUrl = _appSettings.LoginWebAPI; + + var loginInfo = await CommonAD.WebAPIUtil.GetLoginADAsync(webAPIUrl, "CheckADCredentials", model.Username, model.Password); + if (loginInfo != null && loginInfo.result) + { + myUser = new User(); + myUser.Email = loginInfo.Email; + myUser.FirstName = loginInfo.FirstName; + myUser.LastName = loginInfo.LastName; + myUser.Username = loginInfo.StafflinkNo; + //now check the adminuser table + var user = _context.AdminUsers.SingleOrDefault(x => x.StafflinkNo == model.Username); + if (user != null) + { + myUser.Role = user.RoleType; + myUser.Id = user.UserID; + } + else + myUser.Role = AdminRole.Normal; + + // validate + // if (user == null || !BCryptNet.Verify(model.Password, user.PasswordHash)) + + // authentication successful so generate jwt token + var jwtToken = _jwtUtils.GenerateJwtToken(myUser); + statuscode = 1; + retval = new AuthenticateResponse(myUser, jwtToken); + + } + + return new ResultModel() + { + Data = retval, + StatusCode = statuscode + }; + } + + public async Task> LoginAD(AuthenticateRequest model) + { + User myUser = null; + AuthenticateResponse retval = null; + int statuscode = 0; + ADConfig adConfig = new ADConfig() + { + LDAPPassword = _appSettings.LDAPPassword, + LDAPPath = _appSettings.LDAPPath, + LDAPUser = _appSettings.LDAPUser, + ADTimeOutStr = _appSettings.ADTimeOut + }; + myUser = await Task.Run(() => LoginADStaff(adConfig,model.Username, model.Password)); + if (!string.IsNullOrEmpty(myUser.Username)) + { + statuscode = 1; + // authentication successful so generate jwt token + var jwtToken = _jwtUtils.GenerateJwtToken(myUser); + + retval = new AuthenticateResponse(myUser, jwtToken); + } + return new ResultModel() + { + Data = retval, + StatusCode = statuscode + }; + } + + public async Task>> GetAllUsers() + { + var retval = await _context.Users.ToListAsync(); + return new ResultModel>() + { + Data = retval, + StatusCode = 1 + }; + + } + + public async Task> GetById(int id) + { + var user = await _context.Users.FindAsync(id); + if (user == null) throw new KeyNotFoundException("User not found"); + return new ResultModel() + { + Data = user, + StatusCode = 1 + }; + } + public async Task> SearchApiStaff(string staffLinkNo) + { + User myUser = null; + int statuscode = 0; + string webAPIUrl = _appSettings.LoginWebAPI; + var loginInfo = await CommonAD.WebAPIUtil.SearchStaffAsync(webAPIUrl, "SearchStaff", staffLinkNo); + if (loginInfo != null && loginInfo.result) + { + myUser = new User(); + myUser.Email = loginInfo.Email; + myUser.FirstName = loginInfo.FirstName; + myUser.LastName = loginInfo.LastName; + myUser.Username = loginInfo.StafflinkNo; + statuscode = 1; + } + + return new ResultModel() + { + Data = myUser, + StatusCode = statuscode + }; + // return myUser; + + } + + public async Task> SearchADStaff(string staffLinkNo) + { + int statuscode = 0; + ADConfig adConfig = new ADConfig() + { + LDAPPassword = _appSettings.LDAPPassword, + LDAPPath = _appSettings.LDAPPath, + LDAPUser = _appSettings.LDAPUser, + ADTimeOutStr = _appSettings.ADTimeOut + }; + User myUser = await Task.Run(() => SearchADStaff(adConfig, staffLinkNo)); + if (!string.IsNullOrEmpty(myUser.Username)) + statuscode = 1; + return new ResultModel() + { + Data = myUser, + StatusCode = statuscode + }; + + + } + private User SearchADStaff(ADConfig adConfig, string username) + { + + ADStaffLink staffLink = new ADStaffLink(adConfig); + MyADObject myADObj = staffLink.SearchStaff(username); + User user = new() + { + Username = myADObj.StafflinkNo, + Email = myADObj.Email, + FirstName = myADObj.FirstName, + LastName = myADObj.LastName + }; + // myADObj.JobTitle; + return user; + + // return null; + } + private User LoginADStaff(ADConfig adConfig, string username, string password) + { + + ADStaffLink staffLink = new ADStaffLink(adConfig); + MyADObject myADObj = staffLink.CheckADCredentials(username,password); + User user = new() + { + Username = myADObj.StafflinkNo, + Email = myADObj.Email, + FirstName = myADObj.FirstName, + LastName = myADObj.LastName + }; + // myADObj.JobTitle; + return user; + + // return null; + } + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Repository/UserRepository.cs b/CarParkValidationAPI/Repository/UserRepository.cs new file mode 100644 index 0000000..5f6e210 --- /dev/null +++ b/CarParkValidationAPI/Repository/UserRepository.cs @@ -0,0 +1,223 @@ +//using BCryptNet = BCrypt.Net.BCrypt; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using CarParkValidationAPI.Authorization; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Helpers; +using CarParkValidationAPI.Models.Users; +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Datas; +using CarParkValidationAPI.Interface; +using Microsoft.EntityFrameworkCore; +using CommonAD.Models; +using CommonAD; + +namespace CarParkValidationAPI.Repository +{ + public class UserRepository : IUserService + { + private DataContext _context; + private IJwtUtils _jwtUtils; + private readonly AppSettings _appSettings; + + public UserRepository( + DataContext context, + IJwtUtils jwtUtils, + IOptions appSettings) + { + _context = context; + _jwtUtils = jwtUtils; + _appSettings = appSettings.Value; + + } + + public AuthenticateResponse Authenticate(AuthenticateRequest model) + { + var user = _context.Users.SingleOrDefault(x => x.Username == model.Username); + + // validate + // if (user == null || !BCryptNet.Verify(model.Password, user.PasswordHash)) + if (user == null || (model.Password != user.PasswordHash)) + throw new System.Exception("Username or password is incorrect"); + + // authentication successful so generate jwt token + var jwtToken = _jwtUtils.GenerateJwtToken(user); + + return new AuthenticateResponse(user, jwtToken); + } + + public async Task> LoginApiAD(AuthenticateRequest model) + { + User myUser = null; + AuthenticateResponse retval = null; + int statuscode = 0; + string webAPIUrl = _appSettings.LoginWebAPI; + + var loginInfo = await CommonAD.WebAPIUtil.GetLoginADAsync(webAPIUrl, "CheckADCredentials", model.Username, model.Password); + if (loginInfo != null && loginInfo.result) + { + myUser = new User(); + myUser.Email = loginInfo.Email; + myUser.FirstName = loginInfo.FirstName; + myUser.LastName = loginInfo.LastName; + myUser.Username = loginInfo.StafflinkNo; + //now check the adminuser table + var user = _context.AdminUsers.SingleOrDefault(x => x.StafflinkNo == model.Username); + if (user != null) + { + myUser.Role = user.RoleType; + myUser.Id = user.UserID; + } + else + myUser.Role = AdminRole.Normal; + + // validate + // if (user == null || !BCryptNet.Verify(model.Password, user.PasswordHash)) + + // authentication successful so generate jwt token + var jwtToken = _jwtUtils.GenerateJwtToken(myUser); + statuscode = 1; + retval = new AuthenticateResponse(myUser, jwtToken); + + } + + return new ResultModel() + { + Data = retval, + StatusCode = statuscode + }; + } + + public async Task> LoginAD(AuthenticateRequest model) + { + User myUser = null; + AuthenticateResponse retval = null; + int statuscode = 0; + ADConfig adConfig = new ADConfig() + { + LDAPPassword = _appSettings.LDAPPassword, + LDAPPath = _appSettings.LDAPPath, + LDAPUser = _appSettings.LDAPUser, + ADTimeOutStr = _appSettings.ADTimeOut + }; + myUser = await Task.Run(() => LoginADStaff(adConfig,model.Username, model.Password)); + if (!string.IsNullOrEmpty(myUser.Username)) + { + statuscode = 1; + // authentication successful so generate jwt token + var jwtToken = _jwtUtils.GenerateJwtToken(myUser); + + retval = new AuthenticateResponse(myUser, jwtToken); + } + return new ResultModel() + { + Data = retval, + StatusCode = statuscode + }; + } + + public async Task>> GetAllUsers() + { + var retval = await _context.Users.ToListAsync(); + return new ResultModel>() + { + Data = retval, + StatusCode = 1 + }; + + } + + public async Task> GetById(int id) + { + var user = await _context.Users.FindAsync(id); + if (user == null) throw new KeyNotFoundException("User not found"); + return new ResultModel() + { + Data = user, + StatusCode = 1 + }; + } + public async Task> SearchApiStaff(string staffLinkNo) + { + User myUser = null; + int statuscode = 0; + string webAPIUrl = _appSettings.LoginWebAPI; + var loginInfo = await CommonAD.WebAPIUtil.SearchStaffAsync(webAPIUrl, "SearchStaff", staffLinkNo); + if (loginInfo != null && loginInfo.result) + { + myUser = new User(); + myUser.Email = loginInfo.Email; + myUser.FirstName = loginInfo.FirstName; + myUser.LastName = loginInfo.LastName; + myUser.Username = loginInfo.StafflinkNo; + statuscode = 1; + } + + return new ResultModel() + { + Data = myUser, + StatusCode = statuscode + }; + // return myUser; + + } + + public async Task> SearchADStaff(string staffLinkNo) + { + int statuscode = 0; + ADConfig adConfig = new ADConfig() + { + LDAPPassword = _appSettings.LDAPPassword, + LDAPPath = _appSettings.LDAPPath, + LDAPUser = _appSettings.LDAPUser, + ADTimeOutStr = _appSettings.ADTimeOut + }; + User myUser = await Task.Run(() => SearchADStaff(adConfig, staffLinkNo)); + if (!string.IsNullOrEmpty(myUser.Username)) + statuscode = 1; + return new ResultModel() + { + Data = myUser, + StatusCode = statuscode + }; + + + } + private User SearchADStaff(ADConfig adConfig, string username) + { + + ADStaffLink staffLink = new ADStaffLink(adConfig); + MyADObject myADObj = staffLink.SearchStaff(username); + User user = new() + { + Username = myADObj.StafflinkNo, + Email = myADObj.Email, + FirstName = myADObj.FirstName, + LastName = myADObj.LastName + }; + // myADObj.JobTitle; + return user; + + // return null; + } + private User LoginADStaff(ADConfig adConfig, string username, string password) + { + + ADStaffLink staffLink = new ADStaffLink(adConfig); + MyADObject myADObj = staffLink.CheckADCredentials(username,password); + User user = new() + { + Username = myADObj.StafflinkNo, + Email = myADObj.Email, + FirstName = myADObj.FirstName, + LastName = myADObj.LastName + }; + // myADObj.JobTitle; + return user; + + // return null; + } + } +} \ No newline at end of file diff --git a/CarParkValidationAPI/Repository/ValidationPointFackRepository.cs b/CarParkValidationAPI/Repository/ValidationPointFackRepository.cs new file mode 100644 index 0000000..fcc344b --- /dev/null +++ b/CarParkValidationAPI/Repository/ValidationPointFackRepository.cs @@ -0,0 +1,192 @@ +using CarParkValidationAPI.Datas; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Interface; +using CarParkValidationAPI.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace CarParkValidationAPI.Repository +{ + public class ValidationPointFakeRepository : IValidationPoint + { + private DataContext _context; + + private readonly AppSettings _appSettings; + + private List _list = new List(); + + public ValidationPointFakeRepository( + DataContext context, + + IOptions appSettings) + { + _context = context; + _appSettings = appSettings.Value; + } + + private ValidationPointDto FillValidationDto(ValidationPoint item) + { + ValidationPointDto dto = new ValidationPointDto(); + dto.Active = item.Active; + dto.Description = item.Description; + dto.Display = item.DisplayName; + dto.Id = item.ValidationPointID; + return dto; + } + + private ValidationPoint FillValidationModel(ValidationPointDto item, ValidationPoint model) { + + model.Active = item.Active; + model.Description = item.Description; + model.DisplayName = item.Display; + model.ValidationPointID = item.Id; + return model; + } + + public async Task>> LoadValidationPointAsync(bool onlyActive) + { + try + { + /* + var it = await _context.Validations.AsQueryable().ToListAsync(); + */ + + ValidationPointDto dto; + ValidationPoint val; + for (int i = 0; i < 10; i++) + { + val = new ValidationPoint() + { + ValidationPointID = i, + Description = $"Validation {i}", + DisplayName = $"Display {i}", + Active = true, + + + }; + + dto = FillValidationDto(val); + _list.Add(dto); + } + //var it = await Task.Run(() => _list); + + return new ResultModel>() + { + Data = _list, + StatusCode = 1 + }; + + } + catch (Exception ex) + { + throw ex; + } + + } + public async Task> LoadValidationPointByIdAsync(int id) + { + ValidationPoint result = null; + try + { + ValidationPointDto dto; + result = await _context.Validations.FindAsync(id); + dto = FillValidationDto(result); + //result = _list.Find(x => x.Id == id); + //var dto = await Task.Run(() => result); + return new ResultModel() + { + Data = dto, + StatusCode = 1 + }; + } + catch (Exception ex) + { + throw ex; + } + } + public async Task> SaveValidationPointAsync(ValidationPointDto item) + { + int result = default(int); + try + { + ValidationPoint model; + if (item.Id > 0) + { + model = await _context.Validations.FindAsync(item.Id); + model = FillValidationModel(item, model); + await _context.SaveChangesAsync(); + result = item.Id; + } + else //new record + { + model = new ValidationPoint(); + model = FillValidationModel(item, model); + _context.Validations.Add(model); + var id = await _context.SaveChangesAsync(); + result = id; + item.Id = id; + } + + //var dto = await Task.Run(() => result); + return new ResultModel() + { + Data = result, + StatusCode = 1 + }; + } + catch (Exception ex) + { + throw ex; + } + /* + ConcessionTypeDA dataAccess = new ConcessionTypeDA(); + try + { + result = await dataAccess.InsertConcessionTypeAsync(item); + } + catch (Exception ex) + { + throw ex; + } + */ + + + } + + public async Task> DeleteValidationPointAsync(int id) + { + bool result = true; + try + { + + + ValidationPoint model; + if (id > 0) + { + model = await _context.Validations.FindAsync(id); + model.Active = false; + //_context.Validations.Remove(model); + await _context.SaveChangesAsync(); + } + + //var dto = await Task.Run(() => result); + return new ResultModel() + { + Data = result, + StatusCode = 1 + }; + } + catch (Exception ex) + { + throw; + } + + } + + + } +} diff --git a/CarParkValidationAPI/Repository/ValidationPointRepository.cs b/CarParkValidationAPI/Repository/ValidationPointRepository.cs new file mode 100644 index 0000000..f1a6299 --- /dev/null +++ b/CarParkValidationAPI/Repository/ValidationPointRepository.cs @@ -0,0 +1,179 @@ +using CarParkValidationAPI.Datas; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Interface; +using CarParkValidationAPI.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace CarParkValidationAPI.Repository +{ + public class ValidationPointRepository : IValidationPoint + { + private DataContext _context; + + private readonly AppSettings _appSettings; + + private List _list = new List(); + + public ValidationPointRepository( + DataContext context, + + IOptions appSettings) + { + _context = context; + _appSettings = appSettings.Value; + } + + private ValidationPointDto FillValidationDto(ValidationPoint item) + { + ValidationPointDto dto = new ValidationPointDto(); + dto.Active = item.Active; + dto.Description = item.Description; + dto.Display = item.DisplayName; + dto.Id = item.ValidationPointID; + return dto; + } + + private ValidationPoint FillValidationModel(ValidationPointDto item, ValidationPoint model) { + + model.Active = item.Active; + model.Description = item.Description; + model.DisplayName = item.Display; + model.ValidationPointID = item.Id; + return model; + } + + public async Task>> LoadValidationPointAsync(bool onlyActive) + { + int statuscode = 0; + string error = ""; + try + { + var it = await _context.Validations.ToListAsync(); + + ValidationPointDto dto; + for (int i = 0; i < it.Count; i++) + { + dto = FillValidationDto(it[i]); + _list.Add(dto); + } + + statuscode = 1; + + } + catch (Exception ex) + { + error = ex.ToString(); + statuscode = 0; + throw ex; + } + return new ResultModel>() + { + Data = _list, + StatusCode = statuscode, + Message = error + }; + } + public async Task> LoadValidationPointByIdAsync(int id) + { + ValidationPoint result = null; + int statuscode = 0; + string error = ""; + ValidationPointDto dto = null; + try + { + result = await _context.Validations.FindAsync(id); + dto = FillValidationDto(result); + //result = _list.Find(x => x.Id == id); + //var dto = await Task.Run(() => result); + statuscode = 1; + } + catch (Exception ex) + { + error = ex.ToString(); + statuscode = 0; + } + return new ResultModel() + { + Data = dto, + StatusCode = statuscode, + Message = error + }; + } + public async Task> SaveValidationPointAsync(ValidationPointDto item) + { + int result = default(int); + int statuscode = 0; + string error = ""; + try + { + ValidationPoint model; + if (item.Id > 0) + { + model = await _context.Validations.FindAsync(item.Id); + model = FillValidationModel(item, model); + await _context.SaveChangesAsync(); + result = item.Id; + } + else //new record + { + model = new ValidationPoint(); + model = FillValidationModel(item, model); + _context.Validations.Add(model); + var id = await _context.SaveChangesAsync(); + result = id; + item.Id = id; + } + statuscode = 1; + } + catch (Exception ex) + { + error = ex.ToString(); + statuscode = 0; + } + //var dto = await Task.Run(() => result); + return new ResultModel() + { + Data = result, + StatusCode = statuscode, + Message = error + }; + } + + public async Task> DeleteValidationPointAsync(int id) + { + bool result = true; + int statuscode = 0; + string error = ""; + try + { + ValidationPoint model; + if (id > 0) + { + model = await _context.Validations.FindAsync(id); + model.Active = false; + //_context.Validations.Remove(model); + await _context.SaveChangesAsync(); + statuscode = 1; + } + } + catch (Exception ex) + { + error = ex.ToString(); + statuscode = 0; + throw; + } + //var dto = await Task.Run(() => result); + return new ResultModel() + { + Data = result, + StatusCode = statuscode, + Message = error + }; + } + } +} diff --git a/CarParkValidationAPI/Startup.cs b/CarParkValidationAPI/Startup.cs new file mode 100644 index 0000000..37b0950 --- /dev/null +++ b/CarParkValidationAPI/Startup.cs @@ -0,0 +1,137 @@ +using CarParkValidationAPI.Authorization; +using CarParkValidationAPI.Datas; +using CarParkValidationAPI.Entities; +using CarParkValidationAPI.Interface; +using CarParkValidationAPI.Models; +using CarParkValidationAPI.Repository; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Tokens; +using Microsoft.OpenApi.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CarParkValidationAPI +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddControllers(); + //** security + var appSettingsSection = Configuration.GetSection("AppSettings"); + services.Configure(appSettingsSection); + + var appSettings = appSettingsSection.Get(); + var key = Encoding.ASCII.GetBytes(appSettings.Secret); + //*** + services.AddDbContext(); + services.AddCors(); + //*** + services.AddAuthentication(x => + { + + x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }) + .AddJwtBearer(x => + { + x.RequireHttpsMetadata = false; + x.SaveToken = true; + x.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(key), + ValidateIssuer = false, + ValidateAudience = false + }; + }); + + //** + //publish need to take comment out + + services.AddSwaggerGen(c => + { + // c.ResolveConflictingActions(api => api.First()); + c.SwaggerDoc("v1", new OpenApiInfo { Title = "CarParkValidationAPI", Version = "v1" }); + }); + /* + services.AddSwaggerGen(option => + { + option.UseAllOfForInheritance(); + option.UseAllOfToExtendReferenceSchemas(); + option.IgnoreObsoleteActions(); + option.IgnoreObsoleteProperties(); + option.ResolveConflictingActions(api => api.First()); + }); + */ + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + } + + // 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.UseSwagger(); + + app.UseSwaggerUI(c => + { + c.DocExpansion(Swashbuckle.AspNetCore.SwaggerUI.DocExpansion.None); + c.SwaggerEndpoint("/swagger/v1/swagger.json", "CarParkValidationAPI v1"); + }); + + app.UseRouting(); + + // global cors policy + app.UseCors(x => x + .SetIsOriginAllowed(origin => true) + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials()); + + // global error handler + //app.UseMiddleware(); + + // custom jwt auth middleware + app.UseMiddleware(); + + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } + + } +} diff --git a/CarParkValidationAPI/appsettings.Development.json b/CarParkValidationAPI/appsettings.Development.json new file mode 100644 index 0000000..c6f99e0 --- /dev/null +++ b/CarParkValidationAPI/appsettings.Development.json @@ -0,0 +1,23 @@ +{ + "AppSettings": { + "Secret": "Nepean Blue Mountain Super Secret SIGN AND VERIFY JWT TOKENS, BEARER TOKEN USE WHEN CALLING THIS API.", + "SQLConnectionString": "Server=NEPHICT-040931L;Initial Catalog=CarParkValidation;Persist Security Info=False;User ID=bids_admin;Password=Password4BI;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30;", + "LDAPPath": "LDAP://ldap.nswhealth.net:389/OU=Accounts,DC=nswhealth,DC=net", + "LDAPUser": "SRV-NBMS-BIDSPMS", + "LDAPPassword": "42Ytp2AE3nN16eBoyia86UZH6", + "ADTimeOut": "30", + "LoginWebAPI": "http://NEPHMDB-SQL007/CommonWebApiAD/api/AD" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} +/*Positive~1 + user id=bids_admin;password=Password4BI; + Server=tcp:10.60.207.82,1433; +*/ diff --git a/CarParkValidationAPI/appsettings.json b/CarParkValidationAPI/appsettings.json new file mode 100644 index 0000000..796639e --- /dev/null +++ b/CarParkValidationAPI/appsettings.json @@ -0,0 +1,23 @@ +{ + "AppSettings": { + "Secret": "Nepean Blue Mountain Super Secret SIGN AND VERIFY JWT TOKENS, BEARER TOKEN USE WHEN CALLING THIS API.", + "SQLConnectionString": "Server=tcp:10.60.207.82,1433;Initial Catalog=CarParkValidation;Persist Security Info=False;User ID=bids_admin;Password=Password4BI;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30;", + "LDAPPath": "LDAP://ldap.nswhealth.net:389/OU=Accounts,DC=nswhealth,DC=net", + "LDAPUser": "SRV-NBMS-BIDSPMS", + "LDAPPassword": "42Ytp2AE3nN16eBoyia86UZH6", + "ADTimeOut": "30", + "LoginWebAPI": "http://NEPHMDB-SQL007/CommonWebApiAD/api/AD" + + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "OLDLoginWebAPI": "http://virtapp-mdb048/CommonAPI/api/AD/", + "LADP": "http://NEPHMDB-SQL007/CommonWebApiAD/api/AD/", + "AllowedHosts": "*", + "SQLConnectionStringold": "Server=tcp:10.60.207.82,1433;Initial Catalog=CarParkValidation;Persist Security Info=False;User ID=bids_admin;Password=Password4BI;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30;" +} diff --git a/CarParkValidationAPI/web.config b/CarParkValidationAPI/web.config new file mode 100644 index 0000000..e84621f --- /dev/null +++ b/CarParkValidationAPI/web.config @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CommonAD/ADConfig.cs b/CommonAD/ADConfig.cs new file mode 100644 index 0000000..c989760 --- /dev/null +++ b/CommonAD/ADConfig.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Configuration; + +namespace CommonAD.Models +{ + public class ADConfig + { + public string LDAPPath = ""; + public string LDAPUser = ""; + public string LDAPPassword = ""; + private TimeSpan _ADTimeOut = TimeSpan.FromSeconds(0); + + public TimeSpan ADTimeOut + { + get + { + return _ADTimeOut; + } + } + public string ADTimeOutStr + { + set + { + if (!string.IsNullOrEmpty(value)) + _ADTimeOut = TimeSpan.FromSeconds(Convert.ToDouble(value)); + } + } + + /* + public static void Init() + { + LDAPPath = ConfigurationManager.AppSettings["LDAPPath"]; + LDAPUser = ConfigurationManager.AppSettings["LDAPUser"]; + LDAPPassword = ConfigurationManager.AppSettings["LDAPPassword"]; + ADTimeOut = TimeSpan.FromSeconds(Convert.ToDouble(ConfigurationManager.AppSettings["ADTimeOut"])); + } + */ + } +} + + diff --git a/CommonAD/ADStaffLink.cs b/CommonAD/ADStaffLink.cs new file mode 100644 index 0000000..66e380f --- /dev/null +++ b/CommonAD/ADStaffLink.cs @@ -0,0 +1,373 @@ +using CommonAD.Models; +using System; +using System.Collections.Generic; +using System.DirectoryServices; + + +namespace CommonAD +{ + public class ADStaffLink + { + private ADConfig _adConfig; + public ADStaffLink (ADConfig adConfig) + { + _adConfig = adConfig; + } + public MyADObject SearchStaff(string FirstName = "", string LastName = "") + { + + MyADObject ADObj = new MyADObject(); + + using (var DE = new System.DirectoryServices.DirectoryEntry(_adConfig.LDAPPath, _adConfig.LDAPUser, _adConfig.LDAPPassword)) + { + try + { + DirectorySearcher adsSearcher = new DirectorySearcher(DE); + adsSearcher.ClientTimeout = _adConfig.ADTimeOut; + adsSearcher.ServerTimeLimit = _adConfig.ADTimeOut; + adsSearcher.ServerPageTimeLimit = _adConfig.ADTimeOut; + adsSearcher.Filter = string.Format("(&(objectCategory=person)(objectClass=user)(givenname={0})(sn={1}))", FirstName, LastName); + try + { + SearchResult sr = adsSearcher.FindOne(); + if (sr != null) + { + ADObj.result = true; + //LoginResult.Login = GetUserPropertyValue(sr, "sAMAccountName", 0); + ADObj.StafflinkNo = GetUserPropertyValue(sr, "sAMAccountName", 0); + ADObj.FirstName = GetUserPropertyValue(sr, "givenname", 0); + ADObj.LastName = GetUserPropertyValue(sr, "sn", 0); + ADObj.Email = GetUserPropertyValue(sr, "mail", 0); + ADObj.Company = GetUserPropertyValue(sr, "company", 0); + ADObj.Location = GetUserPropertyValue(sr, "physicalDeliveryOfficeName", 0); + ADObj.Department = GetUserPropertyValue(sr, "department", 0); + ADObj.BadPwdCount = GetUserPropertyValue(sr, "badPwdCount", 0); + ADObj.Phone = GetUserPropertyValue(sr, "telephonenumber", 0); + ADObj.DisplayName = GetUserPropertyValue(sr, "displayName", 0); + ADObj.Manager = GetUserPropertyValue(sr, "manager", 0); + ADObj.ReportsTo = GetUserPropertyValue(sr, "directReports", 0); + ADObj.StaffList = GetUserPropertyValue(sr, "staffList", 0); + } + } + catch + { + // Failed to authenticate. Most likely it is caused by unknown user + // id or bad strPassword. + ADObj.result = false; + } + } + catch + { + ADObj.result = false; + } + } + + //LoginResult.Success = res; + //string token = ""; + //long tickTock = DateTime.Now.Ticks; + //if (res) + //{ + // string tokenPT = app + "|" + user + "|" + "|" + tickTock + "|" + "NBM"; + // token = CommonCrypt.EncryptString(tokenPT, "bagmas2011+", "a1b2c3d4"); + // token = CommonEncoding.Base64Encode(token); + //} + //LoginResult.Login = user; + //LoginResult.Token = token; + //LoginResult.Time = tickTock; + return ADObj; + + + } + public MyADObject SearchStaff(string StaffLinkNo) + { + + MyADObject ADObj = new MyADObject(); + + using (var DE = new System.DirectoryServices.DirectoryEntry(_adConfig.LDAPPath, _adConfig.LDAPUser, _adConfig.LDAPPassword)) + { + try + { + DirectorySearcher adsSearcher = new DirectorySearcher(DE); + adsSearcher.ClientTimeout = _adConfig.ADTimeOut; + adsSearcher.ServerTimeLimit = _adConfig.ADTimeOut; + adsSearcher.ServerPageTimeLimit = _adConfig.ADTimeOut; + adsSearcher.Filter = "(SAMAccountName=" + StaffLinkNo + ")"; + try + { + SearchResult sr = adsSearcher.FindOne(); + if (sr != null) + { + ADObj.result = true; + // LoginResult.Login = GetUserPropertyValue(sr, "sAMAccountName", 0); ; + ADObj.StafflinkNo = GetUserPropertyValue(sr, "SAMAccountName", 0); + ADObj.FirstName = GetUserPropertyValue(sr, "givenname", 0); + ADObj.LastName = GetUserPropertyValue(sr, "sn", 0); + ADObj.Email = GetUserPropertyValue(sr, "mail", 0); + ADObj.Company = GetUserPropertyValue(sr, "company", 0); + ADObj.Location = GetUserPropertyValue(sr, "physicalDeliveryOfficeName", 0); + ADObj.Department = GetUserPropertyValue(sr, "department", 0); + ADObj.JobTitle = GetUserPropertyValue(sr, "title", 0); + ADObj.BadPwdCount = GetUserPropertyValue(sr, "badPwdCount", 0); + ADObj.Phone = GetUserPropertyValue(sr, "telephonenumber", 0); + ADObj.DisplayName = GetUserPropertyValue(sr, "displayName", 0); + ADObj.Manager = GetUserPropertyValue(sr, "manager", 0); + ADObj.ReportsTo = GetUserPropertyValue(sr, "directReports", 0); + ADObj.StaffList = GetUserPropertyValue(sr, "staffList", 0); + } + } + catch (Exception ex) + { + // Failed to authenticate. Most likely it is caused by unknown user + // id or bad strPassword. + ADObj.result = false; + } + } + catch + { + ADObj.result = false; + } + } + + //LoginResult.Success = res; + //string token = ""; + //long tickTock = DateTime.Now.Ticks; + //if (res) + //{ + // string tokenPT = app + "|" + user + "|" + "|" + tickTock + "|" + "NBM"; + // token = CommonCrypt.EncryptString(tokenPT, "bagmas2011+", "a1b2c3d4"); + // token = CommonEncoding.Base64Encode(token); + //} + //LoginResult.Login = user; + //LoginResult.Token = token; + //LoginResult.Time = tickTock; + return ADObj; + + + } + public MyADObject CheckADCredentials(string user, string pass) + { + //dynamic LoginResult = new JObject() as dynamic; + bool res = true; + MyADObject ADObj = new MyADObject(); + + using (var DE = new System.DirectoryServices.DirectoryEntry(_adConfig.LDAPPath, user, pass)) + { + try + { + //DE.RefreshCache(); // This will force credentials validation + DirectorySearcher adsSearcher = new DirectorySearcher(DE); + adsSearcher.ClientTimeout = _adConfig.ADTimeOut; + adsSearcher.ServerTimeLimit = _adConfig.ADTimeOut; + adsSearcher.ServerPageTimeLimit = _adConfig.ADTimeOut; + //adsSearcher.Filter = "(&(objectClass=user)(objectCategory=person))"; + adsSearcher.Filter = "(sAMAccountName=" + user + ")"; + + try + { + SearchResult sr = adsSearcher.FindOne(); + if (sr != null) + { + ADObj.StafflinkNo = GetUserPropertyValue(sr, "sAMAccountName", 0); ; + ADObj.FirstName = GetUserPropertyValue(sr, "givenname", 0); + ADObj.LastName = GetUserPropertyValue(sr, "sn", 0); + ADObj.Email = GetUserPropertyValue(sr, "mail", 0); + ADObj.Company = GetUserPropertyValue(sr, "company", 0); + ADObj.Location = GetUserPropertyValue(sr, "physicalDeliveryOfficeName", 0); + ADObj.Department = GetUserPropertyValue(sr, "department", 0); + ADObj.BadPwdCount = GetUserPropertyValue(sr, "badPwdCount", 0); + ADObj.Phone = GetUserPropertyValue(sr, "telephonenumber", 0); + ADObj.DisplayName = GetUserPropertyValue(sr, "displayName", 0); + ADObj.Manager = GetUserPropertyValue(sr, "manager", 0); + + // we will retrieve the count of staff in DirectReports as a flag to determine if this user is a manager + // we will assume if no staff then requests lodged by this user will need signoff by their manager + //LoginResult.StaffListCount = sr.Properties["DirectReports"].Count; + //LoginResult.PWD = ADConfig.LDAPPassword; + //LoginResult.User = ADConfig.LDAPUser; + + + /* // we do not think we need actual staff IDs at this point - a count of staff will be enough for this application + // but leave here in case we need to re-use this in another app. + List StaffList = new List(); + foreach (string objProperty in sr.Properties["DirectReports"]) + { + + + string emp = objProperty.ToString().Split(',')[0]; + emp = emp.Replace("CN=", ""); + StaffList.Add(emp); + //emps.Add(emp); + //user.StaffList += '|'; + //user.StaffList += emp; + // + } + LoginResult.StaffList = JsonConvert.SerializeObject(StaffList); + */ + + try + { + if (ADObj.Manager != String.Empty) + { + String managerInfo = Convert.ToString(ADObj.Manager); + String managerID = managerInfo.Split(',')[0].Split('=')[1]; + String managerOU = managerInfo.Split(',')[1].Split('=')[1]; + List managerDetails = Search(managerID, managerOU); + // JToken managerDetails = Search(managerID); + ADObj.ManagerDetails = managerDetails[0].ToString(); + } + } + catch (Exception ex) + { + ADObj.ManagerDetails = "Not available: " + ex.Message; + } + + } + } + catch (Exception ex2) + { + // Failed to authenticate. Most likely it is caused by unknown user + // id or bad strPassword. + res = false; + } + } + catch + { + res = false; + } + } + + ADObj.result = res; + // string token = ""; + // long tickTock = DateTime.Now.Ticks; + // if (res) + // { + //string tokenPT = app + "|" + user + "|" + pass + "|" + tickTock + "|" + "NBM"; + //token = CommonCrypt.EncryptString(tokenPT, "bagmas2011+", "a1b2c3d4"); + //token = CommonEncoding.Base64Encode(token); + //} + + //LoginResult.Token = token; + //LoginResult.Time = tickTock; + + + //return LoginResult; + return ADObj; + + } + public List Search(string q, string ou) + { + //ou = "Nepean Blue Mountains"; + MyADObject ADObj = new Models.MyADObject(); + //ADConfig.Init(); + + List lstLDAPUser = new List(); + + if (string.IsNullOrEmpty(q)) + q = "______"; //defualt not found + System.DirectoryServices.DirectoryEntry dirEntry = new System.DirectoryServices.DirectoryEntry(_adConfig.LDAPPath, _adConfig.LDAPUser, _adConfig.LDAPPassword); + DirectorySearcher dirSearch = new DirectorySearcher(dirEntry); + dirSearch.ClientTimeout = _adConfig.ADTimeOut; + dirSearch.ServerTimeLimit = _adConfig.ADTimeOut; + dirSearch.ServerPageTimeLimit = _adConfig.ADTimeOut; + dirSearch.Filter = "(&(objectClass=user)(|(cn=" + q + "*)))"; + dirSearch.SearchRoot = dirEntry; + dirSearch.SearchScope = SearchScope.Subtree; + dirSearch.PageSize = 100; + dirSearch.Sort = new SortOption("displayName", SortDirection.Ascending); + + + using (SearchResultCollection src = dirSearch.FindAll()) + { + int i = 0; + foreach (SearchResult sr in src) + { + i++; + if (i > 100) + break; + bool bLogindisabled = true; + + string sTmp = GetUserPropertyValue(sr, "logindisabled", 0); + bLogindisabled = (sTmp == string.Empty ? false : Convert.ToBoolean(sTmp)); + + if (!bLogindisabled) + { + sTmp = GetUserPropertyValue(sr, "passwordexpirationtime", 0); + if (sTmp != "") + { + try + { + if (DateTime.Now > Convert.ToDateTime(sTmp)) + { + bLogindisabled = true; + } + } + catch { } + } + } + + if (!bLogindisabled) + { + MyADObject user = new MyADObject(); + // user.Login = GetUserPropertyValue(sr, "sAMAccountName", 0); + user.StafflinkNo = GetUserPropertyValue(sr, "sAMAccountName", 0); + user.FirstName = GetUserPropertyValue(sr, "givenname", 0); + user.LastName = GetUserPropertyValue(sr, "sn", 0); + user.Email = GetUserPropertyValue(sr, "mail", 0); + user.Company = GetUserPropertyValue(sr, "company", 0); + user.Location = GetUserPropertyValue(sr, "physicalDeliveryOfficeName", 0); + user.Department = GetUserPropertyValue(sr, "department", 0); + user.BadPwdCount = GetUserPropertyValue(sr, "badPwdCount", 0); + //user.company = GetUserPropertyValue(sr, "company", 0); + user.Phone = GetUserPropertyValue(sr, "telephonenumber", 0); + user.DisplayName = GetUserPropertyValue(sr, "displayName", 0); + //user.distinguishedName = GetUserPropertyValue(sr, "distinguishedName", 0); + user.DisplayName = GetUserPropertyValue(sr, "displayName", 0); + + lstLDAPUser.Add(user); + } + + } + + } + if (dirSearch != null) + dirSearch.Dispose(); + if (dirEntry != null) + dirEntry.Dispose(); + return lstLDAPUser; + + }//end method + private string GetUserPropertyValue(SearchResult res, string sPropertyName, int lIndex) + { + try + { + if (res.Properties[sPropertyName].Count > lIndex) + { + string s; + object v = res.Properties[sPropertyName][lIndex]; + + if (v.GetType() == typeof(byte[])) + { + s = System.Text.ASCIIEncoding.ASCII.GetString((byte[])v); + } + else if (v.GetType() == typeof(DateTime)) + { + s = ((DateTime)v).ToLocalTime().ToString("yyyy/MM/dd HH:mm:ss"); + } + else + { + s = v.ToString(); + } + return (s); + } + else + { + return (""); + } + } + catch + { + return (""); + } + } + } +} diff --git a/CommonAD/CommonAD.csproj b/CommonAD/CommonAD.csproj new file mode 100644 index 0000000..d4fb241 --- /dev/null +++ b/CommonAD/CommonAD.csproj @@ -0,0 +1,12 @@ + + + + net5.0 + + + + + + + + diff --git a/CommonAD/MyADObject.cs b/CommonAD/MyADObject.cs new file mode 100644 index 0000000..c9c9123 --- /dev/null +++ b/CommonAD/MyADObject.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Configuration; + + +namespace CommonAD.Models +{ + public class MyADObject + { + public string StafflinkNo { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Email { get; set; } + public string Company { get; set; } + public string Location { get; set; } + public string Department { get; set; } + public string JobTitle { get; set; } + public string BadPwdCount { get; set; } + public string Phone { get; set; } + public string DisplayName { get; set; } + public string Manager { get; set; } + public string ReportsTo { get; set; } + public string StaffList { get; set; } + public string ManagerDetails { get; set; } + public bool result { get; set; } + + + } + + +} diff --git a/CommonAD/WebAPIUtil.cs b/CommonAD/WebAPIUtil.cs new file mode 100644 index 0000000..ddc56f2 --- /dev/null +++ b/CommonAD/WebAPIUtil.cs @@ -0,0 +1,268 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using System.Threading.Tasks; +using CommonAD.Models; +using System.Net.Http.Json; + +namespace CommonAD +{ + public class WebAPIUtil + { + /// + /// SearchStaff + /// + /// "http://virtapp-mdb048/CommonAPI/api/AD/" + /// "SearchStaff" + /// + /// + /// + public static MyADObject SearchStaff(string webAPIUri, string actionEntry, string username) + { + MyADObject result = null; + if (!webAPIUri.EndsWith("/")) + webAPIUri += "/"; + System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; + using (var client = new HttpClient()) + { + client.BaseAddress = new Uri(webAPIUri); + + // We want the response to be JSON. + // client.DefaultRequestHeaders.Accept.Clear(); + // client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + + // Build up the data to POST. + // List> postData = new List>(); + // postData.Add(new KeyValuePair("StaffLinkNo", username)); + // postData.Add(new KeyValuePair("pass", password)); + //postData.Add(new KeyValuePair("client_secret", clientSecret)); + + //var form = new Dictionary + //{ + // {"grant_type", "client_credentials"}, + + //}; + //client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); + //client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(username + ":" + password))); + + // HttpContent content = new StringContent(json, Encoding.UTF8); + + // actionEntry = webAPIUri + actionEntry; + // FormUrlEncodedContent content = new FormUrlEncodedContent(postData); + //FormUrlEncodedContent content = new FormUrlEncodedContent(form); + // Post to the Server and parse the response. + //HttpResponseMessage response = await client.PostAsync("Token", content); + // string jsonString = await response.Content.ReadAsStringAsync(); + //HttpResponseMessage response = client.PostAsync(actionEntry, content).GetAwaiter().GetResult(); + actionEntry = actionEntry + "?StaffLinkNo=" + username; + try + { + var myado = client.GetFromJsonAsync(actionEntry).GetAwaiter().GetResult(); + if (myado != null) + result = myado; + } + catch(Exception ex) + { + throw ex; + } + } + + return result; + } + /// + /// SearchStaff Async version + /// + /// "http://virtapp-mdb048/CommonAPI/api/AD/" + /// "SearchStaff" + /// + /// + public static async Task SearchStaffAsync(string webAPIUri, string actionEntry, string username) + { + MyADObject result = null; + string error = ""; + if (!webAPIUri.EndsWith("/")) + webAPIUri += "/"; + System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; + using (var client = new HttpClient()) + { + client.BaseAddress = new Uri(webAPIUri); + + // We want the response to be JSON. + // client.DefaultRequestHeaders.Accept.Clear(); + // client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + + // Build up the data to POST. + // List> postData = new List>(); + // postData.Add(new KeyValuePair("StaffLinkNo", username)); + // postData.Add(new KeyValuePair("pass", password)); + //postData.Add(new KeyValuePair("client_secret", clientSecret)); + + //var form = new Dictionary + //{ + // {"grant_type", "client_credentials"}, + + //}; + //client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); + //client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(username + ":" + password))); + + // HttpContent content = new StringContent(json, Encoding.UTF8); + + // actionEntry = webAPIUri + actionEntry; + //FormUrlEncodedContent content = new FormUrlEncodedContent(postData); + //FormUrlEncodedContent content = new FormUrlEncodedContent(form); + // Post to the Server and parse the response. + //HttpResponseMessage response = await client.PostAsync("Token", content); + // string jsonString = await response.Content.ReadAsStringAsync(); + //HttpResponseMessage response = client.PostAsync(actionEntry, content).GetAwaiter().GetResult(); + actionEntry = actionEntry + "?StaffLinkNo=" + username; + try + { + result = await client.GetFromJsonAsync(actionEntry); + } + catch (Exception ex) + { + error = ex.ToString(); + result = null; + } + + } + + return result; + } + /// + /// GetLoginAD webAPIUri "http://virtapp-mdb048/CommonAPI/api/AD/"; + /// + /// "http://virtapp-mdb048/CommonAPI/api/AD/" + /// "CheckADCredentials" + /// + /// + /// + /// + public static string GetLoginAD(string webAPIUri, string actionEntry, string username, string password, out string error) + { + string result = ""; + // string tokenstr = ""; + if (!webAPIUri.EndsWith("/")) + webAPIUri += "/"; + string mytoken = ""; + error = ""; + System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; + using (var client = new HttpClient()) + { + client.BaseAddress = new Uri(webAPIUri); + + // We want the response to be JSON. + // client.DefaultRequestHeaders.Accept.Clear(); + // client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + + // Build up the data to POST. + // List> postData = new List>(); + // postData.Add(new KeyValuePair("user", username)); + // postData.Add(new KeyValuePair("pass", password)); + //postData.Add(new KeyValuePair("client_secret", clientSecret)); + + //var form = new Dictionary + //{ + // {"grant_type", "client_credentials"}, + + //}; + //client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); + //client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(username + ":" + password))); + + // HttpContent content = new StringContent(json, Encoding.UTF8); + + // actionEntry = webAPIUri + actionEntry; + // FormUrlEncodedContent content = new FormUrlEncodedContent(postData); + //FormUrlEncodedContent content = new FormUrlEncodedContent(form); + // Post to the Server and parse the response. + //HttpResponseMessage response = await client.PostAsync("Token", content); + // string jsonString = await response.Content.ReadAsStringAsync(); + //HttpResponseMessage response = client.PostAsync(actionEntry, content).GetAwaiter().GetResult(); + actionEntry = actionEntry + "?user=" + username + "&pass=" + password; + //client.GetFromJsonAsync(actionEntry); + + HttpResponseMessage response = client.GetAsync(actionEntry).GetAwaiter().GetResult(); + if (response.StatusCode == HttpStatusCode.OK) + { + mytoken = (response.Content.ReadAsStringAsync().GetAwaiter().GetResult()); + + + result = mytoken; + + } + else + { + result = response.ReasonPhrase.ToString(); + error = result; + result = ""; + } + } + + return result; + } + /// + /// GetLoginAD Async version + /// + /// "http://virtapp-mdb048/CommonAPI/api/AD/" + /// "CheckADCredentials" + /// + /// + /// + public static async Task GetLoginADAsync(string webAPIUri, string actionEntry, string username, string password) + { + MyADObject result = null; + if (!webAPIUri.EndsWith("/")) + webAPIUri += "/"; + string error = ""; + System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; + using (var client = new HttpClient()) + { + client.BaseAddress = new Uri(webAPIUri); + + // We want the response to be JSON. + // client.DefaultRequestHeaders.Accept.Clear(); + // client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + + // Build up the data to POST. + // List> postData = new List>(); + // postData.Add(new KeyValuePair("user", username)); + // postData.Add(new KeyValuePair("pass", password)); + //postData.Add(new KeyValuePair("client_secret", clientSecret)); + + //var form = new Dictionary + //{ + // {"grant_type", "client_credentials"}, + + //}; + //client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); + //client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(username + ":" + password))); + + // HttpContent content = new StringContent(json, Encoding.UTF8); + + // actionEntry = webAPIUri + actionEntry; + // FormUrlEncodedContent content = new FormUrlEncodedContent(postData); + //FormUrlEncodedContent content = new FormUrlEncodedContent(form); + // Post to the Server and parse the response. + //HttpResponseMessage response = await client.PostAsync("Token", content); + // string jsonString = await response.Content.ReadAsStringAsync(); + //HttpResponseMessage response = client.PostAsync(actionEntry, content).GetAwaiter().GetResult(); + actionEntry = actionEntry + "?user=" + username + "&pass=" + password; + try + { + result = await client.GetFromJsonAsync(actionEntry); + } + catch (Exception ex) + { + error = ex.ToString(); + result = null; + } + + } + return result; + } + } +} diff --git a/CommonAuth/ADConfig.cs b/CommonAuth/ADConfig.cs new file mode 100644 index 0000000..24354da --- /dev/null +++ b/CommonAuth/ADConfig.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Configuration; + +namespace CommonApi.Models +{ + public class ADConfig + { + public string LDAPPath = ""; + public string LDAPUser = ""; + public string LDAPPassword = ""; + private TimeSpan _ADTimeOut = TimeSpan.FromSeconds(0); + + public TimeSpan ADTimeOut + { + get + { + return _ADTimeOut; + } + } + public string ADTimeOutStr + { + set + { + if (!string.IsNullOrEmpty(value)) + _ADTimeOut = TimeSpan.FromSeconds(Convert.ToDouble(value)); + } + } + + /* + public static void Init() + { + LDAPPath = ConfigurationManager.AppSettings["LDAPPath"]; + LDAPUser = ConfigurationManager.AppSettings["LDAPUser"]; + LDAPPassword = ConfigurationManager.AppSettings["LDAPPassword"]; + ADTimeOut = TimeSpan.FromSeconds(Convert.ToDouble(ConfigurationManager.AppSettings["ADTimeOut"])); + } + */ + } +} + + diff --git a/CommonAuth/ADStaffLink.cs b/CommonAuth/ADStaffLink.cs new file mode 100644 index 0000000..4b3e675 --- /dev/null +++ b/CommonAuth/ADStaffLink.cs @@ -0,0 +1,374 @@ +using CommonApi.Models; +using CommonAuth.Models; +using System; +using System.Collections.Generic; +using System.DirectoryServices; + + +namespace CommonAuth +{ + public class ADStaffLink + { + private ADConfig _adConfig; + public ADStaffLink (ADConfig adConfig) + { + _adConfig = adConfig; + } + public MyADObject SearchStaff(string FirstName = "", string LastName = "") + { + + MyADObject ADObj = new MyADObject(); + + using (var DE = new System.DirectoryServices.DirectoryEntry(_adConfig.LDAPPath, _adConfig.LDAPUser, _adConfig.LDAPPassword)) + { + try + { + DirectorySearcher adsSearcher = new DirectorySearcher(DE); + adsSearcher.ClientTimeout = _adConfig.ADTimeOut; + adsSearcher.ServerTimeLimit = _adConfig.ADTimeOut; + adsSearcher.ServerPageTimeLimit = _adConfig.ADTimeOut; + adsSearcher.Filter = string.Format("(&(objectCategory=person)(objectClass=user)(givenname={0})(sn={1}))", FirstName, LastName); + try + { + SearchResult sr = adsSearcher.FindOne(); + if (sr != null) + { + ADObj.result = true; + //LoginResult.Login = GetUserPropertyValue(sr, "sAMAccountName", 0); + ADObj.StafflinkNo = GetUserPropertyValue(sr, "sAMAccountName", 0); + ADObj.FirstName = GetUserPropertyValue(sr, "givenname", 0); + ADObj.LastName = GetUserPropertyValue(sr, "sn", 0); + ADObj.Email = GetUserPropertyValue(sr, "mail", 0); + ADObj.Company = GetUserPropertyValue(sr, "company", 0); + ADObj.Location = GetUserPropertyValue(sr, "physicalDeliveryOfficeName", 0); + ADObj.Department = GetUserPropertyValue(sr, "department", 0); + ADObj.BadPwdCount = GetUserPropertyValue(sr, "badPwdCount", 0); + ADObj.Phone = GetUserPropertyValue(sr, "telephonenumber", 0); + ADObj.DisplayName = GetUserPropertyValue(sr, "displayName", 0); + ADObj.Manager = GetUserPropertyValue(sr, "manager", 0); + ADObj.ReportsTo = GetUserPropertyValue(sr, "directReports", 0); + ADObj.StaffList = GetUserPropertyValue(sr, "staffList", 0); + } + } + catch + { + // Failed to authenticate. Most likely it is caused by unknown user + // id or bad strPassword. + ADObj.result = false; + } + } + catch + { + ADObj.result = false; + } + } + + //LoginResult.Success = res; + //string token = ""; + //long tickTock = DateTime.Now.Ticks; + //if (res) + //{ + // string tokenPT = app + "|" + user + "|" + "|" + tickTock + "|" + "NBM"; + // token = CommonCrypt.EncryptString(tokenPT, "bagmas2011+", "a1b2c3d4"); + // token = CommonEncoding.Base64Encode(token); + //} + //LoginResult.Login = user; + //LoginResult.Token = token; + //LoginResult.Time = tickTock; + return ADObj; + + + } + public MyADObject SearchStaff(string StaffLinkNo) + { + + MyADObject ADObj = new MyADObject(); + + using (var DE = new System.DirectoryServices.DirectoryEntry(_adConfig.LDAPPath, _adConfig.LDAPUser, _adConfig.LDAPPassword)) + { + try + { + DirectorySearcher adsSearcher = new DirectorySearcher(DE); + adsSearcher.ClientTimeout = _adConfig.ADTimeOut; + adsSearcher.ServerTimeLimit = _adConfig.ADTimeOut; + adsSearcher.ServerPageTimeLimit = _adConfig.ADTimeOut; + adsSearcher.Filter = "(SAMAccountName=" + StaffLinkNo + ")"; + try + { + SearchResult sr = adsSearcher.FindOne(); + if (sr != null) + { + ADObj.result = true; + // LoginResult.Login = GetUserPropertyValue(sr, "sAMAccountName", 0); ; + ADObj.StafflinkNo = GetUserPropertyValue(sr, "SAMAccountName", 0); + ADObj.FirstName = GetUserPropertyValue(sr, "givenname", 0); + ADObj.LastName = GetUserPropertyValue(sr, "sn", 0); + ADObj.Email = GetUserPropertyValue(sr, "mail", 0); + ADObj.Company = GetUserPropertyValue(sr, "company", 0); + ADObj.Location = GetUserPropertyValue(sr, "physicalDeliveryOfficeName", 0); + ADObj.Department = GetUserPropertyValue(sr, "department", 0); + ADObj.JobTitle = GetUserPropertyValue(sr, "title", 0); + ADObj.BadPwdCount = GetUserPropertyValue(sr, "badPwdCount", 0); + ADObj.Phone = GetUserPropertyValue(sr, "telephonenumber", 0); + ADObj.DisplayName = GetUserPropertyValue(sr, "displayName", 0); + ADObj.Manager = GetUserPropertyValue(sr, "manager", 0); + ADObj.ReportsTo = GetUserPropertyValue(sr, "directReports", 0); + ADObj.StaffList = GetUserPropertyValue(sr, "staffList", 0); + } + } + catch (Exception ex) + { + // Failed to authenticate. Most likely it is caused by unknown user + // id or bad strPassword. + ADObj.result = false; + } + } + catch + { + ADObj.result = false; + } + } + + //LoginResult.Success = res; + //string token = ""; + //long tickTock = DateTime.Now.Ticks; + //if (res) + //{ + // string tokenPT = app + "|" + user + "|" + "|" + tickTock + "|" + "NBM"; + // token = CommonCrypt.EncryptString(tokenPT, "bagmas2011+", "a1b2c3d4"); + // token = CommonEncoding.Base64Encode(token); + //} + //LoginResult.Login = user; + //LoginResult.Token = token; + //LoginResult.Time = tickTock; + return ADObj; + + + } + public MyADObject CheckADCredentials(string user, string pass) + { + //dynamic LoginResult = new JObject() as dynamic; + bool res = true; + MyADObject ADObj = new MyADObject(); + + using (var DE = new System.DirectoryServices.DirectoryEntry(_adConfig.LDAPPath, user, pass)) + { + try + { + //DE.RefreshCache(); // This will force credentials validation + DirectorySearcher adsSearcher = new DirectorySearcher(DE); + adsSearcher.ClientTimeout = _adConfig.ADTimeOut; + adsSearcher.ServerTimeLimit = _adConfig.ADTimeOut; + adsSearcher.ServerPageTimeLimit = _adConfig.ADTimeOut; + //adsSearcher.Filter = "(&(objectClass=user)(objectCategory=person))"; + adsSearcher.Filter = "(sAMAccountName=" + user + ")"; + + try + { + SearchResult sr = adsSearcher.FindOne(); + if (sr != null) + { + ADObj.StafflinkNo = GetUserPropertyValue(sr, "sAMAccountName", 0); ; + ADObj.FirstName = GetUserPropertyValue(sr, "givenname", 0); + ADObj.LastName = GetUserPropertyValue(sr, "sn", 0); + ADObj.Email = GetUserPropertyValue(sr, "mail", 0); + ADObj.Company = GetUserPropertyValue(sr, "company", 0); + ADObj.Location = GetUserPropertyValue(sr, "physicalDeliveryOfficeName", 0); + ADObj.Department = GetUserPropertyValue(sr, "department", 0); + ADObj.BadPwdCount = GetUserPropertyValue(sr, "badPwdCount", 0); + ADObj.Phone = GetUserPropertyValue(sr, "telephonenumber", 0); + ADObj.DisplayName = GetUserPropertyValue(sr, "displayName", 0); + ADObj.Manager = GetUserPropertyValue(sr, "manager", 0); + + // we will retrieve the count of staff in DirectReports as a flag to determine if this user is a manager + // we will assume if no staff then requests lodged by this user will need signoff by their manager + //LoginResult.StaffListCount = sr.Properties["DirectReports"].Count; + //LoginResult.PWD = ADConfig.LDAPPassword; + //LoginResult.User = ADConfig.LDAPUser; + + + /* // we do not think we need actual staff IDs at this point - a count of staff will be enough for this application + // but leave here in case we need to re-use this in another app. + List StaffList = new List(); + foreach (string objProperty in sr.Properties["DirectReports"]) + { + + + string emp = objProperty.ToString().Split(',')[0]; + emp = emp.Replace("CN=", ""); + StaffList.Add(emp); + //emps.Add(emp); + //user.StaffList += '|'; + //user.StaffList += emp; + // + } + LoginResult.StaffList = JsonConvert.SerializeObject(StaffList); + */ + + try + { + if (ADObj.Manager != String.Empty) + { + String managerInfo = Convert.ToString(ADObj.Manager); + String managerID = managerInfo.Split(',')[0].Split('=')[1]; + String managerOU = managerInfo.Split(',')[1].Split('=')[1]; + List managerDetails = Search(managerID, managerOU); + // JToken managerDetails = Search(managerID); + ADObj.ManagerDetails = managerDetails[0].ToString(); + } + } + catch (Exception ex) + { + ADObj.ManagerDetails = "Not available: " + ex.Message; + } + + } + } + catch (Exception ex2) + { + // Failed to authenticate. Most likely it is caused by unknown user + // id or bad strPassword. + res = false; + } + } + catch + { + res = false; + } + } + + ADObj.result = res; + // string token = ""; + // long tickTock = DateTime.Now.Ticks; + // if (res) + // { + //string tokenPT = app + "|" + user + "|" + pass + "|" + tickTock + "|" + "NBM"; + //token = CommonCrypt.EncryptString(tokenPT, "bagmas2011+", "a1b2c3d4"); + //token = CommonEncoding.Base64Encode(token); + //} + + //LoginResult.Token = token; + //LoginResult.Time = tickTock; + + + //return LoginResult; + return ADObj; + + } + public List Search(string q, string ou) + { + //ou = "Nepean Blue Mountains"; + MyADObject ADObj = new Models.MyADObject(); + //ADConfig.Init(); + + List lstLDAPUser = new List(); + + if (string.IsNullOrEmpty(q)) + q = "______"; //defualt not found + System.DirectoryServices.DirectoryEntry dirEntry = new System.DirectoryServices.DirectoryEntry(_adConfig.LDAPPath, _adConfig.LDAPUser, _adConfig.LDAPPassword); + DirectorySearcher dirSearch = new DirectorySearcher(dirEntry); + dirSearch.ClientTimeout = _adConfig.ADTimeOut; + dirSearch.ServerTimeLimit = _adConfig.ADTimeOut; + dirSearch.ServerPageTimeLimit = _adConfig.ADTimeOut; + dirSearch.Filter = "(&(objectClass=user)(|(cn=" + q + "*)))"; + dirSearch.SearchRoot = dirEntry; + dirSearch.SearchScope = SearchScope.Subtree; + dirSearch.PageSize = 100; + dirSearch.Sort = new SortOption("displayName", SortDirection.Ascending); + + + using (SearchResultCollection src = dirSearch.FindAll()) + { + int i = 0; + foreach (SearchResult sr in src) + { + i++; + if (i > 100) + break; + bool bLogindisabled = true; + + string sTmp = GetUserPropertyValue(sr, "logindisabled", 0); + bLogindisabled = (sTmp == string.Empty ? false : Convert.ToBoolean(sTmp)); + + if (!bLogindisabled) + { + sTmp = GetUserPropertyValue(sr, "passwordexpirationtime", 0); + if (sTmp != "") + { + try + { + if (DateTime.Now > Convert.ToDateTime(sTmp)) + { + bLogindisabled = true; + } + } + catch { } + } + } + + if (!bLogindisabled) + { + MyADObject user = new MyADObject(); + // user.Login = GetUserPropertyValue(sr, "sAMAccountName", 0); + user.StafflinkNo = GetUserPropertyValue(sr, "sAMAccountName", 0); + user.FirstName = GetUserPropertyValue(sr, "givenname", 0); + user.LastName = GetUserPropertyValue(sr, "sn", 0); + user.Email = GetUserPropertyValue(sr, "mail", 0); + user.Company = GetUserPropertyValue(sr, "company", 0); + user.Location = GetUserPropertyValue(sr, "physicalDeliveryOfficeName", 0); + user.Department = GetUserPropertyValue(sr, "department", 0); + user.BadPwdCount = GetUserPropertyValue(sr, "badPwdCount", 0); + //user.company = GetUserPropertyValue(sr, "company", 0); + user.Phone = GetUserPropertyValue(sr, "telephonenumber", 0); + user.DisplayName = GetUserPropertyValue(sr, "displayName", 0); + //user.distinguishedName = GetUserPropertyValue(sr, "distinguishedName", 0); + user.DisplayName = GetUserPropertyValue(sr, "displayName", 0); + + lstLDAPUser.Add(user); + } + + } + + } + if (dirSearch != null) + dirSearch.Dispose(); + if (dirEntry != null) + dirEntry.Dispose(); + return lstLDAPUser; + + }//end method + private string GetUserPropertyValue(SearchResult res, string sPropertyName, int lIndex) + { + try + { + if (res.Properties[sPropertyName].Count > lIndex) + { + string s; + object v = res.Properties[sPropertyName][lIndex]; + + if (v.GetType() == typeof(byte[])) + { + s = System.Text.ASCIIEncoding.ASCII.GetString((byte[])v); + } + else if (v.GetType() == typeof(DateTime)) + { + s = ((DateTime)v).ToLocalTime().ToString("yyyy/MM/dd HH:mm:ss"); + } + else + { + s = v.ToString(); + } + return (s); + } + else + { + return (""); + } + } + catch + { + return (""); + } + } + } +} diff --git a/CommonAuth/CommonAuth.csproj b/CommonAuth/CommonAuth.csproj new file mode 100644 index 0000000..51d25f4 --- /dev/null +++ b/CommonAuth/CommonAuth.csproj @@ -0,0 +1,13 @@ + + + + netstandard2.0 + + + + + + + + + diff --git a/CommonAuth/MyADObject.cs b/CommonAuth/MyADObject.cs new file mode 100644 index 0000000..040b45d --- /dev/null +++ b/CommonAuth/MyADObject.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Configuration; + + +namespace CommonAuth.Models +{ + public class MyADObject + { + public string StafflinkNo { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Email { get; set; } + public string Company { get; set; } + public string Location { get; set; } + public string Department { get; set; } + public string JobTitle { get; set; } + public string BadPwdCount { get; set; } + public string Phone { get; set; } + public string DisplayName { get; set; } + public string Manager { get; set; } + public string ReportsTo { get; set; } + public string StaffList { get; set; } + public string ManagerDetails { get; set; } + public bool result { get; set; } + + + } + + +} diff --git a/CommonAuth_old/ADConfig.cs b/CommonAuth_old/ADConfig.cs new file mode 100644 index 0000000..24354da --- /dev/null +++ b/CommonAuth_old/ADConfig.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Configuration; + +namespace CommonApi.Models +{ + public class ADConfig + { + public string LDAPPath = ""; + public string LDAPUser = ""; + public string LDAPPassword = ""; + private TimeSpan _ADTimeOut = TimeSpan.FromSeconds(0); + + public TimeSpan ADTimeOut + { + get + { + return _ADTimeOut; + } + } + public string ADTimeOutStr + { + set + { + if (!string.IsNullOrEmpty(value)) + _ADTimeOut = TimeSpan.FromSeconds(Convert.ToDouble(value)); + } + } + + /* + public static void Init() + { + LDAPPath = ConfigurationManager.AppSettings["LDAPPath"]; + LDAPUser = ConfigurationManager.AppSettings["LDAPUser"]; + LDAPPassword = ConfigurationManager.AppSettings["LDAPPassword"]; + ADTimeOut = TimeSpan.FromSeconds(Convert.ToDouble(ConfigurationManager.AppSettings["ADTimeOut"])); + } + */ + } +} + + diff --git a/CommonAuth_old/ADStaffLink.cs b/CommonAuth_old/ADStaffLink.cs new file mode 100644 index 0000000..56ec333 --- /dev/null +++ b/CommonAuth_old/ADStaffLink.cs @@ -0,0 +1,374 @@ +using CommonApi.Models; +using CommonAuth.Models; +using System; +using System.Collections.Generic; +using System.DirectoryServices; +using System.Reflection.PortableExecutable; + +namespace CommonAuth +{ + public class ADStaffLink + { + private ADConfig _adConfig; + public ADStaffLink (ADConfig adConfig) + { + _adConfig = adConfig; + } + public MyADObject SearchStaff(string FirstName = "", string LastName = "") + { + + MyADObject ADObj = new MyADObject(); + + using (var DE = new System.DirectoryServices.DirectoryEntry(_adConfig.LDAPPath, _adConfig.LDAPUser, _adConfig.LDAPPassword)) + { + try + { + DirectorySearcher adsSearcher = new DirectorySearcher(DE); + adsSearcher.ClientTimeout = _adConfig.ADTimeOut; + adsSearcher.ServerTimeLimit = _adConfig.ADTimeOut; + adsSearcher.ServerPageTimeLimit = _adConfig.ADTimeOut; + adsSearcher.Filter = string.Format("(&(objectCategory=person)(objectClass=user)(givenname={0})(sn={1}))", FirstName, LastName); + try + { + SearchResult sr = adsSearcher.FindOne(); + if (sr != null) + { + ADObj.result = true; + //LoginResult.Login = GetUserPropertyValue(sr, "sAMAccountName", 0); + ADObj.StafflinkNo = GetUserPropertyValue(sr, "sAMAccountName", 0); + ADObj.FirstName = GetUserPropertyValue(sr, "givenname", 0); + ADObj.LastName = GetUserPropertyValue(sr, "sn", 0); + ADObj.Email = GetUserPropertyValue(sr, "mail", 0); + ADObj.Company = GetUserPropertyValue(sr, "company", 0); + ADObj.Location = GetUserPropertyValue(sr, "physicalDeliveryOfficeName", 0); + ADObj.Department = GetUserPropertyValue(sr, "department", 0); + ADObj.BadPwdCount = GetUserPropertyValue(sr, "badPwdCount", 0); + ADObj.Phone = GetUserPropertyValue(sr, "telephonenumber", 0); + ADObj.DisplayName = GetUserPropertyValue(sr, "displayName", 0); + ADObj.Manager = GetUserPropertyValue(sr, "manager", 0); + ADObj.ReportsTo = GetUserPropertyValue(sr, "directReports", 0); + ADObj.StaffList = GetUserPropertyValue(sr, "staffList", 0); + } + } + catch + { + // Failed to authenticate. Most likely it is caused by unknown user + // id or bad strPassword. + ADObj.result = false; + } + } + catch + { + ADObj.result = false; + } + } + + //LoginResult.Success = res; + //string token = ""; + //long tickTock = DateTime.Now.Ticks; + //if (res) + //{ + // string tokenPT = app + "|" + user + "|" + "|" + tickTock + "|" + "NBM"; + // token = CommonCrypt.EncryptString(tokenPT, "bagmas2011+", "a1b2c3d4"); + // token = CommonEncoding.Base64Encode(token); + //} + //LoginResult.Login = user; + //LoginResult.Token = token; + //LoginResult.Time = tickTock; + return ADObj; + + + } + public MyADObject SearchStaff(string StaffLinkNo) + { + + MyADObject ADObj = new MyADObject(); + + using (var DE = new System.DirectoryServices.DirectoryEntry(_adConfig.LDAPPath, _adConfig.LDAPUser, _adConfig.LDAPPassword)) + { + try + { + DirectorySearcher adsSearcher = new DirectorySearcher(DE); + adsSearcher.ClientTimeout = _adConfig.ADTimeOut; + adsSearcher.ServerTimeLimit = _adConfig.ADTimeOut; + adsSearcher.ServerPageTimeLimit = _adConfig.ADTimeOut; + adsSearcher.Filter = "(SAMAccountName=" + StaffLinkNo + ")"; + try + { + SearchResult sr = adsSearcher.FindOne(); + if (sr != null) + { + ADObj.result = true; + // LoginResult.Login = GetUserPropertyValue(sr, "sAMAccountName", 0); ; + ADObj.StafflinkNo = GetUserPropertyValue(sr, "SAMAccountName", 0); + ADObj.FirstName = GetUserPropertyValue(sr, "givenname", 0); + ADObj.LastName = GetUserPropertyValue(sr, "sn", 0); + ADObj.Email = GetUserPropertyValue(sr, "mail", 0); + ADObj.Company = GetUserPropertyValue(sr, "company", 0); + ADObj.Location = GetUserPropertyValue(sr, "physicalDeliveryOfficeName", 0); + ADObj.Department = GetUserPropertyValue(sr, "department", 0); + ADObj.JobTitle = GetUserPropertyValue(sr, "title", 0); + ADObj.BadPwdCount = GetUserPropertyValue(sr, "badPwdCount", 0); + ADObj.Phone = GetUserPropertyValue(sr, "telephonenumber", 0); + ADObj.DisplayName = GetUserPropertyValue(sr, "displayName", 0); + ADObj.Manager = GetUserPropertyValue(sr, "manager", 0); + ADObj.ReportsTo = GetUserPropertyValue(sr, "directReports", 0); + ADObj.StaffList = GetUserPropertyValue(sr, "staffList", 0); + } + } + catch (Exception ex) + { + // Failed to authenticate. Most likely it is caused by unknown user + // id or bad strPassword. + ADObj.result = false; + } + } + catch + { + ADObj.result = false; + } + } + + //LoginResult.Success = res; + //string token = ""; + //long tickTock = DateTime.Now.Ticks; + //if (res) + //{ + // string tokenPT = app + "|" + user + "|" + "|" + tickTock + "|" + "NBM"; + // token = CommonCrypt.EncryptString(tokenPT, "bagmas2011+", "a1b2c3d4"); + // token = CommonEncoding.Base64Encode(token); + //} + //LoginResult.Login = user; + //LoginResult.Token = token; + //LoginResult.Time = tickTock; + return ADObj; + + + } + public MyADObject CheckADCredentials(string user, string pass) + { + //dynamic LoginResult = new JObject() as dynamic; + bool res = true; + MyADObject ADObj = new MyADObject(); + + using (var DE = new System.DirectoryServices.DirectoryEntry(_adConfig.LDAPPath, user, pass)) + { + try + { + //DE.RefreshCache(); // This will force credentials validation + DirectorySearcher adsSearcher = new DirectorySearcher(DE); + adsSearcher.ClientTimeout = _adConfig.ADTimeOut; + adsSearcher.ServerTimeLimit = _adConfig.ADTimeOut; + adsSearcher.ServerPageTimeLimit = _adConfig.ADTimeOut; + //adsSearcher.Filter = "(&(objectClass=user)(objectCategory=person))"; + adsSearcher.Filter = "(sAMAccountName=" + user + ")"; + + try + { + SearchResult sr = adsSearcher.FindOne(); + if (sr != null) + { + ADObj.StafflinkNo = GetUserPropertyValue(sr, "sAMAccountName", 0); ; + ADObj.FirstName = GetUserPropertyValue(sr, "givenname", 0); + ADObj.LastName = GetUserPropertyValue(sr, "sn", 0); + ADObj.Email = GetUserPropertyValue(sr, "mail", 0); + ADObj.Company = GetUserPropertyValue(sr, "company", 0); + ADObj.Location = GetUserPropertyValue(sr, "physicalDeliveryOfficeName", 0); + ADObj.Department = GetUserPropertyValue(sr, "department", 0); + ADObj.BadPwdCount = GetUserPropertyValue(sr, "badPwdCount", 0); + ADObj.Phone = GetUserPropertyValue(sr, "telephonenumber", 0); + ADObj.DisplayName = GetUserPropertyValue(sr, "displayName", 0); + ADObj.Manager = GetUserPropertyValue(sr, "manager", 0); + + // we will retrieve the count of staff in DirectReports as a flag to determine if this user is a manager + // we will assume if no staff then requests lodged by this user will need signoff by their manager + //LoginResult.StaffListCount = sr.Properties["DirectReports"].Count; + //LoginResult.PWD = ADConfig.LDAPPassword; + //LoginResult.User = ADConfig.LDAPUser; + + + /* // we do not think we need actual staff IDs at this point - a count of staff will be enough for this application + // but leave here in case we need to re-use this in another app. + List StaffList = new List(); + foreach (string objProperty in sr.Properties["DirectReports"]) + { + + + string emp = objProperty.ToString().Split(',')[0]; + emp = emp.Replace("CN=", ""); + StaffList.Add(emp); + //emps.Add(emp); + //user.StaffList += '|'; + //user.StaffList += emp; + // + } + LoginResult.StaffList = JsonConvert.SerializeObject(StaffList); + */ + + try + { + if (ADObj.Manager != String.Empty) + { + String managerInfo = Convert.ToString(ADObj.Manager); + String managerID = managerInfo.Split(',')[0].Split('=')[1]; + String managerOU = managerInfo.Split(',')[1].Split('=')[1]; + List managerDetails = Search(managerID, managerOU); + // JToken managerDetails = Search(managerID); + ADObj.ManagerDetails = managerDetails[0].ToString(); + } + } + catch (Exception ex) + { + ADObj.ManagerDetails = "Not available: " + ex.Message; + } + + } + } + catch (Exception ex2) + { + // Failed to authenticate. Most likely it is caused by unknown user + // id or bad strPassword. + res = false; + } + } + catch + { + res = false; + } + } + + ADObj.result = res; + // string token = ""; + // long tickTock = DateTime.Now.Ticks; + // if (res) + // { + //string tokenPT = app + "|" + user + "|" + pass + "|" + tickTock + "|" + "NBM"; + //token = CommonCrypt.EncryptString(tokenPT, "bagmas2011+", "a1b2c3d4"); + //token = CommonEncoding.Base64Encode(token); + //} + + //LoginResult.Token = token; + //LoginResult.Time = tickTock; + + + //return LoginResult; + return ADObj; + + } + public List Search(string q, string ou) + { + //ou = "Nepean Blue Mountains"; + MyADObject ADObj = new Models.MyADObject(); + //ADConfig.Init(); + + List lstLDAPUser = new List(); + + if (string.IsNullOrEmpty(q)) + q = "______"; //defualt not found + System.DirectoryServices.DirectoryEntry dirEntry = new System.DirectoryServices.DirectoryEntry(_adConfig.LDAPPath, _adConfig.LDAPUser, _adConfig.LDAPPassword); + DirectorySearcher dirSearch = new DirectorySearcher(dirEntry); + dirSearch.ClientTimeout = _adConfig.ADTimeOut; + dirSearch.ServerTimeLimit = _adConfig.ADTimeOut; + dirSearch.ServerPageTimeLimit = _adConfig.ADTimeOut; + dirSearch.Filter = "(&(objectClass=user)(|(cn=" + q + "*)))"; + dirSearch.SearchRoot = dirEntry; + dirSearch.SearchScope = SearchScope.Subtree; + dirSearch.PageSize = 100; + dirSearch.Sort = new SortOption("displayName", SortDirection.Ascending); + + + using (SearchResultCollection src = dirSearch.FindAll()) + { + int i = 0; + foreach (SearchResult sr in src) + { + i++; + if (i > 100) + break; + bool bLogindisabled = true; + + string sTmp = GetUserPropertyValue(sr, "logindisabled", 0); + bLogindisabled = (sTmp == string.Empty ? false : Convert.ToBoolean(sTmp)); + + if (!bLogindisabled) + { + sTmp = GetUserPropertyValue(sr, "passwordexpirationtime", 0); + if (sTmp != "") + { + try + { + if (DateTime.Now > Convert.ToDateTime(sTmp)) + { + bLogindisabled = true; + } + } + catch { } + } + } + + if (!bLogindisabled) + { + MyADObject user = new MyADObject(); + // user.Login = GetUserPropertyValue(sr, "sAMAccountName", 0); + user.StafflinkNo = GetUserPropertyValue(sr, "sAMAccountName", 0); + user.FirstName = GetUserPropertyValue(sr, "givenname", 0); + user.LastName = GetUserPropertyValue(sr, "sn", 0); + user.Email = GetUserPropertyValue(sr, "mail", 0); + user.Company = GetUserPropertyValue(sr, "company", 0); + user.Location = GetUserPropertyValue(sr, "physicalDeliveryOfficeName", 0); + user.Department = GetUserPropertyValue(sr, "department", 0); + user.BadPwdCount = GetUserPropertyValue(sr, "badPwdCount", 0); + //user.company = GetUserPropertyValue(sr, "company", 0); + user.Phone = GetUserPropertyValue(sr, "telephonenumber", 0); + user.DisplayName = GetUserPropertyValue(sr, "displayName", 0); + //user.distinguishedName = GetUserPropertyValue(sr, "distinguishedName", 0); + user.DisplayName = GetUserPropertyValue(sr, "displayName", 0); + + lstLDAPUser.Add(user); + } + + } + + } + if (dirSearch != null) + dirSearch.Dispose(); + if (dirEntry != null) + dirEntry.Dispose(); + return lstLDAPUser; + + }//end method + private string GetUserPropertyValue(SearchResult res, string sPropertyName, int lIndex) + { + try + { + if (res.Properties[sPropertyName].Count > lIndex) + { + string s; + object v = res.Properties[sPropertyName][lIndex]; + + if (v.GetType() == typeof(byte[])) + { + s = System.Text.ASCIIEncoding.ASCII.GetString((byte[])v); + } + else if (v.GetType() == typeof(DateTime)) + { + s = ((DateTime)v).ToLocalTime().ToString("yyyy/MM/dd HH:mm:ss"); + } + else + { + s = v.ToString(); + } + return (s); + } + else + { + return (""); + } + } + catch + { + return (""); + } + } + } +} diff --git a/CommonAuth_old/CommonAuth.csproj b/CommonAuth_old/CommonAuth.csproj new file mode 100644 index 0000000..8008d62 --- /dev/null +++ b/CommonAuth_old/CommonAuth.csproj @@ -0,0 +1,11 @@ + + + + net5.0 + + + + + + + diff --git a/CommonAuth_old/MyADObject.cs b/CommonAuth_old/MyADObject.cs new file mode 100644 index 0000000..040b45d --- /dev/null +++ b/CommonAuth_old/MyADObject.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Configuration; + + +namespace CommonAuth.Models +{ + public class MyADObject + { + public string StafflinkNo { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Email { get; set; } + public string Company { get; set; } + public string Location { get; set; } + public string Department { get; set; } + public string JobTitle { get; set; } + public string BadPwdCount { get; set; } + public string Phone { get; set; } + public string DisplayName { get; set; } + public string Manager { get; set; } + public string ReportsTo { get; set; } + public string StaffList { get; set; } + public string ManagerDetails { get; set; } + public bool result { get; set; } + + + } + + +}