aboutsummaryrefslogtreecommitdiff
path: root/src/DevHive.Services/Services/UserService.cs
blob: 460c3c9cabc9f8ece2fb1a8eb7d7c99ffa88f6ab (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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 DevHive.Data.Models;
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
{
	public class UserService
	{
		private readonly UserRepository _userRepository;
		private readonly IMapper _userMapper;
		private readonly JWTOptions _jwtOptions;

		public UserService(DevHiveContext context, IMapper mapper, JWTOptions jwtOptions)
		{
			this._userRepository = new UserRepository(context);
			this._userMapper = mapper;
			this._jwtOptions = jwtOptions;
		}

		public async Task<IActionResult> LoginUser(LoginServiceModel loginModel)
		{
			if (!await this._userRepository.IsUsernameValid(loginModel.UserName))
				return new BadRequestObjectResult("Invalid username!");

			User user = await this._userRepository
				.GetByUsername(loginModel.UserName);

			if (user.PasswordHash != GeneratePasswordHash(loginModel.Password))
				return new BadRequestObjectResult("Incorrect password!");

			return new OkObjectResult(new 
			{
				Token = WriteJWTSecurityToken(user.Role) 
			});
		}

		public async Task<IActionResult> RegisterUser(RegisterServiceModel registerModel)
		{

			if (await this._userRepository.DoesUsernameExist(registerModel.UserName))
				return new BadRequestObjectResult("Username already exists!");

			if (await this._userRepository.DoesEmailExist(registerModel.Email))
				return new BadRequestObjectResult("Username already exists!");

			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);
		}

		public async Task<IActionResult> GetUserById(Guid id)
		{
			User user = await this._userRepository.GetByIdAsync(id);

			if (user == null)
				return new NotFoundObjectResult("User does not exist!");

			return new OkObjectResult(user);
		}

		public async Task<IActionResult> UpdateUser(Guid id, UpdateUserServiceModel updateModel)
		{
			if (!this._userRepository.DoesUserExist(id))
				return new NotFoundObjectResult("User does not exist!");

			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>(updateModel);
			await this._userRepository.EditAsync(user);

			return new AcceptedResult("UpdateUser", user);
		}

		public async Task<IActionResult> DeleteUser(Guid id)
		{
			if (!this._userRepository.DoesUserExist(id))
				return new NotFoundObjectResult("User does not exist!");

			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);
		}
	}
}