public IActionResult ForgotPassword(ForgotPasswordModel forgotPasswordModel) { UserDAO userDAO = new UserDAO(_connection); User user = userDAO.FindUserByEmail(forgotPasswordModel.Email); if (ModelState.IsValid) { if (user != null) { var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(_secret); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Email, user.Email.ToString()) }), Expires = DateTime.UtcNow.AddMinutes(10), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; var token = tokenHandler.CreateToken(tokenDescriptor); var tokenString = tokenHandler.WriteToken(token); auxResetToken = tokenString; PasswordOperations.NewPasswordRequest(forgotPasswordModel.Email, tokenString); auxEmail = forgotPasswordModel.Email; return(Ok(new SuccessMessageModel("Email enviado com sucesso!"))); } } return(BadRequest(new ErrorMessageModel("Email não encontrado!"))); }
/// <summary> /// Método para autenticar um User /// </summary> /// <param name="email">O email do utilizador a ser autenticado</param> /// <param name="password">A password do utilizador a ser autenticado</param> /// <returns>Retorna o User autenticado ou null</returns> public User Authenticate(string email, string password) { // Caso nao o email seja nulo ou vazio ou a password nula ou vazia if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(password)) { return(null); } UserDAO userDAO = new UserDAO(_connection); User user = userDAO.FindUserByEmail(email); // Caso o user seja nulo if (user == null) { return(null); } // Verificar a hash da password para que o user faça o login if (!PasswordOperations.VerifyHash(password, user.Password, user.PasswordSalt)) { return(null); } return(user); }
public void CanGetEncryptedTokenTest() { IMateDAO <Mate> MateDAO = new MateDAO(_connection); Mate testMate = new Mate(); testMate.FirstName = "Miguel"; testMate.LastName = "Dev"; testMate.UserName = "******"; testMate.Password = "******"; testMate.Email = "*****@*****.**"; testMate.Description = "Lorem Ipsum is simply dummy text of the printing and typesetting industry."; testMate.Address = "Figueiró"; testMate.Categories = new[] { Categories.CLEANING, Categories.PLUMBING }; testMate.Rank = Ranks.SUPER_MATE; testMate.Range = 20; Mate returned = MateDAO.Create(testMate); string refreshToken = RefreshTokenHelper.generateRefreshToken(); RefreshTokenDAO refreshTokenDAO = new RefreshTokenDAO(_connection); refreshTokenDAO.saveEncryptedRefreshToken(refreshToken, returned.Email); EncryptedRefreshTokenModel returnedToken = refreshTokenDAO.GetEncryptedRefreshTokenModel(returned.Email); Assert.Equal(returned.Email, returnedToken.Email); Assert.True(PasswordOperations.VerifyHash(refreshToken, returnedToken.Hash, returnedToken.Salt)); _fixture.Dispose(); }
/// <summary> /// Método para atualizar o token refresh guardado na BD /// </summary> /// <param name="refreshToken">Refesh token</param> /// <param name="email">Email do utilizador</param> /// <returns>Retorna True se for atualizado, /// False caso contrário</returns> public bool updateEncryptedRefreshToken(string refreshToken, string email){ try{ using (SqlCommand cmd = _connection.Fetch().CreateCommand()) { cmd.CommandType = CommandType.Text; cmd.CommandText = "UPDATE dbo.[RefreshTokens] SET TokenHash = @Th, TokenSalt = @Ts " + "WHERE Email = @Em"; cmd.Parameters.Add("@Em", SqlDbType.NVarChar).Value = email; var token = PasswordOperations.Encrypt(refreshToken); cmd.Parameters.Add("@Th", SqlDbType.NVarChar).Value = token.Item2; cmd.Parameters.Add("@Ts", SqlDbType.NVarChar).Value = token.Item1; if(cmd.ExecuteNonQuery() == 0){ return false; } return true; } } catch(Exception e) { throw new Exception(e.Message); } }
/// <summary> /// Método para guardar o token refresh encriptado na BD /// </summary> /// <param name="refreshToken">Refesh token</param> /// <param name="email">Email do utilizador</param> /// <returns>Retorna True se for guardado, /// False caso contrário</returns> public bool saveEncryptedRefreshToken(string refreshToken, string email){ UserDAO userDAO = new UserDAO(_connection); User user = userDAO.FindUserByEmail(email); if(user == null){ throw new Exception("O utilizador não existe"); } try{ using (SqlCommand cmd = _connection.Fetch().CreateCommand()) { cmd.CommandType = CommandType.Text; cmd.CommandText = "INSERT INTO dbo.[RefreshTokens] (Email, TokenHash, TokenSalt) " + "VALUES (@Em , @Th, @Ts)"; cmd.Parameters.Add("@Em", SqlDbType.NVarChar).Value = email; var token = PasswordOperations.Encrypt(refreshToken); cmd.Parameters.Add("@Th", SqlDbType.NVarChar).Value = token.Item2; cmd.Parameters.Add("@Ts", SqlDbType.NVarChar).Value = token.Item1; if(cmd.ExecuteNonQuery() == 0){ return false; } return true; } } catch(Exception e) { throw new Exception(e.Message); } }
/// <summary> /// Método para criar um Employer /// na Base de dados /// </summary> /// <param name="model">Modelo do employer com os dados</param> /// <returns>Employer caso seja adicionado com sucesso, /// senão retorna NULL</returns> public Employer Create(Employer model) { try { using (SqlCommand cmd = _connection.Fetch().CreateCommand()) { cmd.CommandType = CommandType.Text; if (model.Description != null) { cmd.CommandText = "INSERT INTO dbo.[User] (UserName, Password, PasswordSalt, Email, Description, FirstName, LastName, RoleId, Address)" + "VALUES (@Un, @Pass, @Slt, @mail, @Desc, @Fn, @Ln, @Rid, @Addr); SELECT @@Identity"; cmd.Parameters.Add("@Desc", SqlDbType.NVarChar).Value = model.Description; } else { cmd.CommandText = "INSERT INTO dbo.[User] (UserName, Password, PasswordSalt, Email, FirstName, LastName, RoleId, Address)" + "VALUES (@Un, @Pass, @Slt, @mail, @Fn, @Ln, @Rid, @Addr); SELECT @@Identity"; } cmd.Parameters.Add("@Un", SqlDbType.NVarChar).Value = model.UserName; var password = PasswordOperations.Encrypt(model.Password); cmd.Parameters.Add("@Pass", SqlDbType.NVarChar).Value = password.Item2; cmd.Parameters.Add("@Slt", SqlDbType.NVarChar).Value = password.Item1; cmd.Parameters.Add("@mail", SqlDbType.NVarChar).Value = model.Email; cmd.Parameters.Add("@Fn", SqlDbType.NVarChar).Value = model.FirstName; cmd.Parameters.Add("@Ln", SqlDbType.NVarChar).Value = model.LastName; cmd.Parameters.Add("@Rid", SqlDbType.Int).Value = Roles.EMPLOYER; cmd.Parameters.Add("@Addr", SqlDbType.NVarChar).Value = model.Address; model.Id = int.Parse(cmd.ExecuteScalar().ToString()); model.Role = Roles.EMPLOYER; model.Password = password.Item2; model.PasswordSalt = password.Item1; } using (SqlCommand cmd = _connection.Fetch().CreateCommand()) { cmd.CommandType = CommandType.Text; cmd.CommandText = "INSERT INTO dbo.[Employer] (Id)" + "VALUES (@Id); SELECT @@Identity"; cmd.Parameters.Add("@Id", SqlDbType.Int).Value = model.Id; cmd.ExecuteScalar(); } return(model); } catch (Exception ex) { throw new Exception(ex.Message); } }
public void CanUserRecoverPasswordTest() { IMateDAO <Mate> MateDAO = new MateDAO(_connection); Mate testMate = new Mate(); testMate.FirstName = "Samuel"; testMate.LastName = "Cunha"; testMate.UserName = "******"; testMate.Password = "******"; testMate.Email = "*****@*****.**"; testMate.Description = "Quero recuperar a pass"; testMate.Address = "Aparecida"; testMate.Categories = new[] { Categories.GARDENING }; testMate.Rank = Ranks.MATE; testMate.Range = 10; Mate returned = MateDAO.Create(testMate); var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes("RQj!O9+Sq|D8XjYa|}kgnk|}ZaQUso)EMF48Fx1~0n~^~%]n|O{NqH(&5RqXbx7"); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Email, testMate.Email.ToString()) }), Expires = DateTime.UtcNow.AddMinutes(10), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; var token = tokenHandler.CreateToken(tokenDescriptor); var tokenString = tokenHandler.WriteToken(token); String auxResetToken = tokenString; PasswordOperations.NewPasswordRequest("*****@*****.**", auxResetToken); LoginDAO loginDAO = new LoginDAO(_connection); RecoverPasswordModel recoverPassword = new RecoverPasswordModel(); recoverPassword.Email = "*****@*****.**"; recoverPassword.Password = "******"; recoverPassword.ConfirmPassword = "******"; recoverPassword.Token = tokenString; Assert.True(loginDAO.RecoverPassword(recoverPassword, returned.Email)); _fixture.Dispose(); }
public void CanRegisterEmployerTest() { IEmployerDAO <Employer> EmployerDAO = new EmployerDAO(_connection); Employer testEmployer = new Employer(); string password = testEmployer.Password; testEmployer.FirstName = "Samuel"; testEmployer.LastName = "Cunha"; testEmployer.UserName = "******"; testEmployer.Password = "******"; testEmployer.Email = "*****@*****.**"; testEmployer.Description = "Lorem Ipsum is simply dummy text of the printing and typesetting industry."; testEmployer.Address = "Aparecida"; Employer returned = EmployerDAO.Create(testEmployer); Assert.True(PasswordOperations.VerifyHash("samuel123", returned.Password, returned.PasswordSalt)); _fixture.Dispose(); }
/// <summary> /// Método que faz o refresh de um token. /// É utilizado o token antigo para validação e para ir buscar as claims /// </summary> /// <param name="tokens">Objeto ResponseTokens com o token antigo /// e token de resfresh</param> /// <param name="secret">Secret para criar um token de acesso novo</param> /// <returns>Retorna um objeto ResponseTokens com o token novo /// e token de resfresh novo</returns> public ResponseTokens Refresh(ResponseTokens tokens, string secret) { var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(secret); SecurityToken validatedToken; var principal = tokenHandler.ValidateToken(tokens.Token, new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = false }, out validatedToken); var jwtToken = validatedToken as JwtSecurityToken; if (jwtToken == null || !jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase)) { throw new SecurityTokenException("Token Inválido!"); } string email = ClaimHelper.GetEmailFromClaimIdentity((ClaimsIdentity)principal.Identity); RefreshTokenDAO refreshTokenDAO = new RefreshTokenDAO(_connection); EncryptedRefreshTokenModel encToken = refreshTokenDAO.GetEncryptedRefreshTokenModel(email); if (encToken == null) { throw new Exception("O token nao existe para o email pretendido!"); } if (PasswordOperations.VerifyHash(tokens.RefreshToken, encToken.Hash, encToken.Salt) == false) { throw new SecurityTokenException("Token Inválido!"); } return(Authenticate(email, secret, principal.Claims.ToArray())); }
/// <summary> /// Método para recuperar a password /// </summary> /// <param name="newPass">Nova Password</param> /// <param name="email">Email do user que vai alterar a password</param> /// <returns>Retorna bool</returns> public bool RecoverPassword(RecoverPasswordModel newPass, string email) { using (SqlCommand cmd = _connection.Fetch().CreateCommand()) { cmd.CommandType = CommandType.Text; cmd.CommandText = "UPDATE dbo.[User] SET Password = @pass, PasswordSalt = @salt " + "WHERE Email = @email"; cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = email; var password = PasswordOperations.Encrypt(newPass.Password); cmd.Parameters.Add("@pass", SqlDbType.NVarChar).Value = password.Item2; cmd.Parameters.Add("@salt", SqlDbType.NVarChar).Value = password.Item1; newPass.Password = password.Item2; cmd.ExecuteNonQuery(); } return(true); }
public void CanRegisterMateWrongPasswordTest() { IMateDAO <Mate> MateDAO = new MateDAO(_connection); Mate testMate = new Mate(); string password = testMate.Password; testMate.FirstName = "Miguel"; testMate.LastName = "Dev"; testMate.UserName = "******"; testMate.Password = "******"; testMate.Email = "*****@*****.**"; testMate.Description = "Lorem Ipsum is simply dummy text of the printing and typesetting industry."; testMate.Address = "Figueir"; testMate.Categories = new[] { Categories.CLEANING, Categories.PLUMBING }; testMate.Rank = Ranks.SUPER_MATE; testMate.Range = 20; Mate returned = MateDAO.Create(testMate); Assert.False(PasswordOperations.VerifyHash("12345", returned.Password, returned.PasswordSalt)); _fixture.Dispose(); }
/// <summary> /// Método que atualiza a password /// de um determindado utilizador /// </summary> /// <param name="newPass">Nova palavra-passe</param> /// <param name="id">Id do utilizador que pretende alterar /// a sua palavra-passe</param> /// <returns> /// True caso a password seja atualizada com sucesso /// False caso contrário /// </returns> public bool UpdatePassword(PasswordUpdateModel newPass, int?id) { User user = FindById((int)id); if (user == null) { throw new Exception("O utilizador não existe!"); } if (PasswordOperations.VerifyHash(newPass.OldPassword, user.Password, user.PasswordSalt)) { using (SqlCommand cmd = _connection.Fetch().CreateCommand()) { cmd.CommandType = CommandType.Text; cmd.CommandText = "UPDATE dbo.[User] " + "SET Password = @pass, PasswordSalt = @salt " + "WHERE Id = @id"; cmd.Parameters.Add("@id", SqlDbType.Int).Value = id; var password = PasswordOperations.Encrypt(newPass.Password); cmd.Parameters.Add("@pass", SqlDbType.NVarChar).Value = password.Item2; cmd.Parameters.Add("@salt", SqlDbType.NVarChar).Value = password.Item1; if (cmd.ExecuteNonQuery() == 0) { return(false); } } return(true); } else { throw new Exception("A password antiga é inválida!"); } }
/// <summary> /// Método para criar/registar um Mate na base de dados /// </summary> /// <param name="model">Modelo do mate com os dados</param> /// <returns>Mate caso seja adicionado com sucesso, /// senão retorna NULL</returns> public Mate Create(Mate model) { try { using (SqlCommand cmd = _connection.Fetch().CreateCommand()) { cmd.CommandType = CommandType.Text; if (model.Description != null) { cmd.CommandText = "INSERT INTO dbo.[User] (UserName, Password, PasswordSalt, Email, Description, FirstName, LastName, RoleId, Address)" + "VALUES (@Un, @Pass, @Slt, @mail, @Desc, @Fn, @Ln, @Rid, @Addr); SELECT @@Identity"; cmd.Parameters.Add("@Desc", SqlDbType.NVarChar).Value = model.Description; } else { cmd.CommandText = "INSERT INTO dbo.[User] (UserName, Password, PasswordSalt, Email, FirstName, LastName, RoleId, Address)" + "VALUES (@Un, @Pass, @Slt, @mail, @Fn, @Ln, @Rid, @Addr); SELECT @@Identity"; } cmd.Parameters.Add("@Un", SqlDbType.NVarChar).Value = model.UserName; var password = PasswordOperations.Encrypt(model.Password); cmd.Parameters.Add("@Pass", SqlDbType.NVarChar).Value = password.Item2; cmd.Parameters.Add("@Slt", SqlDbType.NVarChar).Value = password.Item1; cmd.Parameters.Add("@mail", SqlDbType.NVarChar).Value = model.Email; cmd.Parameters.Add("@Fn", SqlDbType.NVarChar).Value = model.FirstName; cmd.Parameters.Add("@Ln", SqlDbType.NVarChar).Value = model.LastName; cmd.Parameters.Add("@Rid", SqlDbType.Int).Value = Roles.M8; cmd.Parameters.Add("@Addr", SqlDbType.NVarChar).Value = model.Address; model.Id = int.Parse(cmd.ExecuteScalar().ToString()); model.Role = Roles.M8; model.Password = password.Item2; model.PasswordSalt = password.Item1; model.Rank = Ranks.MATE; } using (SqlCommand cmd = _connection.Fetch().CreateCommand()) { cmd.CommandType = CommandType.Text; cmd.CommandText = "INSERT INTO dbo.[Mate] (Id, Range, RankId)" + "VALUES (@Id, @Rng, @Rkid); SELECT @@Identity"; cmd.Parameters.Add("@Id", SqlDbType.Int).Value = model.Id; cmd.Parameters.Add("@Rng", SqlDbType.Int).Value = model.Range; cmd.Parameters.Add("Rkid", SqlDbType.Int).Value = model.Rank; cmd.ExecuteScalar(); } foreach (Categories category in model.Categories) { using (SqlCommand cmd = _connection.Fetch().CreateCommand()) { cmd.CommandType = CommandType.Text; cmd.CommandText = "INSERT INTO dbo.[CategoriesFromM8] (MateId, CategoryId)" + "VALUES (@MtId, @CtgId); SELECT @@Identity"; cmd.Parameters.Add("@MtId", SqlDbType.Int).Value = model.Id; cmd.Parameters.Add("@CtgId", SqlDbType.Int).Value = category; cmd.ExecuteScalar(); } } return(model); } catch (Exception ex) { throw new Exception(ex.Message); } }