views:

56

answers:

3

I'm using Entity Framework 4. I'm not really sure where the responsibility of setting a user's password should be. I thought about on the Repository like SetPassword(User user, string password). But it doesn't seem right.

The main problem is that it can't just be a simple property setter since I also return the salt that's generated.

+1  A: 

It should not be in the Repository as it should only be for database access and not for business logic. I think it should be in User class.

public class User
{
  IUserPasswordManager _userPasswordManager;

  public string SetPassword(string oldPassword, string newPassword)
  {
     //Set password and return salt
     return _userPasswordManager.SetPasswordForUser(this, oldPassword, newPAssword);  

  }

}
Amitabh
Your answer is conflicting with what I've found: http://stackoverflow.com/questions/1307490/password-hashing-etc-in-service-layer-or-repository
TheCloudlessSky
Also consider to make roles explicit and Single Responsibility Principle and make separate type UserPasswordManager. Cos it is a little bit illogical for user to has method SetPassword, it is like saying "hey User, go and change your password" =) Instead of "hey PasswordManager please help me"
Restuta
+3  A: 

You may want to create a module of some sort to handle password creation for the User class to call out to. This is more compliant with the Single Responsibility Principle (a class should have only 1 responsibility, sometimes read as "only 1 reason to change").

Since your passwords should be salted and hashed before they are persisted, that's definately out of the scope of what a User should be doing. Then you could have a module separate of the User for authenticating the password using the same salt and hash method.

Andy_Vulhop
Would you recommend a `SetPassword(string password)` on the User that *calls* the "PasswordManager"?
TheCloudlessSky
That's precisely what I would do. Make an IPasswordManager and inject the dependency, though. Don't go new-ing up your own PasswordManager inside the User. You want to keep a loose coupling between the User and the PasswordManager.
Andy_Vulhop
Cool thanks, I like this idea.
TheCloudlessSky
A: 

You could introduce a Password class. The Password property on the User class should be of type Password, instead of string.

public class User
{
  public Password Password { get; set; }
}

public class Password
{
  private string value;
  private string salt;

  public Password(string value)
  {
    this.salt = "generated salt";
    this.value = value;
  }

  public string ToHashedString()
  {
    // Return the hashed password.
  }
}

The Password class could be responsible for generating the salt itself. You can also introduce a PasswordService that uses other dependencies to generate the salt and construct a Password instance.

Niels van der Rest