diff options
| -rw-r--r-- | src/DevHive.Services/Services/UserService.cs | 47 | ||||
| -rw-r--r-- | src/DevHive.Web/Controllers/UserController.cs | 16 |
2 files changed, 59 insertions, 4 deletions
diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index d3c0d0d..b2d5aee 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -105,6 +105,42 @@ namespace DevHive.Services.Services throw new InvalidOperationException("Unable to delete user!"); } + /// <summary> + /// Checks wether the given token's UserName and Roles are the same as these of the user with the given id. + /// </summary> + public async Task<bool> ValidJWT(Guid id, string rawTokenData) + { + // There is authorization name in the beginning, i.e. "Bearer eyJh..." + var jwt = new JwtSecurityTokenHandler().ReadJwtToken(rawTokenData.Remove(0, 7)); + + User user = await this._userRepository.GetByIdAsync(id) + ?? throw new ArgumentException("User does not exist!"); + + /* Check username */ + string jwtUserName = this.GetClaimTypeValues("unique_name", jwt.Claims)[0]; + + if (jwtUserName != user.UserName) + return false; + + /* Check roles */ + List<string> jwtRoleNames = this.GetClaimTypeValues("role", jwt.Claims); + + // Check if jwt contains all user roles (if it doesn't, jwt is either old or tampered with) + foreach(var role in user.Roles) + { + if (!jwtRoleNames.Contains(role.Name)) + return false; + + jwtRoleNames.Remove(role.Name); + } + + // Check if jwt contains only roles of user + if (jwtRoleNames.Count > 0) + return false; + + return true; + } + private string GeneratePasswordHash(string password) { return string.Join(string.Empty, SHA512.HashData(Encoding.ASCII.GetBytes(password))); @@ -137,5 +173,16 @@ namespace DevHive.Services.Services SecurityToken token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); } + + private List<string> GetClaimTypeValues(string type, IEnumerable<Claim> claims) + { + List<string> toReturn = new(); + + foreach(var claim in claims) + if (claim.Type == type) + toReturn.Add(claim.Value); + + return toReturn; + } } } diff --git a/src/DevHive.Web/Controllers/UserController.cs b/src/DevHive.Web/Controllers/UserController.cs index e339f70..35c39df 100644 --- a/src/DevHive.Web/Controllers/UserController.cs +++ b/src/DevHive.Web/Controllers/UserController.cs @@ -9,7 +9,6 @@ using DevHive.Web.Models.Identity.User; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using DevHive.Common.Models.Identity; -using DevHive.Common.Models; namespace DevHive.Web.Controllers { @@ -56,8 +55,11 @@ namespace DevHive.Web.Controllers //Read [HttpGet] - public async Task<IActionResult> GetById(Guid id) + public async Task<IActionResult> GetById(Guid id, [FromHeader] string authorization) { + if (!await this._userService.ValidJWT(id, authorization)) + return new UnauthorizedResult(); + UserServiceModel userServiceModel = await this._userService.GetUserById(id); UserWebModel userWebModel = this._userMapper.Map<UserWebModel>(userServiceModel); @@ -66,8 +68,11 @@ namespace DevHive.Web.Controllers //Update [HttpPut] - public async Task<IActionResult> Update(Guid id, [FromBody] UpdateUserWebModel updateModel) + public async Task<IActionResult> Update(Guid id, [FromBody] UpdateUserWebModel updateModel, [FromHeader] string authorization) { + if (!await this._userService.ValidJWT(id, authorization)) + return new UnauthorizedResult(); + UpdateUserServiceModel updateUserServiceModel = this._userMapper.Map<UpdateUserServiceModel>(updateModel); updateUserServiceModel.Id = id; @@ -80,8 +85,11 @@ namespace DevHive.Web.Controllers //Delete [HttpDelete] - public async Task<IActionResult> Delete(Guid id) + public async Task<IActionResult> Delete(Guid id, [FromHeader] string authorization) { + if (!await this._userService.ValidJWT(id, authorization)) + return new UnauthorizedResult(); + await this._userService.DeleteUser(id); return new OkResult(); } |
