diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/DevHive.Data/Repositories/UserRepository.cs | 73 | ||||
| -rw-r--r-- | src/DevHive.Services/Services/UserService.cs | 105 | ||||
| -rw-r--r-- | src/DevHive.Web/Configurations/Mapping/UserMappings.cs | 9 | ||||
| -rw-r--r-- | src/DevHive.Web/Controllers/UserController.cs | 31 | ||||
| -rw-r--r-- | src/DevHive.Web/appsettings.json | 7 |
5 files changed, 141 insertions, 84 deletions
diff --git a/src/DevHive.Data/Repositories/UserRepository.cs b/src/DevHive.Data/Repositories/UserRepository.cs index 5b30c30..13ee2bc 100644 --- a/src/DevHive.Data/Repositories/UserRepository.cs +++ b/src/DevHive.Data/Repositories/UserRepository.cs @@ -17,21 +17,7 @@ namespace DevHive.Data.Repositories this._context = context; } - public bool DoesUserExist(Guid id) - { - return this._context - .Set<User>() - .Any(x => x.Id == id); - } - - public bool HasThisUsername(Guid id, string username) - { - return this._context - .Set<User>() - .Any(x => x.Id == id && - x.UserName == username); - } - + //Create public async Task AddAsync(User entity) { await this._context @@ -40,24 +26,31 @@ namespace DevHive.Data.Repositories await this._context.SaveChangesAsync(); } - - public IEnumerable<User> Query(int count) + + //Read + public IEnumerable<User> QueryAll() { return this._context .Set<User>() .AsNoTracking() - .Take(count) .AsEnumerable(); - } - public async Task<User> FindByIdAsync(Guid id) + public async Task<User> GetByIdAsync(Guid id) { return await this._context .Set<User>() .FindAsync(id); } + public async Task<User> GetByUsername(string username) + { + return await this._context + .Set<User>() + .FirstOrDefaultAsync(x => x.UserName == username); + } + + //Update public async Task EditAsync(User newEntity) { this._context @@ -67,6 +60,7 @@ namespace DevHive.Data.Repositories await this._context.SaveChangesAsync(); } + //Delete public async Task DeleteAsync(User entity) { this._context @@ -75,5 +69,44 @@ namespace DevHive.Data.Repositories await this._context.SaveChangesAsync(); } + + //Validations + public bool DoesUserExist(Guid id) + { + return this._context + .Set<User>() + .Any(x => x.Id == id); + } + + public Task<bool> IsUsernameValid(string username) + { + return this._context + .Set<User>() + .AnyAsync(u => u.UserName == username); + } + + public bool DoesUserHaveThisUsername(Guid id, string username) + { + return this._context + .Set<User>() + .Any(x => x.Id == id && + x.UserName == username); + } + + public async Task<bool> DoesUsernameExist(string username) + { + return await this._context + .Set<User>() + .AsNoTracking() + .AnyAsync(u => u.UserName == username); + } + + public async Task<bool> DoesEmailExist(string email) + { + return await this._context + .Set<User>() + .AsNoTracking() + .AnyAsync(u => u.Email == email); + } } } diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index d235755..460c3c9 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -1,14 +1,16 @@ using AutoMapper; using DevHive.Data.Repositories; using DevHive.Services.Options; +using DevHive.Services.Models.Identity.User; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; -using System.IdentityModel.Tokens.Jwt; using DevHive.Data.Models; -using System.Text; -using Microsoft.IdentityModel.Tokens; -using System.Security.Claims; using System; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using Microsoft.IdentityModel.Tokens; +using System.Security.Cryptography; +using System.Text; namespace DevHive.Services.Services { @@ -25,61 +27,44 @@ namespace DevHive.Services.Services this._jwtOptions = jwtOptions; } - public async Task<IActionResult> LoginUser(LoginWebModel loginDTO) + public async Task<IActionResult> LoginUser(LoginServiceModel loginModel) { - User user = this._userRepository.FindByUsername(loginDTO.UserName); + if (!await this._userRepository.IsUsernameValid(loginModel.UserName)) + return new BadRequestObjectResult("Invalid username!"); - if (user == null) - return new NotFoundObjectResult("User does not exist!"); + User user = await this._userRepository + .GetByUsername(loginModel.UserName); - byte[] key = Encoding.ASCII.GetBytes(_jwtOptions.Secret); - - if (user.PasswordHash != GeneratePasswordHash(loginDTO.Password)) + if (user.PasswordHash != GeneratePasswordHash(loginModel.Password)) return new BadRequestObjectResult("Incorrect password!"); - // Create Jwt Token configuration - var tokenDescriptor = new SecurityTokenDescriptor + return new OkObjectResult(new { - Subject = new ClaimsIdentity(new Claim[] - { - new Claim(ClaimTypes.Role, user.Role) // Authorize user by role - }), - Expires = DateTime.UtcNow.AddDays(7), - SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature) - }; - - var tokenHandler = new JwtSecurityTokenHandler(); - var token = tokenHandler.CreateToken(tokenDescriptor); - var tokenString = tokenHandler.WriteToken(token); - - return new OkObjectResult(new { Token = tokenString }); + Token = WriteJWTSecurityToken(user.Role) + }); } - public async Task<IActionResult> RegisterUser(RegisterDTO registerDTO) + public async Task<IActionResult> RegisterUser(RegisterServiceModel registerModel) { - if (this._userRepository.DoesUsernameExist(registerDTO.UserName)) + if (await this._userRepository.DoesUsernameExist(registerModel.UserName)) return new BadRequestObjectResult("Username already exists!"); - User user = this._userMapper.Map<User>(registerDTO); + if (await this._userRepository.DoesEmailExist(registerModel.Email)) + return new BadRequestObjectResult("Username already exists!"); - user.Role = UserRoles.User; - user.PasswordHash = GeneratePasswordHash(registerDTO.Password); + User user = this._userMapper.Map<User>(registerModel); + user.Role = "User"; + user.PasswordHash = GeneratePasswordHash(registerModel.Password); await this._userRepository.AddAsync(user); return new CreatedResult("CreateUser", user); } - private string GeneratePasswordHash(string password) - { - //TODO: Implement - return password; - } - - public async Task<IActionResult> GetUserById(Guid id) + public async Task<IActionResult> GetUserById(Guid id) { - User user = await this._userRepository.FindByIdAsync(id); + User user = await this._userRepository.GetByIdAsync(id); if (user == null) return new NotFoundObjectResult("User does not exist!"); @@ -87,17 +72,17 @@ namespace DevHive.Services.Services return new OkObjectResult(user); } - public async Task<IActionResult> UpdateUser(Guid id, UserDTO userDTO) + public async Task<IActionResult> UpdateUser(Guid id, UpdateUserServiceModel updateModel) { if (!this._userRepository.DoesUserExist(id)) return new NotFoundObjectResult("User does not exist!"); - if (!this._userRepository.HasThisUsername(id, userDTO.UserName) - && this._userRepository.DoesUsernameExist(userDTO.UserName)) + if (!this._userRepository.DoesUserHaveThisUsername(id, updateModel.UserName) + && await this._userRepository.IsUsernameValid(updateModel.UserName)) return new BadRequestObjectResult("Username already exists!"); - User user = this._userMapper.Map<User>(userDTO); - await this._userRepository.EditAsync(id, user); + User user = this._userMapper.Map<User>(updateModel); + await this._userRepository.EditAsync(user); return new AcceptedResult("UpdateUser", user); } @@ -107,9 +92,37 @@ namespace DevHive.Services.Services if (!this._userRepository.DoesUserExist(id)) return new NotFoundObjectResult("User does not exist!"); - await this._userDbRepository.DeleteAsync(id); - + User user = await this._userRepository.GetByIdAsync(id); + await this._userRepository.DeleteAsync(user); + return new OkResult(); } + + private string GeneratePasswordHash(string password) + { + return SHA512.HashData(Encoding.ASCII.GetBytes(password)).ToString(); + } + + private string WriteJWTSecurityToken(string role) + { + //TODO: Try generating the key + byte[] signingKey = Convert.FromBase64String(_jwtOptions.Secret); + + SecurityTokenDescriptor tokenDescriptor = new() + { + Subject = new ClaimsIdentity(new Claim[] + { + new Claim(ClaimTypes.Role, role) + }), + Expires = DateTime.Today.AddDays(7), + SigningCredentials = new SigningCredentials( + new SymmetricSecurityKey(signingKey), + SecurityAlgorithms.HmacSha512Signature) + }; + + JwtSecurityTokenHandler tokenHandler = new(); + SecurityToken token = tokenHandler.CreateToken(tokenDescriptor); + return tokenHandler.WriteToken(token); + } } } diff --git a/src/DevHive.Web/Configurations/Mapping/UserMappings.cs b/src/DevHive.Web/Configurations/Mapping/UserMappings.cs index f3daf5a..2964a00 100644 --- a/src/DevHive.Web/Configurations/Mapping/UserMappings.cs +++ b/src/DevHive.Web/Configurations/Mapping/UserMappings.cs @@ -1,6 +1,7 @@ using DevHive.Data.Models; using AutoMapper; -using DevHive.Services.Models.Identity; +using DevHive.Services.Models.Identity.User; +using DevHive.Web.Models.Identity.User; namespace DevHive.Web.Configurations.Mapping { @@ -8,9 +9,9 @@ namespace DevHive.Web.Configurations.Mapping { public UserMappings() { - CreateMap<UserServiceModel, User>(); - CreateMap<RegisterServiceModel, User>(); - CreateMap<UpdateUserServiceModel, User>(); + CreateMap<LoginWebModel, LoginServiceModel>(); + CreateMap<LoginWebModel, LoginServiceModel>(); + CreateMap<UpdateUserWebModel, UpdateUserServiceModel>(); } } } diff --git a/src/DevHive.Web/Controllers/UserController.cs b/src/DevHive.Web/Controllers/UserController.cs index 14ecb73..480fbe4 100644 --- a/src/DevHive.Web/Controllers/UserController.cs +++ b/src/DevHive.Web/Controllers/UserController.cs @@ -2,6 +2,7 @@ using System; using System.Threading.Tasks; using AutoMapper; using DevHive.Data.Repositories; +using DevHive.Services.Models.Identity.User; using DevHive.Services.Options; using DevHive.Services.Services; using DevHive.Web.Models.Identity.User; @@ -15,44 +16,47 @@ namespace DevHive.Web.Controllers public class UserController: ControllerBase { private readonly UserService _service; + private readonly IMapper _userMapper; public UserController(DevHiveContext context, IMapper mapper, JWTOptions jwtOptions) { this._service = new UserService(context, mapper, jwtOptions); + this._userMapper = mapper; } [HttpPost] [Route("Login")] - public async Task<IActionResult> Login([FromBody] LoginWebModel loginWebModel) + public async Task<IActionResult> Login([FromBody] LoginWebModel loginModel) { - var loginDTO = - return await this._service.LoginUser(loginDTO); - //throw new NotImplementedException(); + LoginServiceModel loginServiceModel = this._userMapper.Map<LoginServiceModel>(loginModel); + + return await this._service.LoginUser(loginServiceModel); } [HttpPost] [Route("Register")] - public async Task<IActionResult> Register([FromBody] RegisterWebModel registerWebModel) + public async Task<IActionResult> Register([FromBody] RegisterWebModel registerModel) { - //return await this._service.RegisterUser(registerDto); - throw new NotImplementedException(); + RegisterServiceModel registerServiceModel = this._userMapper.Map<RegisterServiceModel>(registerModel); + + return await this._service.RegisterUser(registerServiceModel); } //Read [HttpGet] public async Task<IActionResult> GetById(Guid id) { - //return await this._service.GetUserById(id); - throw new NotImplementedException(); + return await this._service.GetUserById(id); } //Update [HttpPut] [Authorize] - public async Task<IActionResult> Update(Guid id, [FromBody] UpdateUserWebModel updateUserWebModel) + public async Task<IActionResult> Update(Guid id, [FromBody] UpdateUserWebModel updateModel) { - //return await this._service.UpdateUser(id, userDTO); - throw new NotImplementedException(); + UpdateUserServiceModel updateUserServiceModel = this._userMapper.Map<UpdateUserServiceModel>(updateModel); + + return await this._service.UpdateUser(id, updateUserServiceModel); } //Delete @@ -60,8 +64,7 @@ namespace DevHive.Web.Controllers [Authorize] public async Task<IActionResult> Delete(Guid id) { - //return await this._service.DeleteUser(id); - throw new NotImplementedException(); + return await this._service.DeleteUser(id); } } } diff --git a/src/DevHive.Web/appsettings.json b/src/DevHive.Web/appsettings.json index 289208b..b0c8a57 100644 --- a/src/DevHive.Web/appsettings.json +++ b/src/DevHive.Web/appsettings.json @@ -4,5 +4,12 @@ },
"ConnectionStrings" : {
"DEV": "Server=localhost;Port=5432;Database=API;User Id=postgres;Password=;"
+ },
+ "Logging" : {
+ "LogLevel" : {
+ "Default" : "Information",
+ "Microsoft" : "Warning",
+ "Microsoft.Hosting.Lifetime" : "Information"
+ }
}
}
|
