package it.unipd.netmus.server;
import it.unipd.netmus.client.service.LoginService;
import it.unipd.netmus.server.persistent.UserAccount;
import it.unipd.netmus.server.utils.BCrypt;
import it.unipd.netmus.shared.LoginDTO;
import it.unipd.netmus.shared.exception.LoginException;
import it.unipd.netmus.shared.exception.RegistrationException;
import javax.servlet.http.HttpSession;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
/**
* Nome: LoginServiceImpl.java
* Autore: VT.G
* Licenza: GNU GPL v3
* Data Creazione: 13 Febbraio 2011
*/
@SuppressWarnings("serial")
public class LoginServiceImpl extends RemoteServiceServlet implements
LoginService {
/**
* Esegue una ricerca della sessione corrente utilizzando i metodi di
* LoginHelper e ritorna, se presenti, le informazioni di base
* (UserSummaryDTO) dell’utente loggato.
*/
@Override
public String getLoggedInUser() throws LoginException {
HttpSession session = getThreadLocalRequest().getSession();
String user = LoginHelper.getLoggedInUser(session);
if (user == null) {
throw new LoginException();
}
return user;
}
/**
* Inserisce i dati di login relativi alla registrazione di un nuovo utente
* nel database. Può lanciare eccezioni di tipo <= RegistrationException in
* caso vi siano problemi nell’inserimento.
*/
@Override
public LoginDTO insertRegistration(LoginDTO login)
throws RegistrationException {
String passwordHash = BCrypt.hashpw(login.getPassword(),
BCrypt.gensalt());
// create new user in the database
try {
new UserAccount(login.getUser(), passwordHash);
} catch (Exception e) {
throw new RegistrationException();
}
return login;
}
/**
* Invalida l’autenticazione dell’utente che viene rimandato alla pagina di
* login.
*/
@Override
public String logout() {
HttpSession session = getThreadLocalRequest().getSession();
String user = (String) session.getAttribute("userLoggedIn");
session.invalidate();
return user;
}
/**
* Recupera un eventuale sessione salvata nei cookie controllandone la
* validità per l’utente dato in input. Questa funzionalità non è valida per
* gli utenti Google dei quali non viene gestito un cookie.
*/
@Override
public String restartSession(String user, String session_id)
throws LoginException {
HttpSession session = getThreadLocalRequest().getSession();
String session_id_new = session.getId();
String userLoggedIn = (String) session.getAttribute("userLoggedIn");
if (userLoggedIn != null)
// deve aggionare i cookie pero' (refresh)
return session_id_new;
else {
if (user == null || session_id == null)
// non deve fare niente sui cookie, non esistono
throw new LoginException();
// restart old session by Cookies (se soddisfa)
UserAccount userAccount = UserAccount.load(user);
if (userAccount == null)
throw new LoginException();
String session_id_old = userAccount.getLastSessionId();
if (session_id_old.equals(session_id)) {
// caricare attributi in nuova session
session.setAttribute("userLoggedIn", user);
// aggiornare il campo lastSessionId
userAccount.setLastSessionId(session_id_new);
// deve aggionare i cookie pero' (refresh)
return session_id_new;
} else {
// non c'e' sessione, ci sono cookie, ma son estranei (altra
// macchina)
throw new LoginException();
}
}
}
/**
* Racchiude tutte i passi di autenticazione dell’utente. Utilizza
* verifyLogin e si occupa di iniziare la sessione dell’utente che si è
* autenticato.
*/
@Override
public String startLogin(LoginDTO login) throws LoginException {
// find user in the database
UserAccount userAccount = verifyLogin(login);
HttpSession session = getThreadLocalRequest().getSession();
String session_id = session.getId();
// set session parameter - userID
LoginHelper.setSession(session, login.getUser());
// set in DB userAccount the new SessionID
userAccount.setLastSessionId(session_id);
return session_id;
}
/**
* Metodo fondamentale per l’autenticazione che confronta i dati in input
* con quelli presenti nel database per verificare se il login è valido. Può
* lanciare eccezioni di tipo <= LoginException in caso il controllo non
* vada a buon fine.
*/
private UserAccount verifyLogin(LoginDTO login) throws LoginException {
// find user in the database
String username = login.getUser();
if (username == null || username.equals(""))
throw new LoginException("User empty");
UserAccount userAccount = UserAccount.load(login.getUser());
if (userAccount == null) {
// user not found in the database
throw new LoginException("User don't exists");
} else {
if (BCrypt.checkpw(login.getPassword(), userAccount.getPassword())) {
// correct password
return userAccount;
} else
throw new LoginException();
}
}
}