package de.tud.kom.socom.web.client.login;
import java.util.Date;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import de.tud.kom.socom.web.client.AppController;
import de.tud.kom.socom.web.client.eventhandler.LoginEventHandler;
import de.tud.kom.socom.web.client.events.CommunicationFailureEvent;
import de.tud.kom.socom.web.client.events.LoginErrorNetworkUserNotFoundEvent;
import de.tud.kom.socom.web.client.events.LoginErrorWrongUserIDPasswortEvent;
import de.tud.kom.socom.web.client.events.LoginEvent;
import de.tud.kom.socom.web.client.events.LoginSuccessEvent;
import de.tud.kom.socom.web.client.events.LogoutEvent;
import de.tud.kom.socom.web.client.sharedmodels.LoginResult;
import de.tud.kom.socom.web.client.util.RequestInformation;
/**
* central class handling the cookie management and RequestInformation update
*
* @author jkonert
*
*/
public class LoginManager implements LoginEventHandler {
private RequestInformation requestInformation;
private HandlerManager eventBus;
private AppController appController;
private NetworkLoginManager networkLoginManager; // lazy loading..
public LoginManager(AppController appController) {
this.appController = appController;
this.eventBus = appController.getEventHandler();
this.eventBus.addHandler(LoginEvent.TYPE, this);
}
public void login(String username, String pw) {
appController.getRPCFactory().getLoginService().login(username, pw, new AsyncCallback<LoginResult>() {
@Override
public void onFailure(Throwable caught) {
Window.alert("Error: " + caught.getMessage());
}
@Override
public void onSuccess(LoginResult result) {
String sid = result.getSid();
if(sid == null) {
storeLoginInformation(new LoginResult(false), true, true);
return;
}
setSessionCookie(sid);
storeLoginInformation(result, true, true);
}
});
}
public void checkIfLoggedIn(RequestInformation rq)
{
this.requestInformation = rq;
String sid = getSessionID();
setSessionCookie(sid);
appController.getRPCFactory().getLoginService().isLoggedIn(sid, new AsyncCallback<LoginResult>() {
@Override
public void onFailure(Throwable caught) {
Window.alert(caught.toString());
eventBus.fireEvent(new CommunicationFailureEvent(caught));
}
@Override
public void onSuccess(LoginResult result) {
storeLoginInformation(result, true, false);
}
});
}
public void setSessionCookie(String sid) {
final long DURATION = 1000 * 60 * 60 * 24 * 14; //duration remembering login. 2 weeks
Date expires = new Date(System.currentTimeMillis() + DURATION);
Cookies.setCookie("sid", sid, expires);
}
/**
* @return sessionid or null if it doesnt exist
*/
public String getSessionID()
{
// FIXME RH: manage this cookie consistent with login/logout events. means: delete it when logout. re-set it when logged in. (JK)
// FIXME don't we need a setSessionID() method as well here? encapsulated in LoginManager?
return Cookies.getCookie("sid");
}
public void logout() {
if (!requestInformation.isLoggedIn())
return;
String sid = getSessionID();
Cookies.removeCookie("sid");
appController.getRPCFactory().getLoginService().logout(sid,new AsyncCallback<Boolean>() {
@Override
public void onFailure(Throwable caught) {
eventBus.fireEvent(new CommunicationFailureEvent(caught));
}
@Override
public void onSuccess(Boolean result) {
eventBus.fireEvent(new LogoutEvent());
}
});
}
/**
* new method to only save user information
*/
public void storeLoginInformation(LoginResult result, boolean fireSuccessEvent, boolean fireFailureEvent){
if(result.isSuccess() && !result.isDeleted()){
// TODO: Each login sets the user online for a short period of
// time
// --> realize by a timestamp in table to user "lastTimeOnline"
// . Each display checks if currentTime-lastTimeOnline <
// PERIOD_ONLINE
// should be automatically done in API on every user-related
// call
requestInformation.setUserID(result.getUid());
requestInformation.setUserName(result.getUsername());
requestInformation.setUserIsAdmin(result.isAdmin());
if(fireSuccessEvent) eventBus.fireEvent(new LoginSuccessEvent(result.getUid()));
}
else
{
if(fireFailureEvent)
{
Window.alert("Error logging in. Username or Password incorrect.");
eventBus.fireEvent(new LoginErrorWrongUserIDPasswortEvent());
}
}
}
public NetworkLoginManager getNetworkLoginManager() {
if (this.networkLoginManager == null) {
this.networkLoginManager = new NetworkLoginManager(appController);
}
return this.networkLoginManager;
}
@Override
public void onLoginSuccessEvent(LoginEvent event) {
// caused by myself. ignore.
// cookie setting etc. could be of course done here, but as we already
// have some admin information that is not in
// the event, it is done above on Async result directly.
}
@Override
public void onLogoutEvent(LogoutEvent event) {
requestInformation.clearUserInformation();
}
@Override
public void onLoginErrorNetworkUserNotFound(LoginErrorNetworkUserNotFoundEvent loginErrorNetworkUserNotFound) {
// ignore
}
@Override
public void onLoginErrorWrongUserIDPasswortEvent(LoginErrorWrongUserIDPasswortEvent loginErrorWrongUserIDPasswortEvent) {
// ignore
}
@Override
public void onLoginNetworkSuccessEvent(LoginEvent event) {
// ignore
}
}