diff options
Diffstat (limited to 'Backend/Api')
-rw-r--r-- | Backend/Api/Api/Api.csproj | 1 | ||||
-rw-r--r-- | Backend/Api/Api/Controllers/AuthController.cs | 13 | ||||
-rw-r--r-- | Backend/Api/Api/Interfaces/IJwtService.cs | 2 | ||||
-rw-r--r-- | Backend/Api/Api/Interfaces/IUserService.cs | 6 | ||||
-rw-r--r-- | Backend/Api/Api/Program.cs | 2 | ||||
-rw-r--r-- | Backend/Api/Api/Services/JwtService.cs | 5 | ||||
-rw-r--r-- | Backend/Api/Api/Services/UserService.cs | 62 |
7 files changed, 82 insertions, 9 deletions
diff --git a/Backend/Api/Api/Api.csproj b/Backend/Api/Api/Api.csproj index dc8b264..10faa3e 100644 --- a/Backend/Api/Api/Api.csproj +++ b/Backend/Api/Api/Api.csproj @@ -11,6 +11,7 @@ <PackageReference Include="MongoDB.Driver" Version="2.18.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.24.0" /> + <PackageReference Include="BCrypt.Net-Next" Version="4.0.3" /> </ItemGroup> </Project> diff --git a/Backend/Api/Api/Controllers/AuthController.cs b/Backend/Api/Api/Controllers/AuthController.cs index 456abd9..6727125 100644 --- a/Backend/Api/Api/Controllers/AuthController.cs +++ b/Backend/Api/Api/Controllers/AuthController.cs @@ -33,5 +33,18 @@ namespace Api.Controllers return Ok(); } + [HttpPost("login")] + public async Task<ActionResult<string>> Login([FromBody] Login creds) + { + var id = await _userService.UserIdFromJwt(); + if (id != null) return Forbid(); + + var jwt= await _userService.Login(creds); + if (jwt != null) + { + return Ok(new { token = jwt }); + } + return BadRequest(); + } } } diff --git a/Backend/Api/Api/Interfaces/IJwtService.cs b/Backend/Api/Api/Interfaces/IJwtService.cs index 1a8fb0a..f9e5d5f 100644 --- a/Backend/Api/Api/Interfaces/IJwtService.cs +++ b/Backend/Api/Api/Interfaces/IJwtService.cs @@ -6,7 +6,7 @@ namespace Api.Interfaces { string GenToken(User user); string TokenToId(string token); - public string GenEmailToken(User user); + public string GenEmailToken(string username); public string EmailTokenToId(string token); } }
\ No newline at end of file diff --git a/Backend/Api/Api/Interfaces/IUserService.cs b/Backend/Api/Api/Interfaces/IUserService.cs index 8faad45..9e4e3b9 100644 --- a/Backend/Api/Api/Interfaces/IUserService.cs +++ b/Backend/Api/Api/Interfaces/IUserService.cs @@ -11,6 +11,12 @@ namespace Api.Interfaces Task<long> updateUser(User user); Task<User> deleteUser(String email); Task<User> getUserById(string id); + Task<string> RenewToken(string existingToken); + Task<string> Login(Login login); + Task<string> Register(Register register); + Task<Boolean> VerifyUser(string _id); + Task<string> UserIdFromJwt(); + } } diff --git a/Backend/Api/Api/Program.cs b/Backend/Api/Api/Program.cs index 26ed445..4643937 100644 --- a/Backend/Api/Api/Program.cs +++ b/Backend/Api/Api/Program.cs @@ -23,6 +23,8 @@ builder.Services.AddSingleton<IMongoClient>(s => builder.Services.AddScoped<IUserService, UserService>(); builder.Services.AddScoped<IJwtService, JwtService>(); +builder.Services.AddHttpContextAccessor(); + diff --git a/Backend/Api/Api/Services/JwtService.cs b/Backend/Api/Api/Services/JwtService.cs index 37ec88e..e3688de 100644 --- a/Backend/Api/Api/Services/JwtService.cs +++ b/Backend/Api/Api/Services/JwtService.cs @@ -56,13 +56,13 @@ namespace Api.Services } } - public string GenEmailToken(User user) + public string GenEmailToken(string username) { var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(_config.GetSection("AppSettings:EmailToken").Value); var tokenDescriptor = new SecurityTokenDescriptor { - Subject = new ClaimsIdentity(new[] { new Claim("username", user.username), new Claim("id", user._id) }), + Subject = new ClaimsIdentity(new[] { new Claim("username", username)}), Expires = DateTime.UtcNow.AddMinutes(30), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; @@ -90,7 +90,6 @@ namespace Api.Services var jwtToken = (JwtSecurityToken)validatedToken; var username = (jwtToken.Claims.First(x => x.Type == "username").Value.ToString()); return username; - //return jwtToken.Claims.First(x => x.Type == "id").Value; } catch { diff --git a/Backend/Api/Api/Services/UserService.cs b/Backend/Api/Api/Services/UserService.cs index 1260814..7c00c05 100644 --- a/Backend/Api/Api/Services/UserService.cs +++ b/Backend/Api/Api/Services/UserService.cs @@ -1,18 +1,22 @@ using Api.Interfaces; using Api.Models; using MongoDB.Driver; +using Microsoft.AspNetCore.Http; +using System.Security.Claims; namespace Api.Services { public class UserService : IUserService { + private readonly IHttpContextAccessor _httpContext; private readonly IMongoCollection<User> _users; private readonly IJwtService _jwtService; - public UserService(IDatabaseConnection settings, IMongoClient mongoClient, IJwtService jwtService) + public UserService(IDatabaseConnection settings, IMongoClient mongoClient, IJwtService jwtService, IHttpContextAccessor httpContextAccessor) { var database = mongoClient.GetDatabase(settings.DatabaseName); _users = database.GetCollection<User>(settings.UserCollectionName); _jwtService=jwtService; + this._httpContext = httpContextAccessor; } public async Task<int> createUser(User user) @@ -20,8 +24,9 @@ namespace Api.Services if (await _users.Find(x => x.email == user.email).FirstOrDefaultAsync() != null) return -1; //email already exists if (await _users.Find(x => x.username == user.username).FirstOrDefaultAsync() != null) - return -2; //username already exists - + return -2; //username already + // + user.password = hashPassword(user.password); await _users.InsertOneAsync(user); return 1; } @@ -68,6 +73,29 @@ namespace Api.Services return 0; } + private static int difficulty = 10; + + public static String hashPassword(String password) + { + String salt = BCrypt.Net.BCrypt.GenerateSalt(difficulty); + String passwordHash = BCrypt.Net.BCrypt.HashPassword(password, salt); + + return passwordHash; + } + + public static Boolean checkPassword(String plainText, String hash) + { + Boolean verified = false; + + if (hash == null || !hash.StartsWith("$2a$")) + return false; + + verified = BCrypt.Net.BCrypt.Verify(plainText, hash); + + return verified; + + } + public async Task<string> Register(Register register) { if (await _users.FindAsync(x => x.email == register.email && x.verified==true).Result.AnyAsync()) @@ -87,15 +115,18 @@ namespace Api.Services } } } + var user = new User(); user.email = register.email; user.username = register.username; user.name = register.name; user.verified = false; - user.password = register.password; // unhashed for now + user.password = hashPassword(register.password); + user.emailToken = _jwtService.GenEmailToken(user.username); + await _users.InsertOneAsync(user); - return ""; + return "User Registered"; } public async Task<Boolean> VerifyUser(string _id) @@ -118,7 +149,28 @@ namespace Api.Services var user = await getUserById(id); return _jwtService.GenToken(user); + } + public async Task<string> Login(Login login) + { + User user = await _users.FindAsync(x => x.email == login.email).Result.FirstAsync(); // add && x.verified == true after implementing + if(user != null && checkPassword(login.password, user.password)) + { + return _jwtService.GenToken(user); + } + return null; + } + public async Task<string> UserIdFromJwt() + { + string id = null; + if (_httpContext.HttpContext.User.FindFirstValue("id") != null) + { + id = _httpContext.HttpContext.User.FindFirstValue("id").ToString(); + var _id = await _users.FindAsync(x => x._id == id).Result.FirstAsync(); + if (_id == null) + id = null; + } + return id; } } } |