382 lines
17 KiB
C#
382 lines
17 KiB
C#
using AutoMapper;
|
|
using DamageAssesment.Api.UsersAccess.Db;
|
|
using DamageAssesment.Api.UsersAccess.Interfaces;
|
|
using DamageAssesment.Api.UsersAccess.Models;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Options;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
using System.Data;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Security.Claims;
|
|
using System.Text;
|
|
|
|
namespace DamageAssesment.Api.UsersAccess.Providers
|
|
{
|
|
public class UsersAccessProvider : IUsersAccessProvider
|
|
{
|
|
private readonly UsersAccessDbContext userAccessDbContext;
|
|
private readonly ILogger<UsersAccessProvider> logger;
|
|
private readonly IMapper mapper;
|
|
private readonly IEmployeeServiceProvider employeeServiceProvider;
|
|
private readonly JwtSettings jwtSettings;
|
|
private readonly ITokenServiceProvider tokenServiceProvider;
|
|
private readonly IConfiguration configuration;
|
|
private readonly IHttpContextAccessor httpContextAccessor;
|
|
|
|
public UsersAccessProvider(IConfiguration configuration,IOptions<JwtSettings> options, ITokenServiceProvider tokenServiceProvider, IHttpContextAccessor httpContextAccessor, UsersAccessDbContext userAccessDbContext, IEmployeeServiceProvider employeeServiceProvider, ILogger<UsersAccessProvider> logger, IMapper mapper)
|
|
{
|
|
this.userAccessDbContext = userAccessDbContext;
|
|
this.employeeServiceProvider = employeeServiceProvider;
|
|
this.logger = logger;
|
|
this.mapper = mapper;
|
|
jwtSettings = options.Value;
|
|
this.tokenServiceProvider = tokenServiceProvider;
|
|
this.httpContextAccessor = httpContextAccessor;
|
|
this.configuration = configuration;
|
|
seedData();
|
|
}
|
|
|
|
public void seedData()
|
|
{
|
|
if (!userAccessDbContext.Users.Any())
|
|
{
|
|
userAccessDbContext.Users.Add(new Db.User { Id = 1, EmployeeId = 1, EmployeeCode = "Emp1", RoleId = 1, IsActive = true, CreateDate = DateTime.Now });
|
|
userAccessDbContext.Users.Add(new Db.User { Id = 2, EmployeeId = 2, EmployeeCode = "Emp2", RoleId = 2, IsActive = true, CreateDate = DateTime.Now });
|
|
userAccessDbContext.Users.Add(new Db.User { Id = 3, EmployeeId = 3, EmployeeCode = "Emp3", RoleId = 3, IsActive = true, CreateDate = DateTime.Now });
|
|
userAccessDbContext.SaveChanges();
|
|
}
|
|
|
|
if (!userAccessDbContext.Roles.Any())
|
|
{
|
|
userAccessDbContext.Roles.Add(new Db.Role { Id = 1, Name = "admin", Description ="Administrator role have full access" });
|
|
userAccessDbContext.Roles.Add(new Db.Role { Id = 2, Name = "user", Description =" User role"});
|
|
userAccessDbContext.Roles.Add(new Db.Role { Id = 3, Name = "survey", Description ="Survey role" });
|
|
userAccessDbContext.Roles.Add(new Db.Role { Id = 4, Name = "report", Description ="Report role"});
|
|
userAccessDbContext.Roles.Add(new Db.Role { Id = 5, Name = "document", Description ="Document role" });
|
|
userAccessDbContext.SaveChanges();
|
|
}
|
|
}
|
|
private string GetToken()
|
|
{
|
|
string token = httpContextAccessor.HttpContext.Request.Headers.Authorization;
|
|
if (token != null)
|
|
{
|
|
token = token.Replace("Bearer ", string.Empty);
|
|
}
|
|
else
|
|
{
|
|
token = "";
|
|
}
|
|
return token;
|
|
}
|
|
public async Task<(bool IsSuccess, IEnumerable<object> Users, string ErrorMessage)> GetUsersAsync()
|
|
{
|
|
try
|
|
{
|
|
logger?.LogInformation("Gell all Users from DB");
|
|
var users = await userAccessDbContext.Users.ToListAsync();
|
|
List<object> userslist= new List<object>();
|
|
if (users != null)
|
|
{
|
|
var employees = await employeeServiceProvider.getEmployeesAsync( GetToken());
|
|
var roles = await userAccessDbContext.Roles.ToListAsync();
|
|
foreach (Db.User user in users)
|
|
{
|
|
var employee = employees.SingleOrDefault(a=>a.Id==user.EmployeeId);
|
|
var role = roles.SingleOrDefault(s => s.Id == user.RoleId);
|
|
userslist.Add(new
|
|
{
|
|
Id = user.Id,
|
|
EmployeeId = user.EmployeeId,
|
|
EmployeeCode = user.EmployeeCode,
|
|
EmployeeName = (employee != null) ? employee.Name : null,
|
|
RoleId = user.RoleId,
|
|
RoleName = (role != null) ? role.Name : null
|
|
});
|
|
}
|
|
logger?.LogInformation($"{users.Count} Items(s) found");
|
|
// var result = mapper.Map<IEnumerable<Db.User>, IEnumerable<Models.User>>(users);
|
|
return (true, userslist, null);
|
|
}
|
|
return (false, null, "Not found");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex.ToString());
|
|
return (false, null, ex.Message);
|
|
}
|
|
}
|
|
public async Task<(bool IsSuccess, object User, string ErrorMessage)> GetUsersAsync(int Id)
|
|
{
|
|
try
|
|
{
|
|
logger?.LogInformation("Querying Users table");
|
|
|
|
var user = await userAccessDbContext.Users.SingleOrDefaultAsync(s => s.Id == Id);
|
|
if (user != null)
|
|
{
|
|
var employee = await employeeServiceProvider.getEmployeeAsync(user.EmployeeId,GetToken());
|
|
var role = await userAccessDbContext.Roles.SingleOrDefaultAsync(s => s.Id == user.RoleId);
|
|
var data = new
|
|
{
|
|
Id = user.Id,
|
|
EmployeeId = user.EmployeeId,
|
|
EmployeeCode=user.EmployeeCode,
|
|
EmployeeName = (employee != null) ? employee.Name : null,
|
|
RoleId = user.RoleId,
|
|
RoleName = (role!=null)?role.Name:null
|
|
};
|
|
logger?.LogInformation($"User Id: {Id} found");
|
|
var result = mapper.Map<Db.User, Models.User>(user);
|
|
return (true, data, null);
|
|
}
|
|
return (false, null, "Not found");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex.ToString());
|
|
return (false, null, ex.Message);
|
|
}
|
|
}
|
|
|
|
public async Task<(bool IsSuccess, Models.User User, string ErrorMessage)> PostUserAsync(Models.User user)
|
|
{
|
|
try
|
|
{
|
|
if (user != null)
|
|
{
|
|
var _user = mapper.Map<Models.User, Db.User>(user);
|
|
userAccessDbContext.Users.Add(_user);
|
|
user.Id = _user.Id;
|
|
await userAccessDbContext.SaveChangesAsync();
|
|
return (true, user, "Successful");
|
|
}
|
|
else
|
|
{
|
|
logger?.LogInformation($"null object cannot be added");
|
|
return (false, null, $"null object cannot be added");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex.ToString());
|
|
return (false, null, ex.Message);
|
|
}
|
|
}
|
|
|
|
public async Task<(bool IsSuccess, Models.User User, string ErrorMessage)> PutUserAsync(int Id, Models.User user)
|
|
{
|
|
try
|
|
{
|
|
if (user != null)
|
|
{
|
|
var _user = await userAccessDbContext.Users.AsNoTracking().Where(s => s.Id == Id).SingleOrDefaultAsync();
|
|
|
|
if (_user != null)
|
|
{
|
|
int count = userAccessDbContext.Users.Where(u => u.Id != user.Id).Count();
|
|
if (count == 0)
|
|
{
|
|
await userAccessDbContext.SaveChangesAsync();
|
|
logger?.LogInformation($"Employee Id: {user.EmployeeId} updated successfuly");
|
|
return (true, mapper.Map<Db.User, Models.User>(_user), $"Employee Id: {_user.EmployeeId} updated successfuly");
|
|
}
|
|
else
|
|
{
|
|
logger?.LogInformation($"Employee Id: {user.EmployeeId} is already exist");
|
|
return (false, null, $"Employee Id: {user.EmployeeId} is already exist");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
logger?.LogInformation($"User Id : {Id} Not found");
|
|
return (false, null, "Not Found");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
logger?.LogInformation($"User Id: {Id} Bad Request");
|
|
return (false, null, "Bad request");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex.ToString());
|
|
return (false, null, ex.Message);
|
|
}
|
|
}
|
|
|
|
public async Task<(bool IsSuccess, Models.User User, string ErrorMessage)> DeleteUserAsync(int Id)
|
|
{
|
|
try
|
|
{
|
|
var user = await userAccessDbContext.Users.Where(x => x.Id == Id).SingleOrDefaultAsync();
|
|
|
|
if (user != null)
|
|
{
|
|
userAccessDbContext.Users.Remove(user);
|
|
await userAccessDbContext.SaveChangesAsync();
|
|
logger?.LogInformation($"User Id: {Id} deleted Successfuly");
|
|
return (true, mapper.Map<Db.User, Models.User>(user), $"User Id: {Id} deleted Successfuly");
|
|
}
|
|
else
|
|
{
|
|
logger?.LogInformation($"User Id : {Id} Not found");
|
|
return (false, null, "Not Found");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex.ToString());
|
|
return (false, null, ex.Message);
|
|
}
|
|
}
|
|
|
|
public async Task<(bool IsSuccess, TokenResponse TokenResponse, string ErrorMessage)> AuthenticateAsync(string employecode)
|
|
{
|
|
|
|
if (employecode != null)
|
|
{
|
|
//implementation for dadeschools authentication
|
|
// var employees = await employeeServiceProvider.getEmployeesAsync();
|
|
// var employee = employees.Where(e=> e.EmployeeCode.ToLower() == employecode.ToLower()).SingleOrDefault();
|
|
var user = userAccessDbContext.Users.Where(x => x.IsActive == true && x.EmployeeCode.ToLower() == employecode.ToLower()).SingleOrDefault();
|
|
|
|
if (user != null)
|
|
{
|
|
|
|
var r = await GetRolesAsync();
|
|
var role = r.Roles.Where(x => x.Id == user.RoleId).SingleOrDefault();
|
|
|
|
var authClaims = new List<Claim> {
|
|
new Claim(ClaimTypes.Name, user.EmployeeCode),
|
|
new Claim(ClaimTypes.Role, role.Name),
|
|
new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString())
|
|
|
|
};
|
|
|
|
/// Generate Token
|
|
var tokenhandler = new JwtSecurityTokenHandler();
|
|
var tokenkey = Encoding.UTF8.GetBytes(jwtSettings.securitykey);
|
|
var tokendesc = new SecurityTokenDescriptor
|
|
{
|
|
Audience = "",
|
|
NotBefore = DateTime.Now,
|
|
Subject = new ClaimsIdentity(authClaims),
|
|
Expires = DateTime.Now.AddMinutes(30),
|
|
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(tokenkey), SecurityAlgorithms.HmacSha256)
|
|
};
|
|
var token = tokenhandler.CreateToken(tokendesc);
|
|
string finaltoken = tokenhandler.WriteToken(token);
|
|
|
|
var response = new TokenResponse() { jwttoken = finaltoken, refreshtoken = await tokenServiceProvider.GenerateToken(mapper.Map<Db.User,Models.User>(user)) };
|
|
return (true, response, "Authentication success and token issued.");
|
|
}
|
|
else
|
|
{
|
|
return (false, null, "user inactive or not exist.");
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
return (false, null, "Credentials are required to authenticate.");
|
|
}
|
|
}
|
|
public async Task<(bool IsSuccess, DadeSchoolToken TokenResponse, string ErrorMessage)> DadeSchoolAuthenticateAsync(string username, string password)
|
|
{
|
|
try
|
|
{
|
|
var client = new HttpClient();
|
|
var request = new HttpRequestMessage(HttpMethod.Post, configuration.GetValue<string>("Dadeschools:TokenUrl"));
|
|
var collection = new List<KeyValuePair<string, string>>();
|
|
collection.Add(new("client_id", configuration.GetValue<string>("Dadeschools:TokenClientId")));
|
|
collection.Add(new("client_secret", configuration.GetValue<string>("Dadeschools:TokenClientSecret")));
|
|
collection.Add(new("scope", configuration.GetValue<string>("Dadeschools:scope")));
|
|
collection.Add(new("grant_type", configuration.GetValue<string>("Dadeschools:grant_type")));
|
|
collection.Add(new("username", username));
|
|
collection.Add(new("password", password));
|
|
var content = new FormUrlEncodedContent(collection);
|
|
request.Content = content;
|
|
var response = await client.SendAsync(request);
|
|
var responseString = await response.Content.ReadAsStringAsync();
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
return (true, JsonConvert.DeserializeObject<DadeSchoolToken>(responseString), "");
|
|
}
|
|
return (false, null, responseString);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return (false, null, ex.Message);
|
|
}
|
|
|
|
}
|
|
public async Task<(bool IsSuccess, IEnumerable<Models.Role> Roles, string ErrorMessage)> GetRolesAsync()
|
|
{
|
|
try
|
|
{
|
|
logger?.LogInformation("Gell all Roles from DB");
|
|
var roles = await userAccessDbContext.Roles.ToListAsync();
|
|
if (roles != null)
|
|
{
|
|
logger?.LogInformation($"{roles.Count} Items(s) found");
|
|
var result = mapper.Map<IEnumerable<Db.Role>, IEnumerable<Models.Role>>(roles);
|
|
return (true, result, null);
|
|
}
|
|
return (false, null, "Not found");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger?.LogError(ex.ToString());
|
|
return (false, null, ex.Message);
|
|
}
|
|
}
|
|
|
|
public async Task<(bool IsSuccess, Models.TokenResponse TokenResponse, string ErrorMessage)> RefreshTokenAsync(TokenResponse tokenResponse)
|
|
{
|
|
//Generate token
|
|
var tokenhandler = new JwtSecurityTokenHandler();
|
|
var tokenkey = Encoding.UTF8.GetBytes(this.jwtSettings.securitykey);
|
|
SecurityToken securityToken;
|
|
var principal = tokenhandler.ValidateToken(tokenResponse.jwttoken, new TokenValidationParameters
|
|
{
|
|
ValidateIssuerSigningKey = true,
|
|
IssuerSigningKey = new SymmetricSecurityKey(tokenkey),
|
|
ValidateIssuer = false,
|
|
ValidateAudience = false,
|
|
|
|
}, out securityToken);
|
|
|
|
var token = securityToken as JwtSecurityToken;
|
|
if (token != null && !token.Header.Alg.Equals(SecurityAlgorithms.HmacSha256))
|
|
{
|
|
return (false, null, "Unauthorized");
|
|
}
|
|
var username = principal.Identity?.Name;
|
|
|
|
var tokens = await userAccessDbContext.Tokens.ToListAsync();
|
|
var users = await userAccessDbContext.Users.ToListAsync();
|
|
|
|
var user = (from u in users
|
|
join t in tokens
|
|
on u.Id equals t.UserId
|
|
where u.EmployeeId == 1
|
|
&& t.RefreshToken == tokenResponse.refreshtoken
|
|
select u).FirstOrDefault();
|
|
|
|
if (user == null)
|
|
return (false, null, "Invalid Token Response object provided");
|
|
|
|
var _user = mapper.Map<Db.User, Models.User>(user);
|
|
var response = tokenServiceProvider.TokenAuthenticate(_user, principal.Claims.ToArray()).Result;
|
|
return (true, response, "Token authenticated and refreshed.");
|
|
}
|
|
|
|
|
|
}
|
|
}
|