package models;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import org.apache.commons.lang3.StringUtils;
import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.core.security.authentication.CryptedSimpleCredentials;
import org.jcrom.JcrMappingException;
import org.jcrom.Jcrom;
import org.jcrom.dao.AbstractJcrDAO;
import play.Logger;
public class UserDAO extends AbstractJcrDAO<User> {
public static final String USER_PATH = "/user";
public final JackrabbitSession session;
public UserDAO(Session session, Jcrom jcrom) {
super(User.class, session, jcrom);
this.session = (JackrabbitSession) session;
}
public User get(CacheableUser cachedUser) {
return loadById(cachedUser.getId());
}
@Override
public User create(User user) {
return create(getRootPath(), user);
}
@Override
public User create(final String path, final User user) {
final User createdUser = super.create(path, user);
try {
session.getUserManager().createUser(jackrabbitAuthUserId(createdUser),"");
} catch (RepositoryException e) {
throw new RuntimeException(e);
}
return createdUser;
}
public User findByEmail(String email) {
for(User u : list()) {
if(StringUtils.equalsIgnoreCase(email, u.getEmail())) {
return u;
}
}
return null;
// issue #158, the following code compares emails case sensitive
// but they are case insensitive (in practice)
// final String nodeName = User.generateNodeName(email);
// return get(USER_PATH+"/"+nodeName);
}
public List<User> list() {
return findAll(getRootPath());
}
public void delete(User user) {
remove(user.getNodePath());
}
/**
* Removes verification without changing the password.
*
* @param user User to suspend
*/
public void suspend(User user) {
user.clearVerificationToken();
user.setVerified(false);
update(user);
}
/**
* Sets account as verified without setting a password.
*
* @param user
*/
public void unsuspend(User user) {
user.setVerified(true);
update(user);
}
private String getRootPath() {
try {
if (!session.nodeExists(USER_PATH)) {
session.getRootNode().addNode(USER_PATH.substring(1));
session.save();
}
return USER_PATH;
} catch (RepositoryException e) {
throw new RuntimeException(e);
}
}
public boolean checkPassword(User user, String candidatePassword) {
// Unverified users may not log in
if (!user.isVerified())
return false;
// Otherwise, check the credentials
CryptedSimpleCredentials creds;
try {
creds = (CryptedSimpleCredentials)
jackrabbitUser(user).getCredentials();
SimpleCredentials candidate = new SimpleCredentials(
creds.getUserID(), candidatePassword.toCharArray());
return creds.matches(candidate);
} catch (RepositoryException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public void setPassword(User user, String clearPassword)
throws RepositoryException {
user.setVerified(true);
update(user);
jackrabbitUser(user).changePassword(clearPassword);
}
public org.apache.jackrabbit.api.security.user.User jackrabbitUser(User user)
throws RepositoryException {
return
(org.apache.jackrabbit.api.security.user.User)
session.getUserManager().getAuthorizable(jackrabbitAuthUserId(user));
}
private String jackrabbitAuthUserId(User user) {
return user.getJackrabbitUserId();
}
// This is relying on knowing how getJackrabbitUserId() works, which is
// probably something that should be fixed.
public User findByJackrabbitID(String userId) {
// if it's admin don't log the exception
if("admin".equals(userId)) {
return null;
}
try {
return loadById(userId);
} catch (JcrMappingException e) {
Logger.debug("Unable to find user by id: "+userId, e);
return null;
}
}
}