Hi,
I'm writing an ASP.NET MVC application which will provide user registration functionality but i am not sure which part of the application (e.g. User Domain model object, Controller, ViewModelMappers) should be responsible for hashing the user's password. I have a registration page that uses a strongly typed ViewModel and a Register action in my UserController as shown:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Register(UserRegisterViewModel userRegisterViewModel)
{
var user = userViewModelMapper.Map(userRegisterViewModel);
INotification validationResult = user.ValidateForRegistration(userRepository);
if (!validationResult.HasErrors)
{
user.HashPassword();
userRepository.AddOrUpdate(user); // i'm using NHibernate
return View("RegistrationAcknowledgement");
}
foreach (IError error in validationResult.Errors)
ModelState.AddModelError(error.Property, error.Message);
ViewData["country"] = new SelectList(countryRepository.GetAll(), "Code", "Name", userRegisterViewModel.Country);
return View("RegistrationForm", userRegisterViewModel);
}
User objects are composed in part by LoginDetail objects as shown and to avoid exposing the internals of the User object beyond what is absolutely required the Password Property is read-only. So i cannot for example do user.LoginDetails.Password = hashedandSaltedPassword;
namespace XXXX.Core.Model
{
public class User
{
private LoginDetails loginDetails;
public virtual LoginDetails LoginDetails
{
get { return loginDetails; }
private set { loginDetails = value; }
}
public virtual void AssignLoginDetails(LoginDetails loginDetails)
{
this.loginDetails = loginDetails;
}
public virtual void HashPassword()
{
IHashGenerator hashGenerator = new HashGenerator(new SaltGenerator());
IHashResult hashResult = hashGenerator.GenerateHash(loginDetails.Password, HashAlgoritm.SHA512);
loginDetails.Password = String.Concat(hashResult.HashValue, hashResult.Salt);
}
}
}
namespace XXXX.Core.Model
{
public class LoginDetails
{
private string username;
private string password;
private string confirmPassword;
private string passwordReminder;
private bool changePassword;
// Properties
#region Constructors
...
public LoginDetails(string username, string password, string confirmPassword, string passwordReminder, bool changePassword)
{
this.username = username;
this.password = password;
this.confirmPassword = confirmPassword;
this.passwordReminder = passwordReminder;
this.changePassword = changePassword;
}
}
}
Currently the responsibility for hashing the password is owned the User (by means of the HashPassword method) but
1. Is this a correct responsibility for the User to have (within the context of DDD and Single Responsibility principle)
2. If not, where should this operation reside?
3. If so, should it be called from the controller as i am doing?
Thanks