public void PasswordHashing_PasswordVerificationWorks()
        {
            var hashed = Passwords.CreateSaltedPasswordHash("test1234");

            Assert.True(Passwords.CheckPassword(hashed, "test1234"));
            Assert.False(Passwords.CheckPassword(hashed, "test12345"));
            Assert.False(Passwords.CheckPassword(hashed, "test123"));
        }
        public void PasswordHashing_DifferentSaltsHaveDifferentResults()
        {
            byte[] salt1 = { 1, 2, 3, 4, 5, 6, 7, 8 };
            byte[] salt2 = { 2, 2, 3, 4, 5, 6, 7, 8 };

            Assert.NotEqual(Passwords.CreateSaltedPasswordHash("test1234", salt1),
                            Passwords.CreateSaltedPasswordHash("test1234", salt2));
        }
        public void PasswordHashing_KnownPasswordHashMatches()
        {
            byte[] salt = { 1, 2, 3, 4, 5, 6, 7, 8 };

            // Hashed string has nonsense in it
            // ReSharper disable StringLiteralTypo
            Assert.Equal("AQIDBAUGBwg=:9CtRsYKuet+gr6NRVnrIjd37nKwH1sTCEI3kdt8i5N0oJF+n1JUR3Idy2SuU1+zi",
                         Passwords.CreateSaltedPasswordHash("test1234", salt));
            // ReSharper enable StringLiteralTypo
        }
        public void PasswordHashing_AutomaticallyGeneratedSaltsAreDifferent()
        {
            var result1 = Passwords.CreateSaltedPasswordHash("test1234");
            var result2 = Passwords.CreateSaltedPasswordHash("test1234");
            var result3 = Passwords.CreateSaltedPasswordHash("test1234");

            if (result1 == result2 && result2 == result3)
            {
                Assert.True(false, "subsequently created hashes without set salt should be different");
            }
        }
        public async Task <IActionResult> Post(RegistrationFormData request)
        {
            if (!csrfVerifier.IsValidCSRFToken(request.CSRF, null, false))
            {
                return(BadRequest("Invalid CSRF"));
            }

            if (!SecurityHelpers.SlowEquals(request.RegistrationCode, configuration.RegistrationCode))
            {
                return(BadRequest("Invalid registration code"));
            }

            if (!request.Email.Contains('@'))
            {
                return(BadRequest("Email is invalid"));
            }

            // Check for conflicting username or email
            if (await database.Users.FirstOrDefaultAsync(u => u.UserName == request.Name) != null ||
                await database.Users.FirstOrDefaultAsync(u => u.Email == request.Email) != null)
            {
                return(BadRequest("There is already an account associated with the given email or name"));
            }

            var password = Passwords.CreateSaltedPasswordHash(request.Password);

            var user = new User()
            {
                Email        = request.Email,
                UserName     = request.Name,
                PasswordHash = password,
                Local        = true
            };

            await database.Users.AddAsync(user);

            Models.User.OnNewUserCreated(user, jobClient);
            await database.SaveChangesAsync();

            logger.LogInformation("New user registered {Name} ({Email})", request.Name, request.Email);

            return(Created($"/users/{user.Id}", user.GetInfo(RecordAccessLevel.Private)));
        }