package mireka.login;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
/**
* This class authenticates users of a {@link GlobalUsers} collection using
* different authentication algorithms corresponding to both SMTP and POP3
* protocols.
*/
public class GlobalUsersLoginSpecification implements LoginSpecification {
private final Map<Username, String> usernamePasswordMap =
new HashMap<Username, String>();
private final Map<Username, Principal> usernamePrincipalMap =
new HashMap<Username, Principal>();
@Override
public LoginResult evaluatePlain(String usernameString, String password) {
Username username = new Username(usernameString);
String actualPassword = usernamePasswordMap.get(username);
if (actualPassword == null) {
return new LoginResult(LoginDecision.USERNAME_NOT_EXISTS, null);
} else if (actualPassword.equals(password)) {
return new LoginResult(LoginDecision.VALID,
usernamePrincipalMap.get(username));
} else {
return new LoginResult(LoginDecision.PASSWORD_DOES_NOT_MATCH, null);
}
}
@Override
public LoginResult evaluateApop(String usernameString, String timestamp,
byte[] digestBytes) {
Username username = new Username(usernameString);
String password = usernamePasswordMap.get(username);
MessageDigest digest;
try {
digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("Assertion failed");
}
String text = timestamp + password;
byte[] textBytes;
try {
textBytes = text.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Assertion failed");
}
byte[] calculatedDigestBytes = digest.digest(textBytes);
boolean isValid =
MessageDigest.isEqual(digestBytes, calculatedDigestBytes);
if (isValid) {
return new LoginResult(LoginDecision.VALID,
usernamePrincipalMap.get(username));
} else {
return new LoginResult(LoginDecision.INVALID, null);
}
}
public void setUsers(GlobalUsers users) {
if (!usernamePasswordMap.isEmpty())
throw new IllegalStateException();
for (GlobalUser user : users) {
usernamePasswordMap.put(user.getUsernameObject(),
user.getPassword());
usernamePrincipalMap.put(user.getUsernameObject(), new Principal(
user.getUsernameObject().toString()));
}
}
}