package eu.europeana.cloud.service.aas.authentication.repository;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.datastax.driver.core.BoundStatement;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.exceptions.NoHostAvailableException;
import com.google.common.collect.ImmutableSet;
import eu.europeana.cloud.cassandra.CassandraConnectionProvider;
import eu.europeana.cloud.common.model.IdentifierErrorInfo;
import eu.europeana.cloud.common.model.User;
import eu.europeana.cloud.service.aas.authentication.SpringUser;
import eu.europeana.cloud.service.aas.authentication.exception.DatabaseConnectionException;
import eu.europeana.cloud.service.aas.authentication.exception.UserDoesNotExistException;
import eu.europeana.cloud.service.aas.authentication.exception.UserExistsException;
import eu.europeana.cloud.service.aas.authentication.status.IdentifierErrorTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
/**
* Used to create / retrieve / update <code>User</code> objects from ecloud's
* database.
*
* @author emmanouil.koufakis@theeuropeanlibrary.org
*/
public class CassandraUserDAO {
private static final Log LOGGER = LogFactory.getLog(CassandraUserDAO.class);
@Qualifier("dbService")
private CassandraConnectionProvider provider;
private PreparedStatement selectUserStatement;
private PreparedStatement createUserStatement;
private PreparedStatement updateUserStatement;
private PreparedStatement deleteUserStatement;
/**
* Default roles for all users of ecloud (that don't have admin, or other
* superpowers)
*/
private static Set<String> DEFAULT_USER_ROLES = ImmutableSet
.of("ROLE_USER");
/**
* Constructs a new <code>CassandraUserDAO</code>.
*
* @param provider
* the <code>Session</code> to use for connectivity with
* Cassandra.
*/
public CassandraUserDAO(final CassandraConnectionProvider provider) {
LOGGER.info("CassandraUserDAO starting...");
this.provider = provider;
prepareStatements();
LOGGER.info("CassandraUserDAO started successfully.");
}
private void prepareStatements() {
selectUserStatement = provider.getSession().prepare(
"SELECT * FROM users WHERE username = ?");
selectUserStatement.setConsistencyLevel(provider.getConsistencyLevel());
createUserStatement = provider
.getSession()
.prepare(
"INSERT INTO users(username, password, roles) VALUES (?,?,?) IF NOT EXISTS;");
createUserStatement.setConsistencyLevel(provider.getConsistencyLevel());
updateUserStatement = provider.getSession().prepare(
"UPDATE users SET password = ? WHERE username = ?;");
updateUserStatement.setConsistencyLevel(provider.getConsistencyLevel());
deleteUserStatement = provider.getSession().prepare(
"DELETE FROM users WHERE username = ?;");
deleteUserStatement.setConsistencyLevel(provider.getConsistencyLevel());
}
public SpringUser getUser(final String username)
throws DatabaseConnectionException, UserDoesNotExistException {
try {
BoundStatement boundStatement = selectUserStatement.bind(username);
ResultSet rs = provider.getSession().execute(boundStatement);
Row result = rs.one();
if (result == null) {
throw new UserDoesNotExistException(
new IdentifierErrorInfo(
IdentifierErrorTemplate.USER_DOES_NOT_EXIST
.getHttpCode(),
IdentifierErrorTemplate.USER_DOES_NOT_EXIST
.getErrorInfo(username)));
}
return mapUser(result);
} catch (NoHostAvailableException e) {
throw new DatabaseConnectionException(
new IdentifierErrorInfo(
IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR
.getHttpCode(),
IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR
.getErrorInfo(provider.getHosts(),
provider.getPort(), e.getMessage())));
}
}
public void createUser(final User user) throws DatabaseConnectionException,
UserExistsException {
try {
if (userAlreadyExistsInDB(user.getUsername())) {
throw new UserExistsException(new IdentifierErrorInfo(
IdentifierErrorTemplate.USER_EXISTS.getHttpCode(),
IdentifierErrorTemplate.USER_EXISTS.getErrorInfo(user
.getUsername())));
} else {
BoundStatement boundStatement = createUserStatement.bind(
user.getUsername(), user.getPassword(), DEFAULT_USER_ROLES);
provider.getSession().execute(boundStatement);
}
} catch (NoHostAvailableException e) {
throw new DatabaseConnectionException(
new IdentifierErrorInfo(
IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR
.getHttpCode(),
IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR
.getErrorInfo(provider.getHosts(),
provider.getPort(), e.getMessage())));
}
}
public void updateUser(final User user) throws DatabaseConnectionException,
UserDoesNotExistException {
try {
BoundStatement boundStatement = selectUserStatement.bind(user
.getUsername());
ResultSet rs = provider.getSession().execute(boundStatement);
Row result = rs.one();
if (result == null) {
throw new UserDoesNotExistException(
new IdentifierErrorInfo(
IdentifierErrorTemplate.USER_DOES_NOT_EXIST
.getHttpCode(),
IdentifierErrorTemplate.USER_DOES_NOT_EXIST
.getErrorInfo(user.getUsername())));
}
} catch (NoHostAvailableException e) {
throw new DatabaseConnectionException(
new IdentifierErrorInfo(
IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR
.getHttpCode(),
IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR
.getErrorInfo(provider.getHosts(),
provider.getPort(), e.getMessage())));
}
try {
BoundStatement boundStatement = updateUserStatement.bind(
user.getUsername(), user.getPassword());
provider.getSession().execute(boundStatement);
} catch (NoHostAvailableException e) {
throw new DatabaseConnectionException(
new IdentifierErrorInfo(
IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR
.getHttpCode(),
IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR
.getErrorInfo(provider.getHosts(),
provider.getPort(), e.getMessage())));
}
}
public void deleteUser(final String username)
throws DatabaseConnectionException, UserDoesNotExistException {
try {
BoundStatement boundStatement = selectUserStatement.bind(username);
ResultSet rs = provider.getSession().execute(boundStatement);
Row result = rs.one();
if (result == null) {
throw new UserDoesNotExistException(
new IdentifierErrorInfo(
IdentifierErrorTemplate.USER_DOES_NOT_EXIST
.getHttpCode(),
IdentifierErrorTemplate.USER_DOES_NOT_EXIST
.getErrorInfo(username)));
}
} catch (NoHostAvailableException e) {
throw new DatabaseConnectionException(
new IdentifierErrorInfo(
IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR
.getHttpCode(),
IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR
.getErrorInfo(provider.getHosts(),
provider.getPort(), e.getMessage())));
}
try {
BoundStatement boundStatement = deleteUserStatement.bind(username);
provider.getSession().execute(boundStatement);
} catch (NoHostAvailableException e) {
throw new DatabaseConnectionException(
new IdentifierErrorInfo(
IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR
.getHttpCode(),
IdentifierErrorTemplate.DATABASE_CONNECTION_ERROR
.getErrorInfo(provider.getHosts(),
provider.getPort(), e.getMessage())));
}
}
private SpringUser mapUser(final Row row) {
final String username = row.getString("username");
final String password = row.getString("password");
final Set<String> roles = row.getSet("roles", String.class);
SpringUser user = new SpringUser(username, password, roles);
return user;
}
private boolean userAlreadyExistsInDB(String userName) {
BoundStatement boundStatement = selectUserStatement.bind(userName);
ResultSet rs = provider.getSession().execute(boundStatement);
Row result = rs.one();
if (result != null) {
return true;
} else {
return false;
}
}
}