コード例 #1
0
        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!")));
        }
コード例 #2
0
        /// <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);
        }
コード例 #3
0
        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();
        }
コード例 #4
0
        /// <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);
            }
        }
コード例 #5
0
        /// <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);
            }
        }
コード例 #6
0
        /// <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);
            }
        }
コード例 #7
0
        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();
        }
コード例 #8
0
        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();
        }
コード例 #9
0
        /// <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()));
        }
コード例 #10
0
        /// <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);
        }
コード例 #11
0
        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();
        }
コード例 #12
0
        /// <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!");
            }
        }
コード例 #13
0
        /// <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);
            }
        }